summaryrefslogtreecommitdiffstats
path: root/cui/source
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /cui/source
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'cui/source')
-rw-r--r--cui/source/customize/CommandCategoryListBox.cxx581
-rw-r--r--cui/source/customize/CustomNotebookbarGenerator.cxx284
-rw-r--r--cui/source/customize/SvxConfigPageHelper.cxx471
-rw-r--r--cui/source/customize/SvxMenuConfigPage.cxx600
-rw-r--r--cui/source/customize/SvxNotebookbarConfigPage.cxx567
-rw-r--r--cui/source/customize/SvxToolbarConfigPage.cxx966
-rw-r--r--cui/source/customize/acccfg.cxx1593
-rw-r--r--cui/source/customize/cfg.cxx3201
-rw-r--r--cui/source/customize/cfgutil.cxx1195
-rw-r--r--cui/source/customize/eventdlg.cxx162
-rw-r--r--cui/source/customize/eventdlg.hxx52
-rw-r--r--cui/source/customize/macropg.cxx668
-rw-r--r--cui/source/customize/macropg_impl.hxx55
-rw-r--r--cui/source/dialogs/DiagramDialog.cxx81
-rw-r--r--cui/source/dialogs/FontFeaturesDialog.cxx227
-rw-r--r--cui/source/dialogs/QrCodeGenDialog.cxx341
-rw-r--r--cui/source/dialogs/SignSignatureLineDialog.cxx293
-rw-r--r--cui/source/dialogs/SignatureLineDialog.cxx210
-rw-r--r--cui/source/dialogs/SignatureLineDialogBase.cxx221
-rw-r--r--cui/source/dialogs/SpellAttrib.hxx118
-rw-r--r--cui/source/dialogs/SpellDialog.cxx2092
-rw-r--r--cui/source/dialogs/about.cxx260
-rw-r--r--cui/source/dialogs/colorpicker.cxx1334
-rw-r--r--cui/source/dialogs/cuicharmap.cxx1250
-rw-r--r--cui/source/dialogs/cuifmsearch.cxx754
-rw-r--r--cui/source/dialogs/cuigaldlg.cxx1011
-rw-r--r--cui/source/dialogs/cuigrfflt.cxx468
-rw-r--r--cui/source/dialogs/cuihyperdlg.cxx293
-rw-r--r--cui/source/dialogs/cuiimapwnd.cxx59
-rw-r--r--cui/source/dialogs/cuitbxform.cxx33
-rw-r--r--cui/source/dialogs/dlgname.cxx104
-rw-r--r--cui/source/dialogs/hangulhanjadlg.cxx1505
-rw-r--r--cui/source/dialogs/hldocntp.cxx479
-rw-r--r--cui/source/dialogs/hldoctp.cxx318
-rw-r--r--cui/source/dialogs/hlinettp.cxx393
-rw-r--r--cui/source/dialogs/hlmailtp.cxx228
-rw-r--r--cui/source/dialogs/hlmarkwn.cxx473
-rw-r--r--cui/source/dialogs/hltpbase.cxx545
-rw-r--r--cui/source/dialogs/hyphen.cxx471
-rw-r--r--cui/source/dialogs/iconcdlg.cxx311
-rw-r--r--cui/source/dialogs/insdlg.cxx583
-rw-r--r--cui/source/dialogs/insrc.cxx59
-rw-r--r--cui/source/dialogs/linkdlg.cxx636
-rw-r--r--cui/source/dialogs/multipat.cxx320
-rw-r--r--cui/source/dialogs/newtabledlg.cxx39
-rw-r--r--cui/source/dialogs/passwdomdlg.cxx171
-rw-r--r--cui/source/dialogs/pastedlg.cxx339
-rw-r--r--cui/source/dialogs/postdlg.cxx180
-rw-r--r--cui/source/dialogs/screenshotannotationdlg.cxx583
-rw-r--r--cui/source/dialogs/scriptdlg.cxx1351
-rw-r--r--cui/source/dialogs/sdrcelldlg.cxx62
-rw-r--r--cui/source/dialogs/showcols.cxx107
-rw-r--r--cui/source/dialogs/splitcelldlg.cxx88
-rw-r--r--cui/source/dialogs/srchxtra.cxx235
-rw-r--r--cui/source/dialogs/thesdlg.cxx343
-rw-r--r--cui/source/dialogs/tipofthedaydlg.cxx168
-rw-r--r--cui/source/dialogs/zoom.cxx406
-rw-r--r--cui/source/factory/cuiexp.cxx40
-rw-r--r--cui/source/factory/cuiresmgr.cxx28
-rw-r--r--cui/source/factory/dlgfact.cxx1699
-rw-r--r--cui/source/factory/dlgfact.hxx981
-rw-r--r--cui/source/factory/init.cxx44
-rw-r--r--cui/source/inc/CommandCategoryListBox.hxx80
-rw-r--r--cui/source/inc/CustomNotebookbarGenerator.hxx42
-rw-r--r--cui/source/inc/DiagramDialog.hxx42
-rw-r--r--cui/source/inc/FontFeaturesDialog.hxx78
-rw-r--r--cui/source/inc/QrCodeGenDialog.hxx50
-rw-r--r--cui/source/inc/SignSignatureLineDialog.hxx56
-rw-r--r--cui/source/inc/SignatureLineDialog.hxx39
-rw-r--r--cui/source/inc/SignatureLineDialogBase.hxx34
-rw-r--r--cui/source/inc/SpellDialog.hxx231
-rw-r--r--cui/source/inc/SvxConfigPageHelper.hxx89
-rw-r--r--cui/source/inc/SvxMenuConfigPage.hxx72
-rw-r--r--cui/source/inc/SvxNotebookbarConfigPage.hxx87
-rw-r--r--cui/source/inc/SvxToolbarConfigPage.hxx90
-rw-r--r--cui/source/inc/about.hxx62
-rw-r--r--cui/source/inc/acccfg.hxx155
-rw-r--r--cui/source/inc/align.hxx122
-rw-r--r--cui/source/inc/autocdlg.hxx417
-rw-r--r--cui/source/inc/backgrnd.hxx70
-rw-r--r--cui/source/inc/bbdlg.hxx44
-rw-r--r--cui/source/inc/border.hxx194
-rw-r--r--cui/source/inc/cfg.hxx673
-rw-r--r--cui/source/inc/cfgutil.hxx269
-rw-r--r--cui/source/inc/chardlg.hxx343
-rw-r--r--cui/source/inc/colorpicker.hxx47
-rw-r--r--cui/source/inc/connect.hxx86
-rw-r--r--cui/source/inc/cuifmsearch.hxx173
-rw-r--r--cui/source/inc/cuigaldlg.hxx277
-rw-r--r--cui/source/inc/cuigrfflt.hxx183
-rw-r--r--cui/source/inc/cuihyperdlg.hxx140
-rw-r--r--cui/source/inc/cuiimapwnd.hxx50
-rw-r--r--cui/source/inc/cuioptgenrl.hxx75
-rw-r--r--cui/source/inc/cuisrchdlg.hxx44
-rw-r--r--cui/source/inc/cuitabarea.hxx739
-rw-r--r--cui/source/inc/cuitabline.hxx378
-rw-r--r--cui/source/inc/cuitbxform.hxx38
-rw-r--r--cui/source/inc/dbregister.hxx112
-rw-r--r--cui/source/inc/defdlgname.hxx30
-rw-r--r--cui/source/inc/dialmgr.hxx26
-rw-r--r--cui/source/inc/dlgname.hxx125
-rw-r--r--cui/source/inc/dstribut.hxx72
-rw-r--r--cui/source/inc/grfpage.hxx109
-rw-r--r--cui/source/inc/hangulhanjadlg.hxx305
-rw-r--r--cui/source/inc/headertablistbox.hxx42
-rw-r--r--cui/source/inc/helpids.h46
-rw-r--r--cui/source/inc/hldocntp.hxx64
-rw-r--r--cui/source/inc/hldoctp.hxx76
-rw-r--r--cui/source/inc/hlinettp.hxx91
-rw-r--r--cui/source/inc/hlmailtp.hxx65
-rw-r--r--cui/source/inc/hlmarkwn.hxx72
-rw-r--r--cui/source/inc/hlmarkwn_def.hxx29
-rw-r--r--cui/source/inc/hltpbase.hxx138
-rw-r--r--cui/source/inc/hyphen.hxx88
-rw-r--r--cui/source/inc/iconcdlg.hxx84
-rw-r--r--cui/source/inc/insdlg.hxx117
-rw-r--r--cui/source/inc/insrc.hxx44
-rw-r--r--cui/source/inc/labdlg.hxx119
-rw-r--r--cui/source/inc/linkdlg.hxx85
-rw-r--r--cui/source/inc/macroass.hxx92
-rw-r--r--cui/source/inc/macropg.hxx131
-rw-r--r--cui/source/inc/measure.hxx98
-rw-r--r--cui/source/inc/multipat.hxx80
-rw-r--r--cui/source/inc/newtabledlg.hxx75
-rw-r--r--cui/source/inc/numfmt.hxx157
-rw-r--r--cui/source/inc/numpages.hxx388
-rw-r--r--cui/source/inc/optasian.hxx61
-rw-r--r--cui/source/inc/optdict.hxx112
-rw-r--r--cui/source/inc/optlingu.hxx152
-rw-r--r--cui/source/inc/optpath.hxx71
-rw-r--r--cui/source/inc/page.hxx185
-rw-r--r--cui/source/inc/paragrph.hxx304
-rw-r--r--cui/source/inc/passwdomdlg.hxx71
-rw-r--r--cui/source/inc/pastedlg.hxx76
-rw-r--r--cui/source/inc/postdlg.hxx103
-rw-r--r--cui/source/inc/screenshotannotationdlg.hxx42
-rw-r--r--cui/source/inc/scriptdlg.hxx171
-rw-r--r--cui/source/inc/sdrcelldlg.hxx49
-rw-r--r--cui/source/inc/showcols.hxx48
-rw-r--r--cui/source/inc/splitcelldlg.hxx51
-rw-r--r--cui/source/inc/srchxtra.hxx84
-rw-r--r--cui/source/inc/swpossizetabpage.hxx133
-rw-r--r--cui/source/inc/tabstpge.hxx149
-rw-r--r--cui/source/inc/textanim.hxx108
-rw-r--r--cui/source/inc/textattr.hxx95
-rw-r--r--cui/source/inc/thesdlg.hxx82
-rw-r--r--cui/source/inc/tipofthedaydlg.hxx48
-rw-r--r--cui/source/inc/transfrm.hxx251
-rw-r--r--cui/source/inc/treeopt.hxx238
-rw-r--r--cui/source/inc/zoom.hxx70
-rw-r--r--cui/source/options/certpath.cxx240
-rw-r--r--cui/source/options/certpath.hxx39
-rw-r--r--cui/source/options/cfgchart.cxx279
-rw-r--r--cui/source/options/cfgchart.hxx100
-rw-r--r--cui/source/options/connpoolconfig.cxx196
-rw-r--r--cui/source/options/connpoolconfig.hxx38
-rw-r--r--cui/source/options/connpooloptions.cxx261
-rw-r--r--cui/source/options/connpooloptions.hxx71
-rw-r--r--cui/source/options/connpoolsettings.cxx82
-rw-r--r--cui/source/options/connpoolsettings.hxx86
-rw-r--r--cui/source/options/cuisrchdlg.cxx50
-rw-r--r--cui/source/options/dbregister.cxx304
-rw-r--r--cui/source/options/dbregisterednamesconfig.cxx122
-rw-r--r--cui/source/options/dbregisterednamesconfig.hxx38
-rw-r--r--cui/source/options/dbregistersettings.cxx55
-rw-r--r--cui/source/options/dbregistersettings.hxx79
-rw-r--r--cui/source/options/doclinkdialog.cxx199
-rw-r--r--cui/source/options/doclinkdialog.hxx61
-rw-r--r--cui/source/options/fontsubs.cxx415
-rw-r--r--cui/source/options/fontsubs.hxx61
-rw-r--r--cui/source/options/optaboutconfig.cxx932
-rw-r--r--cui/source/options/optaboutconfig.hxx95
-rw-r--r--cui/source/options/optaccessibility.cxx111
-rw-r--r--cui/source/options/optaccessibility.hxx42
-rw-r--r--cui/source/options/optasian.cxx384
-rw-r--r--cui/source/options/optbasic.cxx131
-rw-r--r--cui/source/options/optbasic.hxx50
-rw-r--r--cui/source/options/optchart.cxx275
-rw-r--r--cui/source/options/optchart.hxx82
-rw-r--r--cui/source/options/optcolor.cxx888
-rw-r--r--cui/source/options/optcolor.hxx63
-rw-r--r--cui/source/options/optctl.cxx146
-rw-r--r--cui/source/options/optctl.hxx48
-rw-r--r--cui/source/options/optdict.cxx773
-rw-r--r--cui/source/options/optfltr.cxx344
-rw-r--r--cui/source/options/optfltr.hxx83
-rw-r--r--cui/source/options/optgdlg.cxx1897
-rw-r--r--cui/source/options/optgdlg.hxx185
-rw-r--r--cui/source/options/optgenrl.cxx508
-rw-r--r--cui/source/options/opthtml.cxx164
-rw-r--r--cui/source/options/opthtml.hxx63
-rw-r--r--cui/source/options/optinet2.cxx936
-rw-r--r--cui/source/options/optinet2.hxx163
-rw-r--r--cui/source/options/optjava.cxx941
-rw-r--r--cui/source/options/optjava.hxx206
-rw-r--r--cui/source/options/optjsearch.cxx358
-rw-r--r--cui/source/options/optjsearch.hxx71
-rw-r--r--cui/source/options/optlingu.cxx1971
-rw-r--r--cui/source/options/optopencl.cxx88
-rw-r--r--cui/source/options/optopencl.hxx42
-rw-r--r--cui/source/options/optpath.cxx686
-rw-r--r--cui/source/options/optsave.cxx619
-rw-r--r--cui/source/options/optsave.hxx78
-rw-r--r--cui/source/options/optupdt.cxx396
-rw-r--r--cui/source/options/optupdt.hxx72
-rw-r--r--cui/source/options/personalization.cxx177
-rw-r--r--cui/source/options/personalization.hxx65
-rw-r--r--cui/source/options/sdbcdriverenum.cxx98
-rw-r--r--cui/source/options/sdbcdriverenum.hxx54
-rw-r--r--cui/source/options/securityoptions.cxx82
-rw-r--r--cui/source/options/securityoptions.hxx63
-rw-r--r--cui/source/options/treeopt.cxx2104
-rw-r--r--cui/source/options/tsaurls.cxx126
-rw-r--r--cui/source/options/tsaurls.hxx44
-rw-r--r--cui/source/options/webconninfo.cxx227
-rw-r--r--cui/source/options/webconninfo.hxx54
-rw-r--r--cui/source/tabpages/align.cxx774
-rw-r--r--cui/source/tabpages/autocdlg.cxx2355
-rw-r--r--cui/source/tabpages/backgrnd.cxx343
-rw-r--r--cui/source/tabpages/bbdlg.cxx90
-rw-r--r--cui/source/tabpages/border.cxx1522
-rw-r--r--cui/source/tabpages/chardlg.cxx3261
-rw-r--r--cui/source/tabpages/chardlg.h29
-rw-r--r--cui/source/tabpages/connect.cxx419
-rw-r--r--cui/source/tabpages/dstribut.cxx152
-rw-r--r--cui/source/tabpages/grfpage.cxx785
-rw-r--r--cui/source/tabpages/labdlg.cxx514
-rw-r--r--cui/source/tabpages/macroass.cxx389
-rw-r--r--cui/source/tabpages/measure.cxx754
-rw-r--r--cui/source/tabpages/numfmt.cxx1767
-rw-r--r--cui/source/tabpages/numpages.cxx3354
-rw-r--r--cui/source/tabpages/page.cxx1554
-rw-r--r--cui/source/tabpages/paragrph.cxx2311
-rw-r--r--cui/source/tabpages/swpossizetabpage.cxx1891
-rw-r--r--cui/source/tabpages/tabarea.cxx248
-rw-r--r--cui/source/tabpages/tabline.cxx207
-rw-r--r--cui/source/tabpages/tabstpge.cxx667
-rw-r--r--cui/source/tabpages/textanim.cxx536
-rw-r--r--cui/source/tabpages/textattr.cxx668
-rw-r--r--cui/source/tabpages/tparea.cxx465
-rw-r--r--cui/source/tabpages/tpbitmap.cxx825
-rw-r--r--cui/source/tabpages/tpcolor.cxx747
-rw-r--r--cui/source/tabpages/tpgradnt.cxx630
-rw-r--r--cui/source/tabpages/tphatch.cxx558
-rw-r--r--cui/source/tabpages/tpline.cxx1689
-rw-r--r--cui/source/tabpages/tplnedef.cxx839
-rw-r--r--cui/source/tabpages/tplneend.cxx609
-rw-r--r--cui/source/tabpages/tppattern.cxx554
-rw-r--r--cui/source/tabpages/tpshadow.cxx495
-rw-r--r--cui/source/tabpages/tptrans.cxx524
-rw-r--r--cui/source/tabpages/transfrm.cxx1584
-rw-r--r--cui/source/uno/services.cxx41
252 files changed, 97923 insertions, 0 deletions
diff --git a/cui/source/customize/CommandCategoryListBox.cxx b/cui/source/customize/CommandCategoryListBox.cxx
new file mode 100644
index 000000000..d9e3f57b1
--- /dev/null
+++ b/cui/source/customize/CommandCategoryListBox.cxx
@@ -0,0 +1,581 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <CommandCategoryListBox.hxx>
+
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/ui/theUICategoryDescription.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+// include search util
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <tools/diagnose_ex.h>
+#include <unotools/textsearch.hxx>
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/string.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nutil/searchopt.hxx>
+#include <sal/log.hxx>
+
+#include <cfg.hxx> //for SaveInData
+
+CommandCategoryListBox::CommandCategoryListBox(std::unique_ptr<weld::ComboBox> xControl)
+ : pStylesInfo( nullptr )
+ , m_xControl(std::move(xControl))
+{
+ //Initialize search util
+ m_searchOptions.AlgorithmType2 = css::util::SearchAlgorithms2::ABSOLUTE;
+ m_searchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_searchOptions.searchFlag |= (css::util::SearchFlags::REG_NOT_BEGINOFLINE
+ | css::util::SearchFlags::REG_NOT_ENDOFLINE);
+}
+
+CommandCategoryListBox::~CommandCategoryListBox()
+{
+ ClearAll();
+}
+
+void CommandCategoryListBox::ClearAll()
+{
+ // Clear objects from m_aGroupInfo vector to avoid memory leak
+ for (const auto & It : m_aGroupInfo)
+ {
+ if ( It->nKind == SfxCfgKind::GROUP_STYLES && It->pObject )
+ {
+ SfxStyleInfo_Impl* pStyle = static_cast<SfxStyleInfo_Impl*>(It->pObject);
+ delete pStyle;
+ }
+ else if ( It->nKind == SfxCfgKind::FUNCTION_SCRIPT && It->pObject )
+ {
+ OUString* pScriptURI = static_cast<OUString*>(It->pObject);
+ delete pScriptURI;
+ }
+ else if ( It->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER && It->pObject)
+ {
+ css::uno::XInterface* xi = static_cast<css::uno::XInterface *>(It->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ m_aGroupInfo.clear();
+ m_xControl->clear();
+}
+
+void CommandCategoryListBox::Init(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName)
+{
+ // User will not see incomplete UI
+ m_xControl->freeze();
+ ClearAll();
+
+ m_xContext = xContext;
+ m_xFrame = xFrame;
+
+ m_sModuleLongName = sModuleLongName;
+ m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
+ m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
+ m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
+
+ // Support style commands
+ css::uno::Reference<css::frame::XController> xController;
+ css::uno::Reference<css::frame::XModel> xModel;
+ if (xFrame.is())
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(sModuleLongName, xModel);
+ SetStylesInfo(&m_aStylesInfo);
+
+ try
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
+
+ sal_Int32 nGroupsLength = lGroups.getLength();
+
+ if ( nGroupsLength > 0 )
+ {
+ // Add the category of "All commands"
+ m_aGroupInfo.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_ALLFUNCTIONS, 0 ) );
+ m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), CuiResId(RID_SVXSTR_ALLFUNCTIONS));
+ }
+
+ // Separate the "All commands"category from the actual categories
+ m_xControl->append_separator("");
+
+ typedef std::pair<OUString, sal_Int16> str_id;
+ std::vector<str_id> aCategories;
+
+ // Add the actual categories
+ for (sal_Int32 i = 0; i < nGroupsLength; ++i)
+ {
+ sal_Int16 nGroupID = lGroups[i];
+ OUString sGroupID = OUString::number(nGroupID);
+ OUString sGroupName;
+
+ try
+ {
+ m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
+ if (sGroupName.isEmpty())
+ continue;
+ }
+ catch(const css::container::NoSuchElementException&)
+ {
+ continue;
+ }
+ aCategories.emplace_back(std::make_pair(sGroupName, nGroupID));
+ }
+
+ auto const sort = comphelper::string::NaturalStringSorter(
+ comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetUILanguageTag().getLocale());
+
+ std::sort(aCategories.begin(), aCategories.end(),
+ [&sort](const str_id& a, const str_id& b)
+ { return sort.compare(a.first, b.first) < 0; });
+
+ // Add the actual categories
+ for (const auto &a : aCategories)
+ {
+ const OUString& rGroupName = a.first;
+ sal_Int16 nGroupID = a.second;
+ m_aGroupInfo.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_FUNCTION, nGroupID));
+ m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), rGroupName);
+ }
+
+ // Separate regular commands from styles and macros
+ m_xControl->append_separator("");
+
+ // Add macros category
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, nullptr) );
+ m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), CuiResId(RID_SVXSTR_MACROS));
+
+ // Add styles category
+ //TODO: last param should contain user data?
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) );
+ m_xControl->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), CuiResId(RID_SVXSTR_GROUP_STYLES));
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+
+ // Reveal the updated UI to user
+ m_xControl->thaw();
+ m_xControl->set_active(0);
+}
+
+void CommandCategoryListBox::FillFunctionsList(
+ const css::uno::Sequence<css::frame::DispatchInformation>& xCommands,
+ CuiConfigFunctionListBox* pFunctionListBox,
+ const OUString& filterTerm,
+ SaveInData *pCurrentSaveInData )
+{
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch( m_searchOptions );
+
+ for (const auto & rInfo : xCommands)
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rInfo.Command, m_sModuleLongName);
+
+ OUString sUIName = getCommandName(rInfo.Command);
+ OUString sLabel = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+ OUString sTooltipLabel = vcl::CommandInfoProvider::GetTooltipForCommand(rInfo.Command, aProperties, m_xFrame);
+ OUString sPopupLabel =
+ (vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties))
+ .replaceFirst("~", "");
+
+ // Apply the search filter
+ if (!filterTerm.isEmpty()
+ && !textSearch.searchForward( sUIName )
+ && !textSearch.searchForward( sLabel )
+ && !textSearch.searchForward( sTooltipLabel )
+ && !textSearch.searchForward( sPopupLabel ) )
+ {
+ continue;
+ }
+
+ css::uno::Reference<css::graphic::XGraphic> xImage;
+ if (pCurrentSaveInData)
+ xImage = pCurrentSaveInData->GetImage(rInfo.Command);
+
+ m_aGroupInfo.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
+ SfxGroupInfo_Impl* pGrpInfo = m_aGroupInfo.back().get();
+ pGrpInfo->sCommand = rInfo.Command;
+ pGrpInfo->sLabel = sUIName;
+ pGrpInfo->sTooltip = sTooltipLabel;
+ pFunctionListBox->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), sUIName, xImage);
+ }
+}
+
+OUString CommandCategoryListBox::getCommandName(const OUString& sCommand)
+{
+ OUString sUIName;
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(css::uno::Exception&)
+ { sUIName.clear(); }
+
+ // fallback for missing UINames !?
+ if (sUIName.isEmpty())
+ {
+ sUIName = sCommand;
+ }
+
+ return sUIName;
+}
+
+void CommandCategoryListBox::categorySelected(CuiConfigFunctionListBox* pFunctionListBox,
+ const OUString& filterTerm, SaveInData *pCurrentSaveInData)
+{
+ SfxGroupInfo_Impl *pInfo = reinterpret_cast<SfxGroupInfo_Impl*>(m_xControl->get_active_id().toInt64());
+ std::vector<std::unique_ptr<weld::TreeIter>> aNodesToExpand;
+ pFunctionListBox->freeze();
+ pFunctionListBox->ClearAll();
+
+ switch ( pInfo->nKind )
+ {
+ case SfxCfgKind::GROUP_ALLFUNCTIONS:
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider >
+ xProvider( m_xFrame, css::uno::UNO_QUERY );
+ sal_Int32 nEntryCount = m_xControl->get_count();
+
+ for (sal_Int32 nCurPos = 0; nCurPos < nEntryCount; ++nCurPos)
+ {
+ SfxGroupInfo_Impl *pCurrentInfo =
+ reinterpret_cast<SfxGroupInfo_Impl*>(m_xControl->get_id(nCurPos).toInt64());
+
+ if (!pCurrentInfo) //separator
+ continue;
+
+ if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
+ {
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands;
+ try
+ {
+ lCommands = xProvider->getConfigurableDispatchInformation(
+ pCurrentInfo->nUniqueID );
+ FillFunctionsList( lCommands, pFunctionListBox, filterTerm, pCurrentSaveInData );
+ }
+ catch( css::container::NoSuchElementException& )
+ {
+ }
+ }
+ }
+
+ break;
+ }
+ case SfxCfgKind::GROUP_FUNCTION:
+ {
+ sal_uInt16 nGroup = pInfo->nUniqueID;
+ css::uno::Reference< css::frame::XDispatchInformationProvider >
+ xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands =
+ xProvider->getConfigurableDispatchInformation(nGroup);
+ FillFunctionsList( lCommands, pFunctionListBox, filterTerm, pCurrentSaveInData );
+ break;
+ }
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER: //Macros
+ {
+ SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
+ // Add Scripting Framework entries
+ css::uno::Reference< css::script::browse::XBrowseNode > rootNode;
+ try
+ {
+ css::uno::Reference< css::script::browse::XBrowseNodeFactory > xFac
+ = css::script::browse::theBrowseNodeFactory::get( m_xContext );
+ rootNode.set( xFac->createView( css::script::browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
+ }
+ catch( css::uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Caught some exception whilst retrieving browse nodes from factory");
+ // TODO exception handling
+ }
+
+ if ( rootNode.is() && rootNode->hasChildNodes() )
+ {
+ //We call acquire on the XBrowseNode so that it does not
+ //get autodestructed and become invalid when accessed later.
+ rootNode->acquire();
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SCRIPTCONTAINER, 0, static_cast<void *>(rootNode.get()) ) );
+
+ // Add main macro groups
+ const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> aChildNodes = rootNode->getChildNodes();
+ for ( auto const & childGroup : aChildNodes )
+ {
+ OUString sUIName;
+ childGroup->acquire();
+
+ if ( childGroup->hasChildNodes() )
+ {
+ if ( childGroup->getName() == "user" )
+ {
+ sUIName = CuiResId( RID_SVXSTR_MYMACROS );
+ }
+ else if ( childGroup->getName() == "share" )
+ {
+ sUIName = CuiResId( RID_SVXSTR_PRODMACROS );
+ }
+ else
+ {
+ sUIName = childGroup->getName();
+ }
+
+ if (sUIName.isEmpty())
+ {
+ continue;
+ }
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_SCRIPTCONTAINER, 0 ) );
+ std::unique_ptr<weld::TreeIter> xMacroGroup(pFunctionListBox->tree_append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), sUIName));
+
+ {
+ // tdf#128010: Do not nag user asking to enable JRE: if it's disabled,
+ // simply don't show relevant entries (user chose to not use JRE)
+ css::uno::ContextLayer layer(
+ comphelper::NoEnableJavaInteractionContext());
+ //Add the children and the grand children
+ addChildren(xMacroGroup.get(), childGroup, pFunctionListBox, filterTerm,
+ pCurrentSaveInData, aNodesToExpand);
+ }
+
+ // Remove the main group if empty
+ if (!pFunctionListBox->iter_has_child(*xMacroGroup))
+ {
+ pFunctionListBox->remove(*xMacroGroup);
+ }
+ else if (!filterTerm.isEmpty())
+ {
+ aNodesToExpand.emplace_back(std::move(xMacroGroup));
+ }
+ }
+ }
+ }
+
+ break;
+ }
+ case SfxCfgKind::GROUP_STYLES:
+ {
+ const std::vector< SfxStyleInfo_Impl > lStyleFamilies = pStylesInfo->getStyleFamilies();
+
+ for ( const auto & pIt : lStyleFamilies )
+ {
+ if ( pIt.sLabel.isEmpty() )
+ {
+ continue;
+ }
+
+
+ m_aGroupInfo.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0 ) );
+ // pIt.sLabel is Name of the style family
+ std::unique_ptr<weld::TreeIter> xFuncEntry(pFunctionListBox->tree_append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), pIt.sLabel));
+
+ const std::vector< SfxStyleInfo_Impl > lStyles = pStylesInfo->getStyles(pIt.sFamily);
+
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch( m_searchOptions );
+
+ // Insert children (styles)
+ for ( const auto & pStyleIt : lStyles )
+ {
+ OUString sUIName = pStyleIt.sLabel;
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = sUIName.getLength();
+
+ // Apply the search filter
+ if (!filterTerm.isEmpty()
+ && !textSearch.SearchForward( sUIName, &aStartPos, &aEndPos ) )
+ {
+ continue;
+ }
+
+ SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(pStyleIt);
+
+ m_aGroupInfo.push_back(
+ std::make_unique<SfxGroupInfo_Impl>(
+ SfxCfgKind::GROUP_STYLES, 0, pStyle ) );
+
+ m_aGroupInfo.back()->sCommand = pStyle->sCommand;
+ m_aGroupInfo.back()->sLabel = pStyle->sLabel;
+
+ pFunctionListBox->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), sUIName, xFuncEntry.get());
+ }
+
+ // Remove the style group from the list if no children
+ if (!pFunctionListBox->iter_has_child(*xFuncEntry))
+ {
+ pFunctionListBox->remove(*xFuncEntry);
+ }
+ else if (!filterTerm.isEmpty())
+ {
+ aNodesToExpand.emplace_back(std::move(xFuncEntry));
+ }
+ }
+
+ break;
+ }
+ default:
+ // Do nothing, the list box will stay empty
+ SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
+ break;
+ }
+
+ pFunctionListBox->thaw();
+
+ if (pFunctionListBox->n_children())
+ pFunctionListBox->select(0);
+
+ //post freeze
+ for (const auto& it : aNodesToExpand)
+ pFunctionListBox->expand_row(*it);
+}
+
+void CommandCategoryListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
+{
+ pStylesInfo = pStyles;
+}
+
+void CommandCategoryListBox::addChildren(
+ const weld::TreeIter* parentEntry, const css::uno::Reference< css::script::browse::XBrowseNode > &parentNode,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString& filterTerm , SaveInData *pCurrentSaveInData,
+ std::vector<std::unique_ptr<weld::TreeIter>> &rNodesToExpand)
+{
+ // Setup search filter parameters
+ m_searchOptions.searchString = filterTerm;
+ utl::TextSearch textSearch( m_searchOptions );
+
+ const css::uno::Sequence<css::uno::Reference<css::script::browse::XBrowseNode>> aChildNodes = parentNode->getChildNodes();
+ for (auto const & child : aChildNodes)
+ {
+ // Acquire to prevent auto-destruction
+ child->acquire();
+
+ if (child->hasChildNodes())
+ {
+ OUString sUIName = child->getName();
+
+ m_aGroupInfo.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
+ 0, static_cast<void *>( child.get())));
+ std::unique_ptr<weld::TreeIter> xNewEntry(pFunctionListBox->tree_append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), sUIName, parentEntry));
+
+ addChildren(xNewEntry.get(), child, pFunctionListBox, filterTerm, pCurrentSaveInData, rNodesToExpand);
+
+ // Remove the group if empty
+ if (!pFunctionListBox->iter_has_child(*xNewEntry))
+ pFunctionListBox->remove(*xNewEntry);
+ else
+ rNodesToExpand.emplace_back(std::move(xNewEntry));
+ }
+ else if ( child->getType() == css::script::browse::BrowseNodeTypes::SCRIPT )
+ {
+ // Prepare for filtering
+ OUString sUIName = child->getName();
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = sUIName.getLength();
+
+ // Apply the search filter
+ if (!filterTerm.isEmpty()
+ && !textSearch.SearchForward( sUIName, &aStartPos, &aEndPos ) )
+ {
+ continue;
+ }
+
+ OUString uri, description;
+
+ css::uno::Reference < css::beans::XPropertySet >xPropSet( child, css::uno::UNO_QUERY );
+
+ if (!xPropSet.is())
+ {
+ continue;
+ }
+
+ css::uno::Any value = xPropSet->getPropertyValue("URI");
+ value >>= uri;
+
+ try
+ {
+ value = xPropSet->getPropertyValue("Description");
+ value >>= description;
+ }
+ catch (css::uno::Exception &) {
+ // do nothing, the description will be empty
+ }
+
+ if (description.isEmpty())
+ {
+ description = CuiResId( RID_SVXSTR_NOMACRODESC );
+ }
+
+ OUString* pScriptURI = new OUString( uri );
+
+ css::uno::Reference<css::graphic::XGraphic> xImage;
+ if (pCurrentSaveInData)
+ xImage = pCurrentSaveInData->GetImage(uri);
+
+ m_aGroupInfo.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
+ m_aGroupInfo.back()->sCommand = uri;
+ m_aGroupInfo.back()->sLabel = sUIName;
+ m_aGroupInfo.back()->sHelpText = description;
+ pFunctionListBox->append(OUString::number(reinterpret_cast<sal_Int64>(m_aGroupInfo.back().get())), sUIName, xImage, parentEntry);
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/customize/CustomNotebookbarGenerator.cxx b/cui/source/customize/CustomNotebookbarGenerator.cxx
new file mode 100644
index 000000000..893108495
--- /dev/null
+++ b/cui/source/customize/CustomNotebookbarGenerator.cxx
@@ -0,0 +1,284 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/processfactory.hxx>
+#include <rtl/bootstrap.hxx>
+#include <config_folders.h>
+#include <CustomNotebookbarGenerator.hxx>
+#include <osl/file.hxx>
+#include <osl/thread.h>
+#include <vcl/builder.hxx>
+#include <vcl/EnumContext.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <unotools/confignode.hxx>
+#include <libxml/parser.h>
+
+#define aUIPropertiesCount 3
+
+using namespace css;
+
+CustomNotebookbarGenerator::CustomNotebookbarGenerator() {}
+
+static OUString lcl_activeAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "ActiveWriter";
+ break;
+ case vcl::EnumContext::Application::Calc:
+ return "ActiveCalc";
+ break;
+ case vcl::EnumContext::Application::Impress:
+ return "ActiveImpress";
+ break;
+ case vcl::EnumContext::Application::Draw:
+ return "ActiveDraw";
+ break;
+ default:
+ return OUString();
+ break;
+ }
+}
+
+static OUString lcl_getAppName(vcl::EnumContext::Application eApp)
+{
+ switch (eApp)
+ {
+ case vcl::EnumContext::Application::Writer:
+ return "Writer";
+ break;
+ case vcl::EnumContext::Application::Calc:
+ return "Calc";
+ break;
+ case vcl::EnumContext::Application::Impress:
+ return "Impress";
+ break;
+ case vcl::EnumContext::Application::Draw:
+ return "Draw";
+ break;
+ default:
+ return OUString();
+ break;
+ }
+}
+
+static OUString getAppNameRegistryPath()
+{
+ vcl::EnumContext::Application eApp = vcl::EnumContext::Application::Any;
+ const Reference<frame::XFrame>& xFrame
+ = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager
+ = frame::ModuleManager::create(::comphelper::getProcessComponentContext());
+ eApp = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+
+ OUString sAppName(lcl_getAppName(eApp));
+ return "org.openoffice.Office.UI.ToolbarMode/Applications/" + sAppName;
+}
+
+static OUString customizedUIPathBuffer()
+{
+ OUString sDirPath("${$BRAND_BASE_DIR/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE(
+ "bootstrap") ":UserInstallation}/user/config/soffice.cfg/");
+ rtl::Bootstrap::expandMacros(sDirPath);
+ return sDirPath;
+}
+
+OUString CustomNotebookbarGenerator::getCustomizedUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+OUString CustomNotebookbarGenerator::getOriginalUIPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ return VclBuilderContainer::getUIRootDir() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/"
+ + sNotebookbarUIFileName;
+}
+
+static OUString getUIDirPath()
+{
+ OUString sAppName, sNotebookbarUIFileName;
+ CustomNotebookbarGenerator::getFileNameAndAppName(sAppName, sNotebookbarUIFileName);
+ OUString sUIDirPath
+ = customizedUIPathBuffer() + "modules/s" + sAppName.toAsciiLowerCase() + "/ui/";
+ return sUIDirPath;
+}
+
+OString CustomNotebookbarGenerator::getSystemPath(OUString const& sURL)
+{
+ if (sURL.isEmpty())
+ return OString();
+ OUString sSystemPathSettings;
+ if (osl_getSystemPathFromFileURL(sURL.pData, &sSystemPathSettings.pData) != osl_File_E_None)
+ {
+ SAL_WARN("cui.customnotebookbar", "Cannot get system path for :" << sURL);
+ return OString();
+ }
+ OString osSystemPathSettings
+ = OUStringToOString(sSystemPathSettings, osl_getThreadTextEncoding());
+ return osSystemPathSettings;
+}
+
+static void changeNodeValue(xmlNode* pNodePtr, const char* pProperty, const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pProperty))))
+ xmlNodeSetContent(pNodePtr, reinterpret_cast<const xmlChar*>(pValue));
+ xmlFree(UriValue);
+ break;
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static void searchNodeAndAttribute(xmlNode* pNodePtr, const char* pUIItemID, const char* pProperty,
+ const char* pValue)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (pNodePtr->type == XML_ELEMENT_NODE)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("object"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>(pUIItemID))))
+ changeNodeValue(pNodePtr, pProperty, pValue);
+ xmlFree(UriValue);
+ }
+ searchNodeAndAttribute(pNodePtr, pUIItemID, pProperty, pValue);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+static xmlDocPtr notebookbarXMLParser(const OString& rDocName, const OString& rUIItemID,
+ const OString& rProperty, const OString& rValue)
+{
+ xmlDocPtr pDocPtr = xmlParseFile(rDocName.getStr());
+ xmlNodePtr pNodePtr = xmlDocGetRootElement(pDocPtr);
+ searchNodeAndAttribute(pNodePtr, rUIItemID.getStr(), rProperty.getStr(), rValue.getStr());
+ return pDocPtr;
+}
+
+void CustomNotebookbarGenerator::modifyCustomizedUIFile(const Sequence<OUString>& sUIItemProperties)
+{
+ OString sCustomizedUIPath = getSystemPath(getCustomizedUIPath());
+ for (auto const& aValue : sUIItemProperties)
+ {
+ std::vector<OString> aProperties(aUIPropertiesCount);
+ for (sal_Int32 aIndex = 0; aIndex < aUIPropertiesCount; aIndex++)
+ {
+ sal_Int32 nPos = aIndex;
+ OUString sToken = aValue.getToken(nPos, ',', nPos);
+ aProperties[aIndex] = OUStringToOString(sToken, RTL_TEXTENCODING_UTF8);
+ }
+ xmlDocPtr doc = notebookbarXMLParser(sCustomizedUIPath, aProperties[0], aProperties[1],
+ aProperties[2]);
+
+ if (doc != nullptr)
+ {
+ xmlSaveFormatFile(sCustomizedUIPath.getStr(), doc, 1);
+ xmlFreeDoc(doc);
+ }
+ }
+}
+
+void CustomNotebookbarGenerator::getFileNameAndAppName(OUString& sAppName,
+ OUString& sNotebookbarUIFileName)
+{
+ SfxViewFrame* pFrame = SfxViewFrame::Current();
+ if (!pFrame)
+ return;
+
+ const auto xContext = comphelper::getProcessComponentContext();
+ utl::OConfigurationTreeRoot aRoot(xContext, "org.openoffice.Office.UI.ToolbarMode/", false);
+ const Reference<frame::XFrame>& xFrame = pFrame->GetFrame().GetFrameInterface();
+ const Reference<frame::XModuleManager> xModuleManager = frame::ModuleManager::create(xContext);
+
+ vcl::EnumContext::Application eApp
+ = vcl::EnumContext::GetApplicationEnum(xModuleManager->identify(xFrame));
+ OUString sActiveAppName(lcl_activeAppName(eApp));
+ sAppName = lcl_getAppName(eApp);
+ const Any aValue = aRoot.getNodeValue(sActiveAppName);
+ aValue >>= sNotebookbarUIFileName;
+}
+
+void CustomNotebookbarGenerator::createCustomizedUIFile()
+{
+ OUString sUserUIDir = getUIDirPath();
+ OUString sOriginalUIPath = getOriginalUIPath();
+ OUString sCustomizedUIPath = getCustomizedUIPath();
+
+ sal_uInt32 nflag = osl_File_OpenFlag_Read | osl_File_OpenFlag_Write;
+ osl::Directory aDirectory(sUserUIDir);
+ if (aDirectory.open() != osl::FileBase::E_None)
+ osl::Directory::create(sUserUIDir, nflag);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot create the directory or directory was present :" << sUserUIDir);
+
+ osl::File aFile(sCustomizedUIPath);
+ if (aFile.open(nflag) != osl::FileBase::E_None)
+ osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
+ else
+ SAL_WARN("cui.customnotebookbar",
+ "Cannot copy the file or file was present :" << sCustomizedUIPath);
+}
+
+Sequence<OUString> CustomNotebookbarGenerator::getCustomizedUIItem(OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ false);
+
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+ const Any aValue = aModeNode.getNodeValue("UIItemProperties");
+ Sequence<OUString> aValues;
+ aValue >>= aValues;
+ return aValues;
+}
+
+void CustomNotebookbarGenerator::setCustomizedUIItem(Sequence<OUString> sUIItemProperties,
+ OUString sNotebookbarConfigType)
+{
+ OUString aPath = getAppNameRegistryPath();
+ const utl::OConfigurationTreeRoot aAppNode(::comphelper::getProcessComponentContext(), aPath,
+ true);
+ const utl::OConfigurationNode aModesNode = aAppNode.openNode("Modes");
+ const utl::OConfigurationNode aModeNode(aModesNode.openNode(sNotebookbarConfigType));
+
+ css::uno::Any aUIItemProperties(makeAny(sUIItemProperties));
+ aModeNode.setNodeValue("UIItemProperties", aUIItemProperties);
+ aAppNode.commit();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxConfigPageHelper.cxx b/cui/source/customize/SvxConfigPageHelper.cxx
new file mode 100644
index 000000000..3ac1ca9e4
--- /dev/null
+++ b/cui/source/customize/SvxConfigPageHelper.cxx
@@ -0,0 +1,471 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <SvxConfigPageHelper.hxx>
+
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+
+#include <comphelper/random.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svtools/imgdef.hxx>
+#include <svtools/miscopt.hxx>
+
+static sal_Int16 theImageType =
+ css::ui::ImageType::COLOR_NORMAL |
+ css::ui::ImageType::SIZE_DEFAULT;
+
+void SvxConfigPageHelper::RemoveEntry( SvxEntries* pEntries, SvxConfigEntry const * pChildEntry )
+{
+ SvxEntries::iterator iter = pEntries->begin();
+
+ while ( iter != pEntries->end() )
+ {
+ if ( pChildEntry == *iter )
+ {
+ pEntries->erase( iter );
+ break;
+ }
+ ++iter;
+ }
+}
+
+OUString SvxConfigPageHelper::replaceSaveInName( const OUString& rMessage, const OUString& rSaveInName )
+{
+ const OUString placeholder("%SAVE IN SELECTION%" );
+
+ OUString name = rMessage.replaceFirst(placeholder, rSaveInName);
+
+ return name;
+}
+
+OUString SvxConfigPageHelper::stripHotKey( const OUString& str )
+{
+ return str.replaceFirst("~", "");
+}
+
+OUString SvxConfigPageHelper::replaceSixteen( const OUString& str, sal_Int32 nReplacement )
+{
+ return str.replaceAll( OUString::number( 16 ), OUString::number( nReplacement ));
+}
+
+sal_Int16 SvxConfigPageHelper::GetImageType()
+{
+ return theImageType;
+}
+
+void SvxConfigPageHelper::InitImageType()
+{
+ theImageType =
+ css::ui::ImageType::COLOR_NORMAL |
+ css::ui::ImageType::SIZE_DEFAULT;
+
+ if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
+ {
+ theImageType |= css::ui::ImageType::SIZE_LARGE;
+ }
+ else if (SvtMiscOptions().GetCurrentSymbolsSize() == SFX_SYMBOLS_SIZE_32)
+ {
+ theImageType |= css::ui::ImageType::SIZE_32;
+ }
+}
+
+css::uno::Reference< css::graphic::XGraphic > SvxConfigPageHelper::GetGraphic(
+ const css::uno::Reference< css::ui::XImageManager >& xImageManager,
+ const OUString& rCommandURL )
+{
+ css::uno::Reference< css::graphic::XGraphic > result;
+
+ if ( xImageManager.is() )
+ {
+ // TODO handle large graphics
+ css::uno::Sequence< css::uno::Reference< css::graphic::XGraphic > > aGraphicSeq;
+
+ css::uno::Sequence<OUString> aImageCmdSeq { rCommandURL };
+
+ try
+ {
+ aGraphicSeq =
+ xImageManager->getImages( GetImageType(), aImageCmdSeq );
+
+ if ( aGraphicSeq.hasElements() )
+ {
+ result = aGraphicSeq[0];
+ }
+ }
+ catch ( css::uno::Exception& )
+ {
+ // will return empty XGraphic
+ }
+ }
+
+ return result;
+}
+
+OUString
+SvxConfigPageHelper::generateCustomName(
+ const OUString& prefix,
+ SvxEntries* entries,
+ sal_Int32 suffix /*= 1*/ )
+{
+ OUString name;
+ sal_Int32 pos = 0;
+
+ // find and replace the %n placeholder in the prefix string
+ name = prefix.replaceFirst( "%n", OUString::number( suffix ), &pos );
+
+ if ( pos == -1 )
+ {
+ // no placeholder found so just append the suffix
+ name += OUString::number( suffix );
+ }
+
+ if (!entries)
+ return name;
+
+ // now check if there is an already existing entry with this name
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if ( name.equals(entry->GetName()) )
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // name already exists so try the next number up
+ return generateCustomName( prefix, entries, ++suffix );
+ }
+
+ return name;
+}
+
+OUString SvxConfigPageHelper::generateCustomMenuURL(
+ SvxEntries* entries,
+ sal_Int32 suffix /*= 1*/ )
+{
+ OUString url = "vnd.openoffice.org:CustomMenu" + OUString::number( suffix );
+ if (!entries)
+ return url;
+
+ // now check is there is an already existing entry with this url
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if ( url.equals(entry->GetCommand()) )
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // url already exists so try the next number up
+ return generateCustomMenuURL( entries, ++suffix );
+ }
+
+ return url;
+}
+
+sal_uInt32 SvxConfigPageHelper::generateRandomValue()
+{
+ return comphelper::rng::uniform_uint_distribution(0, std::numeric_limits<unsigned int>::max());
+}
+
+OUString SvxConfigPageHelper::generateCustomURL( SvxEntries* entries )
+{
+ OUString url = OUStringLiteral(ITEM_TOOLBAR_URL) + CUSTOM_TOOLBAR_STR +
+ // use a random number to minimize possible clash with existing custom toolbars
+ OUString::number( generateRandomValue(), 16 );
+
+ // now check is there is an already existing entry with this url
+ bool bFoundEntry = false;
+ for (auto const& entry : *entries)
+ {
+ if ( url.equals(entry->GetCommand()) )
+ {
+ bFoundEntry = true;
+ break;
+ }
+ }
+
+ if (bFoundEntry)
+ {
+ // url already exists so try the next number up
+ return generateCustomURL( entries );
+ }
+
+ return url;
+}
+
+OUString SvxConfigPageHelper::GetModuleName( const OUString& aModuleId )
+{
+ if ( aModuleId == "com.sun.star.text.TextDocument" ||
+ aModuleId == "com.sun.star.text.GlobalDocument" )
+ return "Writer";
+ else if ( aModuleId == "com.sun.star.text.WebDocument" )
+ return "Writer/Web";
+ else if ( aModuleId == "com.sun.star.drawing.DrawingDocument" )
+ return "Draw";
+ else if ( aModuleId == "com.sun.star.presentation.PresentationDocument" )
+ return "Impress";
+ else if ( aModuleId == "com.sun.star.sheet.SpreadsheetDocument" )
+ return "Calc";
+ else if ( aModuleId == "com.sun.star.script.BasicIDE" )
+ return "Basic";
+ else if ( aModuleId == "com.sun.star.formula.FormulaProperties" )
+ return "Math";
+ else if ( aModuleId == "com.sun.star.sdb.RelationDesign" )
+ return "Relation Design";
+ else if ( aModuleId == "com.sun.star.sdb.QueryDesign" )
+ return "Query Design";
+ else if ( aModuleId == "com.sun.star.sdb.TableDesign" )
+ return "Table Design";
+ else if ( aModuleId == "com.sun.star.sdb.DataSourceBrowser" )
+ return "Data Source Browser";
+ else if ( aModuleId == "com.sun.star.sdb.DatabaseDocument" )
+ return "Database";
+
+ return OUString();
+}
+
+OUString SvxConfigPageHelper::GetUIModuleName(
+ const OUString& aModuleId,
+ const css::uno::Reference< css::frame::XModuleManager2 >& rModuleManager )
+{
+ assert(rModuleManager.is());
+
+ OUString aModuleUIName;
+
+ try
+ {
+ css::uno::Any a = rModuleManager->getByName( aModuleId );
+ css::uno::Sequence< css::beans::PropertyValue > aSeq;
+
+ if ( a >>= aSeq )
+ {
+ for ( css::beans::PropertyValue const & rProp : std::as_const(aSeq) )
+ {
+ if ( rProp.Name == "ooSetupFactoryUIName" )
+ {
+ rProp.Value >>= aModuleUIName;
+ break;
+ }
+ }
+ }
+ }
+ catch ( css::uno::RuntimeException& )
+ {
+ throw;
+ }
+ catch ( css::uno::Exception& )
+ {
+ }
+
+ if ( aModuleUIName.isEmpty() )
+ aModuleUIName = GetModuleName( aModuleId );
+
+ return aModuleUIName;
+}
+
+bool SvxConfigPageHelper::GetMenuItemData(
+ const css::uno::Reference< css::container::XIndexAccess >& rItemContainer,
+ sal_Int32 nIndex,
+ OUString& rCommandURL,
+ OUString& rLabel,
+ sal_uInt16& rType,
+ sal_Int32& rStyle,
+ css::uno::Reference< css::container::XIndexAccess >& rSubMenu )
+{
+ try
+ {
+ css::uno::Sequence< css::beans::PropertyValue > aProps;
+ if ( rItemContainer->getByIndex( nIndex ) >>= aProps )
+ {
+ for ( css::beans::PropertyValue const & rProp : std::as_const(aProps) )
+ {
+ if ( rProp.Name == ITEM_DESCRIPTOR_COMMANDURL )
+ {
+ rProp.Value >>= rCommandURL;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_CONTAINER )
+ {
+ rProp.Value >>= rSubMenu;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ rProp.Value >>= rStyle;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_LABEL )
+ {
+ rProp.Value >>= rLabel;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_TYPE )
+ {
+ rProp.Value >>= rType;
+ }
+ }
+
+ return true;
+ }
+ }
+ catch ( css::lang::IndexOutOfBoundsException& )
+ {
+ }
+
+ return false;
+}
+
+bool SvxConfigPageHelper::GetToolbarItemData(
+ const css::uno::Reference< css::container::XIndexAccess >& rItemContainer,
+ sal_Int32 nIndex,
+ OUString& rCommandURL,
+ OUString& rLabel,
+ sal_uInt16& rType,
+ bool& rIsVisible,
+ sal_Int32& rStyle )
+{
+ try
+ {
+ css::uno::Sequence< css::beans::PropertyValue > aProps;
+ if ( rItemContainer->getByIndex( nIndex ) >>= aProps )
+ {
+ for ( css::beans::PropertyValue const & rProp : std::as_const(aProps) )
+ {
+ if ( rProp.Name == ITEM_DESCRIPTOR_COMMANDURL )
+ {
+ rProp.Value >>= rCommandURL;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ rProp.Value >>= rStyle;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_LABEL )
+ {
+ rProp.Value >>= rLabel;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_TYPE )
+ {
+ rProp.Value >>= rType;
+ }
+ else if ( rProp.Name == ITEM_DESCRIPTOR_ISVISIBLE )
+ {
+ rProp.Value >>= rIsVisible;
+ }
+ }
+
+ return true;
+ }
+ }
+ catch ( css::lang::IndexOutOfBoundsException& )
+ {
+ }
+
+ return false;
+}
+
+css::uno::Sequence< css::beans::PropertyValue > SvxConfigPageHelper::ConvertSvxConfigEntry(
+ const SvxConfigEntry* pEntry )
+{
+ css::uno::Sequence< css::beans::PropertyValue > aPropSeq( 4 );
+
+ aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
+ aPropSeq[0].Value <<= pEntry->GetCommand();
+
+ aPropSeq[1].Name = ITEM_DESCRIPTOR_TYPE;
+ aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
+
+ // If the name has not been changed, then the label can be stored
+ // as an empty string.
+ // It will be initialised again later using the command to label map.
+ aPropSeq[2].Name = ITEM_DESCRIPTOR_LABEL;
+ if ( !pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty() )
+ {
+ aPropSeq[2].Value <<= OUString();
+ }
+ else
+ {
+ aPropSeq[2].Value <<= pEntry->GetName();
+ }
+
+ aPropSeq[3].Name = ITEM_DESCRIPTOR_STYLE;
+ aPropSeq[3].Value <<= static_cast<sal_Int16>(pEntry->GetStyle());
+
+ return aPropSeq;
+}
+
+css::uno::Sequence< css::beans::PropertyValue > SvxConfigPageHelper::ConvertToolbarEntry(
+ const SvxConfigEntry* pEntry )
+{
+ css::uno::Sequence< css::beans::PropertyValue > aPropSeq( 5 );
+
+ aPropSeq[0].Name = ITEM_DESCRIPTOR_COMMANDURL;
+ aPropSeq[0].Value <<= pEntry->GetCommand();
+
+ aPropSeq[1].Name = ITEM_DESCRIPTOR_TYPE;
+ aPropSeq[1].Value <<= css::ui::ItemType::DEFAULT;
+
+ // If the name has not been changed, then the label can be stored
+ // as an empty string.
+ // It will be initialised again later using the command to label map.
+ aPropSeq[2].Name = ITEM_DESCRIPTOR_LABEL;
+ if ( !pEntry->HasChangedName() && !pEntry->GetCommand().isEmpty() )
+ {
+ aPropSeq[2].Value <<= OUString();
+ }
+ else
+ {
+ aPropSeq[2].Value <<= pEntry->GetName();
+ }
+
+ aPropSeq[3].Name = ITEM_DESCRIPTOR_ISVISIBLE;
+ aPropSeq[3].Value <<= pEntry->IsVisible();
+
+ aPropSeq[4].Name = ITEM_DESCRIPTOR_STYLE;
+ aPropSeq[4].Value <<= static_cast<sal_Int16>(pEntry->GetStyle());
+
+ return aPropSeq;
+}
+
+bool SvxConfigPageHelper::EntrySort( SvxConfigEntry const * a, SvxConfigEntry const * b )
+{
+ return a->GetName().compareTo( b->GetName() ) < 0;
+}
+
+bool SvxConfigPageHelper::SvxConfigEntryModified( SvxConfigEntry const * pEntry )
+{
+ SvxEntries* pEntries = pEntry->GetEntries();
+ if ( !pEntries )
+ return false;
+
+ for ( const auto& entry : *pEntries )
+ {
+ if ( entry->IsModified() || SvxConfigEntryModified( entry ) )
+ return true;
+ }
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxMenuConfigPage.cxx b/cui/source/customize/SvxMenuConfigPage.cxx
new file mode 100644
index 000000000..2adb56183
--- /dev/null
+++ b/cui/source/customize/SvxMenuConfigPage.cxx
@@ -0,0 +1,600 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/commandevent.hxx>
+
+#include <strings.hrc>
+#include <helpids.h>
+
+#include <cfg.hxx>
+#include <SvxMenuConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/ImageType.hpp>
+
+#include <dlgname.hxx>
+
+SvxMenuConfigPage::SvxMenuConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet, bool bIsMenuBar)
+ : SvxConfigPage(pPage, pController, rSet)
+ , m_bIsMenuBar(bIsMenuBar)
+{
+ m_xGearBtn = m_xBuilder->weld_menu_button("menugearbtn");
+ m_xGearBtn->show();
+ m_xContentsListBox.reset(new SvxMenuEntriesListBox(m_xBuilder->weld_tree_view("menucontents"), this));
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, rTreeView));
+ rTreeView.connect_size_allocate(LINK(this, SvxMenuConfigPage, MenuEntriesSizeAllocHdl));
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+ MenuEntriesSizeAllocHdl(aSize);
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.show();
+
+ rTreeView.connect_changed(
+ LINK( this, SvxMenuConfigPage, SelectMenuEntry ) );
+ rTreeView.connect_popup_menu( LINK( this, SvxMenuConfigPage, ContentContextMenuHdl ) );
+
+ m_xFunctions->get_widget().connect_popup_menu(
+ LINK( this, SvxMenuConfigPage, FunctionContextMenuHdl ) );
+
+ m_xGearBtn->connect_selected(LINK(this, SvxMenuConfigPage, GearHdl));
+
+ m_xCommandCategoryListBox->connect_changed(LINK(this, SvxMenuConfigPage, SelectCategory));
+
+ m_xMoveUpButton->connect_clicked( LINK( this, SvxConfigPage, MoveHdl) );
+ m_xMoveDownButton->connect_clicked( LINK( this, SvxConfigPage, MoveHdl) );
+
+ m_xAddCommandButton->connect_clicked( LINK( this, SvxMenuConfigPage, AddCommandHdl ) );
+ m_xRemoveCommandButton->connect_clicked( LINK( this, SvxMenuConfigPage, RemoveCommandHdl ) );
+
+ m_xInsertBtn->connect_selected(
+ LINK( this, SvxMenuConfigPage, InsertHdl ) );
+ m_xModifyBtn->connect_selected(
+ LINK( this, SvxMenuConfigPage, ModifyItemHdl ) );
+ m_xResetBtn->connect_clicked(
+ LINK( this, SvxMenuConfigPage, ResetMenuHdl ) );
+
+ // These operations are not possible on menus/context menus yet
+ m_xModifyBtn->remove_item("changeIcon");
+ m_xModifyBtn->remove_item("resetIcon");
+ m_xModifyBtn->remove_item("restoreItem");
+
+ if ( !bIsMenuBar )
+ {
+ //TODO: Remove this when the gear button is implemented for context menus
+ m_xGearBtn->set_sensitive(false);
+ m_xGearBtn->hide();
+ }
+ else
+ {
+ // TODO: Remove this when it is possible to reset menubar menus individually
+ m_xResetBtn->set_sensitive(false);
+ }
+}
+
+void SvxMenuConfigPage::ListModified()
+{
+ // regenerate with the current ordering within the list
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+ pEntries->clear();
+
+ for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
+ pEntries->push_back(reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(i).toInt64()));
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ UpdateButtonStates();
+}
+
+IMPL_LINK(SvxMenuConfigPage, MenuEntriesSizeAllocHdl, const Size&, rSize, void)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ std::vector<int> aWidths;
+
+ int nExpectedSize = 16;
+
+ int nStandardImageColWidth = rTreeView.get_checkbox_column_width();
+ int nMargin = nStandardImageColWidth - nExpectedSize;
+ if (nMargin < 16)
+ nMargin = 16;
+
+ if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE)
+ nExpectedSize = 24;
+ else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32)
+ nExpectedSize = 32;
+
+ int nImageColWidth = nExpectedSize + nMargin;
+
+ aWidths.push_back(nImageColWidth);
+ aWidths.push_back(rSize.Width() - (nImageColWidth + nStandardImageColWidth));
+ rTreeView.set_column_fixed_widths(aWidths);
+}
+
+SvxMenuConfigPage::~SvxMenuConfigPage()
+{
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ delete reinterpret_cast<SaveInData*>(m_xSaveInListBox->get_id(i).toInt64());
+ m_xSaveInListBox->clear();
+}
+
+// Populates the Menu combo box
+void SvxMenuConfigPage::Init()
+{
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ m_xTopLevelListBox->set_active(0);
+ SelectElement();
+
+ m_xCommandCategoryListBox->Init(
+ comphelper::getProcessComponentContext(),
+ m_xFrame, m_aModuleId);
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, SelectMenuEntry, weld::TreeView&, void)
+{
+ UpdateButtonStates();
+}
+
+void SvxMenuConfigPage::UpdateButtonStates()
+{
+ // Disable Up and Down buttons depending on current selection
+ int selection = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator =
+ selection != -1 && reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(selection).toInt64())->IsSeparator();
+ bool bIsValidSelection =
+ !(m_xContentsListBox->n_children() == 0 || selection == -1);
+
+ m_xMoveUpButton->set_sensitive(
+ bIsValidSelection && selection != 0 );
+ m_xMoveDownButton->set_sensitive(
+ bIsValidSelection && selection != m_xContentsListBox->n_children() - 1);
+
+ m_xRemoveCommandButton->set_sensitive( bIsValidSelection );
+
+ m_xModifyBtn->set_sensitive( bIsValidSelection && !bIsSeparator);
+
+ // If there is no top level selection (menu), then everything working on the right box
+ // which contains the functions of the selected menu/toolbar needs to be disabled
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ m_xInsertBtn->set_sensitive(pMenuData != nullptr);
+
+ m_xAddCommandButton->set_sensitive(pMenuData != nullptr);
+ m_xRemoveCommandButton->set_sensitive(pMenuData != nullptr);
+
+ //Handle the gear button
+ if (pMenuData && m_bIsMenuBar)
+ {
+ // Add option (gear_add) will always be enabled
+ m_xGearBtn->set_item_sensitive( "menu_gear_delete", pMenuData->IsDeletable() );
+ m_xGearBtn->set_item_sensitive( "menu_gear_rename", pMenuData->IsRenamable() );
+ m_xGearBtn->set_item_sensitive( "menu_gear_move", pMenuData->IsMovable() );
+ }
+}
+
+void SvxMenuConfigPage::DeleteSelectedTopLevel()
+{
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ SvxEntries* pParentEntries =
+ FindParentForChild( GetSaveInData()->GetEntries(), pMenuData );
+
+ SvxConfigPageHelper::RemoveEntry( pParentEntries, pMenuData );
+ delete pMenuData;
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified( );
+}
+
+void SvxMenuConfigPage::DeleteSelectedContent()
+{
+ int nActEntry = m_xContentsListBox->get_selected_index();
+
+ if (nActEntry == -1)
+ return;
+
+ // get currently selected menu entry
+ SvxConfigEntry* pMenuEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ // get currently selected menu
+ SvxConfigEntry* pMenu = GetTopLevelSelection();
+
+ // remove menu entry from the list for this menu
+ SvxConfigPageHelper::RemoveEntry( pMenu->GetEntries(), pMenuEntry );
+
+ // remove menu entry from UI
+ m_xContentsListBox->remove(nActEntry);
+
+ // if this is a submenu entry, redraw the menus list box
+ if ( pMenuEntry->IsPopup() )
+ {
+ ReloadTopLevelListBox();
+ }
+
+ // delete data for menu entry
+ delete pMenuEntry;
+
+ GetSaveInData()->SetModified();
+ pMenu->SetModified();
+}
+
+short SvxMenuConfigPage::QueryReset()
+{
+ OUString msg = CuiResId( RID_SVXSTR_CONFIRM_MENU_RESET );
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName( msg, saveInName );
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ label));
+ return xQueryBox->run();
+}
+
+void SvxMenuConfigPage::SelectElement()
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+ if (!pMenuData)
+ rTreeView.clear();
+ else
+ {
+ SvxEntries* pEntries = pMenuData->GetEntries();
+
+ rTreeView.bulk_insert_for_each(pEntries->size(), [this, &rTreeView, pEntries](weld::TreeIter& rIter, int nIdx) {
+ auto const& entry = (*pEntries)[nIdx];
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(entry)));
+ rTreeView.set_id(rIter, sId);
+ InsertEntryIntoUI(entry, rTreeView, rIter, 0);
+ });
+ }
+
+ UpdateButtonStates();
+}
+
+IMPL_LINK(SvxMenuConfigPage, GearHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "menu_gear_add")
+ {
+ SvxMainMenuOrganizerDialog aDialog(GetFrameWeld(),
+ GetSaveInData()->GetEntries(), nullptr, true );
+
+ if (aDialog.run() == RET_OK)
+ {
+ GetSaveInData()->SetEntries(aDialog.ReleaseEntries());
+ ReloadTopLevelListBox(aDialog.GetSelectedEntry());
+ GetSaveInData()->SetModified();
+ }
+ }
+ else if (rIdent == "menu_gear_delete")
+ {
+ DeleteSelectedTopLevel();
+ }
+ else if (rIdent == "menu_gear_rename")
+ {
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ OUString sCurrentName( SvxConfigPageHelper::stripHotKey( pMenuData->GetName() ) );
+ OUString sDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_MENU);
+ aNameDialog.set_title(CuiResId(RID_SVXSTR_RENAME_MENU));
+
+ if ( aNameDialog.run() == RET_OK )
+ {
+ OUString sNewName = aNameDialog.GetName();
+
+ if ( sCurrentName == sNewName )
+ return;
+
+ pMenuData->SetName( sNewName );
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified();
+ }
+ }
+ else if (rIdent == "menu_gear_move")
+ {
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ SvxMainMenuOrganizerDialog aDialog(GetFrameWeld(), GetSaveInData()->GetEntries(),
+ pMenuData, false );
+ if (aDialog.run() == RET_OK)
+ {
+ GetSaveInData()->SetEntries(aDialog.ReleaseEntries());
+
+ ReloadTopLevelListBox();
+
+ GetSaveInData()->SetModified();
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
+ return;
+ }
+
+ UpdateButtonStates();
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, SelectCategory, weld::ComboBox&, void)
+{
+ OUString aSearchTerm( m_xSearchEdit->get_text() );
+
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+}
+
+IMPL_LINK_NOARG( SvxMenuConfigPage, AddCommandHdl, weld::Button&, void )
+{
+ int nPos = AddFunction(-1, /*bAllowDuplicates*/false);
+ if (nPos == -1)
+ return;
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(rTreeView.get_id(nPos).toInt64());
+ InsertEntryIntoUI(pEntry, rTreeView, nPos, 0);
+}
+
+IMPL_LINK_NOARG( SvxMenuConfigPage, RemoveCommandHdl, weld::Button&, void )
+{
+ DeleteSelectedContent();
+ if ( GetSaveInData()->IsModified() )
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK(SvxMenuConfigPage, InsertHdl, const OString&, rIdent, void)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ if (rIdent == "insertseparator")
+ {
+ SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
+ pNewEntryData->SetUserDefined();
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, 0);
+ }
+ else if (rIdent == "insertsubmenu")
+ {
+ OUString aNewName;
+ OUString aDesc = CuiResId( RID_SVXSTR_SUBMENU_NAME );
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_NAME_SUBMENU);
+ aNameDialog.set_title(CuiResId( RID_SVXSTR_ADD_SUBMENU));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ SvxConfigEntry* pNewEntryData =
+ new SvxConfigEntry( aNewName, aNewName, true, /*bParentData*/false );
+ pNewEntryData->SetName( aNewName );
+ pNewEntryData->SetUserDefined();
+
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, rTreeView, nPos, 0);
+
+ ReloadTopLevelListBox();
+
+ m_xContentsListBox->scroll_to_row(nPos);
+ m_xContentsListBox->select(nPos);
+
+ GetSaveInData()->SetModified();
+ }
+
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if ( GetSaveInData()->IsModified() )
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK(SvxMenuConfigPage, ModifyItemHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "renameItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ OUString aNewName( SvxConfigPageHelper::stripHotKey( pEntry->GetName() ) );
+ OUString aDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_MENU_ITEM);
+ aNameDialog.set_title(CuiResId(RID_SVXSTR_RENAME_MENU));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ pEntry->SetName( aNewName );
+ m_xContentsListBox->set_text(nActEntry, aNewName, 1);
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if ( GetSaveInData()->IsModified() )
+ {
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK_NOARG(SvxMenuConfigPage, ResetMenuHdl, weld::Button&, void)
+{
+ SvxConfigEntry* pMenuData = GetTopLevelSelection();
+
+ if (pMenuData == nullptr)
+ {
+ SAL_WARN("cui.customize", "RHB top level selection is null. A menu must be selected to reset!");
+ return;
+ }
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SVXSTR_CONFIRM_RESTORE_DEFAULT_MENU)));
+
+ // Resetting individual top-level menus is not possible at the moment.
+ // So we are resetting only if it is a context menu
+ if (!(!m_bIsMenuBar && xQueryBox->run() == RET_YES))
+ return;
+
+ sal_Int32 nPos = m_xTopLevelListBox->get_active();
+ ContextMenuSaveInData* pSaveInData = static_cast< ContextMenuSaveInData* >(GetSaveInData());
+
+ pSaveInData->ResetContextMenu(pMenuData);
+
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ // Reselect the reset menu
+ m_xTopLevelListBox->set_active(nPos);
+ SelectElement();
+}
+
+SaveInData* SvxMenuConfigPage::CreateSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool bDocConfig )
+{
+ if ( !m_bIsMenuBar )
+ return static_cast< SaveInData* >( new ContextMenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ) );
+
+ return static_cast< SaveInData* >( new MenuSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ) );
+}
+
+IMPL_LINK( SvxMenuConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool )
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (! rTreeView.get_dest_row_at_pos( rCEvt.GetMousePosPixel(), xIter.get(), false ))
+ return false;
+ rTreeView.select(*xIter);
+ SelectMenuEntry( rTreeView );
+
+ int nSelectIndex = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator =
+ nSelectIndex != -1 && reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex).toInt64())->IsSeparator();
+ bool bIsValidSelection =
+ !( m_xContentsListBox->n_children() == 0 || nSelectIndex == -1 );
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder( &rTreeView, "cui/ui/entrycontextmenu.ui" ) );
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", false);
+ xContextMenu->set_visible("remove", bIsValidSelection);
+ xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect( &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1) ) ) );
+
+ if ( sCommand == "remove")
+ {
+ RemoveCommandHdl( *m_xRemoveCommandButton );
+ }
+ else if ( sCommand == "rename" )
+ {
+ ModifyItemHdl( "renameItem" );
+ }
+ else if ( !sCommand.isEmpty() )
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
+ return true;
+}
+
+IMPL_LINK( SvxMenuConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool )
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> xIter(rTreeView.make_iterator());
+ if (! rTreeView.get_dest_row_at_pos( rCEvt.GetMousePosPixel(), xIter.get(), false ))
+ return false;
+ rTreeView.select(*xIter);
+ SelectFunctionHdl( rTreeView );
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder( &rTreeView, "cui/ui/entrycontextmenu.ui" ) );
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", true);
+ xContextMenu->set_visible("remove", false);
+ xContextMenu->set_visible("rename", false);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect( &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1) ) ) );
+
+ if ( sCommand == "add")
+ {
+ AddCommandHdl( *m_xAddCommandButton );
+ }
+ else if ( !sCommand.isEmpty() )
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
+ return true;
+}
+
+ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxNotebookbarConfigPage.cxx b/cui/source/customize/SvxNotebookbarConfigPage.cxx
new file mode 100644
index 000000000..0fb05678b
--- /dev/null
+++ b/cui/source/customize/SvxNotebookbarConfigPage.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 <sal/config.h>
+
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+
+#include <algorithm>
+#include <cstddef>
+
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <cfg.hxx>
+#include <SvxNotebookbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+#include <libxml/parser.h>
+#include <osl/file.hxx>
+#include <CustomNotebookbarGenerator.hxx>
+#include <sfx2/notebookbar/SfxNotebookBar.hxx>
+#include <unotools/configmgr.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+
+namespace uno = com::sun::star::uno;
+namespace frame = com::sun::star::frame;
+namespace lang = com::sun::star::lang;
+namespace container = com::sun::star::container;
+namespace beans = com::sun::star::beans;
+namespace graphic = com::sun::star::graphic;
+
+static bool isCategoryAvailable(const OUString& sClassId, const OUString& sUIItemId,
+ const OUString& sActiveCategory, bool& isCategory)
+{
+ if (sUIItemId == sActiveCategory)
+ return true;
+ else if ((sClassId == "GtkMenu" || sClassId == "GtkGrid") && sUIItemId != sActiveCategory)
+ {
+ isCategory = false;
+ return false;
+ }
+ return false;
+}
+
+static OUString charToString(const char* cString)
+{
+ return OUString(cString, strlen(cString), RTL_TEXTENCODING_UTF8);
+}
+
+static OUString getFileName(const OUString& aFileName)
+{
+ if (aFileName == "notebookbar.ui")
+ return "Tabbed";
+ else if (aFileName == "notebookbar_compact.ui")
+ return "TabbedCompact";
+ else if (aFileName == "notebookbar_groupedbar_full.ui")
+ return "Groupedbar";
+ else if (aFileName == "notebookbar_groupedbar_compact.ui")
+ return "GroupedbarCompact";
+ else
+ return "None";
+}
+
+static OUString getModuleId(const OUString& sModuleName)
+{
+ if (sModuleName == "Writer")
+ return "com.sun.star.text.TextDocument";
+ else if (sModuleName == "Draw")
+ return "com.sun.star.drawing.DrawingDocument";
+ else if (sModuleName == "Impress")
+ return "com.sun.star.presentation.PresentationDocument";
+ else if (sModuleName == "Calc")
+ return "com.sun.star.sheet.SpreadsheetDocument";
+ else
+ return "None";
+}
+
+SvxNotebookbarConfigPage::SvxNotebookbarConfigPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SvxConfigPage(pPage, pController, rSet)
+{
+ m_xCommandCategoryListBox->set_visible(false);
+ m_xDescriptionFieldLb->set_visible(false);
+ m_xSearchEdit->set_visible(false);
+ m_xDescriptionField->set_visible(false);
+ m_xMoveUpButton->set_visible(false);
+ m_xMoveDownButton->set_visible(false);
+ m_xAddCommandButton->set_visible(false);
+ m_xRemoveCommandButton->set_visible(false);
+ m_xLeftFunctionLabel->set_visible(false);
+ m_xSearchLabel->set_visible(false);
+ m_xCategoryLabel->set_visible(false);
+ m_xInsertBtn->set_visible(false);
+ m_xModifyBtn->set_visible(false);
+ m_xResetBtn->set_visible(false);
+ m_xCustomizeLabel->set_visible(false);
+
+ weld::TreeView& rCommandCategoryBox = m_xFunctions->get_widget();
+ rCommandCategoryBox.hide();
+
+ m_xContentsListBox.reset(
+ new SvxNotebookbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
+ m_xDropTargetHelper.reset(
+ new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
+ std::vector<int> aWidths;
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+
+ int nExpectedSize = 16;
+
+ int nStandardImageColWidth = rTreeView.get_checkbox_column_width();
+ int nMargin = nStandardImageColWidth - nExpectedSize;
+ if (nMargin < 16)
+ nMargin = 16;
+
+ if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE)
+ nExpectedSize = 24;
+ else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32)
+ nExpectedSize = 32;
+
+ int nImageColWidth = nExpectedSize + nMargin;
+
+ aWidths.push_back(nStandardImageColWidth);
+ aWidths.push_back(nImageColWidth);
+ rTreeView.set_column_fixed_widths(aWidths);
+
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.set_help_id(HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS);
+ rTreeView.show();
+}
+
+SvxNotebookbarConfigPage::~SvxNotebookbarConfigPage() {}
+
+void SvxNotebookbarConfigPage::DeleteSelectedTopLevel() {}
+
+void SvxNotebookbarConfigPage::DeleteSelectedContent() {}
+
+void SvxNotebookbarConfigPage::Init()
+{
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+ m_xSaveInListBox->clear();
+ CustomNotebookbarGenerator::createCustomizedUIFile();
+ OUString sNotebookbarInterface = getFileName(m_sFileName);
+
+ OUString sScopeName
+ = utl::ConfigManager::getProductName() + " " + m_sAppName + " - " + sNotebookbarInterface;
+ OUString sSaveInListBoxID = notebookbarTabScope;
+
+ m_xSaveInListBox->append(sSaveInListBoxID, sScopeName);
+ m_xSaveInListBox->set_active_id(sSaveInListBoxID);
+
+ m_xTopLevelListBox->append("NotebookBar", "All Commands");
+ m_xTopLevelListBox->set_active_id("NotebookBar");
+ SelectElement();
+}
+
+SaveInData* SvxNotebookbarConfigPage::CreateSaveInData(
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xCfgMgr,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>& xParentCfgMgr,
+ const OUString& aModuleId, bool bDocConfig)
+{
+ return static_cast<SaveInData*>(
+ new ToolbarSaveInData(xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig));
+}
+
+void SvxNotebookbarConfigPage::UpdateButtonStates() {}
+
+short SvxNotebookbarConfigPage::QueryReset()
+{
+ OUString msg = CuiResId(RID_SVXSTR_CONFIRM_TOOLBAR_RESET);
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName(msg, saveInName);
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(
+ GetFrameWeld(), VclMessageType::Question, VclButtonsType::YesNo, label));
+ int nValue = xQueryBox->run();
+ if (nValue == RET_YES)
+ {
+ OUString sOriginalUIPath = CustomNotebookbarGenerator::getOriginalUIPath();
+ OUString sCustomizedUIPath = CustomNotebookbarGenerator::getCustomizedUIPath();
+ osl::File::copy(sOriginalUIPath, sCustomizedUIPath);
+ OUString sNotebookbarInterface = getFileName(m_sFileName);
+ Sequence<OUString> sSequenceEntries;
+ CustomNotebookbarGenerator::setCustomizedUIItem(sSequenceEntries, sNotebookbarInterface);
+ OUString sUIPath = "modules/s" + m_sAppName.toAsciiLowerCase() + "/ui/";
+ sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
+ }
+ return nValue;
+}
+
+void SvxConfigPage::InsertEntryIntoNotebookbarTabUI(const OUString& sClassId,
+ const OUString& sUIItemId,
+ const OUString& sUIItemCommand,
+ weld::TreeView& rTreeView,
+ weld::TreeIter& rIter, int nStartCol)
+{
+ css::uno::Reference<css::container::XNameAccess> m_xCommandToLabelMap;
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference<container::XNameAccess> xNameAccess(
+ css::frame::theUICommandDescription::get(xContext));
+
+ uno::Sequence<beans::PropertyValue> aPropSeq;
+
+ xNameAccess->getByName(getModuleId(m_sAppName)) >>= m_xCommandToLabelMap;
+
+ try
+ {
+ uno::Any aModuleVal = m_xCommandToLabelMap->getByName(sUIItemCommand);
+
+ aModuleVal >>= aPropSeq;
+ }
+ catch (container::NoSuchElementException&)
+ {
+ }
+
+ OUString aLabel;
+ for (auto const& prop : std::as_const(aPropSeq))
+ if (prop.Name == "Name")
+ prop.Value >>= aLabel;
+
+ OUString aName = SvxConfigPageHelper::stripHotKey(aLabel);
+
+ if (sClassId == "GtkSeparatorMenuItem" || sClassId == "GtkSeparator")
+ {
+ OUString sDataInTree = "--------------------------------------------";
+ rTreeView.set_text(rIter, sDataInTree, nStartCol + 1);
+ }
+ else
+ {
+ if (aName.isEmpty())
+ aName = sUIItemId;
+ auto xImage = GetSaveInData()->GetImage(sUIItemCommand);
+ if (xImage.is())
+ rTreeView.set_image(rIter, xImage, nStartCol);
+ rTreeView.set_text(rIter, aName, nStartCol + 1);
+ rTreeView.set_id(rIter, sUIItemId);
+ }
+}
+
+void SvxNotebookbarConfigPage::getNodeValue(xmlNode* pNodePtr, NotebookbarEntries& aNodeEntries)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (!(xmlStrcmp(pNodePtr->name, reinterpret_cast<const xmlChar*>("property"))))
+ {
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("name"));
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("visible"))))
+ {
+ xmlChar* aValue = xmlNodeGetContent(pNodePtr);
+ const char* cVisibleValue = reinterpret_cast<const char*>(aValue);
+ aNodeEntries.sVisibleValue = charToString(cVisibleValue);
+ xmlFree(aValue);
+ }
+ if (!(xmlStrcmp(UriValue, reinterpret_cast<const xmlChar*>("action_name"))))
+ {
+ xmlChar* aValue = xmlNodeGetContent(pNodePtr);
+ const char* cActionName = reinterpret_cast<const char*>(aValue);
+ aNodeEntries.sActionName = charToString(cActionName);
+ xmlFree(aValue);
+ }
+ xmlFree(UriValue);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+void SvxNotebookbarConfigPage::searchNodeandAttribute(std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory,
+ CategoriesEntries& aCurItemEntry,
+ xmlNode* pNodePtr, bool isCategory)
+{
+ pNodePtr = pNodePtr->xmlChildrenNode;
+ while (pNodePtr)
+ {
+ if (pNodePtr->type == XML_ELEMENT_NODE)
+ {
+ const char* cNodeName = reinterpret_cast<const char*>(pNodePtr->name);
+ if (strcmp(cNodeName, "object") == 0)
+ {
+ OUString sSecondVal;
+
+ xmlChar* UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("id"));
+ const char* cUIItemID = reinterpret_cast<const char*>(UriValue);
+ OUString sUIItemId = charToString(cUIItemID);
+ xmlFree(UriValue);
+
+ UriValue = xmlGetProp(pNodePtr, reinterpret_cast<const xmlChar*>("class"));
+ const char* cClassId = reinterpret_cast<const char*>(UriValue);
+ OUString sClassId = charToString(cClassId);
+ xmlFree(UriValue);
+
+ CategoriesEntries aCategoryEntry;
+ if (sClassId == "sfxlo-PriorityHBox")
+ {
+ aCategoryEntry.sDisplayName = sUIItemId;
+ aCategoryEntry.sUIItemId = sUIItemId;
+ aCategoryEntry.sClassType = sClassId;
+ aCategoryList.push_back(aCategoryEntry);
+
+ aCurItemEntry = aCategoryEntry;
+ }
+ else if (sClassId == "sfxlo-PriorityMergedHBox")
+ {
+ aCategoryEntry.sDisplayName = aCurItemEntry.sDisplayName + " | " + sUIItemId;
+ aCategoryEntry.sUIItemId = sUIItemId;
+ aCategoryEntry.sClassType = sClassId;
+
+ if (aCurItemEntry.sClassType == sClassId)
+ {
+ sal_Int32 rPos = 0;
+ aCategoryEntry.sDisplayName
+ = aCurItemEntry.sDisplayName.getToken(rPos, ' ', rPos) + " | "
+ + sUIItemId;
+ }
+ aCategoryList.push_back(aCategoryEntry);
+ aCurItemEntry = aCategoryEntry;
+ }
+ else if (sClassId == "svtlo-ManagedMenuButton")
+ {
+ sal_Int32 rPos = 1;
+ sSecondVal = sUIItemId.getToken(rPos, ':', rPos);
+ if (!sSecondVal.isEmpty())
+ {
+ aCategoryEntry.sDisplayName
+ = aCurItemEntry.sDisplayName + " | " + sSecondVal;
+ aCategoryEntry.sUIItemId = sSecondVal;
+ aCategoryList.push_back(aCategoryEntry);
+ }
+ }
+
+ NotebookbarEntries nodeEntries;
+ if (isCategoryAvailable(sClassId, sUIItemId, sActiveCategory, isCategory)
+ || isCategory)
+ {
+ isCategory = true;
+ if (sClassId == "GtkMenuItem" || sClassId == "GtkToolButton"
+ || sClassId == "GtkMenuToolButton"
+ || (sClassId == "svtlo-ManagedMenuButton" && sSecondVal.isEmpty()))
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName = sUIItemId;
+
+ getNodeValue(pNodePtr, nodeEntries);
+ aEntries.push_back(nodeEntries);
+ }
+ else if (sClassId == "GtkSeparatorMenuItem" || sClassId == "GtkSeparator")
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName = "Null";
+ nodeEntries.sVisibleValue = "Null";
+ nodeEntries.sActionName = "Null";
+ aEntries.push_back(nodeEntries);
+ }
+ else if (sClassId == "sfxlo-PriorityHBox"
+ || sClassId == "sfxlo-PriorityMergedHBox"
+ || sClassId == "svtlo-ManagedMenuButton")
+ {
+ nodeEntries.sClassId = sClassId;
+ nodeEntries.sUIItemId = sUIItemId;
+ nodeEntries.sDisplayName
+ = aCategoryList[aCategoryList.size() - 1].sDisplayName;
+ nodeEntries.sVisibleValue = "Null";
+ nodeEntries.sActionName = "Null";
+ aEntries.push_back(nodeEntries);
+ }
+ }
+ }
+ searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry,
+ pNodePtr, isCategory);
+ }
+ pNodePtr = pNodePtr->next;
+ }
+}
+
+void SvxNotebookbarConfigPage::FillFunctionsList(xmlNodePtr pRootNodePtr,
+ std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory)
+{
+ CategoriesEntries aCurItemEntry;
+ searchNodeandAttribute(aEntries, aCategoryList, sActiveCategory, aCurItemEntry, pRootNodePtr,
+ false);
+}
+
+void SvxNotebookbarConfigPage::SelectElement()
+{
+ OString sUIFileUIPath = CustomNotebookbarGenerator::getSystemPath(
+ CustomNotebookbarGenerator::getCustomizedUIPath());
+ xmlDocPtr pDoc = xmlParseFile(sUIFileUIPath.getStr());
+ if (!pDoc)
+ return;
+ xmlNodePtr pNodePtr = xmlDocGetRootElement(pDoc);
+
+ std::vector<NotebookbarEntries> aEntries;
+ std::vector<CategoriesEntries> aCategoryList;
+ OUString sActiveCategory = m_xTopLevelListBox->get_active_id();
+ FillFunctionsList(pNodePtr, aEntries, aCategoryList, sActiveCategory);
+
+ if (m_xTopLevelListBox->get_count() == 1)
+ {
+ for (std::size_t nIdx = 0; nIdx < aCategoryList.size(); nIdx++)
+ m_xTopLevelListBox->append(aCategoryList[nIdx].sUIItemId,
+ aCategoryList[nIdx].sDisplayName);
+ }
+ unsigned long nStart = 0;
+ if (aEntries[nStart].sClassId == "sfxlo-PriorityHBox"
+ || aEntries[nStart].sClassId == "sfxlo-PriorityMergedHBox")
+ nStart = 1;
+
+ std::vector<NotebookbarEntries> aTempEntries;
+ for (std::size_t nIdx = nStart; nIdx < aEntries.size(); nIdx++)
+ {
+ if (aEntries[nIdx].sClassId == "svtlo-ManagedMenuButton")
+ {
+ aTempEntries.push_back(aEntries[nIdx]);
+ std::vector<NotebookbarEntries> aGtkEntries;
+ sal_Int32 rPos = 1;
+ sActiveCategory = aEntries[nIdx].sUIItemId.getToken(rPos, ':', rPos);
+ FillFunctionsList(pNodePtr, aGtkEntries, aCategoryList, sActiveCategory);
+ for (std::size_t Idx = 0; Idx < aGtkEntries.size(); Idx++)
+ aTempEntries.push_back(aGtkEntries[Idx]);
+ aGtkEntries.clear();
+ }
+ else
+ aTempEntries.push_back(aEntries[nIdx]);
+ }
+
+ aEntries = aTempEntries;
+ aTempEntries.clear();
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ rTreeView.bulk_insert_for_each(
+ aEntries.size(), [this, &rTreeView, &aEntries](weld::TreeIter& rIter, int nIdx) {
+ OUString sId(OUString::number(nIdx));
+ rTreeView.set_id(rIter, sId);
+ if (aEntries[nIdx].sActionName != "Null")
+ {
+ if (aEntries[nIdx].sVisibleValue == "True")
+ {
+ rTreeView.set_toggle(rIter, TRISTATE_TRUE, 0);
+ }
+ else
+ {
+ rTreeView.set_toggle(rIter, TRISTATE_FALSE, 0);
+ }
+ }
+ InsertEntryIntoNotebookbarTabUI(aEntries[nIdx].sClassId, aEntries[nIdx].sDisplayName,
+ aEntries[nIdx].sActionName, rTreeView, rIter, 1);
+ });
+
+ aEntries.clear();
+
+ xmlFreeDoc(pDoc);
+}
+
+SvxNotebookbarEntriesListBox::SvxNotebookbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent,
+ SvxConfigPage* pPg)
+ : SvxMenuEntriesListBox(std::move(xParent), pPg)
+{
+ m_xControl->connect_toggled(LINK(this, SvxNotebookbarEntriesListBox, CheckButtonHdl));
+ m_xControl->connect_key_press(Link<const KeyEvent&, bool>());
+ m_xControl->connect_key_press(LINK(this, SvxNotebookbarEntriesListBox, KeyInputHdl));
+}
+
+SvxNotebookbarEntriesListBox::~SvxNotebookbarEntriesListBox() {}
+
+static void EditRegistryFile(const OUString& sUIItemId, const OUString& sSetEntry,
+ const OUString& sNotebookbarInterface)
+{
+ int nFlag = 0;
+ Sequence<OUString> aOldEntries
+ = CustomNotebookbarGenerator::getCustomizedUIItem(sNotebookbarInterface);
+ Sequence<OUString> aNewEntries(aOldEntries.getLength() + 1);
+ for (int nIdx = 0; nIdx < aOldEntries.getLength(); nIdx++)
+ {
+ sal_Int32 rPos = 0;
+ OUString sFirstValue = aOldEntries[nIdx].getToken(rPos, ',', rPos);
+ if (sFirstValue == sUIItemId)
+ {
+ aOldEntries[nIdx] = sSetEntry;
+ nFlag = 1;
+ break;
+ }
+ aNewEntries[nIdx] = aOldEntries[nIdx];
+ }
+
+ if (nFlag == 0)
+ {
+ aNewEntries[aOldEntries.getLength()] = sSetEntry;
+ CustomNotebookbarGenerator::setCustomizedUIItem(aNewEntries, sNotebookbarInterface);
+ }
+ else
+ {
+ CustomNotebookbarGenerator::setCustomizedUIItem(aOldEntries, sNotebookbarInterface);
+ }
+}
+
+void SvxNotebookbarEntriesListBox::ChangedVisibility(int nRow)
+{
+ OUString sUIItemId = m_xControl->get_selected_id();
+ OUString sNotebookbarInterface = getFileName(m_pPage->GetFileName());
+
+ OUString sVisible;
+ if (m_xControl->get_toggle(nRow, 0) == TRISTATE_TRUE)
+ sVisible = "True";
+ else
+ sVisible = "False";
+ OUString sSetEntries = sUIItemId + ",visible," + sVisible;
+ Sequence<OUString> sSeqOfEntries(1);
+ sSeqOfEntries[0] = sSetEntries;
+ EditRegistryFile(sUIItemId, sSetEntries, sNotebookbarInterface);
+ CustomNotebookbarGenerator::modifyCustomizedUIFile(sSeqOfEntries);
+ OUString sUIPath = "modules/s" + m_pPage->GetAppName().toAsciiLowerCase() + "/ui/";
+ sfx2::SfxNotebookBar::ReloadNotebookBar(sUIPath);
+}
+
+IMPL_LINK(SvxNotebookbarEntriesListBox, CheckButtonHdl, const row_col&, rRowCol, void)
+{
+ ChangedVisibility(rRowCol.first);
+}
+
+IMPL_LINK(SvxNotebookbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ if (rKeyEvent.GetKeyCode() == KEY_SPACE)
+ {
+ int nRow = m_xControl->get_selected_index();
+ m_xControl->set_toggle(
+ nRow, m_xControl->get_toggle(nRow, 0) == TRISTATE_TRUE ? TRISTATE_FALSE : TRISTATE_TRUE,
+ 0);
+ ChangedVisibility(nRow);
+ return true;
+ }
+ return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/SvxToolbarConfigPage.cxx b/cui/source/customize/SvxToolbarConfigPage.cxx
new file mode 100644
index 000000000..ead5792c0
--- /dev/null
+++ b/cui/source/customize/SvxToolbarConfigPage.cxx
@@ -0,0 +1,966 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/commandevent.hxx>
+
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <cfg.hxx>
+#include <SvxToolbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include <dialmgr.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/ImageType.hpp>
+
+#include <dlgname.hxx>
+
+SvxToolbarConfigPage::SvxToolbarConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SvxConfigPage(pPage, pController, rSet)
+{
+ m_xGearBtn = m_xBuilder->weld_menu_button("toolbargearbtn");
+ m_xGearBtn->show();
+ m_xContainer->set_help_id(HID_SVX_CONFIG_TOOLBAR);
+
+ m_xContentsListBox.reset(new SvxToolbarEntriesListBox(m_xBuilder->weld_tree_view("toolcontents"), this));
+ m_xDropTargetHelper.reset(new SvxConfigPageFunctionDropTarget(*this, m_xContentsListBox->get_widget()));
+
+ std::vector<int> aWidths;
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+ Size aSize(m_xFunctions->get_size_request());
+ rTreeView.set_size_request(aSize.Width(), aSize.Height());
+
+ int nExpectedSize = 16;
+
+ int nStandardImageColWidth = rTreeView.get_checkbox_column_width();
+ int nMargin = nStandardImageColWidth - nExpectedSize;
+ if (nMargin < 16)
+ nMargin = 16;
+
+ if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE)
+ nExpectedSize = 24;
+ else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32)
+ nExpectedSize = 32;
+
+ int nImageColWidth = nExpectedSize + nMargin;
+
+ aWidths.push_back(nStandardImageColWidth);
+ aWidths.push_back(nImageColWidth);
+ rTreeView.set_column_fixed_widths(aWidths);
+
+ rTreeView.set_hexpand(true);
+ rTreeView.set_vexpand(true);
+ rTreeView.set_help_id( HID_SVX_CONFIG_TOOLBAR_CONTENTS );
+ rTreeView.show();
+
+ rTreeView.connect_changed(
+ LINK( this, SvxToolbarConfigPage, SelectToolbarEntry ) );
+ rTreeView.connect_popup_menu( LINK( this, SvxToolbarConfigPage, ContentContextMenuHdl ) );
+
+ m_xFunctions->get_widget().connect_popup_menu(
+ LINK( this, SvxToolbarConfigPage, FunctionContextMenuHdl ) );
+
+ m_xTopLevelListBox->set_help_id ( HID_SVX_TOPLEVELLISTBOX );
+ m_xSaveInListBox->set_help_id( HID_SVX_SAVE_IN );
+ m_xMoveUpButton->set_help_id( HID_SVX_UP_TOOLBAR_ITEM );
+ m_xMoveDownButton->set_help_id( HID_SVX_DOWN_TOOLBAR_ITEM );
+ m_xDescriptionField->set_help_id ( HID_SVX_DESCFIELD );
+
+ m_xCommandCategoryListBox->connect_changed(
+ LINK( this, SvxToolbarConfigPage, SelectCategory ) );
+
+ m_xGearBtn->connect_selected(
+ LINK( this, SvxToolbarConfigPage, GearHdl ) );
+
+ m_xMoveUpButton->connect_clicked( LINK( this, SvxToolbarConfigPage, MoveHdl) );
+ m_xMoveDownButton->connect_clicked( LINK( this, SvxToolbarConfigPage, MoveHdl) );
+ // Always enable Up and Down buttons
+ // added for issue i53677 by shizhoubo
+ m_xMoveDownButton->set_sensitive(true);
+ m_xMoveUpButton->set_sensitive(true);
+
+ m_xAddCommandButton->connect_clicked( LINK( this, SvxToolbarConfigPage, AddCommandHdl ) );
+ m_xRemoveCommandButton->connect_clicked( LINK( this, SvxToolbarConfigPage, RemoveCommandHdl ) );
+
+ m_xInsertBtn->connect_selected(
+ LINK( this, SvxToolbarConfigPage, InsertHdl ) );
+ m_xModifyBtn->connect_selected(
+ LINK( this, SvxToolbarConfigPage, ModifyItemHdl ) );
+ m_xResetBtn->connect_clicked(
+ LINK( this, SvxToolbarConfigPage, ResetToolbarHdl ) );
+
+ // "Insert Submenu" is irrelevant to the toolbars
+ m_xInsertBtn->remove_item("insertsubmenu");
+
+ // Gear menu's "Move" action is irrelevant to the toolbars
+ m_xGearBtn->set_item_sensitive("toolbar_gear_move", false);
+
+ // default toolbar to select is standardbar unless a different one
+ // has been passed in
+ m_aURLToSelect = ITEM_TOOLBAR_URL;
+ m_aURLToSelect += "standardbar";
+
+ const SfxPoolItem* pItem =
+ rSet.GetItem( rSet.GetPool()->GetWhich( SID_CONFIG ) );
+
+ if ( pItem )
+ {
+ OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
+ if (text.startsWith( ITEM_TOOLBAR_URL ))
+ {
+ m_aURLToSelect = text.copy( 0 );
+ }
+ }
+}
+
+void SvxToolbarConfigPage::ListModified()
+{
+ // regenerate with the current ordering within the list
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+ pEntries->clear();
+
+ for (int i = 0; i < m_xContentsListBox->n_children(); ++i)
+ pEntries->push_back(reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(i).toInt64()));
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if ( pToolbar )
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar( pToolbar );
+}
+
+SvxToolbarConfigPage::~SvxToolbarConfigPage()
+{
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ {
+ ToolbarSaveInData* pData =
+ reinterpret_cast<ToolbarSaveInData*>(m_xSaveInListBox->get_id(i).toInt64());
+ delete pData;
+ }
+ m_xSaveInListBox->clear();
+}
+
+void SvxToolbarConfigPage::DeleteSelectedTopLevel()
+{
+ const sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>( GetSaveInData() );
+ pSaveInData->RemoveToolbar( GetTopLevelSelection() );
+
+ int nCount = m_xTopLevelListBox->get_count();
+ if (nCount > 1)
+ {
+ // select next entry after the one being deleted
+ // selection position is indexed from 0 so need to
+ // subtract one from the entry count
+ if (nSelectionPos != nCount - 1)
+ {
+ m_xTopLevelListBox->set_active(nSelectionPos + 1);
+ }
+ else
+ {
+ m_xTopLevelListBox->set_active(nSelectionPos - 1);
+ }
+ SelectElement();
+
+ // and now remove the entry
+ m_xTopLevelListBox->remove(nSelectionPos);
+ }
+ else
+ {
+ ReloadTopLevelListBox();
+ }
+}
+
+void SvxToolbarConfigPage::DeleteSelectedContent()
+{
+ int nActEntry = m_xContentsListBox->get_selected_index();
+
+ if (nActEntry == -1)
+ return;
+
+ // get currently selected entry
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ // remove entry from the list for this toolbar
+ SvxConfigPageHelper::RemoveEntry( pToolbar->GetEntries(), pEntry );
+
+ // remove toolbar entry from UI
+ m_xContentsListBox->remove(nActEntry);
+
+ // delete data for toolbar entry
+ delete pEntry;
+
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar( pToolbar );
+ UpdateButtonStates();
+
+ // if this is the last entry in the toolbar and it is a user
+ // defined toolbar pop up a dialog asking the user if they
+ // want to delete the toolbar
+ if ( m_xContentsListBox->n_children() == 0 &&
+ GetTopLevelSelection()->IsDeletable() )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SXVSTR_CONFIRM_DELETE_TOOLBAR)));
+ if (xQueryBox->run() == RET_YES)
+ {
+ DeleteSelectedTopLevel();
+ }
+ }
+}
+
+IMPL_LINK( SvxToolbarConfigPage, MoveHdl, weld::Button&, rButton, void )
+{
+ MoveEntry(&rButton == m_xMoveUpButton.get());
+}
+
+void SvxToolbarConfigPage::MoveEntry( bool bMoveUp )
+{
+ SvxConfigPage::MoveEntry( bMoveUp );
+
+ // Apply change to currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if ( pToolbar )
+ static_cast<ToolbarSaveInData*>(GetSaveInData())->ApplyToolbar( pToolbar );
+ else
+ {
+ SAL_WARN( "cui.customize", "SvxToolbarConfigPage::MoveEntry(): no entry" );
+ UpdateButtonStates();
+ }
+}
+
+void SvxToolbarConfigPage::Init()
+{
+ // ensure that the UI is cleared before populating it
+ m_xTopLevelListBox->clear();
+ m_xContentsListBox->clear();
+
+ ReloadTopLevelListBox();
+
+ sal_Int32 nPos = 0;
+ if ( !m_aURLToSelect.isEmpty() )
+ {
+ for (sal_Int32 i = 0, nCount = m_xTopLevelListBox->get_count(); i < nCount; ++i)
+ {
+ SvxConfigEntry* pData =
+ reinterpret_cast<SvxConfigEntry*>(m_xTopLevelListBox->get_id(i).toInt64());
+
+ if ( pData->GetCommand().equals( m_aURLToSelect ) )
+ {
+ nPos = i;
+ break;
+ }
+ }
+
+ // in future select the default toolbar: Standard
+ m_aURLToSelect = ITEM_TOOLBAR_URL;
+ m_aURLToSelect += "standardbar";
+ }
+
+ m_xTopLevelListBox->set_active(nPos);
+ SelectElement();
+
+ m_xCommandCategoryListBox->Init(
+ comphelper::getProcessComponentContext(),
+ m_xFrame, m_aModuleId);
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), OUString(), GetSaveInData());
+}
+
+SaveInData* SvxToolbarConfigPage::CreateSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool bDocConfig )
+{
+ return static_cast< SaveInData* >(
+ new ToolbarSaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bDocConfig ));
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, SelectToolbarEntry, weld::TreeView&, void)
+{
+ UpdateButtonStates();
+}
+
+IMPL_LINK( SvxToolbarConfigPage, GearHdl, const OString&, rIdent, void )
+{
+ SvxConfigEntry* pCurrentToolbar = GetTopLevelSelection();
+
+ if (rIdent == "toolbar_gear_add")
+ {
+ OUString prefix = CuiResId( RID_SVXSTR_NEW_TOOLBAR );
+
+ OUString aNewName =
+ SvxConfigPageHelper::generateCustomName( prefix, GetSaveInData()->GetEntries() );
+
+ OUString aNewURL =
+ SvxConfigPageHelper::generateCustomURL( GetSaveInData()->GetEntries() );
+
+ SvxNewToolbarDialog aNameDialog(GetFrameWeld(), aNewName);
+
+ // Reflect the actual m_xSaveInListBox into the new toolbar dialog
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ aNameDialog.m_xSaveInListBox->append_text(m_xSaveInListBox->get_text(i));
+
+ aNameDialog.m_xSaveInListBox->set_active(m_xSaveInListBox->get_active());
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ // Where to save the new toolbar? (i.e. Modulewise or documentwise)
+ int nInsertPos = aNameDialog.m_xSaveInListBox->get_active();
+
+ ToolbarSaveInData* pData =
+ reinterpret_cast<ToolbarSaveInData*>(
+ m_xSaveInListBox->get_id(nInsertPos).toInt64() );
+
+ if ( GetSaveInData() != pData )
+ {
+ m_xSaveInListBox->set_active(nInsertPos);
+ SelectSaveInLocation(*m_xSaveInListBox);
+ }
+
+ SvxConfigEntry* pToolbar =
+ new SvxConfigEntry( aNewName, aNewURL, true, false );
+
+ pToolbar->SetUserDefined();
+ pToolbar->SetMain();
+
+ pData->CreateToolbar( pToolbar );
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pToolbar)));
+ m_xTopLevelListBox->append(sId, pToolbar->GetName());
+ m_xTopLevelListBox->set_active_id(sId);
+ SelectElement();
+
+ pData->SetModified();
+ }
+ }
+ else if (rIdent == "toolbar_gear_delete")
+ {
+ if ( pCurrentToolbar && pCurrentToolbar->IsDeletable() )
+ {
+ DeleteSelectedTopLevel();
+ UpdateButtonStates();
+ }
+ }
+ else if (rIdent == "toolbar_gear_rename")
+ {
+ sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+ SvxConfigEntry* pToolbar =
+ reinterpret_cast<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos).toInt64());
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>( GetSaveInData() );
+
+ //Rename the toolbar
+ OUString sCurrentName( SvxConfigPageHelper::stripHotKey( pToolbar->GetName() ) );
+ OUString sDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), sCurrentName, sDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR);
+ aNameDialog.set_title(CuiResId(RID_SVXSTR_RENAME_TOOLBAR));
+
+ if ( aNameDialog.run() == RET_OK )
+ {
+ OUString sNewName = aNameDialog.GetName();
+
+ if (sCurrentName == sNewName)
+ return;
+
+ pToolbar->SetName( sNewName );
+ pSaveInData->ApplyToolbar( pToolbar );
+
+ // have to use remove and insert to change the name
+ m_xTopLevelListBox->remove(nSelectionPos);
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pToolbar)));
+ m_xTopLevelListBox->insert(nSelectionPos, sNewName, &sId, nullptr, nullptr);
+ m_xTopLevelListBox->set_active_id(sId);
+ }
+ }
+ else if (rIdent == "toolbar_gear_iconOnly" || rIdent == "toolbar_gear_textOnly" || rIdent == "toolbar_gear_iconAndText")
+ {
+ ToolbarSaveInData* pSaveInData = static_cast<ToolbarSaveInData*>( GetSaveInData() );
+
+ if (pCurrentToolbar == nullptr || pSaveInData == nullptr)
+ {
+ SAL_WARN("cui.customize", "NULL toolbar or savein data");
+ return;
+ }
+
+ sal_Int32 nStyle = 0;
+ if (rIdent == "toolbar_gear_iconOnly")
+ nStyle = 0;
+ else if (rIdent == "toolbar_gear_textOnly")
+ nStyle = 1;
+ else if (rIdent == "toolbar_gear_iconAndText")
+ nStyle = 2;
+
+ pCurrentToolbar->SetStyle( nStyle );
+ pSaveInData->SetSystemStyle( m_xFrame, pCurrentToolbar->GetCommand(), nStyle );
+
+ SelectElement();
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown gear menu option: " << rIdent);
+ return;
+ }
+}
+
+IMPL_LINK_NOARG( SvxToolbarConfigPage, SelectCategory, weld::ComboBox&, void )
+{
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+}
+
+IMPL_LINK_NOARG( SvxToolbarConfigPage, AddCommandHdl, weld::Button&, void )
+{
+ AddFunction();
+}
+
+IMPL_LINK_NOARG( SvxToolbarConfigPage, RemoveCommandHdl, weld::Button&, void )
+{
+ DeleteSelectedContent();
+}
+
+IMPL_LINK(SvxToolbarConfigPage, InsertHdl, const OString&, rIdent, void)
+{
+ if (rIdent == "insertseparator")
+ {
+ // Get the currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ SvxConfigEntry* pNewEntryData = new SvxConfigEntry;
+ pNewEntryData->SetUserDefined();
+
+ int nPos = AppendEntry(pNewEntryData, -1);
+ InsertEntryIntoUI(pNewEntryData, m_xContentsListBox->get_widget(), nPos, 1);
+
+ static_cast<ToolbarSaveInData*>( GetSaveInData())->ApplyToolbar( pToolbar );
+
+ UpdateButtonStates();
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+}
+
+IMPL_LINK(SvxToolbarConfigPage, ModifyItemHdl, const OString&, rIdent, void)
+{
+ bool bNeedsApply = false;
+
+ // get currently selected toolbar
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ if (rIdent.isEmpty() || pToolbar == nullptr)
+ {
+ SAL_WARN("cui.customize", "No toolbar selected, or empty rIdent!");
+ return;
+ }
+
+ if (rIdent == "renameItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ OUString aNewName( SvxConfigPageHelper::stripHotKey( pEntry->GetName() ) );
+ OUString aDesc = CuiResId( RID_SVXSTR_LABEL_NEW_NAME );
+
+ SvxNameDialog aNameDialog(GetFrameWeld(), aNewName, aDesc);
+ aNameDialog.set_help_id(HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM);
+ aNameDialog.set_title(CuiResId(RID_SVXSTR_RENAME_TOOLBAR));
+
+ if (aNameDialog.run() == RET_OK)
+ {
+ aNewName = aNameDialog.GetName();
+
+ if( aNewName.isEmpty() ) // tdf#80758 - Accelerator character ("~") is passed as
+ pEntry->SetName( "~" ); // the button name in case of empty values.
+ else
+ pEntry->SetName( aNewName );
+
+ m_xContentsListBox->set_text(nActEntry, aNewName, 2);
+ bNeedsApply = true;
+ }
+ }
+ else if (rIdent == "changeIcon")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ SvxIconSelectorDialog aIconDialog(GetFrameWeld(),
+ GetSaveInData()->GetImageManager(),
+ GetSaveInData()->GetParentImageManager());
+
+ if (aIconDialog.run() == RET_OK)
+ {
+ css::uno::Reference< css::graphic::XGraphic > newgraphic =
+ aIconDialog.GetSelectedIcon();
+
+ if ( newgraphic.is() )
+ {
+ css::uno::Sequence< css::uno::Reference< css::graphic::XGraphic > >
+ aGraphicSeq( 1 );
+
+ css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };
+
+ if ( !pEntry->GetBackupGraphic().is() )
+ {
+ css::uno::Reference< css::graphic::XGraphic > backup =
+ SvxConfigPageHelper::GetGraphic(GetSaveInData()->GetImageManager(),
+ aURLSeq[0]);
+
+ if ( backup.is() )
+ {
+ pEntry->SetBackupGraphic(backup);
+ }
+ }
+
+ aGraphicSeq[ 0 ] = newgraphic;
+ try
+ {
+ GetSaveInData()->GetImageManager()->replaceImages(
+ SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq );
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry, pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry, 1);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ GetSaveInData()->PersistChanges(
+ GetSaveInData()->GetImageManager() );
+ }
+ catch ( const css::uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error replacing image");
+ }
+ }
+ }
+ }
+ else if (rIdent == "resetIcon")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ css::uno::Reference< css::graphic::XGraphic > backup =
+ pEntry->GetBackupGraphic();
+
+ css::uno::Sequence< css::uno::Reference< css::graphic::XGraphic > >
+ aGraphicSeq( 1 );
+ aGraphicSeq[ 0 ] = backup;
+
+ css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };
+
+ try
+ {
+ GetSaveInData()->GetImageManager()->replaceImages(
+ SvxConfigPageHelper::GetImageType(), aURLSeq, aGraphicSeq );
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry, pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry, 1);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ // reset backup in entry
+ pEntry->SetBackupGraphic(
+ css::uno::Reference< css::graphic::XGraphic >() );
+
+ GetSaveInData()->PersistChanges(
+ GetSaveInData()->GetImageManager() );
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error resetting image");
+ }
+ }
+ else if (rIdent == "restoreItem")
+ {
+ int nActEntry = m_xContentsListBox->get_selected_index();
+ SvxConfigEntry* pEntry =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nActEntry).toInt64());
+
+ ToolbarSaveInData* pSaveInData =
+ static_cast<ToolbarSaveInData*>( GetSaveInData() );
+
+ OUString aSystemName =
+ pSaveInData->GetSystemUIName( pEntry->GetCommand() );
+
+ if ( !pEntry->GetName().equals( aSystemName ) )
+ {
+ pEntry->SetName( aSystemName );
+ m_xContentsListBox->set_text(
+ nActEntry, SvxConfigPageHelper::stripHotKey(aSystemName), 2);
+ bNeedsApply = true;
+ }
+
+ css::uno::Sequence<OUString> aURLSeq { pEntry->GetCommand() };
+
+ try
+ {
+ GetSaveInData()->GetImageManager()->removeImages(
+ SvxConfigPageHelper::GetImageType(), aURLSeq );
+
+ // reset backup in entry
+ pEntry->SetBackupGraphic(
+ css::uno::Reference< css::graphic::XGraphic >() );
+
+ GetSaveInData()->PersistChanges(
+ GetSaveInData()->GetImageManager() );
+
+ m_xContentsListBox->remove(nActEntry);
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pEntry)));
+ m_xContentsListBox->insert(nActEntry, sId);
+ m_xContentsListBox->set_toggle(nActEntry,
+ pEntry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nActEntry, 1);
+
+ m_xContentsListBox->select(nActEntry);
+ m_xContentsListBox->scroll_to_row(nActEntry);
+
+ bNeedsApply = true;
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Error restoring image");
+ }
+ }
+ else
+ {
+ //This block should never be reached
+ SAL_WARN("cui.customize", "Unknown insert option: " << rIdent);
+ return;
+ }
+
+ if ( bNeedsApply )
+ {
+ static_cast<ToolbarSaveInData*>( GetSaveInData())->ApplyToolbar( pToolbar );
+ UpdateButtonStates();
+ }
+}
+
+IMPL_LINK_NOARG(SvxToolbarConfigPage, ResetToolbarHdl, weld::Button&, void)
+{
+ sal_Int32 nSelectionPos = m_xTopLevelListBox->get_active();
+
+ SvxConfigEntry* pToolbar =
+ reinterpret_cast<SvxConfigEntry*>(m_xTopLevelListBox->get_id(nSelectionPos).toInt64());
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SVXSTR_CONFIRM_RESTORE_DEFAULT)));
+ if (xQueryBox->run() == RET_YES)
+ {
+ ToolbarSaveInData* pSaveInData =
+ static_cast<ToolbarSaveInData*>(GetSaveInData());
+
+ pSaveInData->RestoreToolbar( pToolbar );
+
+ SelectElement();
+ }
+}
+
+void SvxToolbarConfigPage::UpdateButtonStates()
+{
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ int selection = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator =
+ selection != -1 && reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(selection).toInt64())->IsSeparator();
+ bool bIsValidSelection =
+ !(m_xContentsListBox->n_children() == 0 || selection == -1);
+
+ m_xMoveUpButton->set_sensitive( bIsValidSelection );
+ m_xMoveDownButton->set_sensitive( bIsValidSelection );
+
+ m_xRemoveCommandButton->set_sensitive( bIsValidSelection );
+
+ m_xModifyBtn->set_sensitive( bIsValidSelection && !bIsSeparator );
+
+ // Handle the gear button
+ // "toolbar_gear_add" option is always enabled
+ m_xGearBtn->set_item_sensitive("toolbar_gear_delete", pToolbar && pToolbar->IsDeletable());
+ m_xGearBtn->set_item_sensitive("toolbar_gear_rename", pToolbar && pToolbar->IsRenamable());
+}
+
+short SvxToolbarConfigPage::QueryReset()
+{
+ OUString msg = CuiResId( RID_SVXSTR_CONFIRM_TOOLBAR_RESET );
+
+ OUString saveInName = m_xSaveInListBox->get_active_text();
+
+ OUString label = SvxConfigPageHelper::replaceSaveInName( msg, saveInName );
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ label));
+ return xQueryBox->run();
+}
+
+void SvxToolbarConfigPage::SelectElement()
+{
+ m_xContentsListBox->clear();
+
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+ if ( pToolbar == nullptr )
+ {
+ //TODO: Disable related buttons
+ m_xInsertBtn->set_sensitive( false );
+ m_xResetBtn->set_sensitive( false );
+ m_xGearBtn->set_sensitive( false );
+
+ return;
+ }
+ else
+ {
+ m_xInsertBtn->set_sensitive(true);
+ m_xResetBtn->set_sensitive(true);
+ m_xGearBtn->set_sensitive(true);
+ }
+
+ switch (pToolbar->GetStyle())
+ {
+ case 0:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_iconOnly", true);
+ break;
+ }
+ case 1:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_textOnly", true);
+ break;
+ }
+ case 2:
+ {
+ m_xGearBtn->set_item_active("toolbar_gear_iconAndText", true);
+ break;
+ }
+ }
+
+ int i = 0;
+ SvxEntries* pEntries = pToolbar->GetEntries();
+ for (auto const& entry : *pEntries)
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(entry)));
+ m_xContentsListBox->insert(i, sId);
+ if (entry->IsBinding() && !entry->IsSeparator())
+ m_xContentsListBox->set_toggle(i, entry->IsVisible() ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ InsertEntryIntoUI(entry, m_xContentsListBox->get_widget(), i, 1);
+ ++i;
+ }
+
+ UpdateButtonStates();
+}
+
+void SvxToolbarConfigPage::AddFunction(int nTarget)
+{
+ SvxConfigEntry* pToolbar = GetTopLevelSelection();
+
+ if (pToolbar == nullptr)
+ return;
+
+ // Add the command to the contents listbox of the selected toolbar
+ int nNewLBEntry =
+ SvxConfigPage::AddFunction(nTarget, true/*bAllowDuplicates*/);
+
+ if (nNewLBEntry == -1)
+ return;
+
+ SvxConfigEntry* pEntry = reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nNewLBEntry).toInt64());
+
+ if ( pEntry->IsBinding() ) //TODO sep ?
+ {
+ pEntry->SetVisible(true);
+ m_xContentsListBox->set_toggle(nNewLBEntry, TRISTATE_TRUE, 0);
+ }
+
+ InsertEntryIntoUI(pEntry, m_xContentsListBox->get_widget(), nNewLBEntry, 1);
+
+ // Changes are not visible on the toolbar until this point
+ // TODO: Figure out a way to show the changes on the toolbar, but revert if
+ // the dialog is closed by pressing "Cancel"
+ // get currently selected toolbar and apply change
+ if ( pToolbar != nullptr )
+ {
+ static_cast<ToolbarSaveInData*>( GetSaveInData() )->ApplyToolbar( pToolbar );
+ }
+}
+
+SvxToolbarEntriesListBox::SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xParent, SvxToolbarConfigPage* pPg)
+ : SvxMenuEntriesListBox(std::move(xParent), pPg)
+{
+ m_xControl->connect_toggled(LINK(this, SvxToolbarEntriesListBox, CheckButtonHdl));
+ m_xControl->connect_key_press(Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
+ m_xControl->connect_key_press(LINK(this, SvxToolbarEntriesListBox, KeyInputHdl)); // then add the new one
+}
+
+SvxToolbarEntriesListBox::~SvxToolbarEntriesListBox()
+{
+}
+
+void SvxToolbarEntriesListBox::ChangedVisibility(int nRow)
+{
+ SvxConfigEntry* pEntryData =
+ reinterpret_cast<SvxConfigEntry*>(m_xControl->get_id(nRow).toInt64());
+
+ if (pEntryData->IsBinding())
+ {
+ pEntryData->SetVisible(m_xControl->get_toggle(nRow, 0) == TRISTATE_TRUE);
+
+ SvxConfigEntry* pToolbar = m_pPage->GetTopLevelSelection();
+
+ ToolbarSaveInData* pToolbarSaveInData = static_cast<ToolbarSaveInData*>(
+ m_pPage->GetSaveInData() );
+
+ pToolbarSaveInData->ApplyToolbar( pToolbar );
+ }
+}
+
+IMPL_LINK(SvxToolbarEntriesListBox, CheckButtonHdl, const row_col&, rRowCol, void)
+{
+ ChangedVisibility(rRowCol.first);
+}
+
+IMPL_LINK(SvxToolbarEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ // space key will change visibility of toolbar items
+ if ( rKeyEvent.GetKeyCode() == KEY_SPACE )
+ {
+ int nRow = m_xControl->get_selected_index();
+ SvxConfigEntry* pEntryData = reinterpret_cast<SvxConfigEntry*>(m_xControl->get_id(nRow).toInt64());
+ if (pEntryData->IsBinding() && !pEntryData->IsSeparator())
+ {
+ m_xControl->set_toggle(nRow, m_xControl->get_toggle(nRow, 0) == TRISTATE_TRUE ? TRISTATE_FALSE : TRISTATE_TRUE, 0);
+ ChangedVisibility(nRow);
+ }
+ return true;
+ }
+ return SvxMenuEntriesListBox::KeyInputHdl(rKeyEvent);
+}
+
+IMPL_LINK( SvxToolbarConfigPage, ContentContextMenuHdl, const CommandEvent&, rCEvt, bool )
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> rIter(rTreeView.make_iterator());
+ if (! rTreeView.get_dest_row_at_pos( rCEvt.GetMousePosPixel(), &*rIter ))
+ return false;
+ rTreeView.select(*rIter);
+ SelectToolbarEntry( rTreeView );
+
+ int nSelectIndex = m_xContentsListBox->get_selected_index();
+
+ bool bIsSeparator =
+ nSelectIndex != -1 && reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nSelectIndex).toInt64())->IsSeparator();
+ bool bIsValidSelection =
+ !( m_xContentsListBox->n_children() == 0 || nSelectIndex == -1 );
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder( &rTreeView, "cui/ui/entrycontextmenu.ui" ) );
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", false);
+ xContextMenu->set_visible("remove", bIsValidSelection);
+ xContextMenu->set_visible("rename", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("changeIcon", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("resetIcon", bIsValidSelection && !bIsSeparator);
+ xContextMenu->set_visible("restoreDefault", bIsValidSelection && !bIsSeparator);
+ OString sCommand(xContextMenu->popup_at_rect( &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1) ) ) );
+
+ if ( sCommand == "remove")
+ RemoveCommandHdl( *m_xRemoveCommandButton );
+ else if ( sCommand == "rename" )
+ ModifyItemHdl( "renameItem" );
+ else if ( sCommand == "changeIcon" )
+ ModifyItemHdl( "changeIcon" );
+ else if ( sCommand == "resetIcon" )
+ ModifyItemHdl( "resetIcon" );
+ else if ( sCommand == "restoreDefault" )
+ ModifyItemHdl( "restoreItem" );
+ else if ( !sCommand.isEmpty() )
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
+ return true;
+}
+
+IMPL_LINK( SvxToolbarConfigPage, FunctionContextMenuHdl, const CommandEvent&, rCEvt, bool )
+{
+ if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
+ return false;
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+
+ // Select clicked entry
+ std::unique_ptr<weld::TreeIter> rIter(rTreeView.make_iterator());
+ if (! rTreeView.get_dest_row_at_pos( rCEvt.GetMousePosPixel(), &*rIter ))
+ return false;
+ rTreeView.select(*rIter);
+ SelectFunctionHdl( rTreeView );
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder( &rTreeView, "cui/ui/entrycontextmenu.ui" ) );
+ auto xContextMenu = xBuilder->weld_menu("menu");
+ xContextMenu->set_visible("add", true);
+ xContextMenu->set_visible("remove", false);
+ xContextMenu->set_visible("rename", false);
+ xContextMenu->set_visible("changeIcon", false);
+ xContextMenu->set_visible("resetIcon", false);
+ xContextMenu->set_visible("restoreDefault", false);
+ OString sCommand(xContextMenu->popup_at_rect( &rTreeView, tools::Rectangle(rCEvt.GetMousePosPixel(), Size(1,1) ) ) );
+
+ if ( sCommand == "add")
+ AddCommandHdl( *m_xAddCommandButton );
+ else if ( !sCommand.isEmpty() )
+ SAL_WARN("cui.customize", "Unknown context menu action: " << sCommand );
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/acccfg.cxx b/cui/source/customize/acccfg.cxx
new file mode 100644
index 000000000..2ae4f9501
--- /dev/null
+++ b/cui/source/customize/acccfg.cxx
@@ -0,0 +1,1593 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+// include own files
+
+#include <acccfg.hxx>
+#include <cfgutil.hxx>
+#include <dialmgr.hxx>
+
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/minfitem.hxx>
+#include <sfx2/sfxresid.hxx>
+
+#include <sal/macros.h>
+#include <vcl/event.hxx>
+
+#include <strings.hrc>
+#include <sfx2/strings.hrc>
+#include <svx/svxids.hrc>
+
+// include interface declarations
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/embed/StorageFactory.hpp>
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/form/XReset.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/ui/GlobalAcceleratorConfiguration.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/UIConfigurationManager.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+// include search util
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <unotools/textsearch.hxx>
+
+// include other projects
+#include <comphelper/processfactory.hxx>
+#include <svtools/acceleratorexecute.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+// namespaces
+
+using namespace css;
+
+static const char FOLDERNAME_UICONFIG[] = "Configurations2";
+
+static const char MEDIATYPE_PROPNAME[] = "MediaType";
+
+static const sal_uInt16 KEYCODE_ARRAY[] = { KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ KEY_F7,
+ KEY_F8,
+ KEY_F9,
+ KEY_F10,
+ KEY_F11,
+ KEY_F12,
+ KEY_F13,
+ KEY_F14,
+ KEY_F15,
+ KEY_F16,
+
+ KEY_DOWN,
+ KEY_UP,
+ KEY_LEFT,
+ KEY_RIGHT,
+ KEY_HOME,
+ KEY_END,
+ KEY_PAGEUP,
+ KEY_PAGEDOWN,
+ KEY_RETURN,
+ KEY_ESCAPE,
+ KEY_BACKSPACE,
+ KEY_INSERT,
+ KEY_DELETE,
+
+ KEY_OPEN,
+ KEY_CUT,
+ KEY_COPY,
+ KEY_PASTE,
+ KEY_UNDO,
+ KEY_REPEAT,
+ KEY_FIND,
+ KEY_PROPERTIES,
+ KEY_FRONT,
+ KEY_CONTEXTMENU,
+ KEY_MENU,
+ KEY_HELP,
+
+ KEY_SHIFT | KEY_F1,
+ KEY_SHIFT | KEY_F2,
+ KEY_SHIFT | KEY_F3,
+ KEY_SHIFT | KEY_F4,
+ KEY_SHIFT | KEY_F5,
+ KEY_SHIFT | KEY_F6,
+ KEY_SHIFT | KEY_F7,
+ KEY_SHIFT | KEY_F8,
+ KEY_SHIFT | KEY_F9,
+ KEY_SHIFT | KEY_F10,
+ KEY_SHIFT | KEY_F11,
+ KEY_SHIFT | KEY_F12,
+ KEY_SHIFT | KEY_F13,
+ KEY_SHIFT | KEY_F14,
+ KEY_SHIFT | KEY_F15,
+ KEY_SHIFT | KEY_F16,
+
+ KEY_SHIFT | KEY_DOWN,
+ KEY_SHIFT | KEY_UP,
+ KEY_SHIFT | KEY_LEFT,
+ KEY_SHIFT | KEY_RIGHT,
+ KEY_SHIFT | KEY_HOME,
+ KEY_SHIFT | KEY_END,
+ KEY_SHIFT | KEY_PAGEUP,
+ KEY_SHIFT | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_RETURN,
+ KEY_SHIFT | KEY_SPACE,
+ KEY_SHIFT | KEY_ESCAPE,
+ KEY_SHIFT | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_INSERT,
+ KEY_SHIFT | KEY_DELETE,
+ KEY_SHIFT | KEY_EQUAL,
+
+ KEY_MOD1 | KEY_0,
+ KEY_MOD1 | KEY_1,
+ KEY_MOD1 | KEY_2,
+ KEY_MOD1 | KEY_3,
+ KEY_MOD1 | KEY_4,
+ KEY_MOD1 | KEY_5,
+ KEY_MOD1 | KEY_6,
+ KEY_MOD1 | KEY_7,
+ KEY_MOD1 | KEY_8,
+ KEY_MOD1 | KEY_9,
+ KEY_MOD1 | KEY_A,
+ KEY_MOD1 | KEY_B,
+ KEY_MOD1 | KEY_C,
+ KEY_MOD1 | KEY_D,
+ KEY_MOD1 | KEY_E,
+ KEY_MOD1 | KEY_F,
+ KEY_MOD1 | KEY_G,
+ KEY_MOD1 | KEY_H,
+ KEY_MOD1 | KEY_I,
+ KEY_MOD1 | KEY_J,
+ KEY_MOD1 | KEY_K,
+ KEY_MOD1 | KEY_L,
+ KEY_MOD1 | KEY_M,
+ KEY_MOD1 | KEY_N,
+ KEY_MOD1 | KEY_O,
+ KEY_MOD1 | KEY_P,
+ KEY_MOD1 | KEY_Q,
+ KEY_MOD1 | KEY_R,
+ KEY_MOD1 | KEY_S,
+ KEY_MOD1 | KEY_T,
+ KEY_MOD1 | KEY_U,
+ KEY_MOD1 | KEY_V,
+ KEY_MOD1 | KEY_W,
+ KEY_MOD1 | KEY_X,
+ KEY_MOD1 | KEY_Y,
+ KEY_MOD1 | KEY_Z,
+ KEY_MOD1 | KEY_SEMICOLON,
+ KEY_MOD1 | KEY_QUOTERIGHT,
+ KEY_MOD1 | KEY_BRACKETLEFT,
+ KEY_MOD1 | KEY_BRACKETRIGHT,
+ KEY_MOD1 | KEY_POINT,
+ KEY_MOD1 | KEY_COMMA,
+ KEY_MOD1 | KEY_TILDE,
+ KEY_MOD1 | KEY_TAB,
+
+ KEY_MOD1 | KEY_F1,
+ KEY_MOD1 | KEY_F2,
+ KEY_MOD1 | KEY_F3,
+ KEY_MOD1 | KEY_F4,
+ KEY_MOD1 | KEY_F5,
+ KEY_MOD1 | KEY_F6,
+ KEY_MOD1 | KEY_F7,
+ KEY_MOD1 | KEY_F8,
+ KEY_MOD1 | KEY_F9,
+ KEY_MOD1 | KEY_F10,
+ KEY_MOD1 | KEY_F11,
+ KEY_MOD1 | KEY_F12,
+ KEY_MOD1 | KEY_F13,
+ KEY_MOD1 | KEY_F14,
+ KEY_MOD1 | KEY_F15,
+ KEY_MOD1 | KEY_F16,
+
+ KEY_MOD1 | KEY_DOWN,
+ KEY_MOD1 | KEY_UP,
+ KEY_MOD1 | KEY_LEFT,
+ KEY_MOD1 | KEY_RIGHT,
+ KEY_MOD1 | KEY_HOME,
+ KEY_MOD1 | KEY_END,
+ KEY_MOD1 | KEY_PAGEUP,
+ KEY_MOD1 | KEY_PAGEDOWN,
+ KEY_MOD1 | KEY_RETURN,
+ KEY_MOD1 | KEY_SPACE,
+ KEY_MOD1 | KEY_BACKSPACE,
+ KEY_MOD1 | KEY_INSERT,
+ KEY_MOD1 | KEY_DELETE,
+
+ KEY_MOD1 | KEY_ADD,
+ KEY_MOD1 | KEY_SUBTRACT,
+ KEY_MOD1 | KEY_MULTIPLY,
+ KEY_MOD1 | KEY_DIVIDE,
+ KEY_MOD1 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_0,
+ KEY_SHIFT | KEY_MOD1 | KEY_1,
+ KEY_SHIFT | KEY_MOD1 | KEY_2,
+ KEY_SHIFT | KEY_MOD1 | KEY_3,
+ KEY_SHIFT | KEY_MOD1 | KEY_4,
+ KEY_SHIFT | KEY_MOD1 | KEY_5,
+ KEY_SHIFT | KEY_MOD1 | KEY_6,
+ KEY_SHIFT | KEY_MOD1 | KEY_7,
+ KEY_SHIFT | KEY_MOD1 | KEY_8,
+ KEY_SHIFT | KEY_MOD1 | KEY_9,
+ KEY_SHIFT | KEY_MOD1 | KEY_A,
+ KEY_SHIFT | KEY_MOD1 | KEY_B,
+ KEY_SHIFT | KEY_MOD1 | KEY_C,
+ KEY_SHIFT | KEY_MOD1 | KEY_D,
+ KEY_SHIFT | KEY_MOD1 | KEY_E,
+ KEY_SHIFT | KEY_MOD1 | KEY_F,
+ KEY_SHIFT | KEY_MOD1 | KEY_G,
+ KEY_SHIFT | KEY_MOD1 | KEY_H,
+ KEY_SHIFT | KEY_MOD1 | KEY_I,
+ KEY_SHIFT | KEY_MOD1 | KEY_J,
+ KEY_SHIFT | KEY_MOD1 | KEY_K,
+ KEY_SHIFT | KEY_MOD1 | KEY_L,
+ KEY_SHIFT | KEY_MOD1 | KEY_M,
+ KEY_SHIFT | KEY_MOD1 | KEY_N,
+ KEY_SHIFT | KEY_MOD1 | KEY_O,
+ KEY_SHIFT | KEY_MOD1 | KEY_P,
+ KEY_SHIFT | KEY_MOD1 | KEY_Q,
+ KEY_SHIFT | KEY_MOD1 | KEY_R,
+ KEY_SHIFT | KEY_MOD1 | KEY_S,
+ KEY_SHIFT | KEY_MOD1 | KEY_T,
+ KEY_SHIFT | KEY_MOD1 | KEY_U,
+ KEY_SHIFT | KEY_MOD1 | KEY_V,
+ KEY_SHIFT | KEY_MOD1 | KEY_W,
+ KEY_SHIFT | KEY_MOD1 | KEY_X,
+ KEY_SHIFT | KEY_MOD1 | KEY_Y,
+ KEY_SHIFT | KEY_MOD1 | KEY_Z,
+ KEY_SHIFT | KEY_MOD1 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD1 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD1 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD1 | KEY_TILDE,
+ KEY_SHIFT | KEY_MOD1 | KEY_TAB,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_F1,
+ KEY_SHIFT | KEY_MOD1 | KEY_F2,
+ KEY_SHIFT | KEY_MOD1 | KEY_F3,
+ KEY_SHIFT | KEY_MOD1 | KEY_F4,
+ KEY_SHIFT | KEY_MOD1 | KEY_F5,
+ KEY_SHIFT | KEY_MOD1 | KEY_F6,
+ KEY_SHIFT | KEY_MOD1 | KEY_F7,
+ KEY_SHIFT | KEY_MOD1 | KEY_F8,
+ KEY_SHIFT | KEY_MOD1 | KEY_F9,
+ KEY_SHIFT | KEY_MOD1 | KEY_F10,
+ KEY_SHIFT | KEY_MOD1 | KEY_F11,
+ KEY_SHIFT | KEY_MOD1 | KEY_F12,
+ KEY_SHIFT | KEY_MOD1 | KEY_F13,
+ KEY_SHIFT | KEY_MOD1 | KEY_F14,
+ KEY_SHIFT | KEY_MOD1 | KEY_F15,
+ KEY_SHIFT | KEY_MOD1 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_UP,
+ KEY_SHIFT | KEY_MOD1 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD1 | KEY_END,
+ KEY_SHIFT | KEY_MOD1 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD1 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD1 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD1 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD1 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD1 | KEY_EQUAL,
+
+ KEY_MOD2 | KEY_0,
+ KEY_MOD2 | KEY_1,
+ KEY_MOD2 | KEY_2,
+ KEY_MOD2 | KEY_3,
+ KEY_MOD2 | KEY_4,
+ KEY_MOD2 | KEY_5,
+ KEY_MOD2 | KEY_6,
+ KEY_MOD2 | KEY_7,
+ KEY_MOD2 | KEY_8,
+ KEY_MOD2 | KEY_9,
+ KEY_MOD2 | KEY_A,
+ KEY_MOD2 | KEY_B,
+ KEY_MOD2 | KEY_C,
+ KEY_MOD2 | KEY_D,
+ KEY_MOD2 | KEY_E,
+ KEY_MOD2 | KEY_F,
+ KEY_MOD2 | KEY_G,
+ KEY_MOD2 | KEY_H,
+ KEY_MOD2 | KEY_I,
+ KEY_MOD2 | KEY_J,
+ KEY_MOD2 | KEY_K,
+ KEY_MOD2 | KEY_L,
+ KEY_MOD2 | KEY_M,
+ KEY_MOD2 | KEY_N,
+ KEY_MOD2 | KEY_O,
+ KEY_MOD2 | KEY_P,
+ KEY_MOD2 | KEY_Q,
+ KEY_MOD2 | KEY_R,
+ KEY_MOD2 | KEY_S,
+ KEY_MOD2 | KEY_T,
+ KEY_MOD2 | KEY_U,
+ KEY_MOD2 | KEY_V,
+ KEY_MOD2 | KEY_W,
+ KEY_MOD2 | KEY_X,
+ KEY_MOD2 | KEY_Y,
+ KEY_MOD2 | KEY_Z,
+ KEY_MOD2 | KEY_SEMICOLON,
+ KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_MOD2 | KEY_POINT,
+ KEY_MOD2 | KEY_COMMA,
+ KEY_MOD2 | KEY_TILDE,
+
+ KEY_MOD2 | KEY_F1,
+ KEY_MOD2 | KEY_F2,
+ KEY_MOD2 | KEY_F3,
+ KEY_MOD2 | KEY_F4,
+ KEY_MOD2 | KEY_F5,
+ KEY_MOD2 | KEY_F6,
+ KEY_MOD2 | KEY_F7,
+ KEY_MOD2 | KEY_F8,
+ KEY_MOD2 | KEY_F9,
+ KEY_MOD2 | KEY_F10,
+ KEY_MOD2 | KEY_F11,
+ KEY_MOD2 | KEY_F12,
+ KEY_MOD2 | KEY_F13,
+ KEY_MOD2 | KEY_F14,
+ KEY_MOD2 | KEY_F15,
+ KEY_MOD2 | KEY_F16,
+
+ KEY_MOD2 | KEY_DOWN,
+ KEY_MOD2 | KEY_UP,
+ KEY_MOD2 | KEY_LEFT,
+ KEY_MOD2 | KEY_RIGHT,
+ KEY_MOD2 | KEY_HOME,
+ KEY_MOD2 | KEY_END,
+ KEY_MOD2 | KEY_PAGEUP,
+ KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_MOD2 | KEY_RETURN,
+ KEY_MOD2 | KEY_SPACE,
+ KEY_MOD2 | KEY_BACKSPACE,
+ KEY_MOD2 | KEY_INSERT,
+ KEY_MOD2 | KEY_DELETE,
+ KEY_MOD2 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_0,
+ KEY_SHIFT | KEY_MOD2 | KEY_1,
+ KEY_SHIFT | KEY_MOD2 | KEY_2,
+ KEY_SHIFT | KEY_MOD2 | KEY_3,
+ KEY_SHIFT | KEY_MOD2 | KEY_4,
+ KEY_SHIFT | KEY_MOD2 | KEY_5,
+ KEY_SHIFT | KEY_MOD2 | KEY_6,
+ KEY_SHIFT | KEY_MOD2 | KEY_7,
+ KEY_SHIFT | KEY_MOD2 | KEY_8,
+ KEY_SHIFT | KEY_MOD2 | KEY_9,
+ KEY_SHIFT | KEY_MOD2 | KEY_A,
+ KEY_SHIFT | KEY_MOD2 | KEY_B,
+ KEY_SHIFT | KEY_MOD2 | KEY_C,
+ KEY_SHIFT | KEY_MOD2 | KEY_D,
+ KEY_SHIFT | KEY_MOD2 | KEY_E,
+ KEY_SHIFT | KEY_MOD2 | KEY_F,
+ KEY_SHIFT | KEY_MOD2 | KEY_G,
+ KEY_SHIFT | KEY_MOD2 | KEY_H,
+ KEY_SHIFT | KEY_MOD2 | KEY_I,
+ KEY_SHIFT | KEY_MOD2 | KEY_J,
+ KEY_SHIFT | KEY_MOD2 | KEY_K,
+ KEY_SHIFT | KEY_MOD2 | KEY_L,
+ KEY_SHIFT | KEY_MOD2 | KEY_M,
+ KEY_SHIFT | KEY_MOD2 | KEY_N,
+ KEY_SHIFT | KEY_MOD2 | KEY_O,
+ KEY_SHIFT | KEY_MOD2 | KEY_P,
+ KEY_SHIFT | KEY_MOD2 | KEY_Q,
+ KEY_SHIFT | KEY_MOD2 | KEY_R,
+ KEY_SHIFT | KEY_MOD2 | KEY_S,
+ KEY_SHIFT | KEY_MOD2 | KEY_T,
+ KEY_SHIFT | KEY_MOD2 | KEY_U,
+ KEY_SHIFT | KEY_MOD2 | KEY_V,
+ KEY_SHIFT | KEY_MOD2 | KEY_W,
+ KEY_SHIFT | KEY_MOD2 | KEY_X,
+ KEY_SHIFT | KEY_MOD2 | KEY_Y,
+ KEY_SHIFT | KEY_MOD2 | KEY_Z,
+ KEY_SHIFT | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD2 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD2 | KEY_TILDE,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_F1,
+ KEY_SHIFT | KEY_MOD2 | KEY_F2,
+ KEY_SHIFT | KEY_MOD2 | KEY_F3,
+ KEY_SHIFT | KEY_MOD2 | KEY_F4,
+ KEY_SHIFT | KEY_MOD2 | KEY_F5,
+ KEY_SHIFT | KEY_MOD2 | KEY_F6,
+ KEY_SHIFT | KEY_MOD2 | KEY_F7,
+ KEY_SHIFT | KEY_MOD2 | KEY_F8,
+ KEY_SHIFT | KEY_MOD2 | KEY_F9,
+ KEY_SHIFT | KEY_MOD2 | KEY_F10,
+ KEY_SHIFT | KEY_MOD2 | KEY_F11,
+ KEY_SHIFT | KEY_MOD2 | KEY_F12,
+ KEY_SHIFT | KEY_MOD2 | KEY_F13,
+ KEY_SHIFT | KEY_MOD2 | KEY_F14,
+ KEY_SHIFT | KEY_MOD2 | KEY_F15,
+ KEY_SHIFT | KEY_MOD2 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD2 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD2 | KEY_UP,
+ KEY_SHIFT | KEY_MOD2 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD2 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD2 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD2 | KEY_END,
+ KEY_SHIFT | KEY_MOD2 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD2 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD2 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD2 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD2 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD2 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD2 | KEY_EQUAL,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_0,
+ KEY_MOD1 | KEY_MOD2 | KEY_1,
+ KEY_MOD1 | KEY_MOD2 | KEY_2,
+ KEY_MOD1 | KEY_MOD2 | KEY_3,
+ KEY_MOD1 | KEY_MOD2 | KEY_4,
+ KEY_MOD1 | KEY_MOD2 | KEY_5,
+ KEY_MOD1 | KEY_MOD2 | KEY_6,
+ KEY_MOD1 | KEY_MOD2 | KEY_7,
+ KEY_MOD1 | KEY_MOD2 | KEY_8,
+ KEY_MOD1 | KEY_MOD2 | KEY_9,
+ KEY_MOD1 | KEY_MOD2 | KEY_A,
+ KEY_MOD1 | KEY_MOD2 | KEY_B,
+ KEY_MOD1 | KEY_MOD2 | KEY_C,
+ KEY_MOD1 | KEY_MOD2 | KEY_D,
+ KEY_MOD1 | KEY_MOD2 | KEY_E,
+ KEY_MOD1 | KEY_MOD2 | KEY_F,
+ KEY_MOD1 | KEY_MOD2 | KEY_G,
+ KEY_MOD1 | KEY_MOD2 | KEY_H,
+ KEY_MOD1 | KEY_MOD2 | KEY_I,
+ KEY_MOD1 | KEY_MOD2 | KEY_J,
+ KEY_MOD1 | KEY_MOD2 | KEY_K,
+ KEY_MOD1 | KEY_MOD2 | KEY_L,
+ KEY_MOD1 | KEY_MOD2 | KEY_M,
+ KEY_MOD1 | KEY_MOD2 | KEY_N,
+ KEY_MOD1 | KEY_MOD2 | KEY_O,
+ KEY_MOD1 | KEY_MOD2 | KEY_P,
+ KEY_MOD1 | KEY_MOD2 | KEY_Q,
+ KEY_MOD1 | KEY_MOD2 | KEY_R,
+ KEY_MOD1 | KEY_MOD2 | KEY_S,
+ KEY_MOD1 | KEY_MOD2 | KEY_T,
+ KEY_MOD1 | KEY_MOD2 | KEY_U,
+ KEY_MOD1 | KEY_MOD2 | KEY_V,
+ KEY_MOD1 | KEY_MOD2 | KEY_W,
+ KEY_MOD1 | KEY_MOD2 | KEY_X,
+ KEY_MOD1 | KEY_MOD2 | KEY_Y,
+ KEY_MOD1 | KEY_MOD2 | KEY_Z,
+ KEY_MOD1 | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_MOD1 | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_MOD1 | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_POINT,
+ KEY_MOD1 | KEY_MOD2 | KEY_COMMA,
+ KEY_MOD1 | KEY_MOD2 | KEY_TILDE,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_F1,
+ KEY_MOD1 | KEY_MOD2 | KEY_F2,
+ KEY_MOD1 | KEY_MOD2 | KEY_F3,
+ KEY_MOD1 | KEY_MOD2 | KEY_F4,
+ KEY_MOD1 | KEY_MOD2 | KEY_F5,
+ KEY_MOD1 | KEY_MOD2 | KEY_F6,
+ KEY_MOD1 | KEY_MOD2 | KEY_F7,
+ KEY_MOD1 | KEY_MOD2 | KEY_F8,
+ KEY_MOD1 | KEY_MOD2 | KEY_F9,
+ KEY_MOD1 | KEY_MOD2 | KEY_F10,
+ KEY_MOD1 | KEY_MOD2 | KEY_F11,
+ KEY_MOD1 | KEY_MOD2 | KEY_F12,
+ KEY_MOD1 | KEY_MOD2 | KEY_F13,
+ KEY_MOD1 | KEY_MOD2 | KEY_F14,
+ KEY_MOD1 | KEY_MOD2 | KEY_F15,
+ KEY_MOD1 | KEY_MOD2 | KEY_F16,
+
+ KEY_MOD1 | KEY_MOD2 | KEY_DOWN,
+ KEY_MOD1 | KEY_MOD2 | KEY_UP,
+ KEY_MOD1 | KEY_MOD2 | KEY_LEFT,
+ KEY_MOD1 | KEY_MOD2 | KEY_RIGHT,
+ KEY_MOD1 | KEY_MOD2 | KEY_HOME,
+ KEY_MOD1 | KEY_MOD2 | KEY_END,
+ KEY_MOD1 | KEY_MOD2 | KEY_PAGEUP,
+ KEY_MOD1 | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_MOD1 | KEY_MOD2 | KEY_RETURN,
+ KEY_MOD1 | KEY_MOD2 | KEY_SPACE,
+ KEY_MOD1 | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_MOD1 | KEY_MOD2 | KEY_INSERT,
+ KEY_MOD1 | KEY_MOD2 | KEY_DELETE,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_0,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_1,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_2,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_3,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_4,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_5,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_6,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_7,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_8,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_9,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_A,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_B,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_C,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_D,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_E,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_G,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_H,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_I,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_J,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_K,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_L,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_M,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_N,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_O,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_P,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Q,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_R,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_S,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_T,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_U,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_V,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_W,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_X,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Y,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_Z,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_TILDE,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F1,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F2,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F3,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F4,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F5,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F6,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F7,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F8,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F9,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F10,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F11,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F12,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F13,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F14,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F15,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_UP,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_END,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD1 | KEY_MOD2 | KEY_EQUAL
+
+#ifdef __APPLE__
+ ,
+ KEY_MOD3 | KEY_0,
+ KEY_MOD3 | KEY_1,
+ KEY_MOD3 | KEY_2,
+ KEY_MOD3 | KEY_3,
+ KEY_MOD3 | KEY_4,
+ KEY_MOD3 | KEY_5,
+ KEY_MOD3 | KEY_6,
+ KEY_MOD3 | KEY_7,
+ KEY_MOD3 | KEY_8,
+ KEY_MOD3 | KEY_9,
+ KEY_MOD3 | KEY_A,
+ KEY_MOD3 | KEY_B,
+ KEY_MOD3 | KEY_C,
+ KEY_MOD3 | KEY_D,
+ KEY_MOD3 | KEY_E,
+ KEY_MOD3 | KEY_F,
+ KEY_MOD3 | KEY_G,
+ KEY_MOD3 | KEY_H,
+ KEY_MOD3 | KEY_I,
+ KEY_MOD3 | KEY_J,
+ KEY_MOD3 | KEY_K,
+ KEY_MOD3 | KEY_L,
+ KEY_MOD3 | KEY_M,
+ KEY_MOD3 | KEY_N,
+ KEY_MOD3 | KEY_O,
+ KEY_MOD3 | KEY_P,
+ KEY_MOD3 | KEY_Q,
+ KEY_MOD3 | KEY_R,
+ KEY_MOD3 | KEY_S,
+ KEY_MOD3 | KEY_T,
+ KEY_MOD3 | KEY_U,
+ KEY_MOD3 | KEY_V,
+ KEY_MOD3 | KEY_W,
+ KEY_MOD3 | KEY_X,
+ KEY_MOD3 | KEY_Y,
+ KEY_MOD3 | KEY_Z,
+ KEY_MOD3 | KEY_SEMICOLON,
+ KEY_MOD3 | KEY_QUOTERIGHT,
+ KEY_MOD3 | KEY_BRACKETLEFT,
+ KEY_MOD3 | KEY_BRACKETRIGHT,
+ KEY_MOD3 | KEY_POINT,
+ KEY_MOD3 | KEY_COMMA,
+ KEY_MOD3 | KEY_TILDE,
+ KEY_MOD3 | KEY_TAB,
+
+ KEY_MOD3 | KEY_F1,
+ KEY_MOD3 | KEY_F2,
+ KEY_MOD3 | KEY_F3,
+ KEY_MOD3 | KEY_F4,
+ KEY_MOD3 | KEY_F5,
+ KEY_MOD3 | KEY_F6,
+ KEY_MOD3 | KEY_F7,
+ KEY_MOD3 | KEY_F8,
+ KEY_MOD3 | KEY_F9,
+ KEY_MOD3 | KEY_F10,
+ KEY_MOD3 | KEY_F11,
+ KEY_MOD3 | KEY_F12,
+ KEY_MOD3 | KEY_F13,
+ KEY_MOD3 | KEY_F14,
+ KEY_MOD3 | KEY_F15,
+ KEY_MOD3 | KEY_F16,
+
+ KEY_MOD3 | KEY_DOWN,
+ KEY_MOD3 | KEY_UP,
+ KEY_MOD3 | KEY_LEFT,
+ KEY_MOD3 | KEY_RIGHT,
+ KEY_MOD3 | KEY_HOME,
+ KEY_MOD3 | KEY_END,
+ KEY_MOD3 | KEY_PAGEUP,
+ KEY_MOD3 | KEY_PAGEDOWN,
+ KEY_MOD3 | KEY_RETURN,
+ KEY_MOD3 | KEY_SPACE,
+ KEY_MOD3 | KEY_BACKSPACE,
+ KEY_MOD3 | KEY_INSERT,
+ KEY_MOD3 | KEY_DELETE,
+
+ KEY_MOD3 | KEY_ADD,
+ KEY_MOD3 | KEY_SUBTRACT,
+ KEY_MOD3 | KEY_MULTIPLY,
+ KEY_MOD3 | KEY_DIVIDE,
+ KEY_MOD3 | KEY_EQUAL,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_0,
+ KEY_SHIFT | KEY_MOD3 | KEY_1,
+ KEY_SHIFT | KEY_MOD3 | KEY_2,
+ KEY_SHIFT | KEY_MOD3 | KEY_3,
+ KEY_SHIFT | KEY_MOD3 | KEY_4,
+ KEY_SHIFT | KEY_MOD3 | KEY_5,
+ KEY_SHIFT | KEY_MOD3 | KEY_6,
+ KEY_SHIFT | KEY_MOD3 | KEY_7,
+ KEY_SHIFT | KEY_MOD3 | KEY_8,
+ KEY_SHIFT | KEY_MOD3 | KEY_9,
+ KEY_SHIFT | KEY_MOD3 | KEY_A,
+ KEY_SHIFT | KEY_MOD3 | KEY_B,
+ KEY_SHIFT | KEY_MOD3 | KEY_C,
+ KEY_SHIFT | KEY_MOD3 | KEY_D,
+ KEY_SHIFT | KEY_MOD3 | KEY_E,
+ KEY_SHIFT | KEY_MOD3 | KEY_F,
+ KEY_SHIFT | KEY_MOD3 | KEY_G,
+ KEY_SHIFT | KEY_MOD3 | KEY_H,
+ KEY_SHIFT | KEY_MOD3 | KEY_I,
+ KEY_SHIFT | KEY_MOD3 | KEY_J,
+ KEY_SHIFT | KEY_MOD3 | KEY_K,
+ KEY_SHIFT | KEY_MOD3 | KEY_L,
+ KEY_SHIFT | KEY_MOD3 | KEY_M,
+ KEY_SHIFT | KEY_MOD3 | KEY_N,
+ KEY_SHIFT | KEY_MOD3 | KEY_O,
+ KEY_SHIFT | KEY_MOD3 | KEY_P,
+ KEY_SHIFT | KEY_MOD3 | KEY_Q,
+ KEY_SHIFT | KEY_MOD3 | KEY_R,
+ KEY_SHIFT | KEY_MOD3 | KEY_S,
+ KEY_SHIFT | KEY_MOD3 | KEY_T,
+ KEY_SHIFT | KEY_MOD3 | KEY_U,
+ KEY_SHIFT | KEY_MOD3 | KEY_V,
+ KEY_SHIFT | KEY_MOD3 | KEY_W,
+ KEY_SHIFT | KEY_MOD3 | KEY_X,
+ KEY_SHIFT | KEY_MOD3 | KEY_Y,
+ KEY_SHIFT | KEY_MOD3 | KEY_Z,
+ KEY_SHIFT | KEY_MOD3 | KEY_SEMICOLON,
+ KEY_SHIFT | KEY_MOD3 | KEY_QUOTERIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_BRACKETLEFT,
+ KEY_SHIFT | KEY_MOD3 | KEY_BRACKETRIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_POINT,
+ KEY_SHIFT | KEY_MOD3 | KEY_COMMA,
+ KEY_SHIFT | KEY_MOD3 | KEY_TILDE,
+ KEY_SHIFT | KEY_MOD3 | KEY_TAB,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_F1,
+ KEY_SHIFT | KEY_MOD3 | KEY_F2,
+ KEY_SHIFT | KEY_MOD3 | KEY_F3,
+ KEY_SHIFT | KEY_MOD3 | KEY_F4,
+ KEY_SHIFT | KEY_MOD3 | KEY_F5,
+ KEY_SHIFT | KEY_MOD3 | KEY_F6,
+ KEY_SHIFT | KEY_MOD3 | KEY_F7,
+ KEY_SHIFT | KEY_MOD3 | KEY_F8,
+ KEY_SHIFT | KEY_MOD3 | KEY_F9,
+ KEY_SHIFT | KEY_MOD3 | KEY_F10,
+ KEY_SHIFT | KEY_MOD3 | KEY_F11,
+ KEY_SHIFT | KEY_MOD3 | KEY_F12,
+ KEY_SHIFT | KEY_MOD3 | KEY_F13,
+ KEY_SHIFT | KEY_MOD3 | KEY_F14,
+ KEY_SHIFT | KEY_MOD3 | KEY_F15,
+ KEY_SHIFT | KEY_MOD3 | KEY_F16,
+
+ KEY_SHIFT | KEY_MOD3 | KEY_DOWN,
+ KEY_SHIFT | KEY_MOD3 | KEY_UP,
+ KEY_SHIFT | KEY_MOD3 | KEY_LEFT,
+ KEY_SHIFT | KEY_MOD3 | KEY_RIGHT,
+ KEY_SHIFT | KEY_MOD3 | KEY_HOME,
+ KEY_SHIFT | KEY_MOD3 | KEY_END,
+ KEY_SHIFT | KEY_MOD3 | KEY_PAGEUP,
+ KEY_SHIFT | KEY_MOD3 | KEY_PAGEDOWN,
+ KEY_SHIFT | KEY_MOD3 | KEY_RETURN,
+ KEY_SHIFT | KEY_MOD3 | KEY_ESCAPE,
+ KEY_SHIFT | KEY_MOD3 | KEY_SPACE,
+ KEY_SHIFT | KEY_MOD3 | KEY_BACKSPACE,
+ KEY_SHIFT | KEY_MOD3 | KEY_INSERT,
+ KEY_SHIFT | KEY_MOD3 | KEY_DELETE,
+ KEY_SHIFT | KEY_MOD3 | KEY_EQUAL
+#endif
+};
+
+static const sal_uInt16 KEYCODE_ARRAY_SIZE = SAL_N_ELEMENTS(KEYCODE_ARRAY);
+
+/** select the entry, which match the current key input ... excepting
+ keys, which are used for the dialog itself.
+ */
+IMPL_LINK(SfxAcceleratorConfigPage, KeyInputHdl, const KeyEvent&, rKey, bool)
+{
+ vcl::KeyCode aCode1 = rKey.GetKeyCode();
+ sal_uInt16 nCode1 = aCode1.GetCode();
+ sal_uInt16 nMod1 = aCode1.GetModifier();
+
+ // is it related to our list box ?
+ if ((nCode1 != KEY_DOWN) && (nCode1 != KEY_UP) && (nCode1 != KEY_LEFT) && (nCode1 != KEY_RIGHT)
+ && (nCode1 != KEY_PAGEUP) && (nCode1 != KEY_PAGEDOWN))
+ {
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
+ if (pUserData)
+ {
+ sal_uInt16 nCode2 = pUserData->m_aKey.GetCode();
+ sal_uInt16 nMod2 = pUserData->m_aKey.GetModifier();
+
+ if (nCode1 == nCode2 && nMod1 == nMod2)
+ {
+ m_xEntriesBox->select(i);
+ m_xEntriesBox->scroll_to_row(i);
+ return true;
+ }
+ }
+ }
+ }
+
+ // no - handle it as normal dialog input
+ return false;
+}
+
+SfxAcceleratorConfigPage::SfxAcceleratorConfigPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& aSet)
+ : SfxTabPage(pPage, pController, "cui/ui/accelconfigpage.ui", "AccelConfigPage", &aSet)
+ , m_pMacroInfoItem()
+ , aLoadAccelConfigStr(CuiResId(RID_SVXSTR_LOADACCELCONFIG))
+ , aSaveAccelConfigStr(CuiResId(RID_SVXSTR_SAVEACCELCONFIG))
+ , aFilterAllStr(SfxResId(STR_SFX_FILTERNAME_ALL))
+ , aFilterCfgStr(CuiResId(RID_SVXSTR_FILTERNAME_CFG))
+ , m_bStylesInfoInitialized(false)
+ , m_xGlobal()
+ , m_xModule()
+ , m_xAct()
+ , m_aUpdateDataTimer("UpdateDataTimer")
+ , m_xEntriesBox(m_xBuilder->weld_tree_view("shortcuts"))
+ , m_xOfficeButton(m_xBuilder->weld_radio_button("office"))
+ , m_xModuleButton(m_xBuilder->weld_radio_button("module"))
+ , m_xChangeButton(m_xBuilder->weld_button("change"))
+ , m_xRemoveButton(m_xBuilder->weld_button("delete"))
+ , m_xGroupLBox(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("category")))
+ , m_xFunctionBox(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("function")))
+ , m_xKeyBox(m_xBuilder->weld_tree_view("keys"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xLoadButton(m_xBuilder->weld_button("load"))
+ , m_xSaveButton(m_xBuilder->weld_button("save"))
+ , m_xResetButton(m_xBuilder->weld_button("reset"))
+{
+ Size aSize(m_xEntriesBox->get_approximate_digit_width() * 40,
+ m_xEntriesBox->get_height_rows(12));
+ m_xEntriesBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 19,
+ m_xEntriesBox->get_height_rows(10));
+ m_xGroupLBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 21,
+ m_xEntriesBox->get_height_rows(10));
+ m_xFunctionBox->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xEntriesBox->get_approximate_digit_width() * 20,
+ m_xEntriesBox->get_height_rows(10));
+ m_xKeyBox->set_size_request(aSize.Width(), aSize.Height());
+
+ // install handler functions
+ m_xChangeButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, ChangeHdl));
+ m_xRemoveButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, RemoveHdl));
+ m_xEntriesBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xEntriesBox->connect_key_press(LINK(this, SfxAcceleratorConfigPage, KeyInputHdl));
+ m_xGroupLBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xFunctionBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xKeyBox->connect_changed(LINK(this, SfxAcceleratorConfigPage, SelectHdl));
+ m_xLoadButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Load));
+ m_xSaveButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Save));
+ m_xResetButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, Default));
+ m_xOfficeButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, RadioHdl));
+ m_xModuleButton->connect_clicked(LINK(this, SfxAcceleratorConfigPage, RadioHdl));
+ m_xSearchEdit->connect_changed(LINK(this, SfxAcceleratorConfigPage, SearchUpdateHdl));
+ m_xSearchEdit->connect_focus_out(LINK(this, SfxAcceleratorConfigPage, FocusOut_Impl));
+
+ // detect max keyname width
+ int nMaxWidth = 0;
+ for (unsigned short i : KEYCODE_ARRAY)
+ {
+ int nTmp = m_xEntriesBox->get_pixel_size(vcl::KeyCode(i).GetName()).Width();
+ if (nTmp > nMaxWidth)
+ nMaxWidth = nTmp;
+ }
+ // recalc second tab
+ auto nNewTab = nMaxWidth + 5; // additional space
+
+ // initialize Entriesbox
+ std::vector<int> aWidths;
+ aWidths.push_back(nNewTab);
+ m_xEntriesBox->set_column_fixed_widths(aWidths);
+
+ //Initialize search util
+ m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_options.searchFlag
+ |= (util::SearchFlags::REG_NOT_BEGINOFLINE | util::SearchFlags::REG_NOT_ENDOFLINE);
+ // initialize GroupBox
+ m_xGroupLBox->SetFunctionListBox(m_xFunctionBox.get());
+
+ // initialize KeyBox
+ m_xKeyBox->make_sorted();
+
+ m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, ImplUpdateDataHdl));
+ m_aUpdateDataTimer.SetDebugName("SfxAcceleratorConfigPage UpdateDataTimer");
+ m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+
+ m_aFillGroupIdle.SetInvokeHandler(LINK(this, SfxAcceleratorConfigPage, TimeOut_Impl));
+ m_aFillGroupIdle.SetPriority(TaskPriority::HIGHEST);
+ m_aFillGroupIdle.SetDebugName("SfxAcceleratorConfigPage m_aFillGroupIdle");
+}
+
+SfxAcceleratorConfigPage::~SfxAcceleratorConfigPage()
+{
+ m_aFillGroupIdle.Stop();
+
+ // free memory - remove all dynamic user data
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
+ delete pUserData;
+ }
+}
+
+void SfxAcceleratorConfigPage::InitAccCfg()
+{
+ // already initialized ?
+ if (m_xContext.is())
+ return; // yes -> do nothing
+
+ try
+ {
+ // no - initialize this instance
+ m_xContext = comphelper::getProcessComponentContext();
+
+ m_xUICmdDescription = frame::theUICommandDescription::get(m_xContext);
+
+ // get the current active frame, which should be our "parent"
+ // for this session
+ m_xFrame = GetFrame();
+ if (!m_xFrame.is())
+ {
+ uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(m_xContext);
+ m_xFrame = xDesktop->getActiveFrame();
+ }
+
+ // identify module
+ uno::Reference<frame::XModuleManager2> xModuleManager
+ = frame::ModuleManager::create(m_xContext);
+ m_sModuleLongName = xModuleManager->identify(m_xFrame);
+ comphelper::SequenceAsHashMap lModuleProps(xModuleManager->getByName(m_sModuleLongName));
+ m_sModuleUIName
+ = lModuleProps.getUnpackedValueOrDefault("ooSetupFactoryUIName", OUString());
+
+ // get global accelerator configuration
+ m_xGlobal = css::ui::GlobalAcceleratorConfiguration::create(m_xContext);
+
+ // get module accelerator configuration
+
+ uno::Reference<ui::XModuleUIConfigurationManagerSupplier> xModuleCfgSupplier(
+ ui::theModuleUIConfigurationManagerSupplier::get(m_xContext));
+ uno::Reference<ui::XUIConfigurationManager> xUICfgManager
+ = xModuleCfgSupplier->getUIConfigurationManager(m_sModuleLongName);
+ m_xModule = xUICfgManager->getShortCutManager();
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ m_xContext.clear();
+ }
+}
+
+void SfxAcceleratorConfigPage::Init(const uno::Reference<ui::XAcceleratorConfiguration>& xAccMgr)
+{
+ if (!xAccMgr.is())
+ return;
+
+ if (!m_bStylesInfoInitialized)
+ {
+ uno::Reference<frame::XController> xController;
+ uno::Reference<frame::XModel> xModel;
+ if (m_xFrame.is())
+ xController = m_xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(m_sModuleLongName, xModel);
+ m_xGroupLBox->SetStylesInfo(&m_aStylesInfo);
+ m_bStylesInfoInitialized = true;
+ }
+
+ // Insert all editable accelerators into list box. It is possible
+ // that some accelerators are not mapped on the current system/keyboard
+ // but we don't want to lose these mappings.
+ for (sal_Int32 i1 = 0; i1 < KEYCODE_ARRAY_SIZE; ++i1)
+ {
+ vcl::KeyCode aKey = KEYCODE_ARRAY[i1];
+ OUString sKey = aKey.GetName();
+ if (sKey.isEmpty())
+ continue;
+ TAccInfo* pEntry = new TAccInfo(i1, 0 /*nListPos*/, aKey);
+ m_xEntriesBox->append(OUString::number(reinterpret_cast<sal_Int64>(pEntry)), sKey);
+ int nPos = m_xEntriesBox->n_children() - 1;
+ m_xEntriesBox->set_text(nPos, OUString(), 1);
+ m_xEntriesBox->set_sensitive(nPos, true);
+ }
+
+ // Assign all commands to its shortcuts - reading the accelerator config.
+ uno::Sequence<awt::KeyEvent> lKeys = xAccMgr->getAllKeyEvents();
+ sal_Int32 c2 = lKeys.getLength();
+ sal_Int32 i2 = 0;
+
+ for (i2 = 0; i2 < c2; ++i2)
+ {
+ const awt::KeyEvent& aAWTKey = lKeys[i2];
+ OUString sCommand = xAccMgr->getCommandByKeyEvent(aAWTKey);
+ OUString sLabel = GetLabel4Command(sCommand);
+ vcl::KeyCode aKeyCode = svt::AcceleratorExecute::st_AWTKey2VCLKey(aAWTKey);
+ sal_Int32 nPos = MapKeyCodeToPos(aKeyCode);
+
+ if (nPos == -1)
+ continue;
+
+ m_xEntriesBox->set_text(nPos, sLabel, 1);
+
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
+ pEntry->m_bIsConfigurable = true;
+
+ pEntry->m_sCommand = sCommand;
+ }
+
+ // Map the VCL hardcoded key codes and mark them as not changeable
+ size_t c3 = Application::GetReservedKeyCodeCount();
+ size_t i3 = 0;
+ for (i3 = 0; i3 < c3; ++i3)
+ {
+ const vcl::KeyCode* pKeyCode = Application::GetReservedKeyCode(i3);
+ sal_Int32 nPos = MapKeyCodeToPos(*pKeyCode);
+
+ if (nPos == -1)
+ continue;
+
+ // Hardcoded function mapped so no ID possible and mark entry as not changeable
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
+ pEntry->m_bIsConfigurable = false;
+
+ m_xEntriesBox->set_sensitive(nPos, false);
+ }
+}
+
+void SfxAcceleratorConfigPage::Apply(const uno::Reference<ui::XAcceleratorConfiguration>& xAccMgr)
+{
+ if (!xAccMgr.is())
+ return;
+
+ // Go through the list from the bottom to the top ...
+ // because logical accelerator must be preferred instead of
+ // physical ones!
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
+ OUString sCommand;
+ awt::KeyEvent aAWTKey;
+
+ if (pUserData)
+ {
+ sCommand = pUserData->m_sCommand;
+ aAWTKey = svt::AcceleratorExecute::st_VCLKey2AWTKey(pUserData->m_aKey);
+ }
+
+ try
+ {
+ if (!sCommand.isEmpty())
+ xAccMgr->setKeyEvent(aAWTKey, sCommand);
+ else
+ xAccMgr->removeKeyEvent(aAWTKey);
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+ }
+}
+
+void SfxAcceleratorConfigPage::ResetConfig() { m_xEntriesBox->clear(); }
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ImplUpdateDataHdl, Timer*, void)
+{
+ SelectHdl(m_xGroupLBox->get_widget());
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SearchUpdateHdl, weld::Entry&, void)
+{
+ m_aUpdateDataTimer.Start();
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, FocusOut_Impl, weld::Widget&, void)
+{
+ if (m_aUpdateDataTimer.IsActive())
+ {
+ m_aUpdateDataTimer.Stop();
+ m_aUpdateDataTimer.Invoke();
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Load, weld::Button&, void)
+{
+ // ask for filename, where we should load the new config data from
+ StartFileDialog(StartFileDialogType::Open, aLoadAccelConfigStr);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Save, weld::Button&, void)
+{
+ StartFileDialog(StartFileDialogType::SaveAs, aSaveAccelConfigStr);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, Default, weld::Button&, void)
+{
+ uno::Reference<form::XReset> xReset(m_xAct, uno::UNO_QUERY);
+ if (xReset.is())
+ xReset->reset();
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(m_xAct);
+ m_xEntriesBox->thaw();
+ m_xEntriesBox->select(0);
+ SelectHdl(*m_xEntriesBox);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, ChangeHdl, weld::Button&, void)
+{
+ int nPos = m_xEntriesBox->get_selected_index();
+ if (nPos == -1)
+ return;
+
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
+ OUString sNewCommand = m_xFunctionBox->GetCurCommand();
+ OUString sLabel = m_xFunctionBox->GetCurLabel();
+ if (sLabel.isEmpty())
+ sLabel = GetLabel4Command(sNewCommand);
+
+ pEntry->m_sCommand = sNewCommand;
+ m_xEntriesBox->set_text(nPos, sLabel, 1);
+
+ SelectHdl(m_xFunctionBox->get_widget());
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RemoveHdl, weld::Button&, void)
+{
+ // get selected entry
+ int nPos = m_xEntriesBox->get_selected_index();
+ if (nPos == -1)
+ return;
+
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(nPos).toInt64());
+
+ // remove function name from selected entry
+ m_xEntriesBox->set_text(nPos, OUString(), 1);
+ pEntry->m_sCommand.clear();
+
+ SelectHdl(m_xFunctionBox->get_widget());
+}
+
+IMPL_LINK(SfxAcceleratorConfigPage, SelectHdl, weld::TreeView&, rListBox, void)
+{
+ if (&rListBox == m_xEntriesBox.get())
+ {
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_selected_id().toInt64());
+
+ OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
+
+ m_xRemoveButton->set_sensitive(false);
+ m_xChangeButton->set_sensitive(false);
+
+ if (pEntry && pEntry->m_bIsConfigurable)
+ {
+ if (pEntry->isConfigured())
+ m_xRemoveButton->set_sensitive(true);
+ m_xChangeButton->set_sensitive(pEntry->m_sCommand != sPossibleNewCommand);
+ }
+ }
+ else if (&rListBox == &m_xGroupLBox->get_widget())
+ {
+ m_xGroupLBox->GroupSelected();
+
+ // Pause redraw (Do not redraw at each removal)
+ m_xFunctionBox->freeze();
+ // Apply the search filter to the functions list
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+ int nMatchFound = applySearchFilter(aSearchTerm);
+ // Resume redraw
+ m_xFunctionBox->thaw();
+ if (nMatchFound != -1)
+ {
+ m_xFunctionBox->select(nMatchFound);
+ SelectHdl(m_xFunctionBox->get_widget());
+ }
+ else
+ {
+ m_xKeyBox->clear();
+ m_xChangeButton->set_sensitive(false);
+ }
+ }
+ else if (&rListBox == &m_xFunctionBox->get_widget())
+ {
+ m_xRemoveButton->set_sensitive(false);
+ m_xChangeButton->set_sensitive(false);
+
+ // #i36994 First selected can return null!
+ TAccInfo* pEntry = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_selected_id().toInt64());
+ if (pEntry)
+ {
+ OUString sPossibleNewCommand = m_xFunctionBox->GetCurCommand();
+
+ if (pEntry->m_bIsConfigurable)
+ {
+ if (pEntry->isConfigured())
+ m_xRemoveButton->set_sensitive(true);
+ m_xChangeButton->set_sensitive(pEntry->m_sCommand != sPossibleNewCommand
+ && !sPossibleNewCommand.isEmpty());
+ }
+
+ // update key box
+ m_xKeyBox->clear();
+ if (!sPossibleNewCommand.isEmpty())
+ {
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData
+ = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
+ if (pUserData && pUserData->m_sCommand == sPossibleNewCommand)
+ {
+ m_xKeyBox->append(OUString::number(reinterpret_cast<sal_Int64>(pUserData)),
+ pUserData->m_aKey.GetName());
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // goto selected "key" entry of the key box
+ int nP2 = -1;
+ TAccInfo* pU2 = reinterpret_cast<TAccInfo*>(m_xKeyBox->get_selected_id().toInt64());
+ if (pU2)
+ nP2 = MapKeyCodeToPos(pU2->m_aKey);
+ if (nP2 != -1)
+ {
+ m_xEntriesBox->select(nP2);
+ m_xEntriesBox->scroll_to_row(nP2);
+ SelectHdl(*m_xEntriesBox);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, RadioHdl, weld::Button&, void)
+{
+ uno::Reference<ui::XAcceleratorConfiguration> xOld = m_xAct;
+
+ if (m_xOfficeButton->get_active())
+ m_xAct = m_xGlobal;
+ else if (m_xModuleButton->get_active())
+ m_xAct = m_xModule;
+
+ // nothing changed? => do nothing!
+ if (m_xAct.is() && (xOld == m_xAct))
+ return;
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(m_xAct);
+ m_xEntriesBox->thaw();
+
+ m_xGroupLBox->Init(m_xContext, m_xFrame, m_sModuleLongName, true);
+
+ // pb: #133213# do not select NULL entries
+ if (m_xEntriesBox->n_children())
+ m_xEntriesBox->select(0);
+
+ m_aFillGroupIdle.Start();
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, TimeOut_Impl, Timer*, void)
+{
+ // activating the selection, typically "all commands", can take a long time
+ // -> show wait cursor and disable input
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ weld::TreeView& rTreeView = m_xGroupLBox->get_widget();
+ SelectHdl(rTreeView);
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, LoadHdl, sfx2::FileDialogHelper*, void)
+{
+ assert(m_pFileDlg);
+
+ OUString sCfgName;
+ if (ERRCODE_NONE == m_pFileDlg->GetError())
+ sCfgName = m_pFileDlg->GetPath();
+
+ if (sCfgName.isEmpty())
+ return;
+
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ uno::Reference<ui::XUIConfigurationManager> xCfgMgr;
+ uno::Reference<embed::XStorage>
+ xRootStorage; // we must hold the root storage alive, if xCfgMgr is used!
+
+ try
+ {
+ // don't forget to release the storage afterwards!
+ uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+ embed::StorageFactory::create(m_xContext));
+ uno::Sequence<uno::Any> lArgs(2);
+ lArgs[0] <<= sCfgName;
+ lArgs[1] <<= css::embed::ElementModes::READ;
+
+ xRootStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY_THROW);
+ uno::Reference<embed::XStorage> xUIConfig
+ = xRootStorage->openStorageElement(FOLDERNAME_UICONFIG, embed::ElementModes::READ);
+ if (xUIConfig.is())
+ {
+ uno::Reference<ui::XUIConfigurationManager2> xCfgMgr2
+ = ui::UIConfigurationManager::create(m_xContext);
+ xCfgMgr2->setStorage(xUIConfig);
+ xCfgMgr.set(xCfgMgr2, uno::UNO_QUERY_THROW);
+ }
+
+ if (xCfgMgr.is())
+ {
+ // open the configuration and update our UI
+ uno::Reference<ui::XAcceleratorConfiguration> xTempAccMgr(xCfgMgr->getShortCutManager(),
+ uno::UNO_SET_THROW);
+
+ m_xEntriesBox->freeze();
+ ResetConfig();
+ Init(xTempAccMgr);
+ m_xEntriesBox->thaw();
+ if (m_xEntriesBox->n_children())
+ {
+ m_xEntriesBox->select(0);
+ SelectHdl(m_xFunctionBox->get_widget());
+ }
+ }
+
+ // don't forget to close the new opened storage!
+ // We are the owner of it.
+ if (xRootStorage.is())
+ {
+ uno::Reference<lang::XComponent> xComponent;
+ xComponent.set(xCfgMgr, uno::UNO_QUERY);
+ if (xComponent.is())
+ xComponent->dispose();
+ xRootStorage->dispose();
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+IMPL_LINK_NOARG(SfxAcceleratorConfigPage, SaveHdl, sfx2::FileDialogHelper*, void)
+{
+ assert(m_pFileDlg);
+
+ OUString sCfgName;
+ if (ERRCODE_NONE == m_pFileDlg->GetError())
+ sCfgName = m_pFileDlg->GetPath();
+
+ if (sCfgName.isEmpty())
+ return;
+
+ weld::WaitObject aWaitObject(GetFrameWeld());
+
+ uno::Reference<embed::XStorage> xRootStorage;
+
+ try
+ {
+ uno::Reference<lang::XSingleServiceFactory> xStorageFactory(
+ embed::StorageFactory::create(m_xContext));
+ uno::Sequence<uno::Any> lArgs(2);
+ lArgs[0] <<= sCfgName;
+ lArgs[1] <<= embed::ElementModes::WRITE;
+
+ xRootStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), uno::UNO_QUERY_THROW);
+
+ uno::Reference<embed::XStorage> xUIConfig(
+ xRootStorage->openStorageElement(FOLDERNAME_UICONFIG, embed::ElementModes::WRITE),
+ uno::UNO_SET_THROW);
+ uno::Reference<beans::XPropertySet> xUIConfigProps(xUIConfig, uno::UNO_QUERY_THROW);
+
+ // set the correct media type if the storage was new created
+ OUString sMediaType;
+ xUIConfigProps->getPropertyValue(MEDIATYPE_PROPNAME) >>= sMediaType;
+ if (sMediaType.isEmpty())
+ xUIConfigProps->setPropertyValue(
+ MEDIATYPE_PROPNAME, uno::Any(OUString("application/vnd.sun.xml.ui.configuration")));
+
+ uno::Reference<ui::XUIConfigurationManager2> xCfgMgr
+ = ui::UIConfigurationManager::create(m_xContext);
+ xCfgMgr->setStorage(xUIConfig);
+
+ // get the target configuration access and update with all shortcuts
+ // which are set currently at the UI!
+ // Don't copy the m_xAct content to it... because m_xAct will be updated
+ // from the UI on pressing the button "OK" only. And inbetween it's not up to date!
+ uno::Reference<ui::XAcceleratorConfiguration> xTargetAccMgr(xCfgMgr->getShortCutManager(),
+ uno::UNO_SET_THROW);
+ Apply(xTargetAccMgr);
+
+ // commit (order is important!)
+ uno::Reference<ui::XUIConfigurationPersistence> xCommit1(xTargetAccMgr,
+ uno::UNO_QUERY_THROW);
+ uno::Reference<ui::XUIConfigurationPersistence> xCommit2(xCfgMgr, uno::UNO_QUERY_THROW);
+ xCommit1->store();
+ xCommit2->store();
+
+ if (xRootStorage.is())
+ {
+ // Commit root storage
+ uno::Reference<embed::XTransactedObject> xCommit3(xRootStorage, uno::UNO_QUERY_THROW);
+ xCommit3->commit();
+ }
+
+ if (xRootStorage.is())
+ {
+ if (xCfgMgr.is())
+ xCfgMgr->dispose();
+ xRootStorage->dispose();
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void SfxAcceleratorConfigPage::StartFileDialog(StartFileDialogType nType, const OUString& rTitle)
+{
+ bool bSave = nType == StartFileDialogType::SaveAs;
+ short nDialogType = bSave ? ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION
+ : ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE;
+ m_pFileDlg.reset(
+ new sfx2::FileDialogHelper(nDialogType, FileDialogFlags::NONE, GetFrameWeld()));
+
+ m_pFileDlg->SetTitle(rTitle);
+ m_pFileDlg->AddFilter(aFilterAllStr, FILEDIALOG_FILTER_ALL);
+ m_pFileDlg->AddFilter(aFilterCfgStr, "*.cfg");
+ m_pFileDlg->SetCurrentFilter(aFilterCfgStr);
+
+ Link<sfx2::FileDialogHelper*, void> aDlgClosedLink
+ = bSave ? LINK(this, SfxAcceleratorConfigPage, SaveHdl)
+ : LINK(this, SfxAcceleratorConfigPage, LoadHdl);
+ m_pFileDlg->StartExecuteModal(aDlgClosedLink);
+}
+
+bool SfxAcceleratorConfigPage::FillItemSet(SfxItemSet*)
+{
+ Apply(m_xAct);
+ try
+ {
+ m_xAct->store();
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void SfxAcceleratorConfigPage::Reset(const SfxItemSet* rSet)
+{
+ // open accelerator configs
+ // Note: It initialize some other members too, which are needed here ...
+ // e.g. m_sModuleUIName!
+ InitAccCfg();
+
+ // change the description of the radio button, which switch to the module
+ // dependent accelerator configuration
+ OUString sButtonText = m_xModuleButton->get_label();
+ sButtonText
+ = m_xModuleButton->strip_mnemonic(sButtonText).replaceFirst("$(MODULE)", m_sModuleUIName);
+ m_xModuleButton->set_label(sButtonText);
+
+ if (m_xModule.is())
+ m_xModuleButton->set_active(true);
+ else
+ {
+ m_xModuleButton->hide();
+ m_xOfficeButton->set_active(true);
+ }
+
+ RadioHdl(*m_xOfficeButton);
+
+ const SfxPoolItem* pMacroItem = nullptr;
+ if (SfxItemState::SET == rSet->GetItemState(SID_MACROINFO, true, &pMacroItem))
+ {
+ m_pMacroInfoItem = &dynamic_cast<const SfxMacroInfoItem&>(*pMacroItem);
+ m_xGroupLBox->SelectMacro(m_pMacroInfoItem);
+ }
+}
+
+sal_Int32 SfxAcceleratorConfigPage::MapKeyCodeToPos(const vcl::KeyCode& aKey) const
+{
+ sal_uInt16 nCode1 = aKey.GetCode() + aKey.GetModifier();
+ for (int i = 0, nCount = m_xEntriesBox->n_children(); i < nCount; ++i)
+ {
+ TAccInfo* pUserData = reinterpret_cast<TAccInfo*>(m_xEntriesBox->get_id(i).toInt64());
+ if (pUserData)
+ {
+ sal_uInt16 nCode2 = pUserData->m_aKey.GetCode() + pUserData->m_aKey.GetModifier();
+ if (nCode1 == nCode2)
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+OUString SfxAcceleratorConfigPage::GetLabel4Command(const OUString& sCommand)
+{
+ try
+ {
+ // check global command configuration first
+ uno::Reference<container::XNameAccess> xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ OUString sLabel = lProps.getUnpackedValueOrDefault("Name", OUString());
+ if (!sLabel.isEmpty())
+ return sLabel;
+ }
+ }
+ catch (const uno::RuntimeException&)
+ {
+ throw;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ // may be it's a style URL .. they must be handled special
+ SfxStyleInfo_Impl aStyle;
+ aStyle.sCommand = sCommand;
+ if (SfxStylesInfo_Impl::parseStyleCommand(aStyle))
+ {
+ m_aStylesInfo.getLabel4Style(aStyle);
+ return aStyle.sLabel;
+ }
+
+ return sCommand;
+}
+
+/*
+ * Remove entries which doesn't contain the search term
+ */
+int SfxAcceleratorConfigPage::applySearchFilter(OUString const& rSearchTerm)
+{
+ if (rSearchTerm.isEmpty())
+ return -1;
+
+ m_options.searchString = rSearchTerm;
+ utl::TextSearch textSearch(m_options);
+
+ for (int i = m_xFunctionBox->n_children(); i > 0; --i)
+ {
+ int nEntry = i - 1;
+ OUString aStr = m_xFunctionBox->get_text(nEntry);
+ sal_Int32 aStartPos = 0;
+ sal_Int32 aEndPos = aStr.getLength();
+
+ if (!textSearch.SearchForward(aStr, &aStartPos, &aEndPos))
+ m_xFunctionBox->remove(nEntry);
+ }
+
+ return m_xFunctionBox->n_children() ? 0 : -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/cfg.cxx b/cui/source/customize/cfg.cxx
new file mode 100644
index 000000000..04664d511
--- /dev/null
+++ b/cui/source/customize/cfg.cxx
@@ -0,0 +1,3201 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <stdlib.h>
+#include <typeinfo>
+
+#include <vcl/stdtext.hxx>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/event.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/decoview.hxx>
+#include <vcl/virdev.hxx>
+
+#include <sfx2/sfxhelp.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/stritem.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <algorithm>
+#include <strings.hrc>
+
+#include <acccfg.hxx>
+#include <cfg.hxx>
+#include <CustomNotebookbarGenerator.hxx>
+#include <SvxMenuConfigPage.hxx>
+#include <SvxToolbarConfigPage.hxx>
+#include <SvxNotebookbarConfigPage.hxx>
+#include <SvxConfigPageHelper.hxx>
+#include "eventdlg.hxx"
+#include <dialmgr.hxx>
+
+#include <unotools/configmgr.hxx>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/embed/ElementModes.hpp>
+#include <com/sun/star/embed/FileSystemStorageFactory.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/XFrames.hpp>
+#include <com/sun/star/frame/XLayoutManager.hpp>
+#include <com/sun/star/frame/FrameSearchFlag.hpp>
+#include <com/sun/star/frame/XController.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/ui/ItemType.hpp>
+#include <com/sun/star/ui/ItemStyle.hpp>
+#include <com/sun/star/ui/ImageManager.hpp>
+#include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
+#include <com/sun/star/ui/XUIConfigurationPersistence.hpp>
+#include <com/sun/star/ui/XUIElement.hpp>
+#include <com/sun/star/ui/UIElementType.hpp>
+#include <com/sun/star/ui/ImageType.hpp>
+#include <com/sun/star/ui/theWindowStateConfiguration.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/processfactory.hxx>
+
+namespace uno = com::sun::star::uno;
+namespace frame = com::sun::star::frame;
+namespace lang = com::sun::star::lang;
+namespace container = com::sun::star::container;
+namespace beans = com::sun::star::beans;
+namespace graphic = com::sun::star::graphic;
+
+#if OSL_DEBUG_LEVEL > 1
+
+void printPropertySet(
+ const OUString& prefix,
+ const uno::Reference< beans::XPropertySet >& xPropSet )
+{
+ uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
+ xPropSet->getPropertySetInfo();
+
+ const uno::Sequence< beans::Property >& aPropDetails =
+ xPropSetInfo->getProperties();
+
+ SAL_WARN("cui", "printPropertySet: " << aPropDetails.getLength() << " properties" );
+
+ for ( beans::Property const & aPropDetail : aPropDetails )
+ {
+ OUString tmp;
+ sal_Int32 ival;
+
+ uno::Any a = xPropSet->getPropertyValue( aPropDetail.Name );
+
+ if ( a >>= tmp )
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << tmp);
+ }
+ else if ( ( a >>= ival ) )
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << " = " << ival);
+ }
+ else
+ {
+ SAL_WARN("cui", prefix << ": Got property: " << aPropDetail.Name << " of type " << a.getValueTypeName());
+ }
+ }
+}
+
+void printProperties(
+ const OUString& prefix,
+ const uno::Sequence< beans::PropertyValue >& aProp )
+{
+ for (beans::PropertyValue const & aPropVal : aProp)
+ {
+ OUString tmp;
+
+ aPropVal.Value >>= tmp;
+
+ SAL_WARN("cui", prefix << ": Got property: " << aPropVal.Name << " = " << tmp);
+ }
+}
+
+void printEntries(SvxEntries* entries)
+{
+ for (auto const& entry : *entries)
+ {
+ SAL_WARN("cui", "printEntries: " << entry->GetName());
+ }
+}
+
+#endif
+
+bool
+SvxConfigPage::CanConfig( const OUString& aModuleId )
+{
+ return !(aModuleId == "com.sun.star.script.BasicIDE" || aModuleId == "com.sun.star.frame.Bibliography");
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxMenuConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxMenuConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxContextMenuConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxMenuConfigPage>(pPage, pController, *rSet, false);
+}
+
+static std::unique_ptr<SfxTabPage> CreateKeyboardConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SfxAcceleratorConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxNotebookbarConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxNotebookbarConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxToolbarConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxToolbarConfigPage>(pPage, pController, *rSet);
+}
+
+static std::unique_ptr<SfxTabPage> CreateSvxEventConfigPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxEventConfigPage>(pPage, pController, *rSet, SvxEventConfigPage::EarlyInit());
+}
+
+/******************************************************************************
+ *
+ * SvxConfigDialog is the configuration dialog which is brought up from the
+ * Tools menu. It includes tabs for customizing menus, toolbars, events and
+ * key bindings.
+ *
+ *****************************************************************************/
+SvxConfigDialog::SvxConfigDialog(weld::Window * pParent, const SfxItemSet* pInSet)
+ : SfxTabDialogController(pParent, "cui/ui/customizedialog.ui", "CustomizeDialog", pInSet)
+{
+ SvxConfigPageHelper::InitImageType();
+
+ AddTabPage("menus", CreateSvxMenuConfigPage, nullptr);
+ AddTabPage("toolbars", CreateSvxToolbarConfigPage, nullptr);
+ AddTabPage("notebookbar", CreateSvxNotebookbarConfigPage, nullptr);
+ AddTabPage("contextmenus", CreateSvxContextMenuConfigPage, nullptr);
+ AddTabPage("keyboard", CreateKeyboardConfigPage, nullptr);
+ AddTabPage("events", CreateSvxEventConfigPage, nullptr);
+
+ const SfxPoolItem* pItem =
+ pInSet->GetItem( pInSet->GetPool()->GetWhich( SID_CONFIG ) );
+
+ if ( pItem )
+ {
+ OUString text = static_cast<const SfxStringItem*>(pItem)->GetValue();
+
+ if (text.startsWith( ITEM_TOOLBAR_URL ) )
+ {
+ SetCurPageId("toolbars");
+ }
+ }
+}
+
+void SvxConfigDialog::SetFrame(const css::uno::Reference<css::frame::XFrame>& xFrame)
+{
+ m_xFrame = xFrame;
+ OUString aModuleId = SvxConfigPage::GetFrameWithDefaultAndIdentify(m_xFrame);
+
+ if (aModuleId != "com.sun.star.text.TextDocument" &&
+ aModuleId != "com.sun.star.sheet.SpreadsheetDocument" &&
+ aModuleId != "com.sun.star.presentation.PresentationDocument" &&
+ aModuleId != "com.sun.star.drawing.DrawingDocument")
+ RemoveTabPage("notebookbar");
+
+ if (aModuleId == "com.sun.star.frame.StartModule")
+ RemoveTabPage("keyboard");
+}
+
+void SvxConfigDialog::PageCreated(const OString &rId, SfxTabPage& rPage)
+{
+ if (rId == "menus" || rId == "keyboard" || rId == "notebookbar"
+ || rId == "toolbars" || rId == "contextmenus")
+ {
+ rPage.SetFrame(m_xFrame);
+ }
+ else if (rId == "events")
+ {
+ dynamic_cast< SvxEventConfigPage& >( rPage ).LateInit( m_xFrame );
+ }
+}
+
+/******************************************************************************
+ *
+ * The SaveInData class is used to hold data for entries in the Save In
+ * ListBox controls in the menu and toolbar tabs
+ *
+ ******************************************************************************/
+
+// Initialize static variable which holds default XImageManager
+uno::Reference< css::ui::XImageManager>* SaveInData::xDefaultImgMgr = nullptr;
+
+SaveInData::SaveInData(
+ const uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool isDocConfig )
+ :
+ bModified( false ),
+ bDocConfig( isDocConfig ),
+ bReadOnly( false ),
+ m_xCfgMgr( xCfgMgr ),
+ m_xParentCfgMgr( xParentCfgMgr )
+{
+ m_aSeparatorSeq.realloc( 1 );
+ m_aSeparatorSeq[0].Name = ITEM_DESCRIPTOR_TYPE;
+ m_aSeparatorSeq[0].Value <<= css::ui::ItemType::SEPARATOR_LINE;
+
+ if ( bDocConfig )
+ {
+ uno::Reference< css::ui::XUIConfigurationPersistence >
+ xDocPersistence( GetConfigManager(), uno::UNO_QUERY );
+
+ bReadOnly = xDocPersistence->isReadOnly();
+ }
+
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ css::frame::theUICommandDescription::get(xContext) );
+
+ xNameAccess->getByName( aModuleId ) >>= m_xCommandToLabelMap;
+
+ if ( !m_xImgMgr.is() )
+ {
+ m_xImgMgr.set( GetConfigManager()->getImageManager(), uno::UNO_QUERY );
+ }
+
+ if ( !IsDocConfig() )
+ {
+ // If this is not a document configuration then it is the settings
+ // for the module (writer, calc, impress etc.) Use this as the default
+ // XImageManager instance
+ xDefaultImgMgr = &m_xImgMgr;
+ }
+ else
+ {
+ // If this is a document configuration then use the module image manager
+ // as default.
+ if ( m_xParentCfgMgr.is() )
+ {
+ m_xParentImgMgr.set( m_xParentCfgMgr->getImageManager(), uno::UNO_QUERY );
+ xDefaultImgMgr = &m_xParentImgMgr;
+ }
+ }
+}
+
+uno::Reference<graphic::XGraphic> SaveInData::GetImage(const OUString& rCommandURL)
+{
+ uno::Reference< graphic::XGraphic > xGraphic =
+ SvxConfigPageHelper::GetGraphic( m_xImgMgr, rCommandURL );
+
+ if (!xGraphic.is() && xDefaultImgMgr != nullptr && (*xDefaultImgMgr).is())
+ {
+ xGraphic = SvxConfigPageHelper::GetGraphic( (*xDefaultImgMgr), rCommandURL );
+ }
+
+ return xGraphic;
+}
+
+bool SaveInData::PersistChanges(
+ const uno::Reference< uno::XInterface >& xManager )
+{
+ bool result = true;
+
+ try
+ {
+ if ( xManager.is() && !IsReadOnly() )
+ {
+ uno::Reference< css::ui::XUIConfigurationPersistence >
+ xConfigPersistence( xManager, uno::UNO_QUERY );
+
+ if ( xConfigPersistence->isModified() )
+ {
+ xConfigPersistence->store();
+ }
+ }
+ }
+ catch ( css::io::IOException& )
+ {
+ result = false;
+ }
+
+ return result;
+}
+
+/******************************************************************************
+ *
+ * The MenuSaveInData class extends SaveInData and provides menu specific
+ * load and store functionality.
+ *
+ ******************************************************************************/
+
+// Initialize static variable which holds default Menu data
+MenuSaveInData* MenuSaveInData::pDefaultData = nullptr;
+
+MenuSaveInData::MenuSaveInData(
+ const uno::Reference< css::ui::XUIConfigurationManager >& cfgmgr,
+ const uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool isDocConfig )
+ :
+ SaveInData( cfgmgr, xParentCfgMgr, aModuleId, isDocConfig ),
+ m_aMenuResourceURL(
+ ITEM_MENUBAR_URL ),
+ m_aDescriptorContainer(
+ ITEM_DESCRIPTOR_CONTAINER )
+{
+ try
+ {
+ OUString url( ITEM_MENUBAR_URL );
+ m_xMenuSettings = GetConfigManager()->getSettings( url, false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // will use menu settings for the module
+ }
+
+ // If this is not a document configuration then it is the settings
+ // for the module (writer, calc, impress etc.). These settings should
+ // be set as the default to be used for SaveIn locations that do not
+ // have custom settings
+ if ( !IsDocConfig() )
+ {
+ SetDefaultData( this );
+ }
+}
+
+MenuSaveInData::~MenuSaveInData()
+{
+}
+
+SvxEntries*
+MenuSaveInData::GetEntries()
+{
+ if ( pRootEntry == nullptr )
+ {
+ pRootEntry.reset( new SvxConfigEntry( "MainMenus", OUString(), true, /*bParentData*/false) );
+
+ if ( m_xMenuSettings.is() )
+ {
+ LoadSubMenus( m_xMenuSettings, OUString(), pRootEntry.get(), false );
+ }
+ else if ( GetDefaultData() != nullptr )
+ {
+ // If the doc has no config settings use module config settings
+ LoadSubMenus( GetDefaultData()->m_xMenuSettings, OUString(), pRootEntry.get(), false );
+ }
+ }
+
+ return pRootEntry->GetEntries();
+}
+
+void
+MenuSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+void SaveInData::LoadSubMenus( const uno::Reference< container::XIndexAccess >& xMenuSettings,
+ const OUString& rBaseTitle, SvxConfigEntry const * pParentData, bool bContextMenu )
+{
+ SvxEntries* pEntries = pParentData->GetEntries();
+
+ // Don't access non existing menu configuration!
+ if ( !xMenuSettings.is() )
+ return;
+
+ for ( sal_Int32 nIndex = 0; nIndex < xMenuSettings->getCount(); ++nIndex )
+ {
+ uno::Reference< container::XIndexAccess > xSubMenu;
+ OUString aCommandURL;
+ OUString aLabel;
+
+ sal_uInt16 nType( css::ui::ItemType::DEFAULT );
+ sal_Int32 nStyle(0);
+
+ bool bItem = SvxConfigPageHelper::GetMenuItemData( xMenuSettings, nIndex,
+ aCommandURL, aLabel, nType, nStyle, xSubMenu );
+
+ if ( bItem )
+ {
+ bool bIsUserDefined = true;
+
+ if ( nType == css::ui::ItemType::DEFAULT )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( aCommandURL );
+ bIsUserDefined = false;
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ bIsUserDefined = true;
+ }
+
+ bool bUseDefaultLabel = false;
+ // If custom label not set retrieve it from the command
+ // to info service
+ if ( aLabel.isEmpty() )
+ {
+ bUseDefaultLabel = true;
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ OUString aMenuLabel;
+ for ( const beans::PropertyValue& prop : std::as_const(aPropSeq) )
+ {
+ if ( bContextMenu )
+ {
+ if ( prop.Name == "PopupLabel" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ else if ( prop.Name == "Label" )
+ {
+ prop.Value >>= aMenuLabel;
+ }
+ }
+ else if ( prop.Name == "Label" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ }
+ if ( aLabel.isEmpty() )
+ aLabel = aMenuLabel;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ aLabel, aCommandURL, xSubMenu.is(), /*bParentData*/false );
+
+ pEntry->SetStyle( nStyle );
+ pEntry->SetUserDefined( bIsUserDefined );
+ if ( !bUseDefaultLabel )
+ pEntry->SetName( aLabel );
+
+ pEntries->push_back( pEntry );
+
+ if ( xSubMenu.is() )
+ {
+ // popup menu
+ OUString subMenuTitle( rBaseTitle );
+
+ if ( !subMenuTitle.isEmpty() )
+ {
+ subMenuTitle += aMenuSeparatorStr;
+ }
+ else
+ {
+ pEntry->SetMain();
+ }
+
+ subMenuTitle += SvxConfigPageHelper::stripHotKey( aLabel );
+
+ LoadSubMenus( xSubMenu, subMenuTitle, pEntry, bContextMenu );
+ }
+ }
+ else
+ {
+ SvxConfigEntry* pEntry = new SvxConfigEntry;
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntries->push_back( pEntry );
+ }
+ }
+ }
+}
+
+bool MenuSaveInData::Apply()
+{
+ bool result = false;
+
+ if ( IsModified() )
+ {
+ // Apply new menu bar structure to our settings container
+ m_xMenuSettings = GetConfigManager()->createSettings();
+
+ uno::Reference< container::XIndexContainer > xIndexContainer (
+ m_xMenuSettings, uno::UNO_QUERY );
+
+ uno::Reference< lang::XSingleComponentFactory > xFactory (
+ m_xMenuSettings, uno::UNO_QUERY );
+
+ Apply( xIndexContainer, xFactory );
+
+ try
+ {
+ if ( GetConfigManager()->hasSettings( m_aMenuResourceURL ) )
+ {
+ GetConfigManager()->replaceSettings(
+ m_aMenuResourceURL, m_xMenuSettings );
+ }
+ else
+ {
+ GetConfigManager()->insertSettings(
+ m_aMenuResourceURL, m_xMenuSettings );
+ }
+ }
+ catch ( css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught some other exception saving settings");
+ }
+
+ SetModified( false );
+
+ result = PersistChanges( GetConfigManager() );
+ }
+
+ return result;
+}
+
+void MenuSaveInData::Apply(
+ uno::Reference< container::XIndexContainer > const & rMenuBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entryData : *GetEntries())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entryData);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
+ aPropValueSeq[nIndex].Value <<= xSubMenuBar;
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+ ApplyMenu( xSubMenuBar, rFactory, entryData );
+ }
+}
+
+void SaveInData::ApplyMenu(
+ uno::Reference< container::XIndexContainer > const & rMenuBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry* pMenuData )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entry : *pMenuData->GetEntries())
+ {
+ if (entry->IsPopup())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entry);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ aPropValueSeq[nIndex].Name = ITEM_DESCRIPTOR_CONTAINER;
+ aPropValueSeq[nIndex].Value <<= xSubMenuBar;
+
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+
+ ApplyMenu( xSubMenuBar, rFactory, entry );
+ entry->SetModified( false );
+ }
+ else if (entry->IsSeparator())
+ {
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( m_aSeparatorSeq ));
+ }
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertSvxConfigEntry(entry);
+ rMenuBar->insertByIndex(
+ rMenuBar->getCount(), uno::Any( aPropValueSeq ));
+ }
+ }
+ pMenuData->SetModified( false );
+}
+
+void
+MenuSaveInData::Reset()
+{
+ try
+ {
+ GetConfigManager()->removeSettings( m_aMenuResourceURL );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ PersistChanges( GetConfigManager() );
+
+ pRootEntry.reset();
+
+ try
+ {
+ m_xMenuSettings = GetConfigManager()->getSettings(
+ m_aMenuResourceURL, false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // will use default settings
+ }
+}
+
+ContextMenuSaveInData::ContextMenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId, bool bIsDocConfig )
+ : SaveInData( xCfgMgr, xParentCfgMgr, aModuleId, bIsDocConfig )
+{
+ css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::getProcessComponentContext() );
+ css::uno::Reference< css::container::XNameAccess > xConfig( css::ui::theWindowStateConfiguration::get( xContext ) );
+ xConfig->getByName( aModuleId ) >>= m_xPersistentWindowState;
+}
+
+ContextMenuSaveInData::~ContextMenuSaveInData()
+{
+}
+
+OUString ContextMenuSaveInData::GetUIName( const OUString& rResourceURL )
+{
+ if ( m_xPersistentWindowState.is() )
+ {
+ css::uno::Sequence< css::beans::PropertyValue > aProps;
+ try
+ {
+ m_xPersistentWindowState->getByName( rResourceURL ) >>= aProps;
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ for ( const auto& aProp : std::as_const(aProps) )
+ {
+ if ( aProp.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ OUString aResult;
+ aProp.Value >>= aResult;
+ return aResult;
+ }
+ }
+ }
+ return OUString();
+}
+
+SvxEntries* ContextMenuSaveInData::GetEntries()
+{
+ if ( !m_pRootEntry )
+ {
+ std::unordered_map< OUString, bool > aMenuInfo;
+
+ m_pRootEntry.reset( new SvxConfigEntry( "ContextMenus", OUString(), true, /*bParentData*/false ) );
+ css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aElementsInfo;
+ try
+ {
+ aElementsInfo = GetConfigManager()->getUIElementsInfo( css::ui::UIElementType::POPUPMENU );
+ }
+ catch ( const css::lang::IllegalArgumentException& )
+ {}
+
+ for ( const auto& aElement : std::as_const(aElementsInfo) )
+ {
+ OUString aUrl;
+ for ( const auto& aElementProp : aElement )
+ {
+ if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ aElementProp.Value >>= aUrl;
+ break;
+ }
+ }
+
+ css::uno::Reference< css::container::XIndexAccess > xPopupMenu;
+ try
+ {
+ xPopupMenu = GetConfigManager()->getSettings( aUrl, false );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ if ( xPopupMenu.is() )
+ {
+ // insert into std::unordered_map to filter duplicates from the parent
+ aMenuInfo.emplace( aUrl, true );
+
+ OUString aUIMenuName = GetUIName( aUrl );
+ if ( aUIMenuName.isEmpty() )
+ // Menus without UI name aren't supposed to be customized.
+ continue;
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry( aUIMenuName, aUrl, true, /*bParentData*/false );
+ pEntry->SetMain();
+ m_pRootEntry->GetEntries()->push_back( pEntry );
+ LoadSubMenus( xPopupMenu, aUIMenuName, pEntry, true );
+ }
+ }
+
+ // Retrieve also the parent menus, to make it possible to configure module menus and save them into the document.
+ css::uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
+ css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > aParentElementsInfo;
+ try
+ {
+ if ( xParentCfgMgr.is() )
+ aParentElementsInfo = xParentCfgMgr->getUIElementsInfo( css::ui::UIElementType::POPUPMENU );
+ }
+ catch ( const css::lang::IllegalArgumentException& )
+ {}
+
+ for ( const auto& aElement : std::as_const(aParentElementsInfo) )
+ {
+ OUString aUrl;
+ for ( const auto& aElementProp : aElement )
+ {
+ if ( aElementProp.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ aElementProp.Value >>= aUrl;
+ break;
+ }
+ }
+
+ css::uno::Reference< css::container::XIndexAccess > xPopupMenu;
+ try
+ {
+ if ( aMenuInfo.find( aUrl ) == aMenuInfo.end() )
+ xPopupMenu = xParentCfgMgr->getSettings( aUrl, false );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+
+ if ( xPopupMenu.is() )
+ {
+ OUString aUIMenuName = GetUIName( aUrl );
+ if ( aUIMenuName.isEmpty() )
+ continue;
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry( aUIMenuName, aUrl, true, true );
+ pEntry->SetMain();
+ m_pRootEntry->GetEntries()->push_back( pEntry );
+ LoadSubMenus( xPopupMenu, aUIMenuName, pEntry, true );
+ }
+ }
+ std::sort( m_pRootEntry->GetEntries()->begin(), m_pRootEntry->GetEntries()->end(), SvxConfigPageHelper::EntrySort );
+ }
+ return m_pRootEntry->GetEntries();
+}
+
+void ContextMenuSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ m_pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+bool ContextMenuSaveInData::HasURL( const OUString& rURL )
+{
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ if ( pEntry->GetCommand() == rURL )
+ return true;
+
+ return false;
+}
+
+bool ContextMenuSaveInData::HasSettings()
+{
+ return m_pRootEntry && !m_pRootEntry->GetEntries()->empty();
+}
+
+bool ContextMenuSaveInData::Apply()
+{
+ if ( !IsModified() )
+ return false;
+
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ {
+ if ( pEntry->IsModified() || SvxConfigPageHelper::SvxConfigEntryModified( pEntry ) )
+ {
+ css::uno::Reference< css::container::XIndexContainer > xIndexContainer = GetConfigManager()->createSettings();
+ css::uno::Reference< css::lang::XSingleComponentFactory > xFactory( xIndexContainer, css::uno::UNO_QUERY );
+ ApplyMenu( xIndexContainer, xFactory, pEntry );
+
+ const OUString& aUrl = pEntry->GetCommand();
+ try
+ {
+ if ( GetConfigManager()->hasSettings( aUrl ) )
+ GetConfigManager()->replaceSettings( aUrl, xIndexContainer );
+ else
+ GetConfigManager()->insertSettings( aUrl, xIndexContainer );
+ }
+ catch ( const css::uno::Exception& )
+ {}
+ }
+ }
+ SetModified( false );
+ return PersistChanges( GetConfigManager() );
+}
+
+void ContextMenuSaveInData::Reset()
+{
+ SvxEntries* pEntries = GetEntries();
+ for ( const auto& pEntry : *pEntries )
+ {
+ try
+ {
+ GetConfigManager()->removeSettings( pEntry->GetCommand() );
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menus");
+ }
+ }
+ PersistChanges( GetConfigManager() );
+ m_pRootEntry.reset();
+}
+
+void ContextMenuSaveInData::ResetContextMenu( const SvxConfigEntry* pEntry )
+{
+ try
+ {
+ GetConfigManager()->removeSettings( pEntry->GetCommand() );
+ }
+ catch ( const css::uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Exception caught while resetting context menu");
+ }
+ PersistChanges( GetConfigManager() );
+ m_pRootEntry.reset();
+}
+
+void SvxMenuEntriesListBox::CreateDropDown()
+{
+ int nWidth = m_xControl->get_text_height() / 2;
+ m_xDropDown->SetOutputSizePixel(Size(nWidth, nWidth));
+ DecorationView aDecoView(m_xDropDown.get());
+ aDecoView.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth, nWidth)),
+ SymbolType::SPIN_RIGHT, m_xDropDown->GetTextColor(),
+ DrawSymbolFlags::NONE);
+}
+
+/******************************************************************************
+ *
+ * SvxMenuEntriesListBox is the listbox in which the menu items for a
+ * particular menu are shown. We have a custom listbox because we need
+ * to add drag'n'drop support from the Macro Selector and within the
+ * listbox
+ *
+ *****************************************************************************/
+SvxMenuEntriesListBox::SvxMenuEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPg)
+ : m_xControl(std::move(xControl))
+ , m_xDropDown(m_xControl->create_virtual_device())
+ , m_pPage(pPg)
+{
+ CreateDropDown();
+ m_xControl->connect_key_press(LINK(this, SvxMenuEntriesListBox, KeyInputHdl));
+}
+
+SvxMenuEntriesListBox::~SvxMenuEntriesListBox()
+{
+}
+
+IMPL_LINK(SvxMenuEntriesListBox, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ vcl::KeyCode keycode = rKeyEvent.GetKeyCode();
+
+ // support DELETE for removing the current entry
+ if ( keycode == KEY_DELETE )
+ {
+ m_pPage->DeleteSelectedContent();
+ }
+ // support CTRL+UP and CTRL+DOWN for moving selected entries
+ else if ( keycode.GetCode() == KEY_UP && keycode.IsMod1() )
+ {
+ m_pPage->MoveEntry( true );
+ }
+ else if ( keycode.GetCode() == KEY_DOWN && keycode.IsMod1() )
+ {
+ m_pPage->MoveEntry( false );
+ }
+ else
+ {
+ return false; // pass on to default handler
+ }
+ return true;
+}
+
+/******************************************************************************
+ *
+ * SvxConfigPage is the abstract base class on which the Menu and Toolbar
+ * configuration tabpages are based. It includes methods which are common to
+ * both tabpages to add, delete, move and rename items etc.
+ *
+ *****************************************************************************/
+SvxConfigPage::SvxConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/menuassignpage.ui", "MenuAssignPage", &rSet)
+ , m_aUpdateDataTimer("UpdateDataTimer")
+ , bInitialised(false)
+ , pCurrentSaveInData(nullptr)
+ , m_xCommandCategoryListBox(new CommandCategoryListBox(m_xBuilder->weld_combo_box("commandcategorylist")))
+ , m_xFunctions(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("functions")))
+ , m_xCategoryLabel(m_xBuilder->weld_label("categorylabel"))
+ , m_xDescriptionFieldLb(m_xBuilder->weld_label("descriptionlabel"))
+ , m_xDescriptionField(m_xBuilder->weld_text_view("desc"))
+ , m_xLeftFunctionLabel(m_xBuilder->weld_label("leftfunctionlabel"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xSearchLabel(m_xBuilder->weld_label("searchlabel"))
+ , m_xCustomizeLabel(m_xBuilder->weld_label("customizelabel"))
+ , m_xTopLevelListBox(m_xBuilder->weld_combo_box("toplevellist"))
+ , m_xMoveUpButton(m_xBuilder->weld_button("up"))
+ , m_xMoveDownButton(m_xBuilder->weld_button("down"))
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+ , m_xInsertBtn(m_xBuilder->weld_menu_button("insert"))
+ , m_xModifyBtn(m_xBuilder->weld_menu_button("modify"))
+ , m_xResetBtn(m_xBuilder->weld_button("defaultsbtn"))
+ , m_xAddCommandButton(m_xBuilder->weld_button("add"))
+ , m_xRemoveCommandButton(m_xBuilder->weld_button("remove"))
+{
+ CustomNotebookbarGenerator::getFileNameAndAppName(m_sAppName, m_sFileName);
+
+ m_xTopLevelListBox->connect_changed(LINK(this, SvxConfigPage, SelectElementHdl));
+
+ weld::TreeView& rTreeView = m_xFunctions->get_widget();
+ Size aSize(rTreeView.get_approximate_digit_width() * 40, rTreeView.get_height_rows(8));
+ m_xFunctions->set_size_request(aSize.Width(), aSize.Height());
+ m_xDescriptionField->set_size_request(aSize.Width(), m_xDescriptionField->get_height_rows(3));
+
+ m_aUpdateDataTimer.SetInvokeHandler(LINK(this, SvxConfigPage, ImplUpdateDataHdl));
+ m_aUpdateDataTimer.SetDebugName( "SvxConfigPage UpdateDataTimer" );
+ m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
+
+ m_xSearchEdit->connect_changed(LINK(this, SvxConfigPage, SearchUpdateHdl));
+ m_xSearchEdit->connect_focus_out(LINK(this, SvxConfigPage, FocusOut_Impl));
+
+ rTreeView.connect_row_activated(LINK(this, SvxConfigPage, FunctionDoubleClickHdl));
+ rTreeView.connect_changed(LINK(this, SvxConfigPage, SelectFunctionHdl));
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectElementHdl, weld::ComboBox&, void)
+{
+ SelectElement();
+}
+
+SvxConfigPage::~SvxConfigPage()
+{
+}
+
+void SvxConfigPage::Reset( const SfxItemSet* )
+{
+ // If we haven't initialised our XMultiServiceFactory reference
+ // then Reset is being called at the opening of the dialog.
+
+ // Load menu configuration data for the module of the currently
+ // selected document, for the currently selected document, and for
+ // all other open documents of the same module type
+ if ( !bInitialised )
+ {
+ sal_Int32 nPos = 0;
+ uno::Reference < css::ui::XUIConfigurationManager > xCfgMgr;
+ uno::Reference < css::ui::XUIConfigurationManager > xDocCfgMgr;
+
+ uno::Reference< uno::XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext(), uno::UNO_SET_THROW );
+
+ m_xFrame = GetFrame();
+ m_aModuleId = GetFrameWithDefaultAndIdentify( m_xFrame );
+
+ // replace %MODULENAME in the label with the correct module name
+ uno::Reference< css::frame::XModuleManager2 > xModuleManager(
+ css::frame::ModuleManager::create( xContext ));
+ OUString aModuleName = SvxConfigPageHelper::GetUIModuleName( m_aModuleId, xModuleManager );
+
+ uno::Reference< css::ui::XModuleUIConfigurationManagerSupplier >
+ xModuleCfgSupplier( css::ui::theModuleUIConfigurationManagerSupplier::get(xContext) );
+
+ // Set up data for module specific menus
+ SaveInData* pModuleData = nullptr;
+
+ try
+ {
+ xCfgMgr =
+ xModuleCfgSupplier->getUIConfigurationManager( m_aModuleId );
+
+ pModuleData = CreateSaveInData( xCfgMgr,
+ uno::Reference< css::ui::XUIConfigurationManager >(),
+ m_aModuleId,
+ false );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ }
+
+ if ( pModuleData != nullptr )
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pModuleData)));
+ m_xSaveInListBox->append(sId, utl::ConfigManager::getProductName() + " " + aModuleName);
+ }
+
+ // try to retrieve the document based ui configuration manager
+ OUString aTitle;
+ uno::Reference< frame::XController > xController =
+ m_xFrame->getController();
+ if ( CanConfig( m_aModuleId ) && xController.is() )
+ {
+ uno::Reference< frame::XModel > xModel( xController->getModel() );
+ if ( xModel.is() )
+ {
+ uno::Reference< css::ui::XUIConfigurationManagerSupplier >
+ xCfgSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xCfgSupplier.is() )
+ {
+ xDocCfgMgr = xCfgSupplier->getUIConfigurationManager();
+ }
+ aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+ }
+ }
+
+ SaveInData* pDocData = nullptr;
+ if ( xDocCfgMgr.is() )
+ {
+ pDocData = CreateSaveInData( xDocCfgMgr, xCfgMgr, m_aModuleId, true );
+
+ if ( !pDocData->IsReadOnly() )
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pDocData)));
+ m_xSaveInListBox->append(sId, aTitle);
+ }
+ }
+
+ // if an item to select has been passed in (eg. the ResourceURL for a
+ // toolbar) then try to select the SaveInData entry that has that item
+ bool bURLToSelectFound = false;
+ if ( !m_aURLToSelect.isEmpty() )
+ {
+ if ( pDocData && pDocData->HasURL( m_aURLToSelect ) )
+ {
+ m_xSaveInListBox->set_active(nPos);
+ pCurrentSaveInData = pDocData;
+ bURLToSelectFound = true;
+ }
+ else if ( pModuleData && pModuleData->HasURL( m_aURLToSelect ) )
+ {
+ m_xSaveInListBox->set_active(0);
+ pCurrentSaveInData = pModuleData;
+ bURLToSelectFound = true;
+ }
+ }
+
+ if ( !bURLToSelectFound )
+ {
+ // if the document has menu configuration settings select it
+ // it the SaveIn listbox, otherwise select the module data
+ if ( pDocData != nullptr && pDocData->HasSettings() )
+ {
+ m_xSaveInListBox->set_active(nPos);
+ pCurrentSaveInData = pDocData;
+ }
+ else
+ {
+ m_xSaveInListBox->set_active(0);
+ pCurrentSaveInData = pModuleData;
+ }
+ }
+
+#ifdef DBG_UTIL
+ DBG_ASSERT( pCurrentSaveInData, "SvxConfigPage::Reset(): no SaveInData" );
+#endif
+
+ if ( CanConfig( m_aModuleId ) )
+ {
+ // Load configuration for other open documents which have
+ // same module type
+ uno::Sequence< uno::Reference< frame::XFrame > > aFrameList;
+ try
+ {
+ uno::Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create(
+ xContext );
+
+ uno::Reference< frame::XFrames > xFrames =
+ xFramesSupplier->getFrames();
+
+ aFrameList = xFrames->queryFrames(
+ frame::FrameSearchFlag::ALL & ~frame::FrameSearchFlag::SELF );
+
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+
+ for ( uno::Reference < frame::XFrame > const & xf : std::as_const(aFrameList) )
+ {
+ if ( xf.is() && xf != m_xFrame )
+ {
+ OUString aCheckId;
+ try{
+ aCheckId = xModuleManager->identify( xf );
+ } catch(const uno::Exception&)
+ { aCheckId.clear(); }
+
+ if ( m_aModuleId == aCheckId )
+ {
+ // try to get the document based ui configuration manager
+ OUString aTitle2;
+ uno::Reference< frame::XController > xController_ =
+ xf->getController();
+
+ if ( xController_.is() )
+ {
+ uno::Reference< frame::XModel > xModel(
+ xController_->getModel() );
+
+ if ( xModel.is() )
+ {
+ uno::Reference<
+ css::ui::XUIConfigurationManagerSupplier >
+ xCfgSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xCfgSupplier.is() )
+ {
+ xDocCfgMgr =
+ xCfgSupplier->getUIConfigurationManager();
+ }
+ aTitle2 = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+ }
+ }
+
+ if ( xDocCfgMgr.is() )
+ {
+ SaveInData* pData = CreateSaveInData( xDocCfgMgr, xCfgMgr, m_aModuleId, true );
+
+ if ( pData && !pData->IsReadOnly() )
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pData)));
+ m_xSaveInListBox->append(sId, aTitle2);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ m_xSaveInListBox->connect_changed(
+ LINK( this, SvxConfigPage, SelectSaveInLocation ) );
+
+ bInitialised = true;
+
+ Init();
+ }
+ else
+ {
+ if ( QueryReset() == RET_YES )
+ {
+ // Reset menu configuration for currently selected SaveInData
+ GetSaveInData()->Reset();
+
+ Init();
+ }
+ }
+}
+
+OUString SvxConfigPage::GetFrameWithDefaultAndIdentify( uno::Reference< frame::XFrame >& _inout_rxFrame )
+{
+ OUString sModuleID;
+ try
+ {
+ uno::Reference< uno::XComponentContext > xContext(
+ ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create(
+ xContext );
+
+ if ( !_inout_rxFrame.is() )
+ _inout_rxFrame = xDesktop->getActiveFrame();
+
+ if ( !_inout_rxFrame.is() )
+ {
+ _inout_rxFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( !_inout_rxFrame.is() && SfxViewFrame::Current() )
+ _inout_rxFrame = SfxViewFrame::Current()->GetFrame().GetFrameInterface();
+
+ if ( !_inout_rxFrame.is() )
+ {
+ SAL_WARN( "cui.customize", "SvxConfigPage::GetFrameWithDefaultAndIdentify(): no frame found!" );
+ return sModuleID;
+ }
+
+ sModuleID = vcl::CommandInfoProvider::GetModuleIdentifier(_inout_rxFrame);
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+
+ return sModuleID;
+}
+
+OUString SvxConfigPage::GetScriptURL() const
+{
+ OUString result;
+
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xFunctions->get_selected_id().toInt64());
+ if (pData)
+ {
+ if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT ) ||
+ ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT ) ||
+ ( pData->nKind == SfxCfgKind::GROUP_STYLES ) )
+ {
+ result = pData->sCommand;
+ }
+ }
+
+ return result;
+}
+
+OUString SvxConfigPage::GetSelectedDisplayName() const
+{
+ return m_xFunctions->get_selected_text();
+}
+
+bool SvxConfigPage::FillItemSet( SfxItemSet* )
+{
+ bool result = false;
+
+ for (int i = 0, nCount = m_xSaveInListBox->get_count(); i < nCount; ++i)
+ {
+ OUString sId = m_xSaveInListBox->get_id(i);
+ if (sId != notebookbarTabScope)
+ {
+ SaveInData* pData = reinterpret_cast<SaveInData*>(sId.toInt64());
+ result = pData->Apply();
+ }
+ }
+ return result;
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectSaveInLocation, weld::ComboBox&, void)
+{
+ OUString sId = m_xSaveInListBox->get_active_id();
+ if (sId != notebookbarTabScope)
+ pCurrentSaveInData = reinterpret_cast<SaveInData*>(sId.toInt64());
+ Init();
+}
+
+void SvxConfigPage::ReloadTopLevelListBox( SvxConfigEntry const * pToSelect )
+{
+ int nSelectionPos = m_xTopLevelListBox->get_active();
+ m_xTopLevelListBox->clear();
+
+ if ( GetSaveInData() && GetSaveInData()->GetEntries() )
+ {
+ for (auto const& entryData : *GetSaveInData()->GetEntries())
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(entryData)));
+ m_xTopLevelListBox->append(sId, SvxConfigPageHelper::stripHotKey(entryData->GetName()));
+
+ if (entryData == pToSelect)
+ nSelectionPos = m_xTopLevelListBox->get_count() - 1;
+
+ AddSubMenusToUI( SvxConfigPageHelper::stripHotKey( entryData->GetName() ), entryData );
+ }
+ }
+#ifdef DBG_UTIL
+ else
+ {
+ DBG_ASSERT( GetSaveInData(), "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData" );
+ DBG_ASSERT( GetSaveInData()->GetEntries() ,
+ "SvxConfigPage::ReloadTopLevelListBox(): no SaveInData entries" );
+ }
+#endif
+
+ nSelectionPos = (nSelectionPos != -1 && nSelectionPos < m_xTopLevelListBox->get_count()) ?
+ nSelectionPos : m_xTopLevelListBox->get_count() - 1;
+
+ m_xTopLevelListBox->set_active(nSelectionPos);
+ SelectElement();
+}
+
+void SvxConfigPage::AddSubMenusToUI(
+ const OUString& rBaseTitle, SvxConfigEntry const * pParentData )
+{
+ for (auto const& entryData : *pParentData->GetEntries())
+ {
+ if (entryData->IsPopup())
+ {
+ OUString subMenuTitle = rBaseTitle + aMenuSeparatorStr + SvxConfigPageHelper::stripHotKey(entryData->GetName());
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(entryData)));
+ m_xTopLevelListBox->append(sId, subMenuTitle);
+
+ AddSubMenusToUI( subMenuTitle, entryData );
+ }
+ }
+}
+
+SvxEntries* SvxConfigPage::FindParentForChild(
+ SvxEntries* pRootEntries, SvxConfigEntry* pChildData )
+{
+ for (auto const& entryData : *pRootEntries)
+ {
+
+ if (entryData == pChildData)
+ {
+ return pRootEntries;
+ }
+ else if (entryData->IsPopup())
+ {
+ SvxEntries* result =
+ FindParentForChild( entryData->GetEntries(), pChildData );
+
+ if ( result != nullptr )
+ {
+ return result;
+ }
+ }
+ }
+ return nullptr;
+}
+
+int SvxConfigPage::AddFunction(int nTarget, bool bAllowDuplicates)
+{
+ OUString aURL = GetScriptURL();
+ SvxConfigEntry* pParent = GetTopLevelSelection();
+
+ if ( aURL.isEmpty() || pParent == nullptr )
+ {
+ return -1;
+ }
+
+ OUString aDisplayName;
+
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(aURL, m_aModuleId);
+
+ if ( typeid(*pCurrentSaveInData) == typeid(ContextMenuSaveInData) )
+ aDisplayName = vcl::CommandInfoProvider::GetPopupLabelForCommand(aProperties);
+ else if ( typeid(*pCurrentSaveInData) == typeid(MenuSaveInData) )
+ aDisplayName = vcl::CommandInfoProvider::GetMenuLabelForCommand(aProperties);
+ else
+ aDisplayName = vcl::CommandInfoProvider::GetLabelForCommand(aProperties);
+
+ SvxConfigEntry* pNewEntryData =
+ new SvxConfigEntry( aDisplayName, aURL, false, /*bParentData*/false );
+ pNewEntryData->SetUserDefined();
+
+ if ( aDisplayName.isEmpty() )
+ pNewEntryData->SetName( GetSelectedDisplayName() );
+
+ // check that this function is not already in the menu
+ if ( !bAllowDuplicates )
+ {
+ for (auto const& entry : *pParent->GetEntries())
+ {
+ if ( entry->GetCommand() == pNewEntryData->GetCommand() )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Info, VclButtonsType::Ok, CuiResId(RID_SVXSTR_MNUCFG_ALREADY_INCLUDED)));
+ xBox->run();
+ delete pNewEntryData;
+ return -1;
+ }
+ }
+ }
+
+ return AppendEntry(pNewEntryData, nTarget);
+}
+
+int SvxConfigPage::AppendEntry(
+ SvxConfigEntry* pNewEntryData,
+ int nTarget)
+{
+ SvxConfigEntry* pTopLevelSelection = GetTopLevelSelection();
+
+ if (pTopLevelSelection == nullptr)
+ return -1;
+
+ // Grab the entries list for the currently selected menu
+ SvxEntries* pEntries = pTopLevelSelection->GetEntries();
+
+ int nNewEntry = -1;
+ int nCurEntry =
+ nTarget != -1 ? nTarget : m_xContentsListBox->get_selected_index();
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pNewEntryData)));
+
+ if (nCurEntry == -1 || nCurEntry == m_xContentsListBox->n_children() - 1)
+ {
+ pEntries->push_back( pNewEntryData );
+ m_xContentsListBox->insert(-1, sId);
+ nNewEntry = m_xContentsListBox->n_children() - 1;
+ }
+ else
+ {
+ SvxConfigEntry* pEntryData =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nCurEntry).toInt64());
+
+ SvxEntries::iterator iter = pEntries->begin();
+ SvxEntries::const_iterator end = pEntries->end();
+
+ // Advance the iterator to the data for currently selected entry
+ sal_uInt16 nPos = 0;
+ while (*iter != pEntryData && ++iter != end)
+ {
+ ++nPos;
+ }
+
+ // Now step past it to the entry after the currently selected one
+ ++iter;
+ ++nPos;
+
+ // Now add the new entry to the UI and to the parent's list
+ if ( iter != end )
+ {
+ pEntries->insert( iter, pNewEntryData );
+ m_xContentsListBox->insert(nPos, sId);
+ nNewEntry = nPos;
+ }
+ }
+
+ if (nNewEntry != -1)
+ {
+ m_xContentsListBox->select(nNewEntry);
+ m_xContentsListBox->scroll_to_row(nNewEntry);
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+ }
+
+ return nNewEntry;
+}
+
+namespace
+{
+ template<typename itertype> void TmplInsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, itertype& rIter, int nStartCol, SaveInData* pSaveInData, VirtualDevice& rDropDown)
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pNewEntryData)));
+
+ rTreeView.set_id(rIter, sId);
+
+ if (pNewEntryData->IsSeparator())
+ {
+ rTreeView.set_text(rIter, "----------------------------------", nStartCol + 1);
+ }
+ else
+ {
+ auto xImage = pSaveInData->GetImage(pNewEntryData->GetCommand());
+ if (xImage.is())
+ rTreeView.set_image(rIter, xImage, nStartCol);
+ OUString aName = SvxConfigPageHelper::stripHotKey( pNewEntryData->GetName() );
+ rTreeView.set_text(rIter, aName, nStartCol + 1);
+ }
+
+ if (nStartCol == 0) // menus
+ {
+ if (pNewEntryData->IsPopup() || pNewEntryData->GetStyle() & css::ui::ItemStyle::DROP_DOWN)
+ rTreeView.set_image(rIter, rDropDown, nStartCol + 2);
+ else
+ rTreeView.set_image(rIter, css::uno::Reference<css::graphic::XGraphic>(), nStartCol + 2);
+ }
+ }
+}
+
+void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, int nPos, int nStartCol)
+{
+ TmplInsertEntryIntoUI<int>(pNewEntryData, rTreeView, nPos, nStartCol,
+ GetSaveInData(), m_xContentsListBox->get_dropdown_image());
+}
+
+void SvxConfigPage::InsertEntryIntoUI(SvxConfigEntry* pNewEntryData, weld::TreeView& rTreeView, weld::TreeIter& rIter, int nStartCol)
+{
+ TmplInsertEntryIntoUI<weld::TreeIter>(pNewEntryData, rTreeView, rIter, nStartCol,
+ GetSaveInData(), m_xContentsListBox->get_dropdown_image());
+}
+
+IMPL_LINK(SvxConfigPage, MoveHdl, weld::Button&, rButton, void)
+{
+ MoveEntry(&rButton == m_xMoveUpButton.get());
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, FunctionDoubleClickHdl, weld::TreeView&, bool)
+{
+ if (m_xAddCommandButton->get_sensitive())
+ m_xAddCommandButton->clicked();
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SelectFunctionHdl, weld::TreeView&, void)
+{
+ // GetScriptURL() returns a non-empty string if a
+ // valid command is selected on the left box
+ OUString aSelectCommand = GetScriptURL();
+ bool bIsValidCommand = !aSelectCommand.isEmpty();
+
+ // Enable/disable Add and Remove buttons depending on current selection
+ if (bIsValidCommand)
+ {
+ m_xAddCommandButton->set_sensitive(true);
+ m_xRemoveCommandButton->set_sensitive(true);
+
+ if (SfxHelp::IsHelpInstalled())
+ {
+ m_xDescriptionField->set_text(m_xFunctions->GetHelpText(false));
+ }
+ else
+ {
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xFunctions->get_selected_id().toInt64());
+ if (pData)
+ {
+ OUString aLabel = CuiResId(RID_SVXSTR_COMMANDLABEL) + ": " + pData->sLabel + "\n";
+ OUString aName = CuiResId(RID_SVXSTR_COMMANDNAME) + ": " + pData->sCommand + "\n";
+ OUString aTip = CuiResId(RID_SVXSTR_COMMANDTIP) + ": " + pData->sTooltip;
+ m_xDescriptionField->set_text(aLabel + aName + aTip);
+ }
+ }
+ }
+ else
+ {
+
+ m_xAddCommandButton->set_sensitive(false);
+ m_xRemoveCommandButton->set_sensitive(false);
+
+ m_xDescriptionField->set_text("");
+ }
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, ImplUpdateDataHdl, Timer*, void)
+{
+ OUString aSearchTerm(m_xSearchEdit->get_text());
+ m_xCommandCategoryListBox->categorySelected(m_xFunctions.get(), aSearchTerm, GetSaveInData());
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, SearchUpdateHdl, weld::Entry&, void)
+{
+ m_aUpdateDataTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxConfigPage, FocusOut_Impl, weld::Widget&, void)
+{
+ if (m_aUpdateDataTimer.IsActive())
+ {
+ m_aUpdateDataTimer.Stop();
+ m_aUpdateDataTimer.Invoke();
+ }
+}
+
+void SvxConfigPage::MoveEntry(bool bMoveUp)
+{
+ weld::TreeView& rTreeView = m_xContentsListBox->get_widget();
+
+ int nSourceEntry = rTreeView.get_selected_index();
+ int nTargetEntry = -1;
+ int nToSelect = -1;
+
+ if (nSourceEntry == -1)
+ {
+ return;
+ }
+
+ if ( bMoveUp )
+ {
+ // Move Up is just a Move Down with the source and target reversed
+ nTargetEntry = nSourceEntry;
+ nSourceEntry = nTargetEntry - 1;
+ nToSelect = nSourceEntry;
+ }
+ else
+ {
+ nTargetEntry = nSourceEntry + 1;
+ nToSelect = nTargetEntry;
+ }
+
+ if (MoveEntryData(nSourceEntry, nTargetEntry))
+ {
+ rTreeView.swap(nSourceEntry, nTargetEntry);
+ rTreeView.select(nToSelect);
+ rTreeView.scroll_to_row(nToSelect);
+
+ UpdateButtonStates();
+ }
+}
+
+bool SvxConfigPage::MoveEntryData(int nSourceEntry, int nTargetEntry)
+{
+ //#i53677#
+ if (nSourceEntry == -1 || nTargetEntry == -1)
+ {
+ return false;
+ }
+
+ // Grab the entries list for the currently selected menu
+ SvxEntries* pEntries = GetTopLevelSelection()->GetEntries();
+
+ SvxConfigEntry* pSourceData =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nSourceEntry).toInt64());
+
+ SvxConfigEntry* pTargetData =
+ reinterpret_cast<SvxConfigEntry*>(m_xContentsListBox->get_id(nTargetEntry).toInt64());
+
+ if ( pSourceData != nullptr && pTargetData != nullptr )
+ {
+ // remove the source entry from our list
+ SvxConfigPageHelper::RemoveEntry( pEntries, pSourceData );
+
+ SvxEntries::iterator iter = pEntries->begin();
+ SvxEntries::const_iterator end = pEntries->end();
+
+ // advance the iterator to the position of the target entry
+ while (*iter != pTargetData && ++iter != end) ;
+
+ // insert the source entry at the position after the target
+ pEntries->insert( ++iter, pSourceData );
+
+ GetSaveInData()->SetModified();
+ GetTopLevelSelection()->SetModified();
+
+ return true;
+ }
+
+ return false;
+}
+
+SvxMainMenuOrganizerDialog::SvxMainMenuOrganizerDialog(
+ weld::Window* pParent, SvxEntries* entries,
+ SvxConfigEntry const * selection, bool bCreateMenu )
+ : GenericDialogController(pParent, "cui/ui/movemenu.ui", "MoveMenuDialog")
+ , m_xMenuBox(m_xBuilder->weld_widget("namebox"))
+ , m_xMenuNameEdit(m_xBuilder->weld_entry("menuname"))
+ , m_xMenuListBox(m_xBuilder->weld_tree_view("menulist"))
+ , m_xMoveUpButton(m_xBuilder->weld_button("up"))
+ , m_xMoveDownButton(m_xBuilder->weld_button("down"))
+{
+ m_xMenuListBox->set_size_request(-1, m_xMenuListBox->get_height_rows(12));
+
+ // Copy the entries list passed in
+ if ( entries != nullptr )
+ {
+ mpEntries.reset( new SvxEntries );
+ for (auto const& entry : *entries)
+ {
+ m_xMenuListBox->append(OUString::number(reinterpret_cast<sal_uInt64>(entry)),
+ SvxConfigPageHelper::stripHotKey(entry->GetName()));
+ mpEntries->push_back(entry);
+ if (entry == selection)
+ {
+ m_xMenuListBox->select(m_xMenuListBox->n_children() - 1);
+ }
+ }
+ }
+
+ if ( bCreateMenu )
+ {
+ // Generate custom name for new menu
+ OUString prefix = CuiResId( RID_SVXSTR_NEW_MENU );
+
+ OUString newname = SvxConfigPageHelper::generateCustomName( prefix, entries );
+ OUString newurl = SvxConfigPageHelper::generateCustomMenuURL( mpEntries.get() );
+
+ SvxConfigEntry* pNewEntryData =
+ new SvxConfigEntry( newname, newurl, true, /*bParentData*/false );
+ pNewEntryData->SetName( newname );
+ pNewEntryData->SetUserDefined();
+ pNewEntryData->SetMain();
+
+ m_sNewMenuEntryId = OUString::number(reinterpret_cast<sal_uInt64>(pNewEntryData));
+ m_xMenuListBox->append(m_sNewMenuEntryId,
+ SvxConfigPageHelper::stripHotKey(pNewEntryData->GetName()));
+ m_xMenuListBox->select(m_xMenuListBox->n_children() - 1);
+
+ if (mpEntries)
+ mpEntries->push_back(pNewEntryData);
+
+ m_xMenuNameEdit->set_text(newname);
+ m_xMenuNameEdit->connect_changed(LINK(this, SvxMainMenuOrganizerDialog, ModifyHdl));
+ }
+ else
+ {
+ // hide name label and textfield
+ m_xMenuBox->hide();
+ // change the title
+ m_xDialog->set_title(CuiResId(RID_SVXSTR_MOVE_MENU));
+ }
+
+ m_xMenuListBox->connect_changed(LINK(this, SvxMainMenuOrganizerDialog, SelectHdl));
+
+ m_xMoveUpButton->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog, MoveHdl));
+ m_xMoveDownButton->connect_clicked(LINK( this, SvxMainMenuOrganizerDialog, MoveHdl));
+
+ UpdateButtonStates();
+}
+
+SvxMainMenuOrganizerDialog::~SvxMainMenuOrganizerDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog, ModifyHdl, weld::Entry&, void)
+{
+ // if the Edit control is empty do not change the name
+ if (m_xMenuNameEdit->get_text().isEmpty())
+ {
+ return;
+ }
+
+ SvxConfigEntry* pNewEntryData = reinterpret_cast<SvxConfigEntry*>(m_sNewMenuEntryId.toUInt64());
+ pNewEntryData->SetName(m_xMenuNameEdit->get_text());
+
+ const int nNewMenuPos = m_xMenuListBox->find_id(m_sNewMenuEntryId);
+ const int nOldSelection = m_xMenuListBox->get_selected_index();
+ m_xMenuListBox->remove(nNewMenuPos);
+ m_xMenuListBox->insert(nNewMenuPos, pNewEntryData->GetName(), &m_sNewMenuEntryId, nullptr, nullptr);
+ m_xMenuListBox->select(nOldSelection);
+}
+
+IMPL_LINK_NOARG(SvxMainMenuOrganizerDialog, SelectHdl, weld::TreeView&, void)
+{
+ UpdateButtonStates();
+}
+
+void SvxMainMenuOrganizerDialog::UpdateButtonStates()
+{
+ // Disable Up and Down buttons depending on current selection
+ const int nSelected = m_xMenuListBox->get_selected_index();
+ m_xMoveUpButton->set_sensitive(nSelected > 0);
+ m_xMoveDownButton->set_sensitive(nSelected != -1 && nSelected < m_xMenuListBox->n_children() - 1);
+}
+
+IMPL_LINK( SvxMainMenuOrganizerDialog, MoveHdl, weld::Button&, rButton, void )
+{
+ int nSourceEntry = m_xMenuListBox->get_selected_index();
+ if (nSourceEntry == -1)
+ return;
+
+ int nTargetEntry;
+
+ if (&rButton == m_xMoveDownButton.get())
+ {
+ nTargetEntry = nSourceEntry + 1;
+ }
+ else
+ {
+ // Move Up is just a Move Down with the source and target reversed
+ nTargetEntry = nSourceEntry - 1;
+ }
+
+ OUString sId = m_xMenuListBox->get_id(nSourceEntry);
+ OUString sEntry = m_xMenuListBox->get_text(nSourceEntry);
+ m_xMenuListBox->remove(nSourceEntry);
+ m_xMenuListBox->insert(nTargetEntry, sEntry, &sId, nullptr, nullptr);
+ m_xMenuListBox->select(nTargetEntry);
+
+ std::swap(mpEntries->at(nSourceEntry), mpEntries->at(nTargetEntry));
+
+ UpdateButtonStates();
+}
+
+SvxConfigEntry* SvxMainMenuOrganizerDialog::GetSelectedEntry()
+{
+ const int nSelected(m_xMenuListBox->get_selected_index());
+ if (nSelected == -1)
+ return nullptr;
+ return reinterpret_cast<SvxConfigEntry*>(m_xMenuListBox->get_id(nSelected).toUInt64());
+}
+
+SvxConfigEntry::SvxConfigEntry( const OUString& rDisplayName,
+ const OUString& rCommandURL, bool bPopup, bool bParentData )
+ : nId( 1 )
+ , aLabel(rDisplayName)
+ , aCommand(rCommandURL)
+ , bPopUp(bPopup)
+ , bStrEdited( false )
+ , bIsUserDefined( false )
+ , bIsMain( false )
+ , bIsParentData( bParentData )
+ , bIsModified( false )
+ , bIsVisible( true )
+ , nStyle( 0 )
+{
+ if (bPopUp)
+ {
+ mpEntries.reset( new SvxEntries );
+ }
+}
+
+SvxConfigEntry::~SvxConfigEntry()
+{
+ if (mpEntries)
+ {
+ for (auto const& entry : *mpEntries)
+ {
+ delete entry;
+ }
+ }
+}
+
+bool SvxConfigEntry::IsMovable() const
+{
+ return !IsPopup() || IsMain();
+}
+
+bool SvxConfigEntry::IsDeletable() const
+{
+ return !IsMain() || IsUserDefined();
+}
+
+bool SvxConfigEntry::IsRenamable() const
+{
+ return !IsMain() || IsUserDefined();
+}
+
+ToolbarSaveInData::ToolbarSaveInData(
+ const uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
+ const uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool docConfig ) :
+
+ SaveInData ( xCfgMgr, xParentCfgMgr, aModuleId, docConfig ),
+ m_aDescriptorContainer ( ITEM_DESCRIPTOR_CONTAINER )
+
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+ // Initialize the m_xPersistentWindowState variable which is used
+ // to get the default properties of system toolbars such as name
+ uno::Reference< container::XNameAccess > xPWSS = css::ui::theWindowStateConfiguration::get( xContext );
+
+ xPWSS->getByName( aModuleId ) >>= m_xPersistentWindowState;
+}
+
+ToolbarSaveInData::~ToolbarSaveInData()
+{
+}
+
+sal_Int32 ToolbarSaveInData::GetSystemStyle( const OUString& rResourceURL )
+{
+ sal_Int32 result = 0;
+
+ if ( rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL ) )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ prop.Value >>= result;
+ break;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, a default value is returned
+ }
+ }
+
+ return result;
+}
+
+void ToolbarSaveInData::SetSystemStyle(
+ const uno::Reference< frame::XFrame >& xFrame,
+ const OUString& rResourceURL,
+ sal_Int32 nStyle )
+{
+ // change the style using the API
+ SetSystemStyle( rResourceURL, nStyle );
+
+ // this code is a temporary hack as the UI is not updating after
+ // changing the toolbar style via the API
+ uno::Reference< css::frame::XLayoutManager > xLayoutManager;
+ vcl::Window *window = nullptr;
+
+ uno::Reference< beans::XPropertySet > xPropSet( xFrame, uno::UNO_QUERY );
+ if ( xPropSet.is() )
+ {
+ uno::Any a = xPropSet->getPropertyValue( "LayoutManager" );
+ a >>= xLayoutManager;
+ }
+
+ if ( xLayoutManager.is() )
+ {
+ uno::Reference< css::ui::XUIElement > xUIElement =
+ xLayoutManager->getElement( rResourceURL );
+
+ // check reference before we call getRealInterface. The layout manager
+ // can only provide references for elements that have been created
+ // before. It's possible that the current element is not available.
+ uno::Reference< css::awt::XWindow > xWindow;
+ if ( xUIElement.is() )
+ xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY );
+
+ window = VCLUnoHelper::GetWindow( xWindow ).get();
+ }
+
+ if ( !(window != nullptr && window->GetType() == WindowType::TOOLBOX) )
+ return;
+
+ ToolBox* toolbox = static_cast<ToolBox*>(window);
+
+ if ( nStyle == 0 )
+ {
+ toolbox->SetButtonType( ButtonType::SYMBOLONLY );
+ }
+ else if ( nStyle == 1 )
+ {
+ toolbox->SetButtonType( ButtonType::TEXT );
+ }
+ if ( nStyle == 2 )
+ {
+ toolbox->SetButtonType( ButtonType::SYMBOLTEXT );
+ }
+}
+
+void ToolbarSaveInData::SetSystemStyle(
+ const OUString& rResourceURL,
+ sal_Int32 nStyle )
+{
+ if ( !(rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL )) )
+ return;
+
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue& prop : aProps )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_STYLE )
+ {
+ prop.Value <<= nStyle;
+ break;
+ }
+ }
+ }
+
+ uno::Reference< container::XNameReplace >
+ xNameReplace( m_xPersistentWindowState, uno::UNO_QUERY );
+
+ xNameReplace->replaceByName( rResourceURL, uno::Any( aProps ) );
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, a default value is returned
+ SAL_WARN("cui.customize", "Exception setting toolbar style");
+ }
+}
+
+OUString ToolbarSaveInData::GetSystemUIName( const OUString& rResourceURL )
+{
+ OUString result;
+
+ if ( rResourceURL.startsWith( "private" ) &&
+ m_xPersistentWindowState.is() &&
+ m_xPersistentWindowState->hasByName( rResourceURL ) )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aProps;
+ uno::Any a( m_xPersistentWindowState->getByName( rResourceURL ) );
+
+ if ( a >>= aProps )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aProps) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= result;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // do nothing, an empty UIName will be returned
+ }
+ }
+
+ if ( rResourceURL.startsWith( ".uno" ) &&
+ m_xCommandToLabelMap.is() &&
+ m_xCommandToLabelMap->hasByName( rResourceURL ) )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( rResourceURL );
+
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aPropSeq) )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_LABEL )
+ {
+ prop.Value >>= result;
+ }
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ // not a system command name
+ }
+ }
+
+ return result;
+}
+
+SvxEntries* ToolbarSaveInData::GetEntries()
+{
+ typedef std::unordered_map<OUString, bool > ToolbarInfo;
+
+ ToolbarInfo aToolbarInfo;
+
+ if ( pRootEntry == nullptr )
+ {
+
+ pRootEntry.reset( new SvxConfigEntry( "MainToolbars", OUString(), true, /*bParentData*/false) );
+
+ const uno::Sequence< uno::Sequence < beans::PropertyValue > > info =
+ GetConfigManager()->getUIElementsInfo(
+ css::ui::UIElementType::TOOLBAR );
+
+ for ( uno::Sequence<beans::PropertyValue> const & props : info )
+ {
+ OUString url;
+ OUString systemname;
+ OUString uiname;
+
+ for ( const beans::PropertyValue& prop : props )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ prop.Value >>= url;
+ systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
+ }
+ else if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= uiname;
+ }
+ }
+
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings =
+ GetConfigManager()->getSettings( url, false );
+
+ if ( uiname.isEmpty() )
+ {
+ // try to get the name from m_xPersistentWindowState
+ uiname = GetSystemUIName( url );
+
+ if ( uiname.isEmpty() )
+ {
+ uiname = systemname;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ uiname, url, true, /*bParentData*/false );
+
+ pEntry->SetMain();
+ pEntry->SetStyle( GetSystemStyle( url ) );
+
+
+ // insert into std::unordered_map to filter duplicates from the parent
+ aToolbarInfo.emplace( systemname, true );
+
+ OUString custom(CUSTOM_TOOLBAR_STR);
+ if ( systemname.startsWith( custom ) )
+ {
+ pEntry->SetUserDefined();
+ }
+ else
+ {
+ pEntry->SetUserDefined( false );
+ }
+
+ pRootEntry->GetEntries()->push_back( pEntry );
+
+ LoadToolbar( xToolbarSettings, pEntry );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // TODO, handle resourceURL with no settings
+ }
+ }
+
+ uno::Reference< css::ui::XUIConfigurationManager > xParentCfgMgr = GetParentConfigManager();
+ if ( xParentCfgMgr.is() )
+ {
+ // Retrieve also the parent toolbars to make it possible
+ // to configure module toolbars and save them into the document
+ // config manager.
+ const uno::Sequence< uno::Sequence < beans::PropertyValue > > info_ =
+ xParentCfgMgr->getUIElementsInfo(
+ css::ui::UIElementType::TOOLBAR );
+
+ for ( uno::Sequence<beans::PropertyValue> const & props : info_ )
+ {
+ OUString url;
+ OUString systemname;
+ OUString uiname;
+
+ for ( const beans::PropertyValue& prop : props )
+ {
+ if ( prop.Name == ITEM_DESCRIPTOR_RESOURCEURL )
+ {
+ prop.Value >>= url;
+ systemname = url.copy( url.lastIndexOf( '/' ) + 1 );
+ }
+ else if ( prop.Name == ITEM_DESCRIPTOR_UINAME )
+ {
+ prop.Value >>= uiname;
+ }
+ }
+
+ // custom toolbars of the parent are not visible in the document layer
+ OUString custom(CUSTOM_TOOLBAR_STR);
+ if ( systemname.startsWith( custom ) )
+ continue;
+
+ // check if toolbar is already in the document layer
+ ToolbarInfo::const_iterator pIter = aToolbarInfo.find( systemname );
+ if ( pIter == aToolbarInfo.end() )
+ {
+ aToolbarInfo.emplace( systemname, true );
+
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings =
+ xParentCfgMgr->getSettings( url, false );
+
+ if ( uiname.isEmpty() )
+ {
+ // try to get the name from m_xPersistentWindowState
+ uiname = GetSystemUIName( url );
+
+ if ( uiname.isEmpty() )
+ {
+ uiname = systemname;
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ uiname, url, true, true );
+
+ pEntry->SetMain();
+ pEntry->SetStyle( GetSystemStyle( url ) );
+
+ if ( systemname.startsWith( custom ) )
+ {
+ pEntry->SetUserDefined();
+ }
+ else
+ {
+ pEntry->SetUserDefined( false );
+ }
+
+ pRootEntry->GetEntries()->push_back( pEntry );
+
+ LoadToolbar( xToolbarSettings, pEntry );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // TODO, handle resourceURL with no settings
+ }
+ }
+ }
+ }
+
+ std::sort( GetEntries()->begin(), GetEntries()->end(), SvxConfigPageHelper::EntrySort );
+ }
+
+ return pRootEntry->GetEntries();
+}
+
+void
+ToolbarSaveInData::SetEntries( std::unique_ptr<SvxEntries> pNewEntries )
+{
+ pRootEntry->SetEntries( std::move(pNewEntries) );
+}
+
+bool
+ToolbarSaveInData::HasURL( const OUString& rURL )
+{
+ for (auto const& entry : *GetEntries())
+ {
+ if (entry->GetCommand() == rURL)
+ {
+ return !entry->IsParentData();
+ }
+ }
+ return false;
+}
+
+bool ToolbarSaveInData::HasSettings()
+{
+ // return true if there is at least one toolbar entry
+ return !GetEntries()->empty();
+}
+
+void ToolbarSaveInData::Reset()
+{
+ // reset each toolbar by calling removeSettings for its toolbar URL
+ for (auto const& entry : *GetEntries())
+ {
+ try
+ {
+ const OUString& url = entry->GetCommand();
+ GetConfigManager()->removeSettings( url );
+ }
+ catch ( uno::Exception& )
+ {
+ // error occurred removing the settings
+ // TODO - add error dialog in future?
+ }
+ }
+
+ // persist changes to toolbar storage
+ PersistChanges( GetConfigManager() );
+
+ // now delete the root SvxConfigEntry the next call to GetEntries()
+ // causes it to be reinitialised
+ pRootEntry.reset();
+
+ // reset all icons to default
+ try
+ {
+ GetImageManager()->reset();
+ PersistChanges( GetImageManager() );
+ }
+ catch ( uno::Exception& )
+ {
+ SAL_WARN("cui.customize", "Error resetting all icons when resetting toolbars");
+ }
+}
+
+bool ToolbarSaveInData::Apply()
+{
+ // toolbar changes are instantly applied
+ return false;
+}
+
+void ToolbarSaveInData::ApplyToolbar(
+ uno::Reference< container::XIndexContainer > const & rToolbarBar,
+ uno::Reference< lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry const * pToolbarData )
+{
+ uno::Reference<uno::XComponentContext> xContext = ::comphelper::getProcessComponentContext();
+
+ for (auto const& entry : *pToolbarData->GetEntries())
+ {
+ if (entry->IsPopup())
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertToolbarEntry(entry);
+
+ uno::Reference< container::XIndexContainer > xSubMenuBar(
+ rFactory->createInstanceWithContext( xContext ),
+ uno::UNO_QUERY );
+
+ sal_Int32 nIndex = aPropValueSeq.getLength();
+ aPropValueSeq.realloc( nIndex + 1 );
+ aPropValueSeq[nIndex].Name = m_aDescriptorContainer;
+ aPropValueSeq[nIndex].Value <<= xSubMenuBar;
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( aPropValueSeq ));
+
+ ApplyToolbar(xSubMenuBar, rFactory, entry);
+ }
+ else if (entry->IsSeparator())
+ {
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( m_aSeparatorSeq ));
+ }
+ else
+ {
+ uno::Sequence< beans::PropertyValue > aPropValueSeq =
+ SvxConfigPageHelper::ConvertToolbarEntry(entry);
+
+ rToolbarBar->insertByIndex(
+ rToolbarBar->getCount(), uno::Any( aPropValueSeq ));
+ }
+ }
+}
+
+void ToolbarSaveInData::ApplyToolbar( SvxConfigEntry* pToolbar )
+{
+ // Apply new toolbar structure to our settings container
+ uno::Reference< container::XIndexAccess > xSettings =
+ GetConfigManager()->createSettings();
+
+ uno::Reference< container::XIndexContainer > xIndexContainer (
+ xSettings, uno::UNO_QUERY );
+
+ uno::Reference< lang::XSingleComponentFactory > xFactory (
+ xSettings, uno::UNO_QUERY );
+
+ ApplyToolbar( xIndexContainer, xFactory, pToolbar );
+
+ uno::Reference< beans::XPropertySet > xProps(
+ xSettings, uno::UNO_QUERY );
+
+ if ( pToolbar->IsUserDefined() )
+ {
+ xProps->setPropertyValue(
+ ITEM_DESCRIPTOR_UINAME,
+ uno::Any( pToolbar->GetName() ) );
+ }
+
+ try
+ {
+ if ( GetConfigManager()->hasSettings( pToolbar->GetCommand() ) )
+ {
+ GetConfigManager()->replaceSettings(
+ pToolbar->GetCommand(), xSettings );
+ }
+ else
+ {
+ GetConfigManager()->insertSettings(
+ pToolbar->GetCommand(), xSettings );
+ if ( pToolbar->IsParentData() )
+ pToolbar->SetParentData( false );
+ }
+ }
+ catch ( css::uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
+ }
+
+ PersistChanges( GetConfigManager() );
+}
+
+void ToolbarSaveInData::CreateToolbar( SvxConfigEntry* pToolbar )
+{
+ // show the new toolbar in the UI also
+ uno::Reference< container::XIndexAccess >
+ xSettings = GetConfigManager()->createSettings();
+
+ uno::Reference< beans::XPropertySet >
+ xPropertySet( xSettings, uno::UNO_QUERY );
+
+ xPropertySet->setPropertyValue(
+ ITEM_DESCRIPTOR_UINAME,
+ uno::Any( pToolbar->GetName() ) );
+
+ try
+ {
+ GetConfigManager()->insertSettings( pToolbar->GetCommand(), xSettings );
+ }
+ catch ( css::uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "caught exception saving settings");
+ }
+
+ GetEntries()->push_back( pToolbar );
+
+ PersistChanges( GetConfigManager() );
+}
+
+void ToolbarSaveInData::RemoveToolbar( SvxConfigEntry* pToolbar )
+{
+ try
+ {
+ OUString url = pToolbar->GetCommand();
+ GetConfigManager()->removeSettings( url );
+ SvxConfigPageHelper::RemoveEntry( GetEntries(), pToolbar );
+ delete pToolbar;
+
+ PersistChanges( GetConfigManager() );
+
+ // remove the persistent window state data
+ css::uno::Reference< css::container::XNameContainer > xNameContainer(
+ m_xPersistentWindowState, css::uno::UNO_QUERY_THROW );
+
+ xNameContainer->removeByName( url );
+ }
+ catch ( uno::Exception& )
+ {
+ // error occurred removing the settings
+ }
+}
+
+void ToolbarSaveInData::RestoreToolbar( SvxConfigEntry* pToolbar )
+{
+ OUString url = pToolbar->GetCommand();
+
+ // Restore of toolbar is done by removing it from
+ // its configuration manager and then getting it again
+ bool bParentToolbar = pToolbar->IsParentData();
+
+ // Cannot restore parent toolbar
+ if ( bParentToolbar )
+ return;
+
+ try
+ {
+ GetConfigManager()->removeSettings( url );
+ pToolbar->GetEntries()->clear();
+ PersistChanges( GetConfigManager() );
+ }
+ catch ( uno::Exception& )
+ {
+ // if an error occurs removing the settings then just return
+ return;
+ }
+
+ // Now reload the toolbar settings
+ try
+ {
+ uno::Reference< container::XIndexAccess > xToolbarSettings;
+ if ( IsDocConfig() )
+ {
+ xToolbarSettings = GetParentConfigManager()->getSettings( url, false );
+ pToolbar->SetParentData();
+ }
+ else
+ xToolbarSettings = GetConfigManager()->getSettings( url, false );
+
+ LoadToolbar( xToolbarSettings, pToolbar );
+
+ // After reloading, ensure that the icon is reset of each entry
+ // in the toolbar
+ uno::Sequence< OUString > aURLSeq( 1 );
+ for (auto const& entry : *pToolbar->GetEntries())
+ {
+ aURLSeq[ 0 ] = entry->GetCommand();
+
+ try
+ {
+ GetImageManager()->removeImages( SvxConfigPageHelper::GetImageType(), aURLSeq );
+ }
+ catch ( uno::Exception& )
+ {
+ SAL_WARN("cui.customize", "Error restoring icon when resetting toolbar");
+ }
+ }
+ PersistChanges( GetImageManager() );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ // cannot find the resource URL after removing it
+ // so no entry will appear in the toolbar list
+ }
+}
+
+void ToolbarSaveInData::LoadToolbar(
+ const uno::Reference< container::XIndexAccess >& xToolbarSettings,
+ SvxConfigEntry const * pParentData )
+{
+ SvxEntries* pEntries = pParentData->GetEntries();
+
+ for ( sal_Int32 nIndex = 0; nIndex < xToolbarSettings->getCount(); ++nIndex )
+ {
+ OUString aCommandURL;
+ OUString aLabel;
+ bool bIsVisible;
+ sal_Int32 nStyle;
+
+ sal_uInt16 nType( css::ui::ItemType::DEFAULT );
+
+ bool bItem = SvxConfigPageHelper::GetToolbarItemData( xToolbarSettings, nIndex, aCommandURL,
+ aLabel, nType, bIsVisible, nStyle );
+
+ if ( bItem )
+ {
+ bool bIsUserDefined = true;
+
+ if ( nType == css::ui::ItemType::DEFAULT )
+ {
+ uno::Any a;
+ try
+ {
+ a = m_xCommandToLabelMap->getByName( aCommandURL );
+ bIsUserDefined = false;
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ bIsUserDefined = true;
+ }
+
+ bool bUseDefaultLabel = false;
+ // If custom label not set retrieve it from the command
+ // to info service
+ if ( aLabel.isEmpty() )
+ {
+ bUseDefaultLabel = true;
+ uno::Sequence< beans::PropertyValue > aPropSeq;
+ if ( a >>= aPropSeq )
+ {
+ for ( beans::PropertyValue const & prop : std::as_const(aPropSeq) )
+ {
+ if ( prop.Name == "Name" )
+ {
+ prop.Value >>= aLabel;
+ break;
+ }
+ }
+ }
+ }
+
+ SvxConfigEntry* pEntry = new SvxConfigEntry(
+ aLabel, aCommandURL, false, /*bParentData*/false );
+
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntry->SetVisible( bIsVisible );
+ pEntry->SetStyle( nStyle );
+
+ if ( !bUseDefaultLabel )
+ pEntry->SetName( aLabel );
+
+ pEntries->push_back( pEntry );
+ }
+ else
+ {
+ SvxConfigEntry* pEntry = new SvxConfigEntry;
+ pEntry->SetUserDefined( bIsUserDefined );
+ pEntries->push_back( pEntry );
+ }
+ }
+ }
+}
+
+SvxNewToolbarDialog::SvxNewToolbarDialog(weld::Window* pWindow, const OUString& rName)
+ : GenericDialogController(pWindow, "cui/ui/newtoolbardialog.ui", "NewToolbarDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("edit"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+{
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+}
+
+SvxNewToolbarDialog::~SvxNewToolbarDialog()
+{
+}
+
+/*******************************************************************************
+*
+* The SvxIconSelectorDialog class
+*
+*******************************************************************************/
+SvxIconSelectorDialog::SvxIconSelectorDialog(weld::Window *pWindow,
+ const uno::Reference< css::ui::XImageManager >& rXImageManager,
+ const uno::Reference< css::ui::XImageManager >& rXParentImageManager)
+ : GenericDialogController(pWindow, "cui/ui/iconselectordialog.ui", "IconSelector")
+ , m_xImageManager(rXImageManager)
+ , m_xParentImageManager(rXParentImageManager)
+ , m_xTbSymbol(new ValueSet(m_xBuilder->weld_scrolled_window("symbolswin")))
+ , m_xTbSymbolWin(new weld::CustomWeld(*m_xBuilder, "symbolsToolbar", *m_xTbSymbol))
+ , m_xFtNote(m_xBuilder->weld_label("noteLabel"))
+ , m_xBtnImport(m_xBuilder->weld_button("importButton"))
+ , m_xBtnDelete(m_xBuilder->weld_button("deleteButton"))
+{
+ typedef std::unordered_map< OUString, bool > ImageInfo;
+
+ m_nExpectedSize = 16;
+ if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_LARGE)
+ m_nExpectedSize = 24;
+ else if (SvxConfigPageHelper::GetImageType() & css::ui::ImageType::SIZE_32)
+ m_nExpectedSize = 32;
+
+ if ( m_nExpectedSize != 16 )
+ {
+ m_xFtNote->set_label(SvxConfigPageHelper::replaceSixteen(m_xFtNote->get_label(), m_nExpectedSize));
+ }
+
+ m_xTbSymbol->SetStyle(m_xTbSymbol->GetStyle() | WB_ITEMBORDER | WB_VSCROLL);
+ m_xTbSymbol->SetColCount(11);
+ m_xTbSymbol->SetLineCount(5);
+ m_xTbSymbol->SetItemWidth(m_nExpectedSize);
+ m_xTbSymbol->SetItemHeight(m_nExpectedSize);
+ m_xTbSymbol->SetExtraSpacing(6);
+ Size aSize(m_xTbSymbol->CalcWindowSizePixel(Size(m_nExpectedSize, m_nExpectedSize), 11, 5));
+ m_xTbSymbol->set_size_request(aSize.Width(), aSize.Height());
+
+ uno::Reference< uno::XComponentContext > xComponentContext =
+ ::comphelper::getProcessComponentContext();
+
+ m_xGraphProvider.set( graphic::GraphicProvider::create( xComponentContext ) );
+
+ uno::Reference< css::util::XPathSettings > xPathSettings =
+ css::util::thePathSettings::get( xComponentContext );
+
+
+ OUString aDirectory = xPathSettings->getUserConfig();
+
+ sal_Int32 aCount = aDirectory.getLength();
+
+ if ( aCount > 0 )
+ {
+ sal_Unicode aChar = aDirectory[ aCount-1 ];
+ if ( aChar != '/')
+ {
+ aDirectory += "/";
+ }
+ }
+ else
+ {
+ m_xBtnImport->set_sensitive(false);
+ }
+
+ aDirectory += "soffice.cfg/import";
+
+ uno::Reference< lang::XSingleServiceFactory > xStorageFactory(
+ css::embed::FileSystemStorageFactory::create( xComponentContext ) );
+
+ uno::Sequence< uno::Any > aArgs( 2 );
+ aArgs[ 0 ] <<= aDirectory;
+ aArgs[ 1 ] <<= css::embed::ElementModes::READWRITE;
+
+ uno::Reference< css::embed::XStorage > xStorage(
+ xStorageFactory->createInstanceWithArguments( aArgs ), uno::UNO_QUERY );
+
+ uno::Sequence<uno::Any> aProp(comphelper::InitAnyPropertySequence(
+ {
+ {"UserConfigStorage", uno::Any(xStorage)},
+ {"OpenMode", uno::Any(css::embed::ElementModes::READWRITE)}
+ }));
+ m_xImportedImageManager = css::ui::ImageManager::create( xComponentContext );
+ m_xImportedImageManager->initialize(aProp);
+
+ ImageInfo aImageInfo1;
+ if ( m_xImportedImageManager.is() )
+ {
+ const uno::Sequence< OUString > names = m_xImportedImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for (auto const & name : names )
+ aImageInfo1.emplace( name, false );
+ }
+
+ uno::Sequence< OUString > name( 1 );
+ for (auto const& elem : aImageInfo1)
+ {
+ name[ 0 ] = elem.first;
+ uno::Sequence< uno::Reference< graphic::XGraphic> > graphics = m_xImportedImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ if ( graphics.hasElements() )
+ {
+ m_aGraphics.push_back(graphics[0]);
+ Image img(graphics[0]);
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), img, elem.first);
+ }
+ }
+
+ ImageInfo aImageInfo;
+
+ if ( m_xParentImageManager.is() )
+ {
+ const uno::Sequence< OUString > names = m_xParentImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for ( auto const & i : names )
+ aImageInfo.emplace( i, false );
+ }
+
+ const uno::Sequence< OUString > names = m_xImageManager->getAllImageNames( SvxConfigPageHelper::GetImageType() );
+ for ( auto const & i : names )
+ {
+ ImageInfo::iterator pIter = aImageInfo.find( i );
+ if ( pIter != aImageInfo.end() )
+ pIter->second = true;
+ else
+ aImageInfo.emplace( i, true );
+ }
+
+ // large growth factor, expecting many entries
+ for (auto const& elem : aImageInfo)
+ {
+ name[ 0 ] = elem.first;
+
+ uno::Sequence< uno::Reference< graphic::XGraphic> > graphics;
+ try
+ {
+ if (elem.second)
+ graphics = m_xImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ else
+ graphics = m_xParentImageManager->getImages( SvxConfigPageHelper::GetImageType(), name );
+ }
+ catch ( uno::Exception& )
+ {
+ // can't get sequence for this name so it will not be
+ // added to the list
+ }
+
+ if ( graphics.hasElements() )
+ {
+ Image img(graphics[0]);
+ if (!img.GetBitmapEx().IsEmpty())
+ {
+ m_aGraphics.push_back(graphics[0]);
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), img, elem.first);
+ }
+ }
+ }
+
+ m_xBtnDelete->set_sensitive( false );
+ m_xTbSymbol->SetSelectHdl( LINK(this, SvxIconSelectorDialog, SelectHdl) );
+ m_xBtnImport->connect_clicked( LINK(this, SvxIconSelectorDialog, ImportHdl) );
+ m_xBtnDelete->connect_clicked( LINK(this, SvxIconSelectorDialog, DeleteHdl) );
+}
+
+SvxIconSelectorDialog::~SvxIconSelectorDialog()
+{
+}
+
+uno::Reference< graphic::XGraphic> SvxIconSelectorDialog::GetSelectedIcon()
+{
+ uno::Reference<graphic::XGraphic> result;
+
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ if (nId)
+ {
+ result = m_aGraphics[nId - 1];
+ }
+
+ return result;
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, SelectHdl, ValueSet*, void)
+{
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ if (!nId)
+ {
+ m_xBtnDelete->set_sensitive(false);
+ return;
+ }
+
+ OUString aSelImageText = m_xTbSymbol->GetItemText(nId);
+ if (m_xImportedImageManager->hasImage(SvxConfigPageHelper::GetImageType(), aSelImageText))
+ {
+ m_xBtnDelete->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, ImportHdl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aImportDialog(
+ css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW,
+ FileDialogFlags::Graphic | FileDialogFlags::MultiSelection, m_xDialog.get());
+
+ // disable the link checkbox in the dialog
+ uno::Reference< css::ui::dialogs::XFilePickerControlAccess >
+ xController( aImportDialog.GetFilePicker(), uno::UNO_QUERY);
+ if ( xController.is() )
+ {
+ xController->enableControl(
+ css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK,
+ false);
+ }
+
+ aImportDialog.SetCurrentFilter(
+ "PNG - Portable Network Graphic");
+
+ if ( ERRCODE_NONE == aImportDialog.Execute() )
+ {
+ uno::Sequence< OUString > paths = aImportDialog.GetMPath();
+ ImportGraphics ( paths );
+ }
+}
+
+IMPL_LINK_NOARG(SvxIconSelectorDialog, DeleteHdl, weld::Button&, void)
+{
+ OUString message = CuiResId( RID_SVXSTR_DELETE_ICON_CONFIRM );
+
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::OkCancel,
+ message));
+ if (xWarn->run() != RET_OK)
+ return;
+
+ sal_uInt16 nId = m_xTbSymbol->GetSelectedItemId();
+
+ OUString aSelImageText = m_xTbSymbol->GetItemText( nId );
+ uno::Sequence< OUString > URLs { aSelImageText };
+ m_xTbSymbol->RemoveItem(nId);
+ m_xImportedImageManager->removeImages( SvxConfigPageHelper::GetImageType(), URLs );
+ if ( m_xImportedImageManager->isModified() )
+ {
+ m_xImportedImageManager->store();
+ }
+}
+
+bool SvxIconSelectorDialog::ReplaceGraphicItem(
+ const OUString& aURL )
+{
+ uno::Sequence< OUString > URLs(1);
+ uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
+
+ uno::Reference< graphic::XGraphic > xGraphic;
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = "URL";
+ aMediaProps[0].Value <<= aURL;
+
+ css::awt::Size aSize;
+ bool bOK = false;
+ try
+ {
+ xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
+
+ uno::Reference< beans::XPropertySet > props =
+ m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
+ uno::Any a = props->getPropertyValue( "SizePixel" );
+ a >>= aSize;
+ if (0 == aSize.Width || 0 == aSize.Height)
+ return false;
+ else
+ bOK = true;
+ }
+ catch ( uno::Exception& )
+ {
+ return false;
+ }
+
+ bool bResult( false );
+ size_t nCount = m_xTbSymbol->GetItemCount();
+ for (size_t n = 0; n < nCount; ++n)
+ {
+ sal_uInt16 nId = m_xTbSymbol->GetItemId( n );
+
+ if ( m_xTbSymbol->GetItemText( nId ) == aURL )
+ {
+ try
+ {
+ // replace/insert image with provided URL
+ size_t nPos = nId - 1;
+ assert(nPos == m_xTbSymbol->GetItemPos(nId));
+ m_xTbSymbol->RemoveItem(nId);
+ aMediaProps[0].Value <<= aURL;
+
+ Image aImage( xGraphic );
+ if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
+ {
+ BitmapEx aBitmap = aImage.GetBitmapEx();
+ BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
+ aImage = Image( aBitmapex);
+ }
+ m_xTbSymbol->InsertItem(nId, aImage, aURL, nPos); //modify
+
+ m_aGraphics[nPos] = Graphic(aImage.GetBitmapEx()).GetXGraphic();
+
+ URLs[0] = aURL;
+ aImportGraph[ 0 ] = xGraphic;
+ m_xImportedImageManager->replaceImages( SvxConfigPageHelper::GetImageType(), URLs, aImportGraph );
+ m_xImportedImageManager->store();
+
+ bResult = true;
+ break;
+ }
+ catch ( css::uno::Exception& )
+ {
+ break;
+ }
+ }
+ }
+
+ return bResult;
+}
+
+namespace
+{
+ OUString ReplaceIconName(const OUString& rMessage)
+ {
+ OUString name;
+ OUString message = CuiResId( RID_SVXSTR_REPLACE_ICON_WARNING );
+ OUString placeholder("%ICONNAME" );
+ sal_Int32 pos = message.indexOf( placeholder );
+ if ( pos != -1 )
+ {
+ name = message.replaceAt(
+ pos, placeholder.getLength(), rMessage );
+ }
+ return name;
+ }
+
+ class SvxIconReplacementDialog
+ {
+ private:
+ std::unique_ptr<weld::MessageDialog> m_xQueryBox;
+ public:
+ SvxIconReplacementDialog(weld::Window *pParent, const OUString& rMessage, bool bYestoAll)
+ : m_xQueryBox(Application::CreateMessageDialog(pParent, VclMessageType::Warning, VclButtonsType::NONE, ReplaceIconName(rMessage)))
+ {
+ m_xQueryBox->set_title(CuiResId(RID_SVXSTR_REPLACE_ICON_CONFIRM));
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::Yes), 2);
+ if (bYestoAll)
+ m_xQueryBox->add_button(CuiResId(RID_SVXSTR_YESTOALL), 5);
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::No), 4);
+ m_xQueryBox->add_button(GetStandardText(StandardButtonType::Cancel), 6);
+ m_xQueryBox->set_default_response(2);
+ }
+ short run() { return m_xQueryBox->run(); }
+ };
+}
+
+void SvxIconSelectorDialog::ImportGraphics(
+ const uno::Sequence< OUString >& rPaths )
+{
+ uno::Sequence< OUString > rejected( rPaths.getLength() );
+ sal_Int32 rejectedCount = 0;
+
+ sal_uInt16 ret = 0;
+ sal_Int32 aIndex;
+ OUString aIconName;
+
+ if ( rPaths.getLength() == 1 )
+ {
+ if ( m_xImportedImageManager->hasImage( SvxConfigPageHelper::GetImageType(), rPaths[0] ) )
+ {
+ aIndex = rPaths[0].lastIndexOf( '/' );
+ aIconName = rPaths[0].copy( aIndex+1 );
+ SvxIconReplacementDialog aDlg(m_xDialog.get(), aIconName, false);
+ ret = aDlg.run();
+ if ( ret == 2 )
+ {
+ ReplaceGraphicItem( rPaths[0] );
+ }
+ }
+ else
+ {
+ if ( !ImportGraphic( rPaths[0] ) )
+ {
+ rejected[0] = rPaths[0];
+ rejectedCount = 1;
+ }
+ }
+ }
+ else
+ {
+ OUString aSourcePath( rPaths[0] );
+ if ( rPaths[0].lastIndexOf( '/' ) != rPaths[0].getLength() -1 )
+ aSourcePath = rPaths[0] + "/";
+
+ for ( sal_Int32 i = 1; i < rPaths.getLength(); ++i )
+ {
+ OUString aPath = aSourcePath + rPaths[i];
+ if ( m_xImportedImageManager->hasImage( SvxConfigPageHelper::GetImageType(), aPath ) )
+ {
+ aIndex = rPaths[i].lastIndexOf( '/' );
+ aIconName = rPaths[i].copy( aIndex+1 );
+ SvxIconReplacementDialog aDlg(m_xDialog.get(), aIconName, true);
+ ret = aDlg.run();
+ if ( ret == 2 )
+ {
+ ReplaceGraphicItem( aPath );
+ }
+ else if ( ret == 5 )
+ {
+ for ( sal_Int32 k = i; k < rPaths.getLength(); ++k )
+ {
+ aPath = aSourcePath + rPaths[k];
+ bool bHasReplaced = ReplaceGraphicItem( aPath );
+
+ if ( !bHasReplaced )
+ {
+ bool result = ImportGraphic( aPath );
+ if ( !result )
+ {
+ rejected[ rejectedCount ] = rPaths[i];
+ ++rejectedCount;
+ }
+ }
+ }
+ break;
+ }
+ }
+ else
+ {
+ bool result = ImportGraphic( aSourcePath + rPaths[i] );
+ if ( !result )
+ {
+ rejected[ rejectedCount ] = rPaths[i];
+ ++rejectedCount;
+ }
+ }
+ }
+ }
+
+ if ( rejectedCount == 0 )
+ return;
+
+ OUStringBuffer message;
+ OUString fPath;
+ if (rejectedCount > 1)
+ fPath = rPaths[0].copy(8) + "/";
+ for ( sal_Int32 i = 0; i < rejectedCount; ++i )
+ {
+ message.append(fPath).append(rejected[i]).append("\n");
+ }
+
+ SvxIconChangeDialog aDialog(m_xDialog.get(), message.makeStringAndClear());
+ aDialog.run();
+}
+
+bool SvxIconSelectorDialog::ImportGraphic( const OUString& aURL )
+{
+ bool result = false;
+
+ uno::Sequence< beans::PropertyValue > aMediaProps( 1 );
+ aMediaProps[0].Name = "URL";
+
+ uno::Reference< graphic::XGraphic > xGraphic;
+ css::awt::Size aSize;
+ aMediaProps[0].Value <<= aURL;
+ try
+ {
+ uno::Reference< beans::XPropertySet > props =
+ m_xGraphProvider->queryGraphicDescriptor( aMediaProps );
+
+ uno::Any a = props->getPropertyValue("SizePixel");
+
+ xGraphic = m_xGraphProvider->queryGraphic( aMediaProps );
+ if ( xGraphic.is() )
+ {
+ bool bOK = true;
+
+ a >>= aSize;
+ if ( 0 == aSize.Width || 0 == aSize.Height )
+ bOK = false;
+
+ Image aImage( xGraphic );
+
+ if ( bOK && ((aSize.Width != m_nExpectedSize) || (aSize.Height != m_nExpectedSize)) )
+ {
+ BitmapEx aBitmap = aImage.GetBitmapEx();
+ BitmapEx aBitmapex = BitmapEx::AutoScaleBitmap(aBitmap, m_nExpectedSize);
+ aImage = Image( aBitmapex);
+ }
+ if ( bOK && !!aImage )
+ {
+ m_aGraphics.push_back(Graphic(aImage.GetBitmapEx()).GetXGraphic());
+ m_xTbSymbol->InsertItem(m_aGraphics.size(), aImage, aURL);
+
+ uno::Sequence<OUString> aImportURL { aURL };
+ uno::Sequence< uno::Reference<graphic::XGraphic > > aImportGraph( 1 );
+ aImportGraph[ 0 ] = xGraphic;
+ m_xImportedImageManager->insertImages( SvxConfigPageHelper::GetImageType(), aImportURL, aImportGraph );
+ if ( m_xImportedImageManager->isModified() )
+ {
+ m_xImportedImageManager->store();
+ }
+
+ result = true;
+ }
+ else
+ {
+ SAL_WARN("cui.customize", "could not create Image from XGraphic");
+ }
+ }
+ else
+ {
+ SAL_WARN("cui.customize", "could not get query XGraphic");
+ }
+ }
+ catch( uno::Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Caught exception importing XGraphic");
+ }
+ return result;
+}
+
+/*******************************************************************************
+*
+* The SvxIconChangeDialog class added for issue83555
+*
+*******************************************************************************/
+SvxIconChangeDialog::SvxIconChangeDialog(weld::Window *pWindow, const OUString& rMessage)
+ : MessageDialogController(pWindow, "cui/ui/iconchangedialog.ui", "IconChange", "grid")
+ , m_xLineEditDescription(m_xBuilder->weld_text_view("addrTextview"))
+{
+ m_xLineEditDescription->set_size_request(m_xLineEditDescription->get_approximate_digit_width() * 48,
+ m_xLineEditDescription->get_text_height() * 8);
+ m_xLineEditDescription->set_text(rMessage);
+}
+
+SvxConfigPageFunctionDropTarget::SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView)
+ : DropTargetHelper(rTreeView.get_drop_target())
+ , m_rPage(rPage)
+ , m_rTreeView(rTreeView)
+{
+}
+
+sal_Int8 SvxConfigPageFunctionDropTarget::AcceptDrop(const AcceptDropEvent& rEvt)
+{
+ // to enable the autoscroll when we're close to the edges
+ m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, nullptr);
+ return DND_ACTION_MOVE;
+}
+
+sal_Int8 SvxConfigPageFunctionDropTarget::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ weld::TreeView* pSource = m_rTreeView.get_drag_source();
+ // only dragging within the same widget allowed
+ if (!pSource || pSource != &m_rTreeView)
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator());
+ if (!m_rTreeView.get_selected(xSource.get()))
+ return DND_ACTION_NONE;
+
+ std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator());
+ int nTargetPos = -1;
+ if (m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get()))
+ nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);
+ m_rTreeView.move_subtree(*xSource, nullptr, nTargetPos);
+
+ m_rPage.ListModified();
+
+ return DND_ACTION_NONE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/cfgutil.cxx b/cui/source/customize/cfgutil.cxx
new file mode 100644
index 000000000..d8ec5d79c
--- /dev/null
+++ b/cui/source/customize/cfgutil.cxx
@@ -0,0 +1,1195 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cfgutil.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/document/XScriptInvocationContext.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theUICommandDescription.hpp>
+#include <com/sun/star/frame/XDispatchInformationProvider.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/ui/theUICategoryDescription.hpp>
+
+#include <basic/basmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <sfx2/minfitem.hxx>
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <svtools/imagemgr.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <dialmgr.hxx>
+#include <tools/diagnose_ex.h>
+#include <vcl/commandinfoprovider.hxx>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::script;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::document;
+
+SfxStylesInfo_Impl::SfxStylesInfo_Impl()
+{}
+
+void SfxStylesInfo_Impl::init(const OUString& rModuleName, const css::uno::Reference< css::frame::XModel >& xModel)
+{
+ m_aModuleName = rModuleName;
+ m_xDoc = xModel;
+}
+
+static const char CMDURL_STYLEPROT_ONLY[] = ".uno:StyleApply?";
+static const char CMDURL_SPART_ONLY [] = "Style:string=";
+static const char CMDURL_FPART_ONLY [] = "FamilyName:string=";
+
+static const char STYLEPROP_UINAME[] = "DisplayName";
+
+OUString SfxStylesInfo_Impl::generateCommand(const OUString& sFamily, const OUString& sStyle)
+{
+ return ".uno:StyleApply?Style:string="
+ + sStyle
+ + "&FamilyName:string="
+ + sFamily;
+}
+
+bool SfxStylesInfo_Impl::parseStyleCommand(SfxStyleInfo_Impl& aStyle)
+{
+ static const sal_Int32 LEN_STYLEPROT = strlen(CMDURL_STYLEPROT_ONLY);
+ static const sal_Int32 LEN_SPART = strlen(CMDURL_SPART_ONLY);
+ static const sal_Int32 LEN_FPART = strlen(CMDURL_FPART_ONLY);
+
+ if (!aStyle.sCommand.startsWith(CMDURL_STYLEPROT_ONLY))
+ return false;
+
+ aStyle.sFamily.clear();
+ aStyle.sStyle.clear();
+
+ sal_Int32 nCmdLen = aStyle.sCommand.getLength();
+ OUString sCmdArgs = aStyle.sCommand.copy(LEN_STYLEPROT, nCmdLen-LEN_STYLEPROT);
+ sal_Int32 i = sCmdArgs.indexOf('&');
+ if (i<0)
+ return false;
+
+ OUString sArg = sCmdArgs.copy(0, i);
+ if (sArg.startsWith(CMDURL_SPART_ONLY))
+ aStyle.sStyle = sArg.copy(LEN_SPART);
+ else if (sArg.startsWith(CMDURL_FPART_ONLY))
+ aStyle.sFamily = sArg.copy(LEN_FPART);
+
+ sArg = sCmdArgs.copy(i+1, sCmdArgs.getLength()-i-1);
+ if (sArg.startsWith(CMDURL_SPART_ONLY))
+ aStyle.sStyle = sArg.copy(LEN_SPART);
+ else if (sArg.startsWith(CMDURL_FPART_ONLY))
+ aStyle.sFamily = sArg.copy(LEN_FPART);
+
+ return !(aStyle.sFamily.isEmpty() || aStyle.sStyle.isEmpty());
+}
+
+void SfxStylesInfo_Impl::getLabel4Style(SfxStyleInfo_Impl& aStyle)
+{
+ try
+ {
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
+
+ css::uno::Reference< css::container::XNameAccess > xFamilies;
+ if (xModel.is())
+ xFamilies = xModel->getStyleFamilies();
+
+ css::uno::Reference< css::container::XNameAccess > xStyleSet;
+ if (xFamilies.is())
+ xFamilies->getByName(aStyle.sFamily) >>= xStyleSet;
+
+ css::uno::Reference< css::beans::XPropertySet > xStyle;
+ if (xStyleSet.is())
+ xStyleSet->getByName(aStyle.sStyle) >>= xStyle;
+
+ aStyle.sLabel.clear();
+ if (xStyle.is())
+ xStyle->getPropertyValue(STYLEPROP_UINAME) >>= aStyle.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { aStyle.sLabel.clear(); }
+
+ if (aStyle.sLabel.isEmpty())
+ {
+ aStyle.sLabel = aStyle.sCommand;
+ }
+}
+
+std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyleFamilies() const
+{
+ // It's an optional interface!
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY);
+ if (!xModel.is())
+ return std::vector< SfxStyleInfo_Impl >();
+
+ css::uno::Reference< css::container::XNameAccess > xCont = xModel->getStyleFamilies();
+ const css::uno::Sequence< OUString > lFamilyNames = xCont->getElementNames();
+ std::vector< SfxStyleInfo_Impl > lFamilies;
+ for (const auto& aFamily : lFamilyNames)
+ {
+ if ((aFamily == "CellStyles" && m_aModuleName != "com.sun.star.sheet.SpreadsheetDocument") ||
+ aFamily == "cell" || aFamily == "table" || aFamily == "Default")
+ continue;
+
+ SfxStyleInfo_Impl aFamilyInfo;
+ aFamilyInfo.sFamily = aFamily;
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xFamilyInfo;
+ xCont->getByName(aFamilyInfo.sFamily) >>= xFamilyInfo;
+ if (!xFamilyInfo.is())
+ {
+ // TODO_AS currently there is no support for an UIName property .. use internal family name instead
+ aFamilyInfo.sLabel = aFamilyInfo.sFamily;
+ }
+ else
+ xFamilyInfo->getPropertyValue(STYLEPROP_UINAME) >>= aFamilyInfo.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { return std::vector< SfxStyleInfo_Impl >(); }
+
+ lFamilies.push_back(aFamilyInfo);
+ }
+
+ return lFamilies;
+}
+
+std::vector< SfxStyleInfo_Impl > SfxStylesInfo_Impl::getStyles(const OUString& sFamily)
+{
+ css::uno::Sequence< OUString > lStyleNames;
+ css::uno::Reference< css::style::XStyleFamiliesSupplier > xModel(m_xDoc, css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::container::XNameAccess > xFamilies = xModel->getStyleFamilies();
+ css::uno::Reference< css::container::XNameAccess > xStyleSet;
+ try
+ {
+ xFamilies->getByName(sFamily) >>= xStyleSet;
+ lStyleNames = xStyleSet->getElementNames();
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { return std::vector< SfxStyleInfo_Impl >(); }
+
+ std::vector< SfxStyleInfo_Impl > lStyles;
+ sal_Int32 c = lStyleNames.getLength();
+ sal_Int32 i = 0;
+ for (i=0; i<c; ++i)
+ {
+ SfxStyleInfo_Impl aStyleInfo;
+ aStyleInfo.sFamily = sFamily;
+ aStyleInfo.sStyle = lStyleNames[i];
+ aStyleInfo.sCommand = SfxStylesInfo_Impl::generateCommand(aStyleInfo.sFamily, aStyleInfo.sStyle);
+
+ try
+ {
+ css::uno::Reference< css::beans::XPropertySet > xStyle;
+ xStyleSet->getByName(aStyleInfo.sStyle) >>= xStyle;
+ if (!xStyle.is())
+ continue;
+ xStyle->getPropertyValue("DisplayName") >>= aStyleInfo.sLabel;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { continue; }
+
+ lStyles.push_back(aStyleInfo);
+ }
+ return lStyles;
+}
+
+OUString CuiConfigFunctionListBox::GetHelpText( bool bConsiderParent )
+{
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(get_selected_id().toInt64());
+ if (pData)
+ {
+ if ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
+ {
+ if (bConsiderParent)
+ return Application::GetHelp()->GetHelpText(pData->sCommand, m_xTreeView.get());
+ else
+ return Application::GetHelp()->GetHelpText(pData->sCommand, static_cast<weld::Widget*>(nullptr));
+ }
+ else if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ {
+ return pData->sHelpText;
+ }
+ }
+ return OUString();
+}
+
+OUString CuiConfigFunctionListBox::GetCurCommand() const
+{
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(get_selected_id().toInt64());
+ if (!pData)
+ return OUString();
+ return pData->sCommand;
+}
+
+OUString CuiConfigFunctionListBox::GetCurLabel() const
+{
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(get_selected_id().toInt64());
+ if (!pData)
+ return OUString();
+ if (!pData->sLabel.isEmpty())
+ return pData->sLabel;
+ return pData->sCommand;
+}
+
+CuiConfigFunctionListBox::CuiConfigFunctionListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : m_xTreeView(std::move(xTreeView))
+ , m_xScratchIter(m_xTreeView->make_iterator())
+{
+ m_xTreeView->make_sorted();
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
+ m_xTreeView->connect_query_tooltip(LINK(this, CuiConfigFunctionListBox, QueryTooltip));
+}
+
+CuiConfigFunctionListBox::~CuiConfigFunctionListBox()
+{
+ ClearAll();
+}
+
+IMPL_LINK(CuiConfigFunctionListBox, QueryTooltip, const weld::TreeIter&, rIter, OUString)
+{
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter).toInt64());
+ if (!pData)
+ return OUString();
+ OUString aLabel = CuiResId(RID_SVXSTR_COMMANDLABEL) + ": ";
+ OUString aName = CuiResId(RID_SVXSTR_COMMANDNAME) + ": ";
+ OUString aTip = CuiResId(RID_SVXSTR_COMMANDTIP) + ": ";
+ return aLabel + pData->sLabel + "\n" + aName + pData->sCommand+ "\n" + aTip + pData->sTooltip;
+}
+
+void CuiConfigFunctionListBox::ClearAll()
+/* Description
+ Deletes all entries in the FunctionListBox, all UserData and all
+ possibly existing MacroInfo.
+*/
+{
+ sal_uInt16 nCount = aArr.size();
+ for ( sal_uInt16 i=0; i<nCount; ++i )
+ {
+ SfxGroupInfo_Impl *pData = aArr[i].get();
+
+ if ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ {
+ OUString* pScriptURI = static_cast<OUString*>(pData->pObject);
+ delete pScriptURI;
+ }
+
+ if ( pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER )
+ {
+ XInterface* xi = static_cast<XInterface *>(pData->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ aArr.clear();
+ m_xTreeView->clear();
+}
+
+OUString CuiConfigFunctionListBox::GetSelectedScriptURI() const
+{
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(get_selected_id().toInt64());
+ if (pData && pData->nKind == SfxCfgKind::FUNCTION_SCRIPT)
+ return *static_cast<OUString*>(pData->pObject);
+ return OUString();
+}
+
+struct SvxConfigGroupBoxResource_Impl
+{
+ OUString m_sMyMacros;
+ OUString m_sProdMacros;
+ OUString m_sMacros;
+ OUString m_sDlgMacros;
+ OUString m_aStrGroupStyles;
+
+ SvxConfigGroupBoxResource_Impl();
+};
+
+SvxConfigGroupBoxResource_Impl::SvxConfigGroupBoxResource_Impl() :
+ m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS)),
+ m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
+ m_sMacros(CuiResId(RID_SVXSTR_BASICMACROS)),
+ m_sDlgMacros(CuiResId(RID_SVXSTR_PRODMACROS)),
+ m_aStrGroupStyles(CuiResId(RID_SVXSTR_GROUP_STYLES))
+{
+}
+
+void CuiConfigGroupListBox::SetStylesInfo(SfxStylesInfo_Impl* pStyles)
+{
+ m_pStylesInfo = pStyles;
+}
+
+namespace
+{
+
+ /** examines a component whether it supports XEmbeddedScripts, or provides access to such a
+ component by implementing XScriptInvocationContext.
+ @return
+ the model which supports the embedded scripts, or <NULL/> if it cannot find such a
+ model
+ */
+ Reference< XModel > lcl_getDocumentWithScripts_throw( const Reference< XInterface >& _rxComponent )
+ {
+ Reference< XEmbeddedScripts > xScripts( _rxComponent, UNO_QUERY );
+ if ( !xScripts.is() )
+ {
+ Reference< XScriptInvocationContext > xContext( _rxComponent, UNO_QUERY );
+ if ( xContext.is() )
+ xScripts = xContext->getScriptContainer();
+ }
+
+ return Reference< XModel >( xScripts, UNO_QUERY );
+ }
+
+
+ Reference< XModel > lcl_getScriptableDocument_nothrow( const Reference< XFrame >& _rxFrame )
+ {
+ Reference< XModel > xDocument;
+
+ // examine our associated frame
+ try
+ {
+ OSL_ENSURE( _rxFrame.is(), "lcl_getScriptableDocument_nothrow: you need to pass a frame to this dialog/tab page!" );
+ if ( _rxFrame.is() )
+ {
+ // first try the model in the frame
+ Reference< XController > xController( _rxFrame->getController(), UNO_SET_THROW );
+ xDocument = lcl_getDocumentWithScripts_throw( xController->getModel() );
+
+ if ( !xDocument.is() )
+ {
+ // if there is no suitable document in the frame, try the controller
+ xDocument = lcl_getDocumentWithScripts_throw( _rxFrame->getController() );
+ }
+ }
+ }
+ catch( const Exception& )
+ {
+ }
+
+ return xDocument;
+ }
+}
+
+CuiConfigGroupListBox::CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : xImp(new SvxConfigGroupBoxResource_Impl())
+ , m_pFunctionListBox(nullptr)
+ , m_pStylesInfo(nullptr)
+ , m_xTreeView(std::move(xTreeView))
+{
+ m_xTreeView->connect_expanding(LINK(this, CuiConfigGroupListBox, ExpandingHdl));
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 35, m_xTreeView->get_height_rows(9));
+}
+
+CuiConfigGroupListBox::~CuiConfigGroupListBox()
+{
+ ClearAll();
+}
+
+void CuiConfigGroupListBox::ClearAll()
+{
+ sal_uInt16 nCount = aArr.size();
+ for ( sal_uInt16 i=0; i<nCount; ++i )
+ {
+ SfxGroupInfo_Impl *pData = aArr[i].get();
+ if (pData->nKind == SfxCfgKind::GROUP_SCRIPTCONTAINER)
+ {
+ XInterface* xi = static_cast<XInterface *>(pData->pObject);
+ if (xi != nullptr)
+ {
+ xi->release();
+ }
+ }
+ }
+
+ aArr.clear();
+ m_xTreeView->clear();
+}
+
+void CuiConfigGroupListBox::InitModule()
+{
+ try
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider(m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< sal_Int16 > lGroups = xProvider->getSupportedCommandGroups();
+ sal_Int32 c1 = lGroups.getLength();
+ sal_Int32 i1 = 0;
+
+ if ( c1 )
+ {
+ // Add All Commands category
+ aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_ALLFUNCTIONS, 0));
+ m_xTreeView->append(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())),
+ CuiResId(RID_SVXSTR_ALLFUNCTIONS));
+ }
+
+ for (i1=0; i1<c1; ++i1)
+ {
+ sal_Int16& rGroupID = lGroups[i1];
+ OUString sGroupID = OUString::number(rGroupID);
+ OUString sGroupName ;
+
+ try
+ {
+ m_xModuleCategoryInfo->getByName(sGroupID) >>= sGroupName;
+ if (sGroupName.isEmpty())
+ continue;
+ }
+ catch(const css::container::NoSuchElementException&)
+ { continue; }
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_FUNCTION, rGroupID ) );
+ m_xTreeView->append(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())),
+ sGroupName);
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ {}
+}
+
+void CuiConfigGroupListBox::FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
+ const weld::TreeIter* pParentEntry, bool bCheapChildrenOnDemand)
+{
+ try {
+ if ( xRootNode->hasChildNodes() )
+ {
+ // tdf#120362: Don't ask to enable disabled Java when filling script list
+ css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
+
+ const Sequence< Reference< browse::XBrowseNode > > children =
+ xRootNode->getChildNodes();
+ bool bIsRootNode = false;
+
+ OUString user("user");
+ OUString share("share");
+ if ( xRootNode->getName() == "Root" )
+ {
+ bIsRootNode = true;
+ }
+
+ //To mimic current starbasic behaviour we
+ //need to make sure that only the current document
+ //is displayed in the config tree. Tests below
+ //set the bDisplay flag to FALSE if the current
+ //node is a first level child of the Root and is NOT
+ //either the current document, user or share
+ OUString currentDocTitle;
+ Reference< XModel > xDocument( lcl_getScriptableDocument_nothrow( m_xFrame ) );
+ if ( xDocument.is() )
+ {
+ currentDocTitle = ::comphelper::DocumentInfo::getDocumentTitle( xDocument );
+ }
+
+ for ( Reference< browse::XBrowseNode > const & theChild : children )
+ {
+ bool bDisplay = true;
+ OUString uiName = theChild->getName();
+ if ( bIsRootNode )
+ {
+ if ( ! (uiName == user || uiName == share ||
+ uiName == currentDocTitle ) )
+ {
+ bDisplay=false;
+ }
+ else
+ {
+ if ( uiName == user )
+ {
+ uiName = xImp->m_sMyMacros;
+ }
+ else if ( uiName == share )
+ {
+ uiName = xImp->m_sProdMacros;
+ }
+ }
+ }
+ if (theChild->getType() != browse::BrowseNodeTypes::SCRIPT && bDisplay )
+ {
+// We call acquire on the XBrowseNode so that it does not
+// get autodestructed and become invalid when accessed later.
+ theChild->acquire();
+
+ bool bChildOnDemand = false;
+ if ( !bCheapChildrenOnDemand && theChild->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > grandchildren =
+ theChild->getChildNodes();
+
+ for ( const auto& rxNode : grandchildren )
+ {
+ if ( rxNode->getType() == browse::BrowseNodeTypes::CONTAINER )
+ {
+ bChildOnDemand = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* i30923 - Would be nice if there was a better
+ * way to determine if a basic lib had children
+ * without having to ask for them (which forces
+ * the library to be loaded */
+ bChildOnDemand = true;
+ }
+
+ OUString aImage = GetImage(theChild, m_xContext, bIsRootNode);
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_SCRIPTCONTAINER,
+ 0, static_cast<void *>( theChild.get())));
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())));
+ m_xTreeView->insert(pParentEntry, -1, &uiName, &sId, nullptr, nullptr, &aImage, bChildOnDemand, nullptr);
+ }
+ }
+ }
+ }
+ catch (RuntimeException&) {
+ // do nothing, the entry will not be displayed in the UI
+ }
+}
+
+void CuiConfigGroupListBox::FillFunctionsList(const css::uno::Sequence<DispatchInformation>& xCommands)
+{
+ m_pFunctionListBox->freeze();
+ for (const auto & rInfo : xCommands)
+ {
+ auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rInfo.Command, m_sModuleLongName);
+
+ OUString sUIName = MapCommand2UIName(rInfo.Command);
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SLOT, 0 ) );
+ SfxGroupInfo_Impl* pGrpInfo = aArr.back().get();
+ pGrpInfo->sCommand = rInfo.Command;
+ pGrpInfo->sLabel = sUIName;
+ pGrpInfo->sTooltip = vcl::CommandInfoProvider::GetTooltipForCommand(rInfo.Command, aProperties, m_xFrame);
+ m_pFunctionListBox->append(OUString::number(reinterpret_cast<sal_Int64>(pGrpInfo)), sUIName);
+ }
+ m_pFunctionListBox->thaw();
+}
+
+void CuiConfigGroupListBox::Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName,
+ bool bEventMode)
+{
+ m_xTreeView->freeze();
+ ClearAll(); // Remove all old entries from treelist box
+
+ m_xContext = xContext;
+ m_xFrame = xFrame;
+ if( bEventMode )
+ {
+ m_sModuleLongName = sModuleLongName;
+ m_xGlobalCategoryInfo = css::ui::theUICategoryDescription::get( m_xContext );
+ m_xModuleCategoryInfo.set(m_xGlobalCategoryInfo->getByName(m_sModuleLongName), css::uno::UNO_QUERY_THROW);
+ m_xUICmdDescription = css::frame::theUICommandDescription::get( m_xContext );
+
+ InitModule();
+ }
+
+ SAL_INFO("cui.customize", "** ** About to initialise SF Scripts");
+ // Add Scripting Framework entries
+ Reference< browse::XBrowseNode > rootNode;
+ try
+ {
+ Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get( m_xContext );
+ rootNode.set( xFac->createView( browse::BrowseNodeFactoryViewTypes::MACROSELECTOR ) );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.customize", "Caught some exception whilst retrieving browse nodes from factory");
+ // TODO exception handling
+ }
+
+
+ if ( rootNode.is() )
+ {
+ if ( bEventMode )
+ {
+ //We call acquire on the XBrowseNode so that it does not
+ //get autodestructed and become invalid when accessed later.
+ rootNode->acquire();
+
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_SCRIPTCONTAINER, 0,
+ static_cast<void *>(rootNode.get())));
+ OUString aTitle(xImp->m_sDlgMacros);
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())));
+ m_xTreeView->insert(nullptr, -1, &aTitle, &sId, nullptr, nullptr, nullptr, true, nullptr);
+ }
+ else
+ {
+ //We are only showing scripts not slot APIs so skip
+ //Root node and show location nodes
+ FillScriptList(rootNode, nullptr, false);
+ }
+ }
+
+ // add styles
+ if ( bEventMode )
+ {
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, nullptr ) ); // TODO last parameter should contain user data
+ OUString sStyle(xImp->m_aStrGroupStyles);
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())));
+ m_xTreeView->insert(nullptr, -1, &sStyle, &sId, nullptr, nullptr, nullptr, true, nullptr);
+ }
+
+ m_xTreeView->thaw();
+ m_xTreeView->scroll_to_row(0);
+ m_xTreeView->select(0);
+}
+
+OUString CuiConfigGroupListBox::GetImage(
+ const Reference< browse::XBrowseNode >& node,
+ Reference< XComponentContext > const & xCtx,
+ bool bIsRootNode)
+{
+ OUString aImage;
+ if ( bIsRootNode )
+ {
+ if (node->getName() == "user" || node->getName() == "share" )
+ {
+ aImage = RID_CUIBMP_HARDDISK;
+ }
+ else
+ {
+ OUString factoryURL;
+ OUString nodeName = node->getName();
+ Reference<XInterface> xDocumentModel = getDocumentModel(xCtx, nodeName );
+ if ( xDocumentModel.is() )
+ {
+ Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
+ // get the long name of the document:
+ OUString appModule( xModuleManager->identify(
+ xDocumentModel ) );
+ Sequence<beans::PropertyValue> moduleDescr;
+ Any aAny = xModuleManager->getByName(appModule);
+ if( !( aAny >>= moduleDescr ) )
+ {
+ throw RuntimeException("SFTreeListBox::Init: failed to get PropertyValue");
+ }
+ beans::PropertyValue const * pmoduleDescr =
+ moduleDescr.getConstArray();
+ for ( sal_Int32 pos = moduleDescr.getLength(); pos--; )
+ {
+ if ( pmoduleDescr[ pos ].Name == "ooSetupFactoryEmptyDocumentURL" )
+ {
+ pmoduleDescr[ pos ].Value >>= factoryURL;
+ SAL_INFO("cui.customize", "factory url for doc images is " << factoryURL);
+ break;
+ }
+ }
+ }
+ if( !factoryURL.isEmpty() )
+ {
+ aImage = SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL));
+ }
+ else
+ {
+ aImage = RID_CUIBMP_DOC;
+ }
+ }
+ }
+ else
+ {
+ if( node->getType() == browse::BrowseNodeTypes::SCRIPT )
+ aImage = RID_CUIBMP_MACRO;
+ else
+ aImage = RID_CUIBMP_LIB;
+ }
+ return aImage;
+}
+
+Reference< XInterface >
+CuiConfigGroupListBox::getDocumentModel( Reference< XComponentContext > const & xCtx, OUString const & docName )
+{
+ Reference< XInterface > xModel;
+ Reference< frame::XDesktop2 > desktop = frame::Desktop::create( xCtx );
+
+ Reference< container::XEnumerationAccess > componentsAccess =
+ desktop->getComponents();
+ Reference< container::XEnumeration > components =
+ componentsAccess->createEnumeration();
+ while (components->hasMoreElements())
+ {
+ Reference< frame::XModel > model(
+ components->nextElement(), UNO_QUERY );
+ if ( model.is() )
+ {
+ OUString sTdocUrl =
+ ::comphelper::DocumentInfo::getDocumentTitle( model );
+ if( sTdocUrl == docName )
+ {
+ xModel = model;
+ break;
+ }
+ }
+ }
+ return xModel;
+}
+
+OUString CuiConfigGroupListBox::MapCommand2UIName(const OUString& sCommand)
+{
+ OUString sUIName;
+ try
+ {
+ css::uno::Reference< css::container::XNameAccess > xModuleConf;
+ m_xUICmdDescription->getByName(m_sModuleLongName) >>= xModuleConf;
+ if (xModuleConf.is())
+ {
+ ::comphelper::SequenceAsHashMap lProps(xModuleConf->getByName(sCommand));
+ sUIName = lProps.getUnpackedValueOrDefault("Name", OUString());
+ }
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(css::uno::Exception&)
+ { sUIName.clear(); }
+
+ // fallback for missing UINames !?
+ if (sUIName.isEmpty())
+ {
+ sUIName = sCommand;
+ }
+
+ return sUIName;
+}
+
+void CuiConfigGroupListBox::GroupSelected()
+/* Description
+ A function group or a basic module has been selected.
+ All functions/macros are displayed in the functionlistbox.
+*/
+{
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ if (!m_xTreeView->get_selected(xIter.get()))
+ return;
+
+ SfxGroupInfo_Impl *pInfo = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter).toInt64());
+ m_pFunctionListBox->freeze();
+ m_pFunctionListBox->ClearAll();
+
+ switch ( pInfo->nKind )
+ {
+ case SfxCfgKind::GROUP_ALLFUNCTIONS:
+ {
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider( m_xFrame, UNO_QUERY );
+ bool bValidIter = m_xTreeView->get_iter_first(*xIter);
+ while (bValidIter)
+ {
+ SfxGroupInfo_Impl *pCurrentInfo = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(*xIter).toInt64());
+ if (pCurrentInfo->nKind == SfxCfgKind::GROUP_FUNCTION)
+ {
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands;
+ try
+ {
+ lCommands = xProvider->getConfigurableDispatchInformation( pCurrentInfo->nUniqueID );
+ FillFunctionsList( lCommands );
+ }
+ catch ( container::NoSuchElementException& )
+ {
+ }
+ }
+ bValidIter = m_xTreeView->iter_next(*xIter);
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_FUNCTION :
+ {
+ sal_uInt16 nGroup = pInfo->nUniqueID;
+ css::uno::Reference< css::frame::XDispatchInformationProvider > xProvider (m_xFrame, css::uno::UNO_QUERY_THROW);
+ css::uno::Sequence< css::frame::DispatchInformation > lCommands = xProvider->getConfigurableDispatchInformation(nGroup);
+ FillFunctionsList( lCommands );
+ break;
+ }
+
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER:
+ {
+ if (!m_xTreeView->iter_has_child(*xIter))
+ {
+ Reference< browse::XBrowseNode > rootNode(
+ static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
+
+ try {
+ if ( rootNode->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > children =
+ rootNode->getChildNodes();
+
+ for ( const Reference< browse::XBrowseNode >& childNode : children )
+ {
+ if (childNode->getType() == browse::BrowseNodeTypes::SCRIPT)
+ {
+ OUString uri, description;
+
+ Reference < beans::XPropertySet >xPropSet( childNode, UNO_QUERY );
+ if (!xPropSet.is())
+ {
+ continue;
+ }
+
+ Any value =
+ xPropSet->getPropertyValue("URI");
+ value >>= uri;
+
+ try
+ {
+ value = xPropSet->getPropertyValue("Description");
+ value >>= description;
+ }
+ catch (Exception &) {
+ // do nothing, the description will be empty
+ }
+
+ OUString* pScriptURI = new OUString( uri );
+
+ OUString aImage = GetImage(childNode, Reference< XComponentContext >(), false);
+ m_pFunctionListBox->aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::FUNCTION_SCRIPT, 0, pScriptURI ));
+ m_pFunctionListBox->aArr.back()->sCommand = uri;
+ m_pFunctionListBox->aArr.back()->sLabel = childNode->getName();
+ m_pFunctionListBox->aArr.back()->sHelpText = description;
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_pFunctionListBox->aArr.back().get())));
+ m_pFunctionListBox->append(sId, childNode->getName(), aImage);
+ }
+ }
+ }
+ }
+ catch (RuntimeException&) {
+ // do nothing, the entry will not be displayed in the UI
+ }
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_STYLES :
+ {
+ SfxStyleInfo_Impl* pFamily = static_cast<SfxStyleInfo_Impl*>(pInfo->pObject);
+ if (pFamily)
+ {
+ const std::vector< SfxStyleInfo_Impl > lStyles = m_pStylesInfo->getStyles(pFamily->sFamily);
+ for (auto const& lStyle : lStyles)
+ {
+ SfxStyleInfo_Impl* pStyle = new SfxStyleInfo_Impl(lStyle);
+ m_pFunctionListBox->aArr.push_back(std::make_unique<SfxGroupInfo_Impl>(SfxCfgKind::GROUP_STYLES, 0, pStyle));
+ m_pFunctionListBox->aArr.back()->sCommand = pStyle->sCommand;
+ m_pFunctionListBox->aArr.back()->sLabel = pStyle->sLabel;
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_pFunctionListBox->aArr.back().get())));
+ m_pFunctionListBox->append(sId, pStyle->sLabel);
+ }
+ }
+ break;
+ }
+
+ default:
+ // Do nothing, the list box will stay empty
+ SAL_INFO( "cui.customize", "Ignoring unexpected SfxCfgKind: " << static_cast<int>(pInfo->nKind) );
+ break;
+ }
+
+ m_pFunctionListBox->thaw();
+
+ if (m_pFunctionListBox->n_children())
+ m_pFunctionListBox->select(0);
+}
+
+/* Description
+ A basic or a library is opened.
+*/
+IMPL_LINK(CuiConfigGroupListBox, ExpandingHdl, const weld::TreeIter&, rIter, bool)
+{
+ SfxGroupInfo_Impl *pInfo = reinterpret_cast<SfxGroupInfo_Impl*>(m_xTreeView->get_id(rIter).toInt64());
+ switch ( pInfo->nKind )
+ {
+ case SfxCfgKind::GROUP_SCRIPTCONTAINER:
+ {
+ if (!m_xTreeView->iter_has_child(rIter))
+ {
+ Reference< browse::XBrowseNode > rootNode(
+ static_cast< browse::XBrowseNode* >( pInfo->pObject ) ) ;
+ FillScriptList(rootNode, &rIter, true /* i30923 */ );
+ }
+ break;
+ }
+
+ case SfxCfgKind::GROUP_STYLES:
+ {
+ if (!m_xTreeView->iter_has_child(rIter))
+ {
+ const std::vector<SfxStyleInfo_Impl> lStyleFamilies = m_pStylesInfo->getStyleFamilies();
+ for (auto const& lStyleFamily : lStyleFamilies)
+ {
+ SfxStyleInfo_Impl* pFamily = new SfxStyleInfo_Impl(lStyleFamily);
+ aArr.push_back( std::make_unique<SfxGroupInfo_Impl>( SfxCfgKind::GROUP_STYLES, 0, pFamily ));
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(aArr.back().get())));
+ m_xTreeView->insert(&rIter, -1, &pFamily->sLabel, &sId, nullptr, nullptr, nullptr, false, nullptr);
+ }
+ }
+ break;
+ }
+
+ default:
+ OSL_FAIL( "Wrong group type!" );
+ break;
+ }
+ return true;
+}
+
+void CuiConfigGroupListBox::SelectMacro( const SfxMacroInfoItem *pItem )
+{
+ SelectMacro( pItem->GetBasicManager()->GetName(),
+ pItem->GetQualifiedName() );
+}
+
+void CuiConfigGroupListBox::SelectMacro( const OUString& rBasic,
+ const OUString& rMacro )
+{
+ const OUString aBasicName(rBasic + " " + xImp->m_sMacros);
+ sal_Int32 nIdx {rMacro.lastIndexOf('.')};
+ const OUString aMethod( rMacro.copy(nIdx+1) );
+ OUString aLib;
+ OUString aModule;
+ if ( nIdx>0 )
+ {
+ // string contains at least 2 tokens
+ nIdx = rMacro.lastIndexOf('.', nIdx);
+ if (nIdx>=0)
+ {
+ // string contains at least 3 tokens
+ aLib = rMacro.getToken( 0, '.' );
+ aModule = rMacro.getToken( 0, '.', ++nIdx );
+ }
+ }
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xTreeView->make_iterator();
+ if (!m_xTreeView->get_iter_first(*xIter))
+ return;
+
+ do
+ {
+ OUString aEntryBas = m_xTreeView->get_text(*xIter);
+ if (aEntryBas == aBasicName)
+ {
+ m_xTreeView->expand_row(*xIter);
+ std::unique_ptr<weld::TreeIter> xLibIter = m_xTreeView->make_iterator(xIter.get());
+ if (m_xTreeView->get_iter_first(*xLibIter))
+ {
+ do
+ {
+ OUString aEntryLib = m_xTreeView->get_text(*xLibIter);
+ if (aEntryLib == aLib)
+ {
+ m_xTreeView->expand_row(*xLibIter);
+ std::unique_ptr<weld::TreeIter> xModIter = m_xTreeView->make_iterator(xLibIter.get());
+ if (m_xTreeView->get_iter_first(*xModIter))
+ {
+ do
+ {
+ OUString aEntryMod = m_xTreeView->get_text(*xModIter);
+ if ( aEntryMod == aModule )
+ {
+ m_xTreeView->expand_row(*xModIter);
+ m_xTreeView->scroll_to_row(*xModIter);
+ m_xTreeView->select(*xModIter);
+ for (int i = 0, nCount = m_pFunctionListBox->n_children(); i < nCount; ++i)
+ {
+ OUString aEntryMethod = m_pFunctionListBox->get_text(i);
+ if (aEntryMethod == aMethod)
+ {
+ m_pFunctionListBox->select(i);
+ m_pFunctionListBox->scroll_to_row(i);
+ return;
+ }
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xModIter));
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xLibIter));
+ }
+ }
+ } while (m_xTreeView->iter_next_sibling(*xIter));
+}
+
+/*
+ * Implementation of SvxScriptSelectorDialog
+ *
+ * This dialog is used for selecting Slot API commands
+ * and Scripting Framework Scripts.
+ */
+
+SvxScriptSelectorDialog::SvxScriptSelectorDialog(
+ weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& xFrame)
+ : GenericDialogController(pParent, "cui/ui/macroselectordialog.ui", "MacroSelectorDialog")
+ , m_xDialogDescription(m_xBuilder->weld_label("helpmacro"))
+ , m_xCategories(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("categories")))
+ , m_xCommands(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("commands")))
+ , m_xLibraryFT(m_xBuilder->weld_label("libraryft"))
+ , m_xCategoryFT(m_xBuilder->weld_label("categoryft"))
+ , m_xMacronameFT(m_xBuilder->weld_label("macronameft"))
+ , m_xCommandsFT(m_xBuilder->weld_label("commandsft"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xCancelButton(m_xBuilder->weld_button("cancel"))
+ , m_xDescriptionText(m_xBuilder->weld_text_view("description"))
+{
+ m_xCancelButton->show();
+ m_xDialogDescription->show();
+ m_xOKButton->show();
+
+ m_xLibraryFT->set_visible(true);
+ m_xCategoryFT->set_visible(false);
+ m_xMacronameFT->set_visible(true);
+ m_xCommandsFT->set_visible(false);
+
+ const OUString aModuleName(vcl::CommandInfoProvider::GetModuleIdentifier(xFrame));
+ m_xCategories->SetFunctionListBox(m_xCommands.get());
+ m_xCategories->Init(comphelper::getProcessComponentContext(), xFrame, aModuleName, /*bShowSlots*/false);
+
+ m_xCategories->connect_changed(
+ LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
+ m_xCommands->connect_changed( LINK( this, SvxScriptSelectorDialog, SelectHdl ) );
+ m_xCommands->connect_row_activated( LINK( this, SvxScriptSelectorDialog, FunctionDoubleClickHdl ) );
+
+ m_xOKButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
+ m_xCancelButton->connect_clicked( LINK( this, SvxScriptSelectorDialog, ClickHdl ) );
+
+ m_sDefaultDesc = m_xDescriptionText->get_text();
+
+ // Support style commands
+ uno::Reference<frame::XController> xController;
+ uno::Reference<frame::XModel> xModel;
+ if (xFrame.is())
+ xController = xFrame->getController();
+ if (xController.is())
+ xModel = xController->getModel();
+
+ m_aStylesInfo.init(aModuleName, xModel);
+ m_xCategories->SetStylesInfo(&m_aStylesInfo);
+
+ UpdateUI();
+}
+
+SvxScriptSelectorDialog::~SvxScriptSelectorDialog()
+{
+}
+
+IMPL_LINK(SvxScriptSelectorDialog, SelectHdl, weld::TreeView&, rCtrl, void)
+{
+ if (&rCtrl == &m_xCategories->get_widget())
+ {
+ m_xCategories->GroupSelected();
+ }
+ UpdateUI();
+}
+
+IMPL_LINK_NOARG(SvxScriptSelectorDialog, FunctionDoubleClickHdl, weld::TreeView&, bool)
+{
+ if (m_xOKButton->get_sensitive())
+ ClickHdl(*m_xOKButton);
+ return true;
+}
+
+// Check if command is selected and enable the OK button accordingly
+// Grab the help text for this id if available and update the description field
+void
+SvxScriptSelectorDialog::UpdateUI()
+{
+ OUString url = GetScriptURL();
+ if ( !url.isEmpty() )
+ {
+ OUString sMessage = m_xCommands->GetHelpText();
+ m_xDescriptionText->set_text(sMessage.isEmpty() ? m_sDefaultDesc : sMessage);
+
+ m_xOKButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xDescriptionText->set_text(m_sDefaultDesc);
+ m_xOKButton->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SvxScriptSelectorDialog, ClickHdl, weld::Button&, rButton, void)
+{
+ if (&rButton == m_xCancelButton.get())
+ {
+ m_xDialog->response(RET_CANCEL);
+ }
+ else if (&rButton == m_xOKButton.get())
+ {
+ m_xDialog->response(RET_OK);
+ }
+}
+
+void
+SvxScriptSelectorDialog::SetRunLabel()
+{
+ m_xOKButton->set_label(CuiResId(RID_SVXSTR_SELECTOR_RUN));
+}
+
+OUString
+SvxScriptSelectorDialog::GetScriptURL() const
+{
+ OUString result;
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xCommands->make_iterator();
+ if (m_xCommands->get_selected(xIter.get()))
+ {
+ SfxGroupInfo_Impl *pData = reinterpret_cast<SfxGroupInfo_Impl*>(m_xCommands->get_id(*xIter).toInt64());
+ if ( ( pData->nKind == SfxCfgKind::FUNCTION_SLOT )
+ || ( pData->nKind == SfxCfgKind::FUNCTION_SCRIPT )
+ || ( pData->nKind == SfxCfgKind::GROUP_STYLES )
+ )
+ {
+ result = pData->sCommand;
+ }
+ }
+
+ return result;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/eventdlg.cxx b/cui/source/customize/eventdlg.cxx
new file mode 100644
index 000000000..72cd08b16
--- /dev/null
+++ b/cui/source/customize/eventdlg.cxx
@@ -0,0 +1,162 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/document/XEventsSupplier.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <unotools/configmgr.hxx>
+#include <rtl/ustring.hxx>
+
+#include "eventdlg.hxx"
+#include "macropg_impl.hxx"
+
+#include <cfg.hxx>
+
+using namespace ::com::sun::star;
+
+
+SvxEventConfigPage::SvxEventConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet,
+ SvxEventConfigPage::EarlyInit)
+ : SvxMacroTabPage_(pPage, pController, "cui/ui/eventsconfigpage.ui", "EventsConfigPage", rSet)
+ , m_xSaveInListBox(m_xBuilder->weld_combo_box("savein"))
+{
+ mpImpl->xEventLB = m_xBuilder->weld_tree_view("events");
+ mpImpl->xAssignPB = m_xBuilder->weld_button("macro");
+ mpImpl->xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->xAssignComponentPB = m_xBuilder->weld_button("component");
+
+ mpImpl->xEventLB->set_size_request(mpImpl->xEventLB->get_approximate_digit_width() * 70,
+ mpImpl->xEventLB->get_height_rows(20));
+
+ InitResources();
+
+ m_xSaveInListBox->connect_changed( LINK( this, SvxEventConfigPage,
+ SelectHdl_Impl ) );
+
+ uno::Reference< frame::XGlobalEventBroadcaster > xSupplier =
+ frame::theGlobalEventBroadcaster::get(::comphelper::getProcessComponentContext());
+
+ m_xAppEvents = xSupplier->getEvents();
+ m_xSaveInListBox->append(OUString::boolean(true), utl::ConfigManager::getProductName());
+ m_xSaveInListBox->set_active(0);
+}
+
+void SvxEventConfigPage::LateInit( const uno::Reference< frame::XFrame >& _rxFrame )
+{
+ SetFrame( _rxFrame );
+ ImplInitDocument();
+
+ InitAndSetHandler( m_xAppEvents, m_xDocumentEvents, m_xDocumentModifiable );
+
+ SelectHdl_Impl( *m_xSaveInListBox );
+}
+
+SvxEventConfigPage::~SvxEventConfigPage()
+{
+}
+
+void SvxEventConfigPage::ImplInitDocument()
+{
+ uno::Reference< frame::XFrame > xFrame( GetFrame() );
+ OUString aModuleId = SvxConfigPage::GetFrameWithDefaultAndIdentify( xFrame );
+ if ( !xFrame.is() )
+ return;
+
+ try
+ {
+ uno::Reference< frame::XModel > xModel;
+ if ( !SvxConfigPage::CanConfig( aModuleId ) )
+ return;
+
+ uno::Reference< frame::XController > xController =
+ xFrame->getController();
+
+ if ( xController.is() )
+ {
+ xModel = xController->getModel();
+ }
+
+ if ( !xModel.is() )
+ return;
+
+ uno::Reference< document::XEventsSupplier > xSupplier( xModel, uno::UNO_QUERY );
+
+ if ( xSupplier.is() )
+ {
+ m_xDocumentEvents = xSupplier->getEvents();
+ m_xDocumentModifiable.set(xModel, css::uno::UNO_QUERY);
+
+ OUString aTitle = ::comphelper::DocumentInfo::getDocumentTitle( xModel );
+
+ m_xSaveInListBox->append(OUString::boolean(false), aTitle);
+ m_xSaveInListBox->set_active(m_xSaveInListBox->get_count() - 1);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+}
+
+IMPL_LINK_NOARG( SvxEventConfigPage, SelectHdl_Impl, weld::ComboBox&, void )
+{
+ bool bApp = m_xSaveInListBox->get_active_id().toBoolean();
+
+ mpImpl->xEventLB->freeze();
+ if (bApp)
+ {
+ SetReadOnly( false );
+ SvxMacroTabPage_::DisplayAppEvents( true );
+ }
+ else
+ {
+ bool isReadonly = false;
+
+ uno::Reference< frame::XDesktop2 > xFramesSupplier = frame::Desktop::create(
+ ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< frame::XFrame > xFrame =
+ xFramesSupplier->getActiveFrame();
+
+ if ( xFrame.is() )
+ {
+ uno::Reference< frame::XController > xController =
+ xFrame->getController();
+
+ if ( xController.is() )
+ {
+ uno::Reference< frame::XStorable > xStorable(
+ xController->getModel(), uno::UNO_QUERY );
+ isReadonly = xStorable->isReadonly();
+ }
+ }
+
+ SetReadOnly( isReadonly );
+ SvxMacroTabPage_::DisplayAppEvents( false );
+ }
+
+ mpImpl->xEventLB->thaw();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/eventdlg.hxx b/cui/source/customize/eventdlg.hxx
new file mode 100644
index 000000000..2d368e982
--- /dev/null
+++ b/cui/source/customize/eventdlg.hxx
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <macropg.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+
+class SvxEventConfigPage : public SvxMacroTabPage_
+{
+ css::uno::Reference< css::container::XNameReplace > m_xAppEvents;
+ css::uno::Reference< css::container::XNameReplace > m_xDocumentEvents;
+ css::uno::Reference< css::util::XModifiable > m_xDocumentModifiable;
+
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ DECL_LINK( SelectHdl_Impl, weld::ComboBox&, void );
+
+ SvxEventConfigPage (const SvxEventConfigPage &) = delete;
+ SvxEventConfigPage & operator= (const SvxEventConfigPage &) = delete;
+
+public:
+
+ /// this is only to let callers know that there is a LateInit which *must* be called
+ struct EarlyInit { };
+ SvxEventConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet, EarlyInit);
+ virtual ~SvxEventConfigPage() override;
+
+ void LateInit( const css::uno::Reference< css::frame::XFrame >& _rxFrame );
+
+private:
+ void ImplInitDocument();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/macropg.cxx b/cui/source/customize/macropg.cxx
new file mode 100644
index 000000000..7b45afa86
--- /dev/null
+++ b/cui/source/customize/macropg.cxx
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <macropg.hxx>
+#include <svl/eitem.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <bitmaps.hlst>
+#include <cfgutil.hxx>
+#include <dialmgr.hxx>
+#include <helpids.h>
+#include <headertablistbox.hxx>
+#include "macropg_impl.hxx"
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <comphelper/namedvaluecollection.hxx>
+
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+static const char aVndSunStarUNO[] = "vnd.sun.star.UNO:";
+
+SvxMacroTabPage_Impl::SvxMacroTabPage_Impl( const SfxItemSet& rAttrSet )
+ : bReadOnly(false)
+ , bIDEDialogMode(false)
+{
+ const SfxPoolItem* pItem;
+ if ( SfxItemState::SET == rAttrSet.GetItemState( SID_ATTR_MACROITEM, false, &pItem ) )
+ bIDEDialogMode = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+}
+
+MacroEventListBox::MacroEventListBox(std::unique_ptr<weld::TreeView> xTreeView)
+ : m_xTreeView(std::move(xTreeView))
+{
+ m_xTreeView->set_help_id(HID_MACRO_HEADERTABLISTBOX);
+ m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 70, m_xTreeView->get_height_rows(9));
+}
+
+// assign button ("Add Command") is enabled only if it is not read only
+// delete button ("Remove Command") is enabled if a current binding exists
+// and it is not read only
+void SvxMacroTabPage_::EnableButtons()
+{
+ int nEvent = mpImpl->xEventLB->get_selected_index();
+ if (nEvent != -1)
+ {
+ mpImpl->xDeletePB->set_sensitive( !mpImpl->bReadOnly );
+ mpImpl->xAssignPB->set_sensitive( !mpImpl->bReadOnly );
+ if( mpImpl->xAssignComponentPB )
+ mpImpl->xAssignComponentPB->set_sensitive( !mpImpl->bReadOnly );
+ }
+}
+
+SvxMacroTabPage_::SvxMacroTabPage_(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription,
+ const OString& rID, const SfxItemSet& rAttrSet)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, &rAttrSet)
+ , bDocModified(false)
+ , bAppEvents(false)
+ , bInitialized(false)
+{
+ mpImpl.reset( new SvxMacroTabPage_Impl( rAttrSet ) );
+}
+
+SvxMacroTabPage_::~SvxMacroTabPage_()
+{
+ mpImpl.reset();
+}
+
+void SvxMacroTabPage_::InitResources()
+{
+ // Note: the order here controls the order in which the events are displayed in the UI!
+
+ // the event name to UI string mappings for App Events
+ aDisplayNames.emplace_back( "OnStartApp", RID_SVXSTR_EVENT_STARTAPP );
+ aDisplayNames.emplace_back( "OnCloseApp", RID_SVXSTR_EVENT_CLOSEAPP );
+ aDisplayNames.emplace_back( "OnCreate", RID_SVXSTR_EVENT_CREATEDOC );
+ aDisplayNames.emplace_back( "OnNew", RID_SVXSTR_EVENT_NEWDOC );
+ aDisplayNames.emplace_back( "OnLoadFinished", RID_SVXSTR_EVENT_LOADDOCFINISHED );
+ aDisplayNames.emplace_back( "OnLoad", RID_SVXSTR_EVENT_OPENDOC );
+ aDisplayNames.emplace_back( "OnPrepareUnload", RID_SVXSTR_EVENT_PREPARECLOSEDOC );
+ aDisplayNames.emplace_back( "OnUnload", RID_SVXSTR_EVENT_CLOSEDOC ) ;
+ aDisplayNames.emplace_back( "OnViewCreated", RID_SVXSTR_EVENT_VIEWCREATED );
+ aDisplayNames.emplace_back( "OnPrepareViewClosing", RID_SVXSTR_EVENT_PREPARECLOSEVIEW );
+ aDisplayNames.emplace_back( "OnViewClosed", RID_SVXSTR_EVENT_CLOSEVIEW ) ;
+ aDisplayNames.emplace_back( "OnFocus", RID_SVXSTR_EVENT_ACTIVATEDOC );
+ aDisplayNames.emplace_back( "OnUnfocus", RID_SVXSTR_EVENT_DEACTIVATEDOC );
+ aDisplayNames.emplace_back( "OnSave", RID_SVXSTR_EVENT_SAVEDOC );
+ aDisplayNames.emplace_back( "OnSaveDone", RID_SVXSTR_EVENT_SAVEDOCDONE );
+ aDisplayNames.emplace_back( "OnSaveFailed", RID_SVXSTR_EVENT_SAVEDOCFAILED );
+ aDisplayNames.emplace_back( "OnSaveAs", RID_SVXSTR_EVENT_SAVEASDOC );
+ aDisplayNames.emplace_back( "OnSaveAsDone", RID_SVXSTR_EVENT_SAVEASDOCDONE );
+ aDisplayNames.emplace_back( "OnSaveAsFailed", RID_SVXSTR_EVENT_SAVEASDOCFAILED );
+ aDisplayNames.emplace_back( "OnCopyTo", RID_SVXSTR_EVENT_COPYTODOC );
+ aDisplayNames.emplace_back( "OnCopyToDone", RID_SVXSTR_EVENT_COPYTODOCDONE );
+ aDisplayNames.emplace_back( "OnCopyToFailed", RID_SVXSTR_EVENT_COPYTODOCFAILED );
+ aDisplayNames.emplace_back( "OnPrint", RID_SVXSTR_EVENT_PRINTDOC );
+ aDisplayNames.emplace_back( "OnModifyChanged", RID_SVXSTR_EVENT_MODIFYCHANGED );
+ aDisplayNames.emplace_back( "OnTitleChanged", RID_SVXSTR_EVENT_TITLECHANGED );
+
+ // application specific events
+ aDisplayNames.emplace_back( "OnMailMerge", RID_SVXSTR_EVENT_MAILMERGE );
+ aDisplayNames.emplace_back( "OnMailMergeFinished", RID_SVXSTR_EVENT_MAILMERGE_END );
+ aDisplayNames.emplace_back( "OnFieldMerge", RID_SVXSTR_EVENT_FIELDMERGE );
+ aDisplayNames.emplace_back( "OnFieldMergeFinished", RID_SVXSTR_EVENT_FIELDMERGE_FINISHED );
+ aDisplayNames.emplace_back( "OnPageCountChange", RID_SVXSTR_EVENT_PAGECOUNTCHANGE );
+ aDisplayNames.emplace_back( "OnSubComponentOpened", RID_SVXSTR_EVENT_SUBCOMPONENT_OPENED );
+ aDisplayNames.emplace_back( "OnSubComponentClosed", RID_SVXSTR_EVENT_SUBCOMPONENT_CLOSED );
+ aDisplayNames.emplace_back( "OnSelect", RID_SVXSTR_EVENT_SELECTIONCHANGED );
+ aDisplayNames.emplace_back( "OnDoubleClick", RID_SVXSTR_EVENT_DOUBLECLICK );
+ aDisplayNames.emplace_back( "OnRightClick", RID_SVXSTR_EVENT_RIGHTCLICK );
+ aDisplayNames.emplace_back( "OnCalculate", RID_SVXSTR_EVENT_CALCULATE );
+ aDisplayNames.emplace_back( "OnChange", RID_SVXSTR_EVENT_CONTENTCHANGED );
+
+ // the event name to UI string mappings for forms & dialogs
+
+ aDisplayNames.emplace_back( "approveAction", RID_SVXSTR_EVENT_APPROVEACTIONPERFORMED );
+ aDisplayNames.emplace_back( "actionPerformed", RID_SVXSTR_EVENT_ACTIONPERFORMED );
+ aDisplayNames.emplace_back( "changed", RID_SVXSTR_EVENT_CHANGED );
+ aDisplayNames.emplace_back( "textChanged", RID_SVXSTR_EVENT_TEXTCHANGED );
+ aDisplayNames.emplace_back( "itemStateChanged", RID_SVXSTR_EVENT_ITEMSTATECHANGED );
+ aDisplayNames.emplace_back( "focusGained", RID_SVXSTR_EVENT_FOCUSGAINED );
+ aDisplayNames.emplace_back( "focusLost", RID_SVXSTR_EVENT_FOCUSLOST );
+ aDisplayNames.emplace_back( "keyPressed", RID_SVXSTR_EVENT_KEYTYPED );
+ aDisplayNames.emplace_back( "keyReleased", RID_SVXSTR_EVENT_KEYUP );
+ aDisplayNames.emplace_back( "mouseEntered", RID_SVXSTR_EVENT_MOUSEENTERED );
+ aDisplayNames.emplace_back( "mouseDragged", RID_SVXSTR_EVENT_MOUSEDRAGGED );
+ aDisplayNames.emplace_back( "mouseMoved", RID_SVXSTR_EVENT_MOUSEMOVED );
+ aDisplayNames.emplace_back( "mousePressed", RID_SVXSTR_EVENT_MOUSEPRESSED );
+ aDisplayNames.emplace_back( "mouseReleased", RID_SVXSTR_EVENT_MOUSERELEASED );
+ aDisplayNames.emplace_back( "mouseExited", RID_SVXSTR_EVENT_MOUSEEXITED );
+ aDisplayNames.emplace_back( "approveReset", RID_SVXSTR_EVENT_APPROVERESETTED );
+ aDisplayNames.emplace_back( "resetted", RID_SVXSTR_EVENT_RESETTED );
+ aDisplayNames.emplace_back( "approveSubmit", RID_SVXSTR_EVENT_SUBMITTED );
+ aDisplayNames.emplace_back( "approveUpdate", RID_SVXSTR_EVENT_BEFOREUPDATE );
+ aDisplayNames.emplace_back( "updated", RID_SVXSTR_EVENT_AFTERUPDATE );
+ aDisplayNames.emplace_back( "loaded", RID_SVXSTR_EVENT_LOADED );
+ aDisplayNames.emplace_back( "reloading", RID_SVXSTR_EVENT_RELOADING );
+ aDisplayNames.emplace_back( "reloaded", RID_SVXSTR_EVENT_RELOADED );
+ aDisplayNames.emplace_back( "unloading", RID_SVXSTR_EVENT_UNLOADING );
+ aDisplayNames.emplace_back( "unloaded", RID_SVXSTR_EVENT_UNLOADED );
+ aDisplayNames.emplace_back( "confirmDelete", RID_SVXSTR_EVENT_CONFIRMDELETE );
+ aDisplayNames.emplace_back( "approveRowChange", RID_SVXSTR_EVENT_APPROVEROWCHANGE );
+ aDisplayNames.emplace_back( "rowChanged", RID_SVXSTR_EVENT_ROWCHANGE );
+ aDisplayNames.emplace_back( "approveCursorMove", RID_SVXSTR_EVENT_POSITIONING );
+ aDisplayNames.emplace_back( "cursorMoved", RID_SVXSTR_EVENT_POSITIONED );
+ aDisplayNames.emplace_back( "approveParameter", RID_SVXSTR_EVENT_APPROVEPARAMETER );
+ aDisplayNames.emplace_back( "errorOccured", RID_SVXSTR_EVENT_ERROROCCURRED );
+ aDisplayNames.emplace_back( "adjustmentValueChanged", RID_SVXSTR_EVENT_ADJUSTMENTVALUECHANGED );
+}
+
+// the following method is called when the user clicks OK
+// We use the contents of the hashes to replace the settings
+bool SvxMacroTabPage_::FillItemSet( SfxItemSet* /*rSet*/ )
+{
+ try
+ {
+ OUString eventName;
+ if( m_xAppEvents.is() )
+ {
+ for (auto const& appEvent : m_appEventsHash)
+ {
+ eventName = appEvent.first;
+ try
+ {
+ m_xAppEvents->replaceByName( eventName, GetPropsByName( eventName, m_appEventsHash ) );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+ }
+ }
+ if( m_xDocEvents.is() && bDocModified )
+ {
+ for (auto const& docEvent : m_docEventsHash)
+ {
+ eventName = docEvent.first;
+ try
+ {
+ m_xDocEvents->replaceByName( eventName, GetPropsByName( eventName, m_docEventsHash ) );
+ }
+ catch (const Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.customize");
+ }
+ }
+ // if we have a valid XModifiable (in the case of doc events)
+ // call setModified(true)
+ // in principle this should not be necessary (see issue ??)
+ if(m_xModifiable.is())
+ {
+ m_xModifiable->setModified( true );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ // what is the return value about??
+ return false;
+}
+
+// the following method clears the bindings in the hashes for both doc & app
+void SvxMacroTabPage_::Reset( const SfxItemSet* )
+{
+ // called once in creation - don't reset the data this time
+ if(!bInitialized)
+ {
+ bInitialized = true;
+ return;
+ }
+
+ try
+ {
+ if( m_xAppEvents.is() )
+ {
+ for (auto & appEvent : m_appEventsHash)
+ {
+ appEvent.second.second.clear();
+ }
+ }
+ if( m_xDocEvents.is() && bDocModified )
+ {
+ for (auto & docEvent : m_docEventsHash)
+ {
+ docEvent.second.second.clear();
+ }
+ // if we have a valid XModifiable (in the case of doc events)
+ // call setModified(true)
+ if(m_xModifiable.is())
+ {
+ m_xModifiable->setModified( true );
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+ DisplayAppEvents(bAppEvents);
+}
+
+void SvxMacroTabPage_::SetReadOnly( bool bSet )
+{
+ mpImpl->bReadOnly = bSet;
+}
+
+bool SvxMacroTabPage_::IsReadOnly() const
+{
+ return mpImpl->bReadOnly;
+}
+
+namespace
+{
+ OUString GetEventDisplayText(const OUString &rURL)
+ {
+ if (rURL.isEmpty())
+ return OUString();
+ sal_Int32 nIndex = rURL.indexOf(aVndSunStarUNO);
+ bool bUNO = nIndex == 0;
+ OUString aPureMethod;
+ if (bUNO)
+ {
+ aPureMethod = rURL.copy(strlen(aVndSunStarUNO));
+ }
+ else
+ {
+ aPureMethod = rURL.copy(strlen("vnd.sun.star.script:"));
+ aPureMethod = aPureMethod.copy( 0, aPureMethod.indexOf( '?' ) );
+ }
+ return aPureMethod;
+ }
+
+ OUString GetEventDisplayImage(const OUString &rURL)
+ {
+ if (rURL.isEmpty())
+ return OUString();
+ sal_Int32 nIndex = rURL.indexOf(aVndSunStarUNO);
+ bool bUNO = nIndex == 0;
+ return bUNO ? OUString(RID_SVXBMP_COMPONENT) : OUString(RID_SVXBMP_MACRO);
+ }
+}
+
+// displays the app events if appEvents=true, otherwise displays the doc events
+void SvxMacroTabPage_::DisplayAppEvents( bool appEvents)
+{
+ bAppEvents = appEvents;
+
+ mpImpl->xEventLB->freeze();
+ mpImpl->xEventLB->clear();
+ EventsHash* eventsHash;
+ Reference< container::XNameReplace> nameReplace;
+ if(bAppEvents)
+ {
+ eventsHash = &m_appEventsHash;
+ nameReplace = m_xAppEvents;
+ }
+ else
+ {
+ eventsHash = &m_docEventsHash;
+ nameReplace = m_xDocEvents;
+ }
+ // have to use the original XNameReplace since the hash iterators do
+ // not guarantee the order in which the elements are returned
+ if(!nameReplace.is())
+ return;
+
+ Sequence< OUString > eventNames = nameReplace->getElementNames();
+ std::set< OUString > aEventNamesCache;
+ std::copy(
+ eventNames.begin(),
+ eventNames.end(),
+ std::insert_iterator< std::set< OUString > >( aEventNamesCache, aEventNamesCache.end() )
+ );
+
+ for (auto const& displayableEvent : aDisplayNames)
+ {
+ OUString sEventName( OUString::createFromAscii( displayableEvent.pAsciiEventName ) );
+ if ( !nameReplace->hasByName( sEventName ) )
+ continue;
+
+ EventsHash::iterator h_it = eventsHash->find( sEventName );
+ if( h_it == eventsHash->end() )
+ {
+ OSL_FAIL( "SvxMacroTabPage_::DisplayAppEvents: something's suspicious here!" );
+ continue;
+ }
+
+ OUString eventURL = h_it->second.second;
+ OUString displayName(CuiResId(displayableEvent.pEventResourceID));
+
+ int nRow = mpImpl->xEventLB->n_children();
+ mpImpl->xEventLB->append(sEventName, displayName);
+ mpImpl->xEventLB->set_image(nRow, GetEventDisplayImage(eventURL), 1);
+ mpImpl->xEventLB->set_text(nRow, GetEventDisplayText(eventURL), 2);
+ }
+
+ mpImpl->xEventLB->thaw();
+
+ if (mpImpl->xEventLB->n_children())
+ {
+ mpImpl->xEventLB->select(0);
+ mpImpl->xEventLB->scroll_to_row(0);
+ }
+
+ EnableButtons();
+}
+
+// select event handler on the listbox
+IMPL_LINK_NOARG( SvxMacroTabPage_, SelectEvent_Impl, weld::TreeView&, void)
+{
+ int nEntry = mpImpl->xEventLB->get_selected_index();
+
+ if (nEntry == -1)
+ {
+ DBG_ASSERT(false, "Where does the empty entry come from?" );
+ return;
+ }
+
+ EnableButtons();
+}
+
+IMPL_LINK( SvxMacroTabPage_, AssignDeleteHdl_Impl, weld::Button&, rBtn, void )
+{
+ GenericHandler_Impl(this, &rBtn);
+}
+
+IMPL_LINK_NOARG( SvxMacroTabPage_, DoubleClickHdl_Impl, weld::TreeView&, bool)
+{
+ GenericHandler_Impl(this, nullptr);
+ return true;
+}
+
+// handler for double click on the listbox, and for the assign/delete buttons
+void SvxMacroTabPage_::GenericHandler_Impl(SvxMacroTabPage_* pThis, const weld::Button* pBtn)
+{
+ SvxMacroTabPage_Impl* pImpl = pThis->mpImpl.get();
+ weld::TreeView& rListBox = *pImpl->xEventLB;
+ int nEntry = rListBox.get_selected_index();
+ if (nEntry == -1)
+ {
+ DBG_ASSERT(false, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != pImpl->xDeletePB.get() && pImpl->xAssignPB->get_sensitive();
+
+ OUString sEventName = rListBox.get_id(nEntry);
+
+ OUString sEventURL;
+ OUString sEventType;
+ if(pThis->bAppEvents)
+ {
+ EventsHash::iterator h_it = pThis->m_appEventsHash.find(sEventName);
+ if(h_it != pThis->m_appEventsHash.end() )
+ {
+ sEventType = h_it->second.first;
+ sEventURL = h_it->second.second;
+ }
+ }
+ else
+ {
+ EventsHash::iterator h_it = pThis->m_docEventsHash.find(sEventName);
+ if(h_it != pThis->m_docEventsHash.end() )
+ {
+ sEventType = h_it->second.first;
+ sEventURL = h_it->second.second;
+ }
+ }
+
+ bool bDoubleClick = (pBtn == nullptr);
+ bool bUNOAssigned = sEventURL.startsWith( aVndSunStarUNO );
+ if( pBtn == pImpl->xDeletePB.get() )
+ {
+ // delete pressed
+ sEventType = "Script" ;
+ sEventURL.clear();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ else if ( ( ( pBtn != nullptr )
+ && ( pBtn == pImpl->xAssignComponentPB.get() )
+ )
+ || ( bDoubleClick
+ && bUNOAssigned
+ )
+ )
+ {
+ AssignComponentDialog aAssignDlg(pThis->GetFrameWeld(), sEventURL);
+
+ short ret = aAssignDlg.run();
+ if( ret )
+ {
+ sEventType = "UNO";
+ sEventURL = aAssignDlg.getURL();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ }
+ else if( bAssEnabled )
+ {
+ // assign pressed
+ SvxScriptSelectorDialog aDlg(pThis->GetFrameWeld(), pThis->GetFrame());
+ short ret = aDlg.run();
+ if ( ret )
+ {
+ sEventType = "Script";
+ sEventURL = aDlg.GetScriptURL();
+ if(!pThis->bAppEvents)
+ pThis->bDocModified = true;
+ }
+ }
+
+ // update the hashes
+ if(pThis->bAppEvents)
+ {
+ EventsHash::iterator h_it = pThis->m_appEventsHash.find(sEventName);
+ h_it->second.first = sEventType;
+ h_it->second.second = sEventURL;
+ }
+ else
+ {
+ EventsHash::iterator h_it = pThis->m_docEventsHash.find(sEventName);
+ h_it->second.first = sEventType;
+ h_it->second.second = sEventURL;
+ }
+
+ rListBox.set_image(nEntry, GetEventDisplayImage(sEventURL), 1);
+ rListBox.set_text(nEntry, GetEventDisplayText(sEventURL), 2);
+
+ rListBox.select(nEntry );
+ rListBox.scroll_to_row(nEntry);
+
+ pThis->EnableButtons();
+}
+
+// pass in the XNameReplace.
+// can remove the 3rd arg once issue ?? is fixed
+void SvxMacroTabPage_::InitAndSetHandler( const Reference< container::XNameReplace>& xAppEvents, const Reference< container::XNameReplace>& xDocEvents, const Reference< util::XModifiable >& xModifiable )
+{
+ m_xAppEvents = xAppEvents;
+ m_xDocEvents = xDocEvents;
+ m_xModifiable = xModifiable;
+ Link<weld::Button&,void> aLnk(LINK(this, SvxMacroTabPage_, AssignDeleteHdl_Impl ));
+ mpImpl->xDeletePB->connect_clicked(aLnk);
+ mpImpl->xAssignPB->connect_clicked(aLnk);
+ if( mpImpl->xAssignComponentPB )
+ mpImpl->xAssignComponentPB->connect_clicked( aLnk );
+ mpImpl->xEventLB->connect_row_activated( LINK(this, SvxMacroTabPage_, DoubleClickHdl_Impl ) );
+ mpImpl->xEventLB->connect_changed( LINK( this, SvxMacroTabPage_, SelectEvent_Impl ));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(mpImpl->xEventLB->get_approximate_digit_width() * 32);
+ aWidths.push_back(mpImpl->xEventLB->get_checkbox_column_width());
+ mpImpl->xEventLB->set_column_fixed_widths(aWidths);
+
+ mpImpl->xEventLB->show();
+ mpImpl->xEventLB->set_sensitive(true);
+
+ if(!m_xAppEvents.is())
+ {
+ return;
+ }
+ Sequence< OUString > eventNames = m_xAppEvents->getElementNames();
+ sal_Int32 nEventCount = eventNames.getLength();
+ for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
+ {
+ //need exception handling here
+ try
+ {
+ m_appEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xAppEvents->getByName( eventNames[nEvent] ) );
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+ if(!m_xDocEvents.is())
+ return;
+
+ eventNames = m_xDocEvents->getElementNames();
+ nEventCount = eventNames.getLength();
+ for(sal_Int32 nEvent = 0; nEvent < nEventCount; ++nEvent )
+ {
+ try
+ {
+ m_docEventsHash[ eventNames[nEvent] ] = GetPairFromAny( m_xDocEvents->getByName( eventNames[nEvent] ) );
+ }
+ catch (const Exception&)
+ {
+ }
+ }
+}
+
+// returns the two props EventType & Script for a given event name
+Any SvxMacroTabPage_::GetPropsByName( const OUString& eventName, EventsHash& eventsHash )
+{
+ const std::pair< OUString, OUString >& rAssignedEvent( eventsHash[ eventName ] );
+
+ Any aReturn;
+ ::comphelper::NamedValueCollection aProps;
+ if ( !(rAssignedEvent.first.isEmpty() || rAssignedEvent.second.isEmpty()) )
+ {
+ aProps.put( "EventType", rAssignedEvent.first );
+ aProps.put( "Script", rAssignedEvent.second );
+ }
+ aReturn <<= aProps.getPropertyValues();
+
+ return aReturn;
+}
+
+// converts the Any returned by GetByName into a pair which can be stored in
+// the EventHash
+std::pair< OUString, OUString > SvxMacroTabPage_::GetPairFromAny( const Any& aAny )
+{
+ Sequence< beans::PropertyValue > props;
+ OUString type, url;
+ if( aAny >>= props )
+ {
+ ::comphelper::NamedValueCollection aProps( props );
+ type = aProps.getOrDefault( "EventType", type );
+ url = aProps.getOrDefault( "Script", url );
+ }
+ return std::make_pair( type, url );
+}
+
+SvxMacroTabPage::SvxMacroTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const Reference< frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ Reference< container::XNameReplace > const & xNameReplace,
+ sal_uInt16 nSelectedIndex)
+ : SvxMacroTabPage_(pPage, pController, "cui/ui/macroassignpage.ui", "MacroAssignPage", rSet)
+{
+ mpImpl->xEventLB = m_xBuilder->weld_tree_view("assignments");
+ mpImpl->xEventLB->set_size_request(mpImpl->xEventLB->get_approximate_digit_width() * 70,
+ mpImpl->xEventLB->get_height_rows(9));
+ mpImpl->xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->xAssignComponentPB = m_xBuilder->weld_button("component");
+
+ SetFrame( _rxDocumentFrame );
+
+ if( !mpImpl->bIDEDialogMode )
+ {
+ mpImpl->xAssignComponentPB->hide();
+ mpImpl->xAssignComponentPB->set_sensitive(false);
+ }
+
+ InitResources();
+
+ InitAndSetHandler( xNameReplace, Reference< container::XNameReplace>(nullptr), Reference< util::XModifiable >(nullptr));
+ DisplayAppEvents(true);
+ mpImpl->xEventLB->select(nSelectedIndex);
+}
+
+SvxMacroAssignDlg::SvxMacroAssignDlg(weld::Window* pParent, const Reference< frame::XFrame >& _rxDocumentFrame, const SfxItemSet& rSet,
+ const Reference< container::XNameReplace >& xNameReplace, sal_uInt16 nSelectedIndex)
+ : SvxMacroAssignSingleTabDialog(pParent, rSet)
+{
+ SetTabPage(std::make_unique<SvxMacroTabPage>(get_content_area(), this, _rxDocumentFrame, rSet, xNameReplace, nSelectedIndex));
+}
+
+IMPL_LINK_NOARG(AssignComponentDialog, ButtonHandler, weld::Button&, void)
+{
+ OUString aMethodName = mxMethodEdit->get_text();
+ maURL.clear();
+ if( !aMethodName.isEmpty() )
+ {
+ maURL = aVndSunStarUNO;
+ maURL += aMethodName;
+ }
+ m_xDialog->response(RET_OK);
+}
+
+AssignComponentDialog::AssignComponentDialog(weld::Window* pParent, const OUString& rURL)
+ : GenericDialogController(pParent, "cui/ui/assigncomponentdialog.ui", "AssignComponent")
+ , maURL( rURL )
+ , mxMethodEdit(m_xBuilder->weld_entry("methodEntry"))
+ , mxOKButton(m_xBuilder->weld_button("ok"))
+{
+ mxOKButton->connect_clicked(LINK(this, AssignComponentDialog, ButtonHandler));
+
+ OUString aMethodName;
+ if( maURL.startsWith( aVndSunStarUNO ) )
+ {
+ aMethodName = maURL.copy( strlen(aVndSunStarUNO) );
+ }
+ mxMethodEdit->set_text(aMethodName);
+ mxMethodEdit->select_region(0, -1);
+}
+
+AssignComponentDialog::~AssignComponentDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxMacroAssignSingleTabDialog, OKHdl_Impl, weld::Button&, void)
+{
+ m_xSfxPage->FillItemSet(nullptr);
+ m_xDialog->response(RET_OK);
+}
+
+SvxMacroAssignSingleTabDialog::SvxMacroAssignSingleTabDialog(weld::Window *pParent,
+ const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet, "cui/ui/macroassigndialog.ui", "MacroAssignDialog")
+{
+ GetOKButton().connect_clicked(LINK(this, SvxMacroAssignSingleTabDialog, OKHdl_Impl));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/customize/macropg_impl.hxx b/cui/source/customize/macropg_impl.hxx
new file mode 100644
index 000000000..2a36d0f5c
--- /dev/null
+++ b/cui/source/customize/macropg_impl.hxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <svl/itemset.hxx>
+#include <vcl/weld.hxx>
+
+class SvxMacroTabPage_Impl
+{
+public:
+ explicit SvxMacroTabPage_Impl( const SfxItemSet& rAttrSet );
+
+ std::unique_ptr<weld::Button> xAssignPB;
+ std::unique_ptr<weld::Button> xAssignComponentPB;
+ std::unique_ptr<weld::Button> xDeletePB;
+ std::unique_ptr<weld::TreeView> xEventLB;
+ bool bReadOnly;
+ bool bIDEDialogMode;
+};
+
+class AssignComponentDialog : public weld::GenericDialogController
+{
+private:
+ OUString maURL;
+
+ std::unique_ptr<weld::Entry> mxMethodEdit;
+ std::unique_ptr<weld::Button> mxOKButton;
+
+ DECL_LINK(ButtonHandler, weld::Button&, void);
+
+public:
+ AssignComponentDialog(weld::Window* pParent, const OUString& rURL);
+ virtual ~AssignComponentDialog() override;
+
+ const OUString& getURL() const { return maURL; }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/DiagramDialog.cxx b/cui/source/dialogs/DiagramDialog.cxx
new file mode 100644
index 000000000..f3a4a069a
--- /dev/null
+++ b/cui/source/dialogs/DiagramDialog.cxx
@@ -0,0 +1,81 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+* This file is part of the LibreOffice project.
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#include <DiagramDialog.hxx>
+
+#include <comphelper/dispatchcommand.hxx>
+#include <svx/DiagramDataInterface.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+
+DiagramDialog::DiagramDialog(weld::Window* pWindow,
+ std::shared_ptr<DiagramDataInterface> pDiagramData)
+ : GenericDialogController(pWindow, "cui/ui/diagramdialog.ui", "DiagramDialog")
+ , mpDiagramData(pDiagramData)
+ , mpBtnOk(m_xBuilder->weld_button("btnOk"))
+ , mpBtnCancel(m_xBuilder->weld_button("btnCancel"))
+ , mpBtnAdd(m_xBuilder->weld_button("btnAdd"))
+ , mpBtnRemove(m_xBuilder->weld_button("btnRemove"))
+ , mpTreeDiagram(m_xBuilder->weld_tree_view("treeDiagram"))
+ , mpTextAdd(m_xBuilder->weld_text_view("textAdd"))
+{
+ mpBtnAdd->connect_clicked(LINK(this, DiagramDialog, OnAddClick));
+ mpBtnRemove->connect_clicked(LINK(this, DiagramDialog, OnRemoveClick));
+
+ populateTree(nullptr, OUString());
+
+ // expand all items
+ weld::TreeView* pTreeDiagram = mpTreeDiagram.get();
+ pTreeDiagram->all_foreach([pTreeDiagram](weld::TreeIter& rEntry) {
+ pTreeDiagram->expand_row(rEntry);
+ return false;
+ });
+}
+
+IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, void)
+{
+ OUString sText = mpTextAdd->get_text();
+ if (!sText.isEmpty())
+ {
+ OUString sNodeId = mpDiagramData->addNode(sText);
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ mpTreeDiagram->insert(nullptr, -1, &sText, &sNodeId, nullptr, nullptr, nullptr, false,
+ pEntry.get());
+ mpTreeDiagram->select(*pEntry);
+ comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+ }
+}
+
+IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, void)
+{
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ if (mpTreeDiagram->get_selected(pEntry.get()))
+ {
+ if (mpDiagramData->removeNode(mpTreeDiagram->get_id(*pEntry)))
+ {
+ mpTreeDiagram->remove(*pEntry);
+ comphelper::dispatchCommand(".uno:RegenerateDiagram", {});
+ }
+ }
+}
+
+void DiagramDialog::populateTree(const weld::TreeIter* pParent, const OUString& rParentId)
+{
+ auto aItems = mpDiagramData->getChildren(rParentId);
+ for (auto& aItem : aItems)
+ {
+ std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
+ mpTreeDiagram->insert(pParent, -1, &aItem.second, &aItem.first, nullptr, nullptr, nullptr,
+ false, pEntry.get());
+ populateTree(pEntry.get(), aItem.first);
+ }
+}
+
+DiagramDialog::~DiagramDialog() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/FontFeaturesDialog.cxx b/cui/source/dialogs/FontFeaturesDialog.cxx
new file mode 100644
index 000000000..a34912d5d
--- /dev/null
+++ b/cui/source/dialogs/FontFeaturesDialog.cxx
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ */
+
+#include <FontFeaturesDialog.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/font/FeatureParser.hxx>
+#include <vcl/virdev.hxx>
+#include <svtools/colorcfg.hxx>
+#include <unordered_set>
+
+using namespace css;
+
+namespace cui
+{
+FontFeaturesDialog::FontFeaturesDialog(weld::Window* pParent, OUString const& rFontName)
+ : GenericDialogController(pParent, "cui/ui/fontfeaturesdialog.ui", "FontFeaturesDialog")
+ , m_sFontName(rFontName)
+ , m_xContentWindow(m_xBuilder->weld_scrolled_window("contentWindow"))
+ , m_xContentGrid(m_xBuilder->weld_container("contentGrid"))
+ , m_xPreviewWindow(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWindow))
+{
+ svtools::ColorConfig aColorConfig;
+ Color aFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
+ m_aPreviewWindow.SetBackColor(aFillColor);
+ initialize();
+}
+
+FontFeaturesDialog::~FontFeaturesDialog() {}
+
+static sal_Int32 makeEnumComboBox(weld::ComboBox& rNameBox,
+ vcl::font::FeatureDefinition const& rFeatureDefinition,
+ uint32_t nDefault)
+{
+ sal_Int32 nRes = 0;
+ int count = 0;
+ for (vcl::font::FeatureParameter const& rParameter : rFeatureDefinition.getEnumParameters())
+ {
+ rNameBox.append(OUString::number(rParameter.getCode()), rParameter.getDescription());
+ if (rParameter.getCode() == nDefault)
+ nRes = count;
+ ++count;
+ }
+ return nRes;
+}
+
+void FontFeaturesDialog::initialize()
+{
+ ScopedVclPtrInstance<VirtualDevice> aVDev(*Application::GetDefaultDevice(),
+ DeviceFormat::DEFAULT, DeviceFormat::DEFAULT);
+ aVDev->SetOutputSizePixel(Size(10, 10));
+
+ vcl::Font aFont = aVDev->GetFont();
+ aFont.SetFamilyName(m_sFontName);
+ aVDev->SetFont(aFont);
+
+ std::vector<vcl::font::Feature> rFontFeatures;
+
+ if (!aVDev->GetFontFeatures(rFontFeatures))
+ return;
+
+ std::unordered_set<sal_uInt32> aDoneFeatures;
+ std::vector<vcl::font::Feature> rFilteredFontFeatures;
+
+ for (vcl::font::Feature const& rFontFeature : rFontFeatures)
+ {
+ sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
+ if (!aDoneFeatures.insert(nFontFeatureCode).second)
+ continue;
+ rFilteredFontFeatures.push_back(rFontFeature);
+ }
+
+ fillGrid(rFilteredFontFeatures);
+
+ updateFontPreview();
+}
+
+void FontFeaturesDialog::fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures)
+{
+ vcl::font::FeatureParser aParser(m_sFontName);
+ auto aExistingFeatures = aParser.getFeaturesMap();
+
+ sal_Int32 i = 0;
+ for (vcl::font::Feature const& rFontFeature : rFontFeatures)
+ {
+ sal_uInt32 nFontFeatureCode = rFontFeature.m_aID.m_aFeatureCode;
+
+ vcl::font::FeatureDefinition aDefinition;
+ if (rFontFeature.m_aDefinition)
+ aDefinition = rFontFeature.m_aDefinition;
+ if (!aDefinition)
+ aDefinition = { nFontFeatureCode, nullptr };
+
+ m_aFeatureItems.emplace_back(m_xContentGrid.get());
+
+ uint32_t nValue = 0;
+ if (aExistingFeatures.find(nFontFeatureCode) != aExistingFeatures.end())
+ nValue = aExistingFeatures.at(nFontFeatureCode);
+ else
+ nValue = aDefinition.getDefault();
+
+ FontFeatureItem& aCurrentItem = m_aFeatureItems.back();
+ aCurrentItem.m_aFeatureCode = nFontFeatureCode;
+ aCurrentItem.m_nDefault = aDefinition.getDefault();
+
+ sal_Int32 nGridPositionX = (i % 2) * 2;
+ sal_Int32 nGridPositionY = i / 2;
+ aCurrentItem.m_xContainer->set_grid_left_attach(nGridPositionX);
+ aCurrentItem.m_xContainer->set_grid_top_attach(nGridPositionY);
+
+ Link<weld::ComboBox&, void> aComboBoxSelectHandler
+ = LINK(this, FontFeaturesDialog, ComboBoxSelectedHdl);
+ Link<weld::ToggleButton&, void> aCheckBoxToggleHandler
+ = LINK(this, FontFeaturesDialog, CheckBoxToggledHdl);
+
+ if (aDefinition.getType() == vcl::font::FeatureParameterType::ENUM)
+ {
+ aCurrentItem.m_xText->set_label(aDefinition.getDescription());
+ aCurrentItem.m_xText->show();
+
+ sal_Int32 nInit = makeEnumComboBox(*aCurrentItem.m_xCombo, aDefinition, nValue);
+
+ aCurrentItem.m_xCombo->set_active(nInit);
+ aCurrentItem.m_xCombo->connect_changed(aComboBoxSelectHandler);
+ aCurrentItem.m_xCombo->show();
+ }
+ else
+ {
+ aCurrentItem.m_xCheck->set_active(nValue > 0);
+ aCurrentItem.m_xCheck->set_label(aDefinition.getDescription());
+ aCurrentItem.m_xCheck->connect_toggled(aCheckBoxToggleHandler);
+ aCurrentItem.m_xCheck->show();
+ }
+
+ i++;
+ }
+}
+
+void FontFeaturesDialog::updateFontPreview()
+{
+ vcl::Font rPreviewFont = m_aPreviewWindow.GetFont();
+ vcl::Font rPreviewFontCJK = m_aPreviewWindow.GetCJKFont();
+ vcl::Font rPreviewFontCTL = m_aPreviewWindow.GetCTLFont();
+
+ OUString sNewFontName = createFontNameWithFeatures();
+
+ rPreviewFont.SetFamilyName(sNewFontName);
+ rPreviewFontCJK.SetFamilyName(sNewFontName);
+ rPreviewFontCTL.SetFamilyName(sNewFontName);
+
+ m_aPreviewWindow.SetFont(rPreviewFont, rPreviewFontCJK, rPreviewFontCTL);
+}
+
+IMPL_LINK_NOARG(FontFeaturesDialog, CheckBoxToggledHdl, weld::ToggleButton&, void)
+{
+ updateFontPreview();
+}
+
+IMPL_LINK_NOARG(FontFeaturesDialog, ComboBoxSelectedHdl, weld::ComboBox&, void)
+{
+ updateFontPreview();
+}
+
+OUString FontFeaturesDialog::createFontNameWithFeatures()
+{
+ OUString sResultFontName;
+ OUStringBuffer sNameSuffix;
+ bool bFirst = true;
+
+ for (const FontFeatureItem& rItem : m_aFeatureItems)
+ {
+ if (rItem.m_xCheck->get_visible())
+ {
+ if (sal_uInt32(rItem.m_xCheck->get_active()) != rItem.m_nDefault)
+ {
+ if (!bFirst)
+ sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
+ else
+ bFirst = false;
+
+ sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
+ if (!rItem.m_xCheck->get_active())
+ sNameSuffix.append("=0");
+ }
+ }
+ else if (rItem.m_xCombo->get_visible() && rItem.m_xText->get_visible())
+ {
+ sal_Int32 nSelection = rItem.m_xCombo->get_active_id().toInt32();
+ if (nSelection != int(rItem.m_nDefault))
+ {
+ if (!bFirst)
+ sNameSuffix.append(OUString(vcl::font::FeatureSeparator));
+ else
+ bFirst = false;
+
+ sNameSuffix.append(vcl::font::featureCodeAsString(rItem.m_aFeatureCode));
+ sNameSuffix.append("=");
+ sNameSuffix.append(OUString::number(nSelection));
+ }
+ }
+ }
+ sResultFontName = vcl::font::trimFontNameFeatures(m_sFontName);
+ if (!sNameSuffix.isEmpty())
+ sResultFontName
+ += OUStringChar(vcl::font::FeaturePrefix) + sNameSuffix.makeStringAndClear();
+ return sResultFontName;
+}
+
+short FontFeaturesDialog::run()
+{
+ short nResult = GenericDialogController::run();
+ if (nResult == RET_OK)
+ {
+ m_sResultFontName = createFontNameWithFeatures();
+ }
+ return nResult;
+}
+
+} // end svx namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/QrCodeGenDialog.cxx b/cui/source/dialogs/QrCodeGenDialog.cxx
new file mode 100644
index 000000000..7f3f6a806
--- /dev/null
+++ b/cui/source/dialogs/QrCodeGenDialog.cxx
@@ -0,0 +1,341 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <QrCodeGenDialog.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <tools/stream.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <unotools/streamwrap.hxx>
+#include <utility>
+#include <vcl/svapp.hxx>
+
+#if ENABLE_QRCODEGEN
+#if defined(SYSTEM_QRCODEGEN)
+#include <qrcodegen/QrCode.hpp>
+#else
+#include <QrCode.hpp>
+#endif
+#endif
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/drawing/QRCode.hpp>
+#include <com/sun/star/drawing/QRCodeErrorCorrection.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+#include <config_fuzzers.h>
+#include <com/sun/star/drawing/XDrawView.hpp>
+#include <com/sun/star/drawing/XDrawPage.hpp>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::container;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::frame;
+using namespace css::sheet;
+using namespace css::text;
+using namespace css::drawing;
+using namespace css::graphic;
+#if ENABLE_QRCODEGEN
+using namespace qrcodegen;
+#endif
+
+QrCodeGenDialog::QrCodeGenDialog(weld::Widget* pParent, Reference<XModel> xModel,
+ bool bEditExisting)
+ : GenericDialogController(pParent, "cui/ui/qrcodegen.ui", "QrCodeGenDialog")
+ , m_xModel(std::move(xModel))
+ , m_xEdittext(m_xBuilder->weld_entry("edit_text"))
+ , m_xECC{ m_xBuilder->weld_radio_button("button_low"),
+ m_xBuilder->weld_radio_button("button_medium"),
+ m_xBuilder->weld_radio_button("button_quartile"),
+ m_xBuilder->weld_radio_button("button_high") }
+ , m_xSpinBorder(m_xBuilder->weld_spin_button("edit_border"))
+#if ENABLE_QRCODEGEN
+ , mpParent(pParent)
+#endif
+{
+ if (!bEditExisting)
+ {
+ // TODO: This only works in Writer doc. Should also work in shapes
+ Reference<XIndexAccess> xSelections(m_xModel->getCurrentSelection(), UNO_QUERY);
+ if (xSelections.is())
+ {
+ Reference<XTextRange> xSelection(xSelections->getByIndex(0), UNO_QUERY);
+ if (xSelection.is())
+ m_xEdittext->set_text(xSelection->getString());
+ }
+ return;
+ }
+
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ Reference<XPropertySet> xProps(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ // Read properties from selected QR Code
+ css::drawing::QRCode aQRCode;
+ xProps->getPropertyValue("QRCodeProperties") >>= aQRCode;
+
+ m_xEdittext->set_text(aQRCode.Payload);
+
+ //Get Error Correction Constant from selected QR Code
+ GetErrorCorrection(aQRCode.ErrorCorrection);
+
+ m_xSpinBorder->set_value(aQRCode.Border);
+
+ // Mark this as existing shape
+ m_xExistingShapeProperties = xProps;
+}
+
+short QrCodeGenDialog::run()
+{
+#if ENABLE_QRCODEGEN
+ short nRet;
+ while (true)
+ {
+ nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ {
+ try
+ {
+ Apply();
+ break;
+ }
+ catch (const qrcodegen::data_too_long&)
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(
+ mpParent, VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_QRCODEDATALONG)));
+ xBox->run();
+ }
+ }
+ else
+ break;
+ }
+ return nRet;
+#else
+ return RET_CANCEL;
+#endif
+}
+
+void QrCodeGenDialog::Apply()
+{
+#if ENABLE_QRCODEGEN
+ css::drawing::QRCode aQRCode;
+ aQRCode.Payload = m_xEdittext->get_text();
+
+ bool bLowECCActive(m_xECC[0]->get_active());
+ bool bMediumECCActive(m_xECC[1]->get_active());
+ bool bQuartileECCActive(m_xECC[2]->get_active());
+
+ if (bLowECCActive)
+ {
+ aQRCode.ErrorCorrection = css::drawing::QRCodeErrorCorrection::LOW;
+ }
+ else if (bMediumECCActive)
+ {
+ aQRCode.ErrorCorrection = css::drawing::QRCodeErrorCorrection::MEDIUM;
+ }
+ else if (bQuartileECCActive)
+ {
+ aQRCode.ErrorCorrection = css::drawing::QRCodeErrorCorrection::QUARTILE;
+ }
+ else
+ {
+ aQRCode.ErrorCorrection = css::drawing::QRCodeErrorCorrection::HIGH;
+ }
+
+ aQRCode.Border = m_xSpinBorder->get_value();
+
+ // Read svg and replace placeholder texts
+ OUString aSvgImage = GenerateQRCode(aQRCode.Payload, aQRCode.ErrorCorrection, aQRCode.Border);
+
+ // Insert/Update graphic
+ SvMemoryStream aSvgStream(4096, 4096);
+ aSvgStream.WriteOString(OUStringToOString(aSvgImage, RTL_TEXTENCODING_UTF8));
+ Reference<XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream));
+ Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
+ Reference<XGraphicProvider> xProvider = css::graphic::GraphicProvider::create(xContext);
+
+ Sequence<PropertyValue> aMediaProperties(1);
+ aMediaProperties[0].Name = "InputStream";
+ aMediaProperties[0].Value <<= xInputStream;
+ Reference<XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
+
+ bool bIsExistingQRCode = m_xExistingShapeProperties.is();
+ Reference<XPropertySet> xShapeProps;
+ if (bIsExistingQRCode)
+ xShapeProps = m_xExistingShapeProperties;
+ else
+ xShapeProps.set(Reference<lang::XMultiServiceFactory>(m_xModel, UNO_QUERY_THROW)
+ ->createInstance("com.sun.star.drawing.GraphicObjectShape"),
+ UNO_QUERY);
+
+ xShapeProps->setPropertyValue("Graphic", Any(xGraphic));
+
+ // Set QRCode properties
+ xShapeProps->setPropertyValue("QRCodeProperties", Any(aQRCode));
+
+ if (bIsExistingQRCode)
+ return;
+
+ // Default size
+ Reference<XShape> xShape(xShapeProps, UNO_QUERY);
+ awt::Size aShapeSize;
+ aShapeSize.Height = 4000;
+ aShapeSize.Width = 4000;
+ xShape->setSize(aShapeSize);
+
+ // Default anchoring
+ xShapeProps->setPropertyValue("AnchorType", Any(TextContentAnchorType_AT_PARAGRAPH));
+
+ const Reference<XServiceInfo> xServiceInfo(m_xModel, UNO_QUERY_THROW);
+
+ // Writer
+ if (xServiceInfo->supportsService("com.sun.star.text.TextDocument"))
+ {
+ Reference<XTextContent> xTextContent(xShape, UNO_QUERY_THROW);
+ Reference<XTextViewCursorSupplier> xViewCursorSupplier(m_xModel->getCurrentController(),
+ UNO_QUERY_THROW);
+ Reference<XTextViewCursor> xCursor = xViewCursorSupplier->getViewCursor();
+ // use cursor's XText - it might be in table cell, frame, ...
+ Reference<XText> const xText(xCursor->getText());
+ assert(xText.is());
+ xText->insertTextContent(xCursor, xTextContent, true);
+ return;
+ }
+
+ // Calc
+ else if (xServiceInfo->supportsService("com.sun.star.sheet.SpreadsheetDocument"))
+ {
+ Reference<XPropertySet> xSheetCell(m_xModel->getCurrentSelection(), UNO_QUERY_THROW);
+ awt::Point aCellPosition;
+ xSheetCell->getPropertyValue("Position") >>= aCellPosition;
+ xShape->setPosition(aCellPosition);
+
+ Reference<XSpreadsheetView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XSpreadsheet> xSheet(xView->getActiveSheet(), UNO_SET_THROW);
+ Reference<XDrawPageSupplier> xDrawPageSupplier(xSheet, UNO_QUERY_THROW);
+ Reference<XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xDrawPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+ return;
+ }
+
+ //Impress and Draw
+ else if (xServiceInfo->supportsService("com.sun.star.presentation.PresentationDocument")
+ || xServiceInfo->supportsService("com.sun.star.drawing.DrawingDocument"))
+ {
+ Reference<XDrawView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XDrawPage> xPage(xView->getCurrentPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+ return;
+ }
+
+ else
+ {
+ //Not implemented for math,base and other apps.
+ throw uno::RuntimeException("Not implemented");
+ }
+#endif
+}
+
+OUString QrCodeGenDialog::GenerateQRCode(OUString aQRText, long aQRECC, int aQRBorder)
+{
+#if ENABLE_QRCODEGEN
+ //Select ECC:: value from aQrECC
+ qrcodegen::QrCode::Ecc bqrEcc = qrcodegen::QrCode::Ecc::LOW;
+
+ switch (aQRECC)
+ {
+ case 1:
+ {
+ bqrEcc = qrcodegen::QrCode::Ecc::LOW;
+ break;
+ }
+ case 2:
+ {
+ bqrEcc = qrcodegen::QrCode::Ecc::MEDIUM;
+ break;
+ }
+ case 3:
+ {
+ bqrEcc = qrcodegen::QrCode::Ecc::QUARTILE;
+ break;
+ }
+ case 4:
+ {
+ bqrEcc = qrcodegen::QrCode::Ecc::HIGH;
+ break;
+ }
+ }
+
+ //OuString to char* qrtext
+ OString o = OUStringToOString(aQRText, RTL_TEXTENCODING_UTF8);
+ const char* qrtext = o.pData->buffer;
+
+ // From QR Code library
+ qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText(qrtext, bqrEcc);
+ std::string svg = qr0.toSvgString(aQRBorder);
+ //cstring to OUString
+ return OUString::createFromAscii(svg.c_str());
+#else
+ (void)aQRText;
+ (void)aQRECC;
+ (void)aQRBorder;
+ return OUString();
+#endif
+}
+
+void QrCodeGenDialog::GetErrorCorrection(long ErrorCorrection)
+{
+ switch (ErrorCorrection)
+ {
+ case css::drawing::QRCodeErrorCorrection::LOW:
+ {
+ m_xECC[0]->set_active(true);
+ break;
+ }
+ case css::drawing::QRCodeErrorCorrection::MEDIUM:
+ {
+ m_xECC[1]->set_active(true);
+ break;
+ }
+ case css::drawing::QRCodeErrorCorrection::QUARTILE:
+ {
+ m_xECC[2]->set_active(true);
+ break;
+ }
+ case css::drawing::QRCodeErrorCorrection::HIGH:
+ {
+ m_xECC[3]->set_active(true);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignSignatureLineDialog.cxx b/cui/source/dialogs/SignSignatureLineDialog.cxx
new file mode 100644
index 000000000..10f80f729
--- /dev/null
+++ b/cui/source/dialogs/SignSignatureLineDialog.cxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignSignatureLineDialog.hxx>
+
+#include <sal/log.hxx>
+#include <sal/types.h>
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <comphelper/graphicmimetype.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/xmlsechelper.hxx>
+#include <comphelper/storagehelper.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/xoutbmp.hxx>
+#include <tools/date.hxx>
+#include <tools/stream.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <unotools/syslocale.hxx>
+#include <utility>
+#include <vcl/graph.hxx>
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/security/CertificateKind.hpp>
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
+#include <com/sun/star/ui/dialogs/FilePicker.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+
+using namespace comphelper;
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::frame;
+using namespace css::text;
+using namespace css::graphic;
+using namespace css::security;
+using namespace css::ui::dialogs;
+
+SignSignatureLineDialog::SignSignatureLineDialog(weld::Widget* pParent, Reference<XModel> xModel)
+ : SignatureLineDialogBase(pParent, std::move(xModel), "cui/ui/signsignatureline.ui",
+ "SignSignatureLineDialog")
+ , m_xEditName(m_xBuilder->weld_entry("edit_name"))
+ , m_xEditComment(m_xBuilder->weld_text_view("edit_comment"))
+ , m_xBtnLoadImage(m_xBuilder->weld_button("btn_load_image"))
+ , m_xBtnClearImage(m_xBuilder->weld_button("btn_clear_image"))
+ , m_xBtnChooseCertificate(m_xBuilder->weld_button("btn_select_certificate"))
+ , m_xBtnSign(m_xBuilder->weld_button("ok"))
+ , m_xLabelHint(m_xBuilder->weld_label("label_hint"))
+ , m_xLabelHintText(m_xBuilder->weld_label("label_hint_text"))
+ , m_xLabelAddComment(m_xBuilder->weld_label("label_add_comment"))
+ , m_bShowSignDate(false)
+{
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ m_xShapeProperties.set(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ bool bIsSignatureLine(false);
+ m_xShapeProperties->getPropertyValue("IsSignatureLine") >>= bIsSignatureLine;
+ if (!bIsSignatureLine)
+ {
+ SAL_WARN("cui.dialogs", "No signature line selected!");
+ return;
+ }
+
+ m_xBtnLoadImage->connect_clicked(LINK(this, SignSignatureLineDialog, loadImage));
+ m_xBtnClearImage->connect_clicked(LINK(this, SignSignatureLineDialog, clearImage));
+ m_xBtnChooseCertificate->connect_clicked(
+ LINK(this, SignSignatureLineDialog, chooseCertificate));
+ m_xEditName->connect_changed(LINK(this, SignSignatureLineDialog, entryChanged));
+
+ // Read properties from selected signature line
+ m_xShapeProperties->getPropertyValue("SignatureLineId") >>= m_aSignatureLineId;
+ m_xShapeProperties->getPropertyValue("SignatureLineSuggestedSignerName")
+ >>= m_aSuggestedSignerName;
+ m_xShapeProperties->getPropertyValue("SignatureLineSuggestedSignerTitle")
+ >>= m_aSuggestedSignerTitle;
+ OUString aSigningInstructions;
+ m_xShapeProperties->getPropertyValue("SignatureLineSigningInstructions")
+ >>= aSigningInstructions;
+ m_xShapeProperties->getPropertyValue("SignatureLineShowSignDate") >>= m_bShowSignDate;
+ bool bCanAddComment(false);
+ m_xShapeProperties->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComment;
+
+ if (aSigningInstructions.isEmpty())
+ {
+ m_xLabelHint->hide();
+ m_xLabelHintText->hide();
+ }
+ else
+ {
+ m_xLabelHintText->set_label(aSigningInstructions);
+ }
+
+ if (bCanAddComment)
+ {
+ m_xEditComment->set_size_request(m_xEditComment->get_approximate_digit_width() * 48,
+ m_xEditComment->get_text_height() * 5);
+ }
+ else
+ {
+ m_xLabelAddComment->hide();
+ m_xEditComment->hide();
+ m_xEditComment->set_size_request(0, 0);
+ }
+
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, loadImage, weld::Button&, void)
+{
+ Reference<XComponentContext> xContext = comphelper::getProcessComponentContext();
+ Reference<XFilePicker3> xFilePicker
+ = FilePicker::createWithMode(xContext, TemplateDescription::FILEOPEN_PREVIEW);
+ if (!xFilePicker->execute())
+ return;
+
+ Sequence<OUString> aSelectedFiles = xFilePicker->getSelectedFiles();
+ if (!aSelectedFiles.hasElements())
+ return;
+
+ Reference<XGraphicProvider> xProvider = GraphicProvider::create(xContext);
+ Sequence<PropertyValue> aMediaProperties(1);
+ aMediaProperties[0].Name = "URL";
+ aMediaProperties[0].Value <<= aSelectedFiles[0];
+ m_xSignatureImage = xProvider->queryGraphic(aMediaProperties);
+ m_sOriginalImageBtnLabel = m_xBtnLoadImage->get_label();
+
+ INetURLObject aObj(aSelectedFiles[0]);
+ m_xBtnLoadImage->set_label(aObj.GetLastName());
+
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, clearImage, weld::Button&, void)
+{
+ m_xSignatureImage.set(nullptr);
+ m_xBtnLoadImage->set_label(m_sOriginalImageBtnLabel);
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, chooseCertificate, weld::Button&, void)
+{
+ // Document needs to be saved before selecting a certificate
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if (!pShell->PrepareForSigning(m_xDialog.get()))
+ return;
+
+ Reference<XDocumentDigitalSignatures> xSigner;
+ if (pShell->GetMedium()->GetFilter()->IsAlienFormat())
+ {
+ xSigner
+ = DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext());
+ }
+ else
+ {
+ OUString const aODFVersion(
+ comphelper::OStorageHelper::GetODFVersionFromStorage(pShell->GetStorage()));
+ xSigner = DocumentDigitalSignatures::createWithVersion(
+ comphelper::getProcessComponentContext(), aODFVersion);
+ }
+ xSigner->setParentWindow(m_xDialog->GetXWindow());
+ OUString aDescription;
+ CertificateKind certificateKind = CertificateKind_NONE;
+ // When signing ooxml, we only want X.509 certificates
+ if (pShell->GetMedium()->GetFilter()->IsAlienFormat())
+ certificateKind = CertificateKind_X509;
+ Reference<XCertificate> xSignCertificate
+ = xSigner->selectSigningCertificateWithType(certificateKind, aDescription);
+
+ if (xSignCertificate.is())
+ {
+ m_xSelectedCertifate = xSignCertificate;
+ m_xBtnChooseCertificate->set_label(xmlsec::GetContentPart(
+ xSignCertificate->getSubjectName(), xSignCertificate->getCertificateKind()));
+ }
+ ValidateFields();
+}
+
+IMPL_LINK_NOARG(SignSignatureLineDialog, entryChanged, weld::Entry&, void) { ValidateFields(); }
+
+void SignSignatureLineDialog::ValidateFields()
+{
+ bool bEnableSignBtn = m_xSelectedCertifate.is()
+ && (!m_xEditName->get_text().isEmpty() || m_xSignatureImage.is());
+ m_xBtnSign->set_sensitive(bEnableSignBtn);
+
+ m_xEditName->set_sensitive(!m_xSignatureImage.is());
+ m_xBtnLoadImage->set_sensitive(m_xEditName->get_text().isEmpty());
+ m_xBtnClearImage->set_sensitive(m_xSignatureImage.is());
+}
+
+void SignSignatureLineDialog::Apply()
+{
+ if (!m_xSelectedCertifate.is())
+ {
+ SAL_WARN("cui.dialogs", "No certificate selected!");
+ return;
+ }
+
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ Reference<XGraphic> xValidGraphic = getSignedGraphic(true);
+ Reference<XGraphic> xInvalidGraphic = getSignedGraphic(false);
+ pShell->SignSignatureLine(m_xDialog.get(), m_aSignatureLineId, m_xSelectedCertifate,
+ xValidGraphic, xInvalidGraphic, m_xEditComment->get_text());
+}
+
+css::uno::Reference<css::graphic::XGraphic> SignSignatureLineDialog::getSignedGraphic(bool bValid)
+{
+ // Read svg and replace placeholder texts
+ OUString aSvgImage(getSignatureImage());
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(m_aSuggestedSignerName));
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(m_aSuggestedSignerTitle));
+
+ OUString aIssuerLine
+ = CuiResId(RID_SVXSTR_SIGNATURELINE_SIGNED_BY)
+ .replaceFirst("%1",
+ xmlsec::GetContentPart(m_xSelectedCertifate->getSubjectName(),
+ m_xSelectedCertifate->getCertificateKind()));
+ aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", getCDataString(aIssuerLine));
+ if (bValid)
+ aSvgImage = aSvgImage.replaceAll("[INVALID_SIGNATURE]", "");
+
+ OUString aDate;
+ if (m_bShowSignDate && bValid)
+ {
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ Date aDateTime(Date::SYSTEM);
+ aDate = rLocaleData.getDate(aDateTime);
+ }
+ aSvgImage = aSvgImage.replaceAll("[DATE]", aDate);
+
+ // Custom signature image
+ if (m_xSignatureImage.is())
+ {
+ OUString aGraphicInBase64;
+ Graphic aGraphic(m_xSignatureImage);
+ if (!XOutBitmap::GraphicToBase64(aGraphic, aGraphicInBase64, false))
+ SAL_WARN("cui.dialogs", "Could not convert graphic to base64");
+
+ OUString aImagePart = "<image y=\"825\" x=\"1300\" "
+ "xlink:href=\"data:[MIMETYPE];base64,[BASE64_IMG]>\" "
+ "preserveAspectRatio=\"xMidYMid\" height=\"1520\" "
+ "width=\"7600\" />";
+ aImagePart = aImagePart.replaceAll(
+ "[MIMETYPE]", GraphicMimeTypeHelper::GetMimeTypeForXGraphic(m_xSignatureImage));
+ aImagePart = aImagePart.replaceAll("[BASE64_IMG]", aGraphicInBase64);
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", aImagePart);
+
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", "");
+ }
+ else
+ {
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE_IMAGE]", "");
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", getCDataString(m_xEditName->get_text()));
+ }
+
+ // Create graphic
+ SvMemoryStream aSvgStream(4096, 4096);
+ aSvgStream.WriteOString(OUStringToOString(aSvgImage, RTL_TEXTENCODING_UTF8));
+ Reference<XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream));
+ Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
+ Reference<XGraphicProvider> xProvider = css::graphic::GraphicProvider::create(xContext);
+
+ Sequence<PropertyValue> aMediaProperties(1);
+ aMediaProperties[0].Name = "InputStream";
+ aMediaProperties[0].Value <<= xInputStream;
+ return xProvider->queryGraphic(aMediaProperties);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignatureLineDialog.cxx b/cui/source/dialogs/SignatureLineDialog.cxx
new file mode 100644
index 000000000..e295e288e
--- /dev/null
+++ b/cui/source/dialogs/SignatureLineDialog.cxx
@@ -0,0 +1,210 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignatureLineDialog.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/xmltools.hxx>
+#include <tools/stream.hxx>
+#include <unotools/streamwrap.hxx>
+#include <utility>
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/drawing/XShape.hpp>
+#include <com/sun/star/graphic/GraphicProvider.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sheet/XSpreadsheet.hpp>
+#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
+#include <com/sun/star/sheet/XSpreadsheetView.hpp>
+#include <com/sun/star/text/TextContentAnchorType.hpp>
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextDocument.hpp>
+#include <com/sun/star/text/XTextViewCursor.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::container;
+using namespace css::frame;
+using namespace css::io;
+using namespace css::lang;
+using namespace css::frame;
+using namespace css::sheet;
+using namespace css::text;
+using namespace css::drawing;
+using namespace css::graphic;
+
+SignatureLineDialog::SignatureLineDialog(weld::Widget* pParent, Reference<XModel> xModel,
+ bool bEditExisting)
+ : SignatureLineDialogBase(pParent, std::move(xModel), "cui/ui/signatureline.ui",
+ "SignatureLineDialog")
+ , m_xEditName(m_xBuilder->weld_entry("edit_name"))
+ , m_xEditTitle(m_xBuilder->weld_entry("edit_title"))
+ , m_xEditEmail(m_xBuilder->weld_entry("edit_email"))
+ , m_xEditInstructions(m_xBuilder->weld_text_view("edit_instructions"))
+ , m_xCheckboxCanAddComments(m_xBuilder->weld_check_button("checkbox_can_add_comments"))
+ , m_xCheckboxShowSignDate(m_xBuilder->weld_check_button("checkbox_show_sign_date"))
+{
+ m_xEditInstructions->set_size_request(m_xEditInstructions->get_approximate_digit_width() * 48,
+ m_xEditInstructions->get_text_height() * 5);
+
+ // No signature line selected - start with empty dialog and set some default values
+ if (!bEditExisting)
+ {
+ m_xCheckboxCanAddComments->set_active(true);
+ m_xCheckboxShowSignDate->set_active(true);
+ return;
+ }
+
+ Reference<container::XIndexAccess> xIndexAccess(m_xModel->getCurrentSelection(),
+ UNO_QUERY_THROW);
+ Reference<XPropertySet> xProps(xIndexAccess->getByIndex(0), UNO_QUERY_THROW);
+
+ // Read properties from selected signature line
+ xProps->getPropertyValue("SignatureLineId") >>= m_aSignatureLineId;
+ OUString aSuggestedSignerName;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerName") >>= aSuggestedSignerName;
+ m_xEditName->set_text(aSuggestedSignerName);
+ OUString aSuggestedSignerTitle;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerTitle") >>= aSuggestedSignerTitle;
+ m_xEditTitle->set_text(aSuggestedSignerTitle);
+ OUString aSuggestedSignerEmail;
+ xProps->getPropertyValue("SignatureLineSuggestedSignerEmail") >>= aSuggestedSignerEmail;
+ m_xEditEmail->set_text(aSuggestedSignerEmail);
+ OUString aSigningInstructions;
+ xProps->getPropertyValue("SignatureLineSigningInstructions") >>= aSigningInstructions;
+ m_xEditInstructions->set_text(aSigningInstructions);
+ bool bCanAddComments = false;
+ xProps->getPropertyValue("SignatureLineCanAddComment") >>= bCanAddComments;
+ m_xCheckboxCanAddComments->set_active(bCanAddComments);
+ bool bShowSignDate = false;
+ xProps->getPropertyValue("SignatureLineShowSignDate") >>= bShowSignDate;
+ m_xCheckboxShowSignDate->set_active(bShowSignDate);
+
+ // Mark this as existing shape
+ m_xExistingShapeProperties = xProps;
+}
+
+void SignatureLineDialog::Apply()
+{
+ if (m_aSignatureLineId.isEmpty())
+ m_aSignatureLineId
+ = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_ASCII_US);
+ OUString aSignerName(m_xEditName->get_text());
+ OUString aSignerTitle(m_xEditTitle->get_text());
+ OUString aSignerEmail(m_xEditEmail->get_text());
+ OUString aSigningInstructions(m_xEditInstructions->get_text());
+ bool bCanAddComments(m_xCheckboxCanAddComments->get_active());
+ bool bShowSignDate(m_xCheckboxShowSignDate->get_active());
+
+ // Read svg and replace placeholder texts
+ OUString aSvgImage(getSignatureImage());
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", getCDataString(aSignerName));
+ aSvgImage = aSvgImage.replaceAll("[SIGNER_TITLE]", getCDataString(aSignerTitle));
+
+ // These are only filled if the signature line is signed.
+ aSvgImage = aSvgImage.replaceAll("[SIGNATURE]", "");
+ aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", "");
+ aSvgImage = aSvgImage.replaceAll("[INVALID_SIGNATURE]", "");
+ aSvgImage = aSvgImage.replaceAll("[DATE]", "");
+
+ // Insert/Update graphic
+ SvMemoryStream aSvgStream(4096, 4096);
+ aSvgStream.WriteOString(OUStringToOString(aSvgImage, RTL_TEXTENCODING_UTF8));
+ Reference<XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream));
+ Reference<XComponentContext> xContext(comphelper::getProcessComponentContext());
+ Reference<XGraphicProvider> xProvider = css::graphic::GraphicProvider::create(xContext);
+
+ Sequence<PropertyValue> aMediaProperties(1);
+ aMediaProperties[0].Name = "InputStream";
+ aMediaProperties[0].Value <<= xInputStream;
+ Reference<XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
+
+ bool bIsExistingSignatureLine = m_xExistingShapeProperties.is();
+ Reference<XPropertySet> xShapeProps;
+ if (bIsExistingSignatureLine)
+ xShapeProps = m_xExistingShapeProperties;
+ else
+ xShapeProps.set(Reference<lang::XMultiServiceFactory>(m_xModel, UNO_QUERY_THROW)
+ ->createInstance("com.sun.star.drawing.GraphicObjectShape"),
+ UNO_QUERY);
+
+ xShapeProps->setPropertyValue("Graphic", Any(xGraphic));
+ xShapeProps->setPropertyValue("SignatureLineUnsignedImage", Any(xGraphic));
+
+ // Set signature line properties
+ xShapeProps->setPropertyValue("IsSignatureLine", Any(true));
+ xShapeProps->setPropertyValue("SignatureLineId", Any(m_aSignatureLineId));
+ if (!aSignerName.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerName", Any(aSignerName));
+ if (!aSignerTitle.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerTitle", Any(aSignerTitle));
+ if (!aSignerEmail.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSuggestedSignerEmail", Any(aSignerEmail));
+ if (!aSigningInstructions.isEmpty())
+ xShapeProps->setPropertyValue("SignatureLineSigningInstructions",
+ Any(aSigningInstructions));
+ xShapeProps->setPropertyValue("SignatureLineShowSignDate", Any(bShowSignDate));
+ xShapeProps->setPropertyValue("SignatureLineCanAddComment", Any(bCanAddComments));
+
+ if (bIsExistingSignatureLine)
+ return;
+
+ // Default size
+ Reference<XShape> xShape(xShapeProps, UNO_QUERY);
+ awt::Size aShapeSize;
+ aShapeSize.Height = 3000;
+ aShapeSize.Width = 6000;
+ xShape->setSize(aShapeSize);
+
+ // Default anchoring
+ xShapeProps->setPropertyValue("AnchorType", Any(TextContentAnchorType_AT_PARAGRAPH));
+
+ // Writer
+ const Reference<XTextDocument> xTextDocument(m_xModel, UNO_QUERY);
+ if (xTextDocument.is())
+ {
+ Reference<XTextContent> xTextContent(xShape, UNO_QUERY_THROW);
+ Reference<XTextViewCursorSupplier> xViewCursorSupplier(m_xModel->getCurrentController(),
+ UNO_QUERY_THROW);
+ Reference<XTextViewCursor> xCursor = xViewCursorSupplier->getViewCursor();
+ // use cursor's XText - it might be in table cell, frame, ...
+ Reference<XText> const xText(xCursor->getText());
+ assert(xText.is());
+ xText->insertTextContent(xCursor, xTextContent, true);
+ return;
+ }
+
+ // Calc
+ const Reference<XSpreadsheetDocument> xSpreadsheetDocument(m_xModel, UNO_QUERY);
+ if (!xSpreadsheetDocument.is())
+ return;
+
+ Reference<XPropertySet> xSheetCell(m_xModel->getCurrentSelection(), UNO_QUERY_THROW);
+ awt::Point aCellPosition;
+ xSheetCell->getPropertyValue("Position") >>= aCellPosition;
+ xShape->setPosition(aCellPosition);
+
+ Reference<XSpreadsheetView> xView(m_xModel->getCurrentController(), UNO_QUERY_THROW);
+ Reference<XSpreadsheet> xSheet(xView->getActiveSheet(), UNO_SET_THROW);
+ Reference<XDrawPageSupplier> xDrawPageSupplier(xSheet, UNO_QUERY_THROW);
+ Reference<XDrawPage> xDrawPage(xDrawPageSupplier->getDrawPage(), UNO_SET_THROW);
+ Reference<XShapes> xShapes(xDrawPage, UNO_QUERY_THROW);
+
+ xShapes->add(xShape);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SignatureLineDialogBase.cxx b/cui/source/dialogs/SignatureLineDialogBase.cxx
new file mode 100644
index 000000000..4dadbf68e
--- /dev/null
+++ b/cui/source/dialogs/SignatureLineDialogBase.cxx
@@ -0,0 +1,221 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <SignatureLineDialogBase.hxx>
+
+#include <utility>
+#include <vcl/weld.hxx>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::frame;
+
+SignatureLineDialogBase::SignatureLineDialogBase(weld::Widget* pParent, Reference<XModel> xModel,
+ const OUString& rUIFile, const OString& rDialogId)
+ : GenericDialogController(pParent, rUIFile, rDialogId)
+ , m_xModel(std::move(xModel))
+{
+}
+
+short SignatureLineDialogBase::run()
+{
+ short nRet = GenericDialogController::run();
+ if (nRet == RET_OK)
+ Apply();
+ return nRet;
+}
+
+OUString SignatureLineDialogBase::getCDataString(const OUString& rString)
+{
+ return "<![CDATA[" + rString + "]]>";
+}
+
+OUString SignatureLineDialogBase::getSignatureImage()
+{
+ OUString const svg(
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><svg "
+ "xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:cc=\"http://creativecommons.org/ns#\" "
+ "xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" "
+ "xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" "
+ "xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\" "
+ "xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\" version=\"1.2\" "
+ "width=\"90mm\" height=\"45mm\" viewBox=\"0 0 9000 4500\" preserveAspectRatio=\"xMidYMid\" "
+ "fill-rule=\"evenodd\" stroke-width=\"28.222\" stroke-linejoin=\"round\" "
+ "xml:space=\"preserve\" id=\"svg577\" inkscape:version=\"0.92.2 (5c3e80d, "
+ "2017-08-06)\"><metadata id=\"metadata581\"><rdf:RDF><cc:Work "
+ "rdf:about=\"\"><dc:format>image/svg+xml</dc:format><dc:type "
+ "rdf:resource=\"http://purl.org/dc/dcmitype/StillImage\" /><dc:title "
+ "/></cc:Work></rdf:RDF></metadata><sodipodi:namedview pagecolor=\"#ffffff\" "
+ "bordercolor=\"#666666\" borderopacity=\"1\" objecttolerance=\"10\" gridtolerance=\"10\" "
+ "guidetolerance=\"10\" inkscape:pageopacity=\"0\" inkscape:pageshadow=\"2\" "
+ "inkscape:window-width=\"1865\" inkscape:window-height=\"1145\" id=\"namedview579\" "
+ "showgrid=\"false\" inkscape:zoom=\"3.6100926\" inkscape:cx=\"231.72208\" "
+ "inkscape:cy=\"122.80267\" inkscape:window-x=\"55\" inkscape:window-y=\"27\" "
+ "inkscape:window-maximized=\"1\" inkscape:current-layer=\"g575\" "
+ "inkscape:pagecheckerboard=\"false\" /><defs class=\"ClipPathGroup\" "
+ "id=\"defs8\"><clipPath id=\"presentation_clip_path\" "
+ "clipPathUnits=\"userSpaceOnUse\"><rect x=\"0\" y=\"0\" width=\"9000\" height=\"4500\" "
+ "id=\"rect2\" /></clipPath></defs><defs id=\"defs49\" /><defs id=\"defs86\" /><defs "
+ "class=\"TextShapeIndex\" id=\"defs90\" /><defs class=\"EmbeddedBulletChars\" "
+ "id=\"defs122\" /><defs class=\"TextEmbeddedBitmaps\" id=\"defs124\" /><g id=\"g129\"><g "
+ "id=\"id2\" class=\"Master_Slide\"><g id=\"bg-id2\" class=\"Background\" /><g "
+ "id=\"bo-id2\" class=\"BackgroundObjects\" /></g></g><g class=\"SlideGroup\" "
+ "id=\"g575\"><g id=\"g573\"><g id=\"container-id1\"><g id=\"id1\" class=\"Slide\" "
+ "clip-path=\"url(#presentation_clip_path)\"><g class=\"Page\" id=\"g569\"><g "
+ "class=\"com.sun.star.drawing.LineShape\" id=\"g154\"><g id=\"id3\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"-27\" y=\"2373\" width=\"9055\" "
+ "height=\"55\" id=\"rect131\" /><desc id=\"desc133\">150</desc><desc "
+ "id=\"desc135\">139</desc><desc id=\"desc137\">132</desc><desc id=\"desc139\">512: "
+ "XPATHSTROKE_SEQ_BEGIN</desc><desc id=\"desc141\">132</desc><desc "
+ "id=\"desc143\">133</desc><desc id=\"desc145\">109</desc><path fill=\"none\" "
+ "stroke=\"rgb(0,0,0)\" stroke-width=\"53\" stroke-linejoin=\"round\" d=\"M 0,2400 L "
+ "9000,2400\" id=\"path147\" /><desc id=\"desc149\">512: XPATHSTROKE_SEQ_END</desc><desc "
+ "id=\"desc151\">140</desc></g></g><g class=\"com.sun.star.drawing.ClosedBezierShape\" "
+ "id=\"g173\"><g id=\"id4\"><rect class=\"BoundingBox\" stroke=\"none\" fill=\"none\" "
+ "x=\"301\" y=\"1400\" width=\"801\" height=\"801\" id=\"rect156\" /><desc "
+ "id=\"desc158\">150</desc><desc id=\"desc160\">139</desc><desc "
+ "id=\"desc162\">133</desc><desc id=\"desc164\">132</desc><desc "
+ "id=\"desc166\">111</desc><path fill=\"rgb(0,0,0)\" stroke=\"none\" d=\"M 969,2200 C "
+ "880,2083 792,1967 704,1850 614,1967 523,2083 433,2200 389,2200 345,2200 301,2200 413,2061 "
+ "525,1923 637,1784 533,1656 430,1528 327,1400 371,1400 415,1400 459,1400 541,1505 623,1609 "
+ "704,1714 784,1609 863,1505 943,1400 987,1400 1031,1400 1075,1400 975,1527 874,1653 "
+ "773,1780 882,1920 992,2060 1101,2200 1057,2200 1013,2200 969,2200 Z\" id=\"path168\" "
+ "/><desc id=\"desc170\">140</desc></g></g><g class=\"com.sun.star.drawing.TextShape\" "
+ "id=\"g236\"><g id=\"id5\"><rect class=\"BoundingBox\" stroke=\"none\" fill=\"none\" "
+ "x=\"1300\" y=\"1500\" width=\"8001\" height=\"925\" id=\"rect175\" /><desc "
+ "id=\"desc177\">150</desc><desc id=\"desc179\">512: XTEXT_PAINTSHAPE_BEGIN</desc><text "
+ "class=\"TextShape\" id=\"text233\"><desc class=\"Paragraph\" id=\"desc181\" /><tspan "
+ "class=\"TextParagraph\" font-family=\"Liberation Sans, sans-serif\" font-size=\"600px\" "
+ "font-weight=\"400\" id=\"tspan231\"><desc id=\"desc183\">138</desc><desc "
+ "id=\"desc185\">136</desc><desc id=\"desc187\">135</desc><desc "
+ "id=\"desc189\">134</desc><desc id=\"desc191\">113</desc><desc class=\"TextPortion\" "
+ "id=\"desc193\">type: Text; content: [SIGNATURE]; </desc><tspan class=\"TextPosition\" "
+ "x=\"1550\" y=\"2171\" id=\"tspan229\"><tspan fill=\"rgb(0,0,0)\" stroke=\"none\" "
+ "id=\"tspan195\">[SIGNATURE]</tspan><desc id=\"desc197\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc199\">512: XTEXT_EOC</desc><desc id=\"desc201\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc203\">512: XTEXT_EOC</desc><desc id=\"desc205\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc207\">512: XTEXT_EOC</desc><desc id=\"desc209\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc211\">512: XTEXT_EOC</desc><desc id=\"desc213\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc215\">512: XTEXT_EOC</desc><desc id=\"desc217\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc219\">512: XTEXT_EOC</desc><desc id=\"desc221\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc223\">512: XTEXT_EOL</desc><desc id=\"desc225\">512: XTEXT_EOP</desc><desc "
+ "id=\"desc227\">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g "
+ "class=\"com.sun.star.drawing.TextShape\" id=\"g303\"><g id=\"id6\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"100\" y=\"2500\" width=\"8901\" "
+ "height=\"726\" id=\"rect238\" /><desc id=\"desc240\">150</desc><desc id=\"desc242\">512: "
+ "XTEXT_PAINTSHAPE_BEGIN</desc><text class=\"TextShape\" id=\"text300\"><desc "
+ "class=\"Paragraph\" id=\"desc244\" /><tspan class=\"TextParagraph\" "
+ "font-family=\"Liberation Sans, sans-serif\" font-size=\"423px\" font-weight=\"400\" "
+ "id=\"tspan298\"><desc id=\"desc246\">138</desc><desc id=\"desc248\">136</desc><desc "
+ "id=\"desc250\">135</desc><desc id=\"desc252\">134</desc><desc "
+ "id=\"desc254\">113</desc><desc class=\"TextPortion\" id=\"desc256\">type: Text; content: "
+ "[SIGNER_NAME]; </desc><tspan class=\"TextPosition\" x=\"350\" y=\"3010\" "
+ "id=\"tspan296\"><tspan fill=\"rgb(0,0,0)\" stroke=\"none\" "
+ "id=\"tspan258\">[SIGNER_NAME]</tspan><desc id=\"desc260\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc262\">512: XTEXT_EOC</desc><desc id=\"desc264\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc266\">512: XTEXT_EOC</desc><desc id=\"desc268\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc270\">512: XTEXT_EOC</desc><desc id=\"desc272\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc274\">512: XTEXT_EOC</desc><desc id=\"desc276\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc278\">512: XTEXT_EOC</desc><desc id=\"desc280\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc282\">512: XTEXT_EOC</desc><desc id=\"desc284\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc286\">512: XTEXT_EOC</desc><desc id=\"desc288\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc290\">512: XTEXT_EOL</desc><desc id=\"desc292\">512: XTEXT_EOP</desc><desc "
+ "id=\"desc294\">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g "
+ "class=\"com.sun.star.drawing.TextShape\" id=\"g372\"><g id=\"id7\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"100\" y=\"3075\" width=\"8901\" "
+ "height=\"726\" id=\"rect305\" /><desc id=\"desc307\">150</desc><desc id=\"desc309\">512: "
+ "XTEXT_PAINTSHAPE_BEGIN</desc><text class=\"TextShape\" id=\"text369\"><desc "
+ "class=\"Paragraph\" id=\"desc311\" /><tspan class=\"TextParagraph\" "
+ "font-family=\"Liberation Sans, sans-serif\" font-size=\"423px\" font-weight=\"400\" "
+ "id=\"tspan367\"><desc id=\"desc313\">138</desc><desc id=\"desc315\">136</desc><desc "
+ "id=\"desc317\">135</desc><desc id=\"desc319\">134</desc><desc "
+ "id=\"desc321\">113</desc><desc class=\"TextPortion\" id=\"desc323\">type: Text; content: "
+ "[SIGNER_TITLE]; </desc><tspan class=\"TextPosition\" x=\"350\" y=\"3585\" "
+ "id=\"tspan365\"><tspan fill=\"rgb(0,0,0)\" stroke=\"none\" "
+ "id=\"tspan325\">[SIGNER_TITLE]</tspan><desc id=\"desc327\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc329\">512: XTEXT_EOC</desc><desc id=\"desc331\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc333\">512: XTEXT_EOC</desc><desc id=\"desc335\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc337\">512: XTEXT_EOC</desc><desc id=\"desc339\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc341\">512: XTEXT_EOC</desc><desc id=\"desc343\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc345\">512: XTEXT_EOC</desc><desc id=\"desc347\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc349\">512: XTEXT_EOC</desc><desc id=\"desc351\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc353\">512: XTEXT_EOC</desc><desc id=\"desc355\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc357\">512: XTEXT_EOW</desc><desc id=\"desc359\">512: XTEXT_EOL</desc><desc "
+ "id=\"desc361\">512: XTEXT_EOP</desc><desc id=\"desc363\">512: "
+ "XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g "
+ "class=\"com.sun.star.drawing.TextShape\" id=\"g435\"><g id=\"id8\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"100\" y=\"3660\" width=\"8901\" "
+ "height=\"726\" id=\"rect374\" /><desc id=\"desc376\">150</desc><desc id=\"desc378\">512: "
+ "XTEXT_PAINTSHAPE_BEGIN</desc><text class=\"TextShape\" id=\"text432\"><desc "
+ "class=\"Paragraph\" id=\"desc380\" /><tspan class=\"TextParagraph\" "
+ "font-family=\"Liberation Sans, sans-serif\" font-size=\"423px\" font-weight=\"400\" "
+ "id=\"tspan430\"><desc id=\"desc382\">138</desc><desc id=\"desc384\">136</desc><desc "
+ "id=\"desc386\">135</desc><desc id=\"desc388\">134</desc><desc "
+ "id=\"desc390\">113</desc><desc class=\"TextPortion\" id=\"desc392\">type: Text; content: "
+ "[SIGNED_BY]; </desc><tspan class=\"TextPosition\" x=\"350\" y=\"4170\" "
+ "id=\"tspan428\"><tspan fill=\"rgb(0,0,0)\" stroke=\"none\" "
+ "id=\"tspan394\">[SIGNED_BY]</tspan><desc id=\"desc396\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc398\">512: XTEXT_EOC</desc><desc id=\"desc400\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc402\">512: XTEXT_EOC</desc><desc id=\"desc404\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc406\">512: XTEXT_EOC</desc><desc id=\"desc408\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc410\">512: XTEXT_EOC</desc><desc id=\"desc412\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc414\">512: XTEXT_EOC</desc><desc id=\"desc416\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc418\">512: XTEXT_EOC</desc><desc id=\"desc420\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc422\">512: XTEXT_EOL</desc><desc id=\"desc424\">512: XTEXT_EOP</desc><desc "
+ "id=\"desc426\">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g "
+ "class=\"com.sun.star.drawing.TextShape\" id=\"g488\"><g id=\"id9\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"4800\" y=\"0\" width=\"4201\" "
+ "height=\"726\" id=\"rect437\" /><desc id=\"desc439\">150</desc><desc id=\"desc441\">512: "
+ "XTEXT_PAINTSHAPE_BEGIN</desc><text class=\"TextShape\" id=\"text485\" x=\"2648.345\" "
+ "y=\"0\" style=\"text-align:end;text-anchor:end\"><desc class=\"Paragraph\" id=\"desc443\" "
+ "/><tspan class=\"TextParagraph\" font-size=\"423px\" font-weight=\"400\" id=\"tspan483\" "
+ "style=\"font-weight:400;font-size:423px;font-family:'Liberation Sans', "
+ "sans-serif;text-align:end;text-anchor:end\"><desc id=\"desc445\">138</desc><desc "
+ "id=\"desc447\">136</desc><desc id=\"desc449\">135</desc><desc "
+ "id=\"desc451\">134</desc><desc id=\"desc453\">113</desc><desc class=\"TextPortion\" "
+ "id=\"desc455\">type: Text; content: [DATE]; </desc><tspan class=\"TextPosition\" "
+ "x=\"8792.835\" y=\"510\" id=\"tspan481\" style=\"text-align:end;text-anchor:end\"><tspan "
+ "id=\"tspan457\" "
+ "style=\"text-align:end;text-anchor:end;fill:#000000;stroke:none\">[DATE]</tspan><desc "
+ "id=\"desc459\">512: XTEXT_EOC</desc><desc id=\"desc461\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc463\">512: XTEXT_EOW</desc><desc id=\"desc465\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc467\">512: XTEXT_EOC</desc><desc id=\"desc469\">512: XTEXT_EOC</desc><desc "
+ "id=\"desc471\">512: XTEXT_EOC</desc><desc id=\"desc473\">512: XTEXT_EOW</desc><desc "
+ "id=\"desc475\">512: XTEXT_EOL</desc><desc id=\"desc477\">512: XTEXT_EOP</desc><desc "
+ "id=\"desc479\">512: XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g><g "
+ "class=\"com.sun.star.drawing.TextShape\" id=\"g567\"><g id=\"id10\"><rect "
+ "class=\"BoundingBox\" stroke=\"none\" fill=\"none\" x=\"0\" y=\"1\" width=\"9001\" "
+ "height=\"726\" id=\"rect490\" /><desc id=\"desc492\">150</desc><desc id=\"desc494\">512: "
+ "XTEXT_PAINTSHAPE_BEGIN</desc><text class=\"TextShape\" id=\"text564\"><desc "
+ "class=\"Paragraph\" id=\"desc496\" /><tspan class=\"TextParagraph\" "
+ "font-family=\"Liberation Sans, sans-serif\" font-size=\"423px\" font-weight=\"700\" "
+ "id=\"tspan562\"><desc id=\"desc498\">138</desc><desc id=\"desc500\">136</desc><desc "
+ "id=\"desc502\">135</desc><desc id=\"desc504\">134</desc><desc "
+ "id=\"desc506\">113</desc><desc class=\"TextPortion\" id=\"desc508\">type: Text; content: "
+ "[INVALID_SIGNATURE]; </desc><tspan class=\"TextPosition\" x=\"2180\" y=\"511\" "
+ "id=\"tspan560\"><tspan fill=\"rgb(239,65,61)\" stroke=\"none\" "
+ "id=\"tspan510\">[INVALID_SIGNATURE]</tspan><desc id=\"desc512\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc514\">512: XTEXT_EOC</desc><desc id=\"desc516\">512: "
+ "XTEXT_EOW</desc><desc id=\"desc518\">512: XTEXT_EOC</desc><desc id=\"desc520\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc522\">512: XTEXT_EOC</desc><desc id=\"desc524\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc526\">512: XTEXT_EOC</desc><desc id=\"desc528\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc530\">512: XTEXT_EOC</desc><desc id=\"desc532\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc534\">512: XTEXT_EOC</desc><desc id=\"desc536\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc538\">512: XTEXT_EOC</desc><desc id=\"desc540\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc542\">512: XTEXT_EOC</desc><desc id=\"desc544\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc546\">512: XTEXT_EOC</desc><desc id=\"desc548\">512: "
+ "XTEXT_EOC</desc><desc id=\"desc550\">512: XTEXT_EOC</desc><desc id=\"desc552\">512: "
+ "XTEXT_EOW</desc><desc id=\"desc554\">512: XTEXT_EOL</desc><desc id=\"desc556\">512: "
+ "XTEXT_EOP</desc><desc id=\"desc558\">512: "
+ "XTEXT_PAINTSHAPE_END</desc></tspan></tspan></text></g></g></g></g></g></"
+ "g>[SIGNATURE_IMAGE]</g></svg>");
+ return svg;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/dialogs/SpellAttrib.hxx b/cui/source/dialogs/SpellAttrib.hxx
new file mode 100644
index 000000000..c086fe3d0
--- /dev/null
+++ b/cui/source/dialogs/SpellAttrib.hxx
@@ -0,0 +1,118 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
+
+namespace svx{
+struct SpellErrorDescription
+{
+ bool bIsGrammarError;
+ OUString sErrorText;
+ OUString sDialogTitle;
+ OUString sExplanation;
+ OUString sExplanationURL;
+ css::lang::Locale aLocale;
+ css::uno::Reference< css::linguistic2::XProofreader > xGrammarChecker;
+ css::uno::Sequence< OUString > aSuggestions;
+ OUString sRuleId;
+
+ SpellErrorDescription( bool bGrammar,
+ const OUString& rText,
+ const css::lang::Locale& rLocale,
+ const css::uno::Sequence< OUString >& rSuggestions,
+ css::uno::Reference< css::linguistic2::XProofreader > const & rxGrammarChecker,
+ const OUString* pDialogTitle = nullptr,
+ const OUString* pExplanation = nullptr,
+ const OUString* pRuleId = nullptr,
+ const OUString* pExplanationURL = nullptr ) :
+ bIsGrammarError( bGrammar ),
+ sErrorText( rText ),
+ sDialogTitle( ),
+ sExplanation( ),
+ sExplanationURL( ),
+ aLocale( rLocale ),
+ xGrammarChecker( rxGrammarChecker ),
+ aSuggestions( rSuggestions )
+ {
+ if( pDialogTitle )
+ sDialogTitle = *pDialogTitle;
+ if( pExplanation )
+ sExplanation = *pExplanation;
+ if( pExplanationURL )
+ sExplanationURL = *pExplanationURL;
+ if( pRuleId )
+ sRuleId = *pRuleId;
+ };
+
+ SpellErrorDescription()
+ : bIsGrammarError(false)
+ {
+ }
+
+ bool operator==( const SpellErrorDescription& rDesc ) const
+ {
+ return bIsGrammarError == rDesc.bIsGrammarError &&
+ sErrorText == rDesc.sErrorText &&
+ aLocale.Language == rDesc.aLocale.Language &&
+ aLocale.Country == rDesc.aLocale.Country &&
+ aLocale.Variant == rDesc.aLocale.Variant &&
+ aSuggestions == rDesc.aSuggestions &&
+ xGrammarChecker == rDesc.xGrammarChecker &&
+ sDialogTitle == rDesc.sDialogTitle &&
+ sExplanation == rDesc.sExplanation &&
+ sExplanationURL == rDesc.sExplanationURL &&
+ sRuleId == rDesc.sRuleId;
+ }
+
+ css::uno::Sequence<css::uno::Any> toSequence() const
+ {
+ css::uno::Sequence<css::uno::Any> aEntries(9);
+ aEntries[0] <<= bIsGrammarError;
+ aEntries[1] <<= sErrorText;
+ aEntries[2] <<= sDialogTitle;
+ aEntries[3] <<= sExplanation;
+ aEntries[4] <<= sExplanationURL;
+ aEntries[5] <<= aLocale;
+ aEntries[6] <<= xGrammarChecker;
+ aEntries[7] <<= aSuggestions;
+ aEntries[8] <<= sRuleId;
+ return aEntries;
+ }
+
+ void fromSequence(const css::uno::Sequence<css::uno::Any>& rEntries)
+ {
+ rEntries[0] >>= bIsGrammarError;
+ rEntries[1] >>= sErrorText;
+ rEntries[2] >>= sDialogTitle;
+ rEntries[3] >>= sExplanation;
+ rEntries[4] >>= sExplanationURL;
+ rEntries[5] >>= aLocale;
+ rEntries[6] >>= xGrammarChecker;
+ rEntries[7] >>= aSuggestions;
+ rEntries[8] >>= sRuleId;
+ }
+};
+
+}//namespace svx
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/SpellDialog.cxx b/cui/source/dialogs/SpellDialog.cxx
new file mode 100644
index 000000000..b3b66d9e6
--- /dev/null
+++ b/cui/source/dialogs/SpellDialog.cxx
@@ -0,0 +1,2092 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include "SpellAttrib.hxx"
+#include <sfx2/bindings.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/viewfrm.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/undo.hxx>
+#include <tools/debug.hxx>
+#include <unotools/lingucfg.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/eeitem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/splwrap.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/wghtitem.hxx>
+#include <linguistic/misc.hxx>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSpellAlternatives.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
+#include <sfx2/app.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <vcl/specialchars.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/texteng.hxx>
+#include <vcl/weld.hxx>
+#include <svx/SpellDialogChildWindow.hxx>
+#include <SpellDialog.hxx>
+#include <optlingu.hxx>
+#include <treeopt.hxx>
+#include <svtools/langtab.hxx>
+#include <sal/log.hxx>
+#include <i18nlangtag/languagetag.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::linguistic2;
+using namespace linguistic;
+
+
+// struct SpellDialog_Impl ---------------------------------------------
+
+struct SpellDialog_Impl
+{
+ Sequence< Reference< XDictionary > > aDics;
+};
+
+
+#define SPELLUNDO_START 200
+
+#define SPELLUNDO_CHANGE_LANGUAGE (SPELLUNDO_START + 1)
+#define SPELLUNDO_CHANGE_TEXTENGINE (SPELLUNDO_START + 2)
+#define SPELLUNDO_CHANGE_NEXTERROR (SPELLUNDO_START + 3)
+#define SPELLUNDO_CHANGE_ADD_TO_DICTIONARY (SPELLUNDO_START + 4)
+#define SPELLUNDO_CHANGE_GROUP (SPELLUNDO_START + 5) //undo list
+#define SPELLUNDO_MOVE_ERROREND (SPELLUNDO_START + 6)
+#define SPELLUNDO_UNDO_EDIT_MODE (SPELLUNDO_START + 7)
+#define SPELLUNDO_ADD_IGNORE_RULE (SPELLUNDO_START + 8)
+
+namespace svx{
+class SpellUndoAction_Impl : public SfxUndoAction
+{
+ sal_uInt16 m_nId;
+ const Link<SpellUndoAction_Impl&,void>& m_rActionLink;
+ //undo of button enabling
+ bool m_bEnableChangePB;
+ bool m_bEnableChangeAllPB;
+ //undo of MarkNextError - used in change and change all, ignore and ignore all
+ long m_nOldErrorStart;
+ long m_nOldErrorEnd;
+ bool m_bIsErrorLanguageSelected;
+ //undo of AddToDictionary
+ Reference<XDictionary> m_xDictionary;
+ OUString m_sAddedWord;
+ //move end of error - ::ChangeMarkedWord()
+ long m_nOffset;
+
+public:
+ SpellUndoAction_Impl(sal_uInt16 nId, const Link<SpellUndoAction_Impl&,void>& rActionLink) :
+ m_nId(nId),
+ m_rActionLink( rActionLink),
+ m_bEnableChangePB(false),
+ m_bEnableChangeAllPB(false),
+ m_nOldErrorStart(-1),
+ m_nOldErrorEnd(-1),
+ m_bIsErrorLanguageSelected(false),
+ m_nOffset(0)
+ {}
+
+ virtual void Undo() override;
+ sal_uInt16 GetId() const;
+
+ void SetEnableChangePB(){m_bEnableChangePB = true;}
+ bool IsEnableChangePB() const {return m_bEnableChangePB;}
+
+ void SetEnableChangeAllPB(){m_bEnableChangeAllPB = true;}
+ bool IsEnableChangeAllPB() const {return m_bEnableChangeAllPB;}
+
+ void SetErrorMove(long nOldStart, long nOldEnd)
+ {
+ m_nOldErrorStart = nOldStart;
+ m_nOldErrorEnd = nOldEnd;
+ }
+ long GetOldErrorStart() const { return m_nOldErrorStart;}
+ long GetOldErrorEnd() const { return m_nOldErrorEnd;}
+
+ void SetErrorLanguageSelected(bool bSet){ m_bIsErrorLanguageSelected = bSet;}
+ bool IsErrorLanguageSelected() const {return m_bIsErrorLanguageSelected;}
+
+ void SetDictionary(const Reference<XDictionary>& xDict) { m_xDictionary = xDict; }
+ const Reference<XDictionary>& GetDictionary() const { return m_xDictionary; }
+ void SetAddedWord(const OUString& rWord) {m_sAddedWord = rWord;}
+ const OUString& GetAddedWord() const { return m_sAddedWord;}
+
+ void SetOffset(long nSet) {m_nOffset = nSet;}
+ long GetOffset() const {return m_nOffset;}
+};
+}//namespace svx
+using namespace ::svx;
+
+void SpellUndoAction_Impl::Undo()
+{
+ m_rActionLink.Call(*this);
+}
+
+
+sal_uInt16 SpellUndoAction_Impl::GetId()const
+{
+ return m_nId;
+}
+
+// class SvxSpellCheckDialog ---------------------------------------------
+
+SpellDialog::SpellDialog(SpellDialogChildWindow* pChildWindow,
+ weld::Window * pParent, SfxBindings* _pBindings)
+ : SfxModelessDialogController (_pBindings, pChildWindow,
+ pParent, "cui/ui/spellingdialog.ui", "SpellingDialog")
+ , aDialogUndoLink(LINK (this, SpellDialog, DialogUndoHdl))
+ , bFocusLocked(true)
+ , rParent(*pChildWindow)
+ , pImpl( new SpellDialog_Impl )
+ , m_xAltTitle(m_xBuilder->weld_label("alttitleft"))
+ , m_xResumeFT(m_xBuilder->weld_label("resumeft"))
+ , m_xNoSuggestionsFT(m_xBuilder->weld_label("nosuggestionsft"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+ , m_xExplainFT(m_xBuilder->weld_label("explain"))
+ , m_xExplainLink(m_xBuilder->weld_link_button("explainlink"))
+ , m_xNotInDictFT(m_xBuilder->weld_label("notindictft"))
+ , m_xSentenceED(new SentenceEditWindow_Impl)
+ , m_xSuggestionFT(m_xBuilder->weld_label("suggestionsft"))
+ , m_xSuggestionLB(m_xBuilder->weld_tree_view("suggestionslb"))
+ , m_xIgnorePB(m_xBuilder->weld_button("ignore"))
+ , m_xIgnoreAllPB(m_xBuilder->weld_button("ignoreall"))
+ , m_xIgnoreRulePB(m_xBuilder->weld_button("ignorerule"))
+ , m_xAddToDictPB(m_xBuilder->weld_button("add"))
+ , m_xAddToDictMB(m_xBuilder->weld_menu_button("addmb"))
+ , m_xChangePB(m_xBuilder->weld_button("change"))
+ , m_xChangeAllPB(m_xBuilder->weld_button("changeall"))
+ , m_xAutoCorrPB(m_xBuilder->weld_button("autocorrect"))
+ , m_xCheckGrammarCB(m_xBuilder->weld_check_button("checkgrammar"))
+ , m_xOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xUndoPB(m_xBuilder->weld_button("undo"))
+ , m_xClosePB(m_xBuilder->weld_button("close"))
+ , m_xToolbar(m_xBuilder->weld_toolbar("toolbar"))
+ , m_xSentenceEDWeld(new weld::CustomWeld(*m_xBuilder, "sentence", *m_xSentenceED))
+{
+ m_xSentenceED->SetSpellDialog(this);
+ m_xSentenceED->Init(m_xToolbar.get());
+
+ m_sTitleSpellingGrammar = m_xDialog->get_title();
+ m_sTitleSpelling = m_xAltTitle->get_label();
+
+ // fdo#68794 set initial title for cases where no text has been processed
+ // yet to show its language attributes
+ OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle.replaceFirst("$LANGUAGE ($LOCATION)", "")));
+
+ m_sResumeST = m_xResumeFT->get_label();
+ m_sNoSuggestionsST = m_xNoSuggestionsFT->strip_mnemonic(m_xNoSuggestionsFT->get_label());
+
+ Size aEdSize(m_xSuggestionLB->get_approximate_digit_width() * 60,
+ m_xSuggestionLB->get_height_rows(6));
+ m_xSuggestionLB->set_size_request(aEdSize.Width(), -1);
+ m_sIgnoreOnceST = m_xIgnorePB->get_label();
+ m_xAddToDictMB->set_help_id(m_xAddToDictPB->get_help_id());
+ xSpell = LinguMgr::GetSpellChecker();
+
+ Init_Impl();
+
+ // disable controls if service is missing
+ m_xDialog->set_sensitive(xSpell.is());
+
+ //InitHdl wants to use virtual methods, so it
+ //can't be called during the ctor, so init
+ //it on next event cycle post-ctor
+ Application::PostUserEvent(LINK(this, SpellDialog, InitHdl));
+}
+
+SpellDialog::~SpellDialog()
+{
+ if (pImpl)
+ {
+ // save possibly modified user-dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ SaveDictionaries( xDicList );
+
+ pImpl.reset();
+ }
+}
+
+void SpellDialog::Init_Impl()
+{
+ // initialize handler
+ m_xClosePB->connect_clicked(LINK( this, SpellDialog, CancelHdl ) );
+ m_xChangePB->connect_clicked(LINK( this, SpellDialog, ChangeHdl ) );
+ m_xChangeAllPB->connect_clicked(LINK( this, SpellDialog, ChangeAllHdl ) );
+ m_xIgnorePB->connect_clicked(LINK( this, SpellDialog, IgnoreHdl ) );
+ m_xIgnoreAllPB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+ m_xIgnoreRulePB->connect_clicked(LINK( this, SpellDialog, IgnoreAllHdl ) );
+ m_xUndoPB->connect_clicked(LINK( this, SpellDialog, UndoHdl ) );
+
+ m_xAutoCorrPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
+ m_xCheckGrammarCB->connect_clicked( LINK( this, SpellDialog, CheckGrammarHdl ));
+ m_xOptionsPB->connect_clicked( LINK( this, SpellDialog, ExtClickHdl ) );
+
+ m_xSuggestionLB->connect_row_activated( LINK( this, SpellDialog, DoubleClickChangeHdl ) );
+
+ m_xSentenceED->SetModifyHdl(LINK ( this, SpellDialog, ModifyHdl) );
+
+ m_xAddToDictMB->connect_selected(LINK ( this, SpellDialog, AddToDictSelectHdl ) );
+ m_xAddToDictPB->connect_clicked(LINK ( this, SpellDialog, AddToDictClickHdl ) );
+
+ m_xLanguageLB->connect_changed(LINK( this, SpellDialog, LanguageSelectHdl ) );
+
+ // initialize language ListBox
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::SPELL_USED, false, false, true);
+
+ m_xSentenceED->ClearModifyFlag();
+ LinguMgr::GetChangeAllList()->clear();
+}
+
+void SpellDialog::UpdateBoxes_Impl(bool bCallFromSelectHdl)
+{
+ sal_Int32 i;
+ m_xSuggestionLB->clear();
+
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+
+ LanguageType nAltLanguage = LANGUAGE_NONE;
+ Sequence< OUString > aNewWords;
+ bool bIsGrammarError = false;
+ if( bSpellErrorDescription )
+ {
+ nAltLanguage = LanguageTag::convertToLanguageType( aSpellErrorDescription.aLocale );
+ aNewWords = aSpellErrorDescription.aSuggestions;
+ bIsGrammarError = aSpellErrorDescription.bIsGrammarError;
+ m_xExplainLink->set_uri( aSpellErrorDescription.sExplanationURL );
+ m_xExplainFT->set_label( aSpellErrorDescription.sExplanation );
+ }
+ if( bSpellErrorDescription && !aSpellErrorDescription.sDialogTitle.isEmpty() )
+ {
+ // use this function to apply the correct image to be used...
+ SetTitle_Impl( nAltLanguage );
+ // then change the title to the one to be actually used
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(aSpellErrorDescription.sDialogTitle));
+ }
+ else
+ SetTitle_Impl( nAltLanguage );
+ if( !bCallFromSelectHdl )
+ m_xLanguageLB->set_active_id( nAltLanguage );
+ int nDicts = InitUserDicts();
+
+ // enter alternatives
+ const OUString *pNewWords = aNewWords.getConstArray();
+ const sal_Int32 nSize = aNewWords.getLength();
+ for ( i = 0; i < nSize; ++i )
+ {
+ OUString aTmp( pNewWords[i] );
+ if (m_xSuggestionLB->find_text(aTmp) == -1)
+ m_xSuggestionLB->append_text(aTmp);
+ }
+ if(!nSize)
+ m_xSuggestionLB->append_text(m_sNoSuggestionsST);
+ m_xAutoCorrPB->set_sensitive( nSize > 0 );
+
+ m_xSuggestionFT->set_sensitive(nSize > 0);
+ m_xSuggestionLB->set_sensitive(nSize > 0);
+ if( nSize )
+ {
+ m_xSuggestionLB->select(0);
+ }
+ m_xChangePB->set_sensitive( nSize > 0);
+ m_xChangeAllPB->set_sensitive(nSize > 0);
+ bool bShowChangeAll = !bIsGrammarError;
+ m_xChangeAllPB->set_visible( bShowChangeAll );
+ m_xExplainFT->set_visible( !bShowChangeAll );
+ m_xLanguageLB->set_sensitive( bShowChangeAll );
+ m_xIgnoreAllPB->set_visible( bShowChangeAll );
+
+ m_xAddToDictMB->set_visible( bShowChangeAll && nDicts > 1);
+ m_xAddToDictPB->set_visible( bShowChangeAll && nDicts <= 1);
+ m_xIgnoreRulePB->set_visible( !bShowChangeAll );
+ m_xIgnoreRulePB->set_sensitive(bSpellErrorDescription && !aSpellErrorDescription.sRuleId.isEmpty());
+ m_xAutoCorrPB->set_visible( bShowChangeAll && rParent.HasAutoCorrection() );
+
+ bool bOldShowGrammar = m_xCheckGrammarCB->get_visible();
+ bool bOldShowExplain = m_xExplainLink->get_visible();
+
+ m_xCheckGrammarCB->set_visible(rParent.HasGrammarChecking());
+ m_xExplainLink->set_visible(!m_xExplainLink->get_uri().isEmpty());
+ if (m_xExplainFT->get_label().isEmpty())
+ {
+ m_xExplainFT->hide();
+ m_xExplainLink->hide();
+ }
+
+ if (bOldShowExplain != m_xExplainLink->get_visible() || bOldShowGrammar != m_xCheckGrammarCB->get_visible())
+ m_xDialog->resize_to_request();
+}
+
+void SpellDialog::SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bIgnoreCurrentError)
+{
+ //initially or after the last error of a sentence MarkNextError will fail
+ //then GetNextSentence() has to be called followed again by MarkNextError()
+ //MarkNextError is not initially called if the UndoEdit mode is active
+ bool bNextSentence = false;
+ if(!((!m_xSentenceED->IsUndoEditMode() && m_xSentenceED->MarkNextError( bIgnoreCurrentError, xSpell )) ||
+ ( bNextSentence = GetNextSentence_Impl(pGuard, bUseSavedSentence, m_xSentenceED->IsUndoEditMode()) && m_xSentenceED->MarkNextError( false, xSpell ))))
+ return;
+
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ if (bSpellErrorDescription)
+ {
+ UpdateBoxes_Impl();
+ weld::Widget* aControls[] =
+ {
+ m_xNotInDictFT.get(),
+ m_xSentenceED->GetDrawingArea(),
+ m_xLanguageFT.get(),
+ nullptr
+ };
+ sal_Int32 nIdx = 0;
+ do
+ {
+ aControls[nIdx]->set_sensitive(true);
+ }
+ while(aControls[++nIdx]);
+
+ }
+ if( bNextSentence )
+ {
+ //remove undo if a new sentence is active
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+ }
+}
+/* Initialize, asynchronous to prevent virtual calls
+ from a constructor
+ */
+IMPL_LINK_NOARG( SpellDialog, InitHdl, void*, void)
+{
+ m_xDialog->freeze();
+ //show or hide AutoCorrect depending on the modules abilities
+ m_xAutoCorrPB->set_visible(rParent.HasAutoCorrection());
+ SpellContinue_Impl(nullptr);
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+
+ // get current language
+ UpdateBoxes_Impl();
+
+ // fill dictionary PopupMenu
+ InitUserDicts();
+
+ LockFocusChanges(true);
+ if( m_xChangePB->get_sensitive() )
+ m_xChangePB->grab_focus();
+ else if( m_xIgnorePB->get_sensitive() )
+ m_xIgnorePB->grab_focus();
+ else if( m_xClosePB->get_sensitive() )
+ m_xClosePB->grab_focus();
+ LockFocusChanges(false);
+ //show grammar CheckBox depending on the modules abilities
+ m_xCheckGrammarCB->set_active(rParent.IsGrammarChecking());
+ m_xDialog->thaw();
+};
+
+IMPL_LINK( SpellDialog, ExtClickHdl, weld::Button&, rBtn, void )
+{
+ if (m_xOptionsPB.get() == &rBtn)
+ StartSpellOptDlg_Impl();
+ else if (m_xAutoCorrPB.get() == &rBtn)
+ {
+ //get the currently selected wrong word
+ OUString sCurrentErrorText = m_xSentenceED->GetErrorText();
+ //get the wrong word from the XSpellAlternative
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ if (bSpellErrorDescription)
+ {
+ OUString sWrong(aSpellErrorDescription.sErrorText);
+ //if the word has not been edited in the MultiLineEdit then
+ //the current suggestion should be used
+ //if it's not the 'no suggestions' entry
+ if(sWrong == sCurrentErrorText &&
+ m_xSuggestionLB->get_sensitive() && m_xSuggestionLB->get_selected_index() != -1 &&
+ m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
+ {
+ sCurrentErrorText = m_xSuggestionLB->get_selected_text();
+ }
+ if(sWrong != sCurrentErrorText)
+ {
+ SvxPrepareAutoCorrect( sWrong, sCurrentErrorText );
+ LanguageType eLang = GetSelectedLang_Impl();
+ rParent.AddAutoCorrection( sWrong, sCurrentErrorText, eLang );
+ }
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SpellDialog, CheckGrammarHdl, weld::Button&, void)
+{
+ rParent.SetGrammarChecking(m_xCheckGrammarCB->get_active());
+ Impl_Restore(true);
+}
+
+void SpellDialog::StartSpellOptDlg_Impl()
+{
+ SfxItemSet aSet( SfxGetpApp()->GetPool(), svl::Items<SID_AUTOSPELL_CHECK,SID_AUTOSPELL_CHECK>{});
+ SfxSingleTabDialogController aDlg(m_xDialog.get(), &aSet, "cui/ui/spelloptionsdialog.ui", "SpellOptionsDialog");
+
+ std::unique_ptr<SfxTabPage> xPage = SvxLinguTabPage::Create(aDlg.get_content_area(), &aDlg, &aSet);
+ static_cast<SvxLinguTabPage*>(xPage.get())->HideGroups( GROUP_MODULES );
+ aDlg.SetTabPage(std::move(xPage));
+ if (RET_OK == aDlg.run())
+ {
+ InitUserDicts();
+ const SfxItemSet* pOutSet = aDlg.GetOutputItemSet();
+ if(pOutSet)
+ OfaTreeOptionsDialog::ApplyLanguageOptions(*pOutSet);
+ }
+}
+
+namespace
+{
+ OUString getDotReplacementString(const OUString &rErrorText, const OUString &rSuggestedReplacement)
+ {
+ OUString aString = rErrorText;
+
+ //dots are sometimes part of the spelled word but they are not necessarily part of the replacement
+ bool bDot = aString.endsWith(".");
+
+ aString = rSuggestedReplacement;
+
+ if(bDot && (aString.isEmpty() || !aString.endsWith(".")))
+ aString += ".";
+
+ return aString;
+ }
+}
+
+OUString SpellDialog::getReplacementString() const
+{
+ OUString sOrigString = m_xSentenceED->GetErrorText();
+
+ OUString sReplacement(sOrigString);
+
+ if(m_xSuggestionLB->get_sensitive() &&
+ m_xSuggestionLB->get_selected_index() != -1 &&
+ m_sNoSuggestionsST != m_xSuggestionLB->get_selected_text())
+ sReplacement = m_xSuggestionLB->get_selected_text();
+
+ return getDotReplacementString(sOrigString, sReplacement);
+}
+
+IMPL_LINK_NOARG(SpellDialog, DoubleClickChangeHdl, weld::TreeView&, bool)
+{
+ ChangeHdl(*m_xChangePB);
+ return true;
+}
+
+/* tdf#132822 start an undo group in ctor and close it in the dtor. This can
+ then be passed to SpellContinue_Impl which can delete it in advance of its
+ natural scope to force closing the undo group if SpellContinue_Impl needs to
+ fetch a new paragraph and discard all undo information which can only be
+ done properly if there are no open undo groups */
+class UndoChangeGroupGuard
+{
+private:
+ SentenceEditWindow_Impl& m_rSentenceED;
+public:
+ UndoChangeGroupGuard(SentenceEditWindow_Impl& rSentenceED)
+ : m_rSentenceED(rSentenceED)
+ {
+ m_rSentenceED.UndoActionStart(SPELLUNDO_CHANGE_GROUP);
+ }
+ ~UndoChangeGroupGuard()
+ {
+ m_rSentenceED.UndoActionEnd();
+ }
+};
+
+IMPL_LINK_NOARG(SpellDialog, ChangeHdl, weld::Button&, void)
+{
+ if (m_xSentenceED->IsUndoEditMode())
+ {
+ SpellContinue_Impl();
+ }
+ else
+ {
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ OUString aString = getReplacementString();
+ m_xSentenceED->ChangeMarkedWord(aString, GetSelectedLang_Impl());
+ SpellContinue_Impl(&xGuard);
+ }
+ if(!m_xChangePB->get_sensitive())
+ m_xIgnorePB->grab_focus();
+}
+
+IMPL_LINK_NOARG(SpellDialog, ChangeAllHdl, weld::Button&, void)
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ OUString aString = getReplacementString();
+ LanguageType eLang = GetSelectedLang_Impl();
+
+ // add new word to ChangeAll list
+ OUString aOldWord( m_xSentenceED->GetErrorText() );
+ SvxPrepareAutoCorrect( aOldWord, aString );
+ Reference<XDictionary> aXDictionary = LinguMgr::GetChangeAllList();
+ DictionaryError nAdded = AddEntryToDic( aXDictionary,
+ aOldWord, true,
+ aString );
+
+ if(nAdded == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary(aXDictionary);
+ pAction->SetAddedWord(aOldWord);
+ m_xSentenceED->AddUndoAction(std::move(pAction));
+ }
+
+ m_xSentenceED->ChangeMarkedWord(aString, eLang);
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK( SpellDialog, IgnoreAllHdl, weld::Button&, rButton, void )
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+ // add word to IgnoreAll list
+ Reference< XDictionary > aXDictionary = LinguMgr::GetIgnoreAllList();
+ //in case the error has been changed manually it has to be restored
+ m_xSentenceED->RestoreCurrentError();
+ if (&rButton == m_xIgnoreRulePB.get())
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ bool bSpellErrorDescription = m_xSentenceED->GetAlternatives(aSpellErrorDescription);
+ try
+ {
+ if( bSpellErrorDescription && aSpellErrorDescription.xGrammarChecker.is() )
+ {
+ aSpellErrorDescription.xGrammarChecker->ignoreRule(aSpellErrorDescription.sRuleId,
+ aSpellErrorDescription.aLocale);
+ // refresh the layout (workaround to launch a dictionary event)
+ aXDictionary->setActive(false);
+ aXDictionary->setActive(true);
+ }
+ }
+ catch( const uno::Exception& )
+ {
+ }
+ }
+ else
+ {
+ OUString sErrorText(m_xSentenceED->GetErrorText());
+ DictionaryError nAdded = AddEntryToDic( aXDictionary,
+ sErrorText, false,
+ OUString() );
+ if (nAdded == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary(aXDictionary);
+ pAction->SetAddedWord(sErrorText);
+ m_xSentenceED->AddUndoAction(std::move(pAction));
+ }
+ }
+
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK_NOARG(SpellDialog, UndoHdl, weld::Button&, void)
+{
+ m_xSentenceED->Undo();
+ if(!m_xSentenceED->GetUndoActionCount())
+ m_xUndoPB->set_sensitive(false);
+}
+
+
+IMPL_LINK( SpellDialog, DialogUndoHdl, SpellUndoAction_Impl&, rAction, void )
+{
+ switch(rAction.GetId())
+ {
+ case SPELLUNDO_CHANGE_TEXTENGINE:
+ {
+ if(rAction.IsEnableChangePB())
+ m_xChangePB->set_sensitive(false);
+ if(rAction.IsEnableChangeAllPB())
+ m_xChangeAllPB->set_sensitive(false);
+ }
+ break;
+ case SPELLUNDO_CHANGE_NEXTERROR:
+ {
+ m_xSentenceED->MoveErrorMarkTo(static_cast<sal_Int32>(rAction.GetOldErrorStart()),
+ static_cast<sal_Int32>(rAction.GetOldErrorEnd()),
+ false);
+ if(rAction.IsErrorLanguageSelected())
+ {
+ UpdateBoxes_Impl();
+ }
+ }
+ break;
+ case SPELLUNDO_CHANGE_ADD_TO_DICTIONARY:
+ {
+ if(rAction.GetDictionary().is())
+ rAction.GetDictionary()->remove(rAction.GetAddedWord());
+ }
+ break;
+ case SPELLUNDO_MOVE_ERROREND :
+ {
+ if(rAction.GetOffset() != 0)
+ m_xSentenceED->MoveErrorEnd(rAction.GetOffset());
+ }
+ break;
+ case SPELLUNDO_UNDO_EDIT_MODE :
+ {
+ //refill the dialog with the currently spelled sentence - throw away all changes
+ SpellContinue_Impl(nullptr, true);
+ }
+ break;
+ case SPELLUNDO_ADD_IGNORE_RULE:
+ //undo of ignored rules is not supported
+ break;
+ }
+}
+
+void SpellDialog::Impl_Restore(bool bUseSavedSentence)
+{
+ //clear the "ChangeAllList"
+ LinguMgr::GetChangeAllList()->clear();
+ //get a new sentence
+ m_xSentenceED->SetText(OUString());
+ m_xSentenceED->ResetModified();
+ //Resolves: fdo#39348 refill the dialog with the currently spelled sentence
+ SpellContinue_Impl(nullptr, bUseSavedSentence);
+ m_xIgnorePB->set_label(m_sIgnoreOnceST);
+}
+
+IMPL_LINK_NOARG(SpellDialog, IgnoreHdl, weld::Button&, void)
+{
+ if (m_sResumeST == m_xIgnorePB->get_label())
+ {
+ Impl_Restore(false);
+ }
+ else
+ {
+ //in case the error has been changed manually it has to be restored,
+ // since the users choice now was to ignore the error
+ m_xSentenceED->RestoreCurrentError();
+
+ // the word is being ignored
+ SpellContinue_Impl(nullptr, false, true);
+ }
+}
+
+void SpellDialog::Close()
+{
+ if (IsClosing())
+ return;
+
+ // We have to call ToggleChildWindow directly; calling SfxDispatcher's
+ // Execute() does not work here when we are in a document with protected
+ // section - in that case, the cursor can move from the editable field to
+ // the protected area, and the slots get disabled because of
+ // SfxDisableFlags::SwOnProtectedCursor (see FN_SPELL_GRAMMAR_DIALOG in .sdi).
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ pViewFrame->ToggleChildWindow(rParent.GetType());
+}
+
+LanguageType SpellDialog::GetSelectedLang_Impl() const
+{
+ LanguageType nLang = m_xLanguageLB->get_active_id();
+ return nLang;
+}
+
+IMPL_LINK_NOARG(SpellDialog, LanguageSelectHdl, weld::ComboBox&, void)
+{
+ //If selected language changes, then add->list should be regenerated to
+ //match
+ InitUserDicts();
+
+ //if currently an error is selected then search for alternatives for
+ //this word and fill the alternatives ListBox accordingly
+ OUString sError = m_xSentenceED->GetErrorText();
+ m_xSuggestionLB->clear();
+ if (!sError.isEmpty())
+ {
+ LanguageType eLanguage = m_xLanguageLB->get_active_id();
+ Reference <XSpellAlternatives> xAlt = xSpell->spell( sError, static_cast<sal_uInt16>(eLanguage),
+ Sequence< PropertyValue >() );
+ if( xAlt.is() )
+ m_xSentenceED->SetAlternatives( xAlt );
+ else
+ {
+ m_xSentenceED->ChangeMarkedWord( sError, eLanguage );
+ SpellContinue_Impl();
+ }
+
+ m_xSentenceED->AddUndoAction(std::make_unique<SpellUndoAction_Impl>(SPELLUNDO_CHANGE_LANGUAGE, aDialogUndoLink));
+ }
+ SpellDialog::UpdateBoxes_Impl(true);
+}
+
+void SpellDialog::SetTitle_Impl(LanguageType nLang)
+{
+ OUString sTitle = rParent.HasGrammarChecking() ? m_sTitleSpellingGrammar : m_sTitleSpelling;
+ sTitle = sTitle.replaceFirst( "$LANGUAGE ($LOCATION)", SvtLanguageTable::GetLanguageString(nLang) );
+ m_xDialog->set_title(m_xDialog->strip_mnemonic(sTitle));
+}
+
+int SpellDialog::InitUserDicts()
+{
+ const LanguageType nLang = m_xLanguageLB->get_active_id();
+
+ const Reference< XDictionary > *pDic = nullptr;
+
+ // get list of dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ // add active, positive dictionary to dic-list (if not already done).
+ // This is to ensure that there is at least on dictionary to which
+ // words could be added.
+ Reference< XDictionary > xDic( LinguMgr::GetStandardDic() );
+ if (xDic.is())
+ xDic->setActive( true );
+
+ pImpl->aDics = xDicList->getDictionaries();
+ }
+
+ SvtLinguConfig aCfg;
+
+ // list suitable dictionaries
+ bool bEnable = false;
+ const sal_Int32 nSize = pImpl->aDics.getLength();
+ pDic = pImpl->aDics.getConstArray();
+ m_xAddToDictMB->clear();
+ sal_uInt16 nItemId = 1; // menu items should be enumerated from 1 and not 0
+ for (sal_Int32 i = 0; i < nSize; ++i)
+ {
+ uno::Reference< linguistic2::XDictionary > xDicTmp = pDic[i];
+ if (!xDicTmp.is() || LinguMgr::GetIgnoreAllList() == xDicTmp)
+ continue;
+
+ uno::Reference< frame::XStorable > xStor( xDicTmp, uno::UNO_QUERY );
+ LanguageType nActLanguage = LanguageTag( xDicTmp->getLocale() ).getLanguageType();
+ if( xDicTmp->isActive()
+ && xDicTmp->getDictionaryType() != linguistic2::DictionaryType_NEGATIVE
+ && (nLang == nActLanguage || LANGUAGE_NONE == nActLanguage )
+ && (!xStor.is() || !xStor->isReadonly()) )
+ {
+ bEnable = true;
+
+ OUString aDictionaryImageUrl;
+ uno::Reference< lang::XServiceInfo > xSvcInfo( xDicTmp, uno::UNO_QUERY );
+ if (xSvcInfo.is())
+ {
+ aDictionaryImageUrl = aCfg.GetSpellAndGrammarContextDictionaryImage(
+ xSvcInfo->getImplementationName());
+ }
+
+ m_xAddToDictMB->append_item(OUString::number(nItemId), xDicTmp->getName(), aDictionaryImageUrl);
+
+ ++nItemId;
+ }
+ }
+ m_xAddToDictMB->set_sensitive( bEnable );
+ m_xAddToDictPB->set_sensitive( bEnable );
+
+ int nDicts = nItemId-1;
+
+ m_xAddToDictMB->set_visible( nDicts > 1 );
+ m_xAddToDictPB->set_visible( nDicts <= 1 );
+
+ return nDicts;
+}
+
+IMPL_LINK_NOARG(SpellDialog, AddToDictClickHdl, weld::Button&, void)
+{
+ AddToDictionaryExecute(OString::number(1));
+}
+
+IMPL_LINK(SpellDialog, AddToDictSelectHdl, const OString&, rIdent, void)
+{
+ AddToDictionaryExecute(rIdent);
+}
+
+void SpellDialog::AddToDictionaryExecute(const OString& rItemId)
+{
+ auto xGuard(std::make_unique<UndoChangeGroupGuard>(*m_xSentenceED));
+
+ //GetErrorText() returns the current error even if the text is already
+ //manually changed
+ const OUString aNewWord = m_xSentenceED->GetErrorText();
+
+ OUString aDicName(m_xAddToDictMB->get_item_label(rItemId));
+
+ uno::Reference< linguistic2::XDictionary > xDic;
+ uno::Reference< linguistic2::XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ xDic = xDicList->getDictionaryByName( aDicName );
+
+ DictionaryError nAddRes = DictionaryError::UNKNOWN;
+ if (xDic.is())
+ {
+ nAddRes = AddEntryToDic( xDic, aNewWord, false, OUString() );
+ // save modified user-dictionary if it is persistent
+ uno::Reference< frame::XStorable > xSavDic( xDic, uno::UNO_QUERY );
+ if (xSavDic.is())
+ xSavDic->store();
+
+ if (nAddRes == DictionaryError::NONE)
+ {
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_ADD_TO_DICTIONARY, aDialogUndoLink));
+ pAction->SetDictionary( xDic );
+ pAction->SetAddedWord( aNewWord );
+ m_xSentenceED->AddUndoAction( std::move(pAction) );
+ }
+ // failed because there is already an entry?
+ if (DictionaryError::NONE != nAddRes && xDic->getEntry( aNewWord ).is())
+ nAddRes = DictionaryError::NONE;
+ }
+ if (DictionaryError::NONE != nAddRes)
+ {
+ SvxDicError(m_xDialog.get(), nAddRes);
+ return; // don't continue
+ }
+
+ // go on
+ SpellContinue_Impl(&xGuard);
+}
+
+IMPL_LINK_NOARG(SpellDialog, ModifyHdl, LinkParamNone*, void)
+{
+ m_xSuggestionLB->unselect_all();
+ m_xSuggestionLB->set_sensitive(false);
+ m_xAutoCorrPB->set_sensitive(false);
+ std::unique_ptr<SpellUndoAction_Impl> pSpellAction(new SpellUndoAction_Impl(SPELLUNDO_CHANGE_TEXTENGINE, aDialogUndoLink));
+ if(!m_xChangeAllPB->get_sensitive())
+ {
+ m_xChangeAllPB->set_sensitive(true);
+ pSpellAction->SetEnableChangeAllPB();
+ }
+ if(!m_xChangePB->get_sensitive())
+ {
+ m_xChangePB->set_sensitive(true);
+ pSpellAction->SetEnableChangePB();
+ }
+ m_xSentenceED->AddUndoAction(std::move(pSpellAction));
+}
+
+IMPL_LINK_NOARG(SpellDialog, CancelHdl, weld::Button&, void)
+{
+ //apply changes and ignored text parts first - if there are any
+ rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), false);
+ Close();
+}
+
+void SpellDialog::ToplevelFocusChanged()
+{
+ /* #i38338#
+ * FIXME: LoseFocus and GetFocus are signals from vcl that
+ * a window actually got/lost the focus, it never should be
+ * forwarded from another window, that is simply wrong.
+ * FIXME: overriding the virtual methods GetFocus and LoseFocus
+ * in SpellDialogChildWindow by making them pure is at least questionable.
+ * The only sensible thing would be to call the new Method differently,
+ * e.g. DialogGot/LostFocus or so.
+ */
+ if (!(m_xDialog->get_visible() && !bFocusLocked))
+ return;
+
+ if (m_xDialog->has_toplevel_focus())
+ {
+ //notify the child window of the focus change
+ rParent.GetFocus();
+ }
+ else
+ {
+ //notify the child window of the focus change
+ rParent.LoseFocus();
+ }
+}
+
+void SpellDialog::Activate()
+{
+ SfxModelessDialogController::Activate();
+ ToplevelFocusChanged();
+}
+
+void SpellDialog::Deactivate()
+{
+ SfxModelessDialogController::Activate();
+ ToplevelFocusChanged();
+}
+
+void SpellDialog::InvalidateDialog()
+{
+ if( bFocusLocked )
+ return;
+ m_xIgnorePB->set_label(m_sResumeST);
+ weld::Widget* aDisableArr[] =
+ {
+ m_xNotInDictFT.get(),
+ m_xSentenceED->GetDrawingArea(),
+ m_xSuggestionFT.get(),
+ m_xSuggestionLB.get(),
+ m_xLanguageFT.get(),
+ m_xLanguageLB->get_widget(),
+ m_xIgnoreAllPB.get(),
+ m_xIgnoreRulePB.get(),
+ m_xAddToDictMB.get(),
+ m_xAddToDictPB.get(),
+ m_xChangePB.get(),
+ m_xChangeAllPB.get(),
+ m_xAutoCorrPB.get(),
+ m_xUndoPB.get(),
+ nullptr
+ };
+ sal_Int16 i = 0;
+ while(aDisableArr[i])
+ {
+ aDisableArr[i]->set_sensitive(false);
+ i++;
+ }
+ SfxModelessDialogController::Deactivate();
+}
+
+bool SpellDialog::GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck)
+{
+ bool bRet = false;
+ if(!bUseSavedSentence)
+ {
+ //apply changes and ignored text parts
+ rParent.ApplyChangedSentence(m_xSentenceED->CreateSpellPortions(), bRecheck);
+ }
+ m_xSentenceED->ResetIgnoreErrorsAt();
+ m_xSentenceED->ResetModified();
+ SpellPortions aSentence = bUseSavedSentence ? m_aSavedSentence : rParent.GetNextWrongSentence( bRecheck );
+ if(!bUseSavedSentence)
+ m_aSavedSentence = aSentence;
+ bool bHasReplaced = false;
+ while(!aSentence.empty())
+ {
+ //apply all changes that are already part of the "ChangeAllList"
+ //returns true if the list still contains errors after the changes have been applied
+
+ if(!ApplyChangeAllList_Impl(aSentence, bHasReplaced))
+ {
+ rParent.ApplyChangedSentence(aSentence, bRecheck);
+ aSentence = rParent.GetNextWrongSentence( bRecheck );
+ }
+ else
+ break;
+ }
+
+ if(!aSentence.empty())
+ {
+ OUStringBuffer sText;
+ for (auto const& elem : aSentence)
+ {
+ // hidden text has to be ignored
+ if(!elem.bIsHidden)
+ sText.append(elem.sText);
+ }
+ // tdf#132822 fire undo-stack UndoActionEnd to close undo stack because we're about to throw away the paragraph entirely
+ if (pGuard)
+ pGuard->reset();
+ m_xSentenceED->SetText(sText.makeStringAndClear());
+ sal_Int32 nStartPosition = 0;
+ sal_Int32 nEndPosition = 0;
+
+ for (auto const& elem : aSentence)
+ {
+ // hidden text has to be ignored
+ if(!elem.bIsHidden)
+ {
+ nEndPosition += elem.sText.getLength();
+ if(elem.xAlternatives.is())
+ {
+ uno::Reference< container::XNamed > xNamed( elem.xAlternatives, uno::UNO_QUERY );
+ OUString sServiceName;
+ if( xNamed.is() )
+ sServiceName = xNamed->getName();
+ SpellErrorDescription aDesc( false, elem.xAlternatives->getWord(),
+ elem.xAlternatives->getLocale(), elem.xAlternatives->getAlternatives(), nullptr);
+ SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
+ aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ m_xSentenceED->SetAttrib(aSpellErrorDescription, nStartPosition, nEndPosition);
+ }
+ else if(elem.bIsGrammarError )
+ {
+ beans::PropertyValues aProperties = elem.aGrammarError.aProperties;
+ OUString sFullCommentURL;
+ sal_Int32 i = 0;
+ while ( sFullCommentURL.isEmpty() && i < aProperties.getLength() )
+ {
+ if ( aProperties[i].Name == "FullCommentURL" )
+ {
+ uno::Any aValue = aProperties[i].Value;
+ aValue >>= sFullCommentURL;
+ }
+ ++i;
+ }
+
+ SpellErrorDescription aDesc( true,
+ elem.sText,
+ LanguageTag::convertToLocale( elem.eLanguage ),
+ elem.aGrammarError.aSuggestions,
+ elem.xGrammarChecker,
+ &elem.sDialogTitle,
+ &elem.aGrammarError.aFullComment,
+ &elem.aGrammarError.aRuleIdentifier,
+ &sFullCommentURL );
+
+ SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
+ aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ m_xSentenceED->SetAttrib(aSpellErrorDescriptionItem, nStartPosition, nEndPosition);
+ }
+
+ if (elem.bIsField)
+ m_xSentenceED->SetAttrib(SvxBackgroundColorItem(COL_LIGHTGRAY, EE_CHAR_BKGCOLOR), nStartPosition, nEndPosition);
+ m_xSentenceED->SetAttrib(SvxLanguageItem(elem.eLanguage, EE_CHAR_LANGUAGE), nStartPosition, nEndPosition);
+ nStartPosition = nEndPosition;
+ }
+ }
+ //the edit field needs to be modified to apply the change from the ApplyChangeAllList
+ if(!bHasReplaced)
+ m_xSentenceED->ClearModifyFlag();
+ m_xSentenceED->ResetUndo();
+ m_xUndoPB->set_sensitive(false);
+ bRet = nStartPosition > 0;
+ }
+ return bRet;
+}
+/*-------------------------------------------------------------------------
+ replace errors that have a replacement in the ChangeAllList
+ returns false if the result doesn't contain errors after the replacement
+ -----------------------------------------------------------------------*/
+bool SpellDialog::ApplyChangeAllList_Impl(SpellPortions& rSentence, bool &bHasReplaced)
+{
+ bHasReplaced = false;
+ bool bRet = true;
+ Reference<XDictionary> xChangeAll = LinguMgr::GetChangeAllList();
+ if(!xChangeAll->getCount())
+ return bRet;
+ bRet = false;
+ for (auto & elem : rSentence)
+ {
+ if(elem.xAlternatives.is())
+ {
+ const OUString &rString = elem.sText;
+
+ Reference<XDictionaryEntry> xEntry = xChangeAll->getEntry(rString);
+
+ if(xEntry.is())
+ {
+ elem.sText = getDotReplacementString(rString, xEntry->getReplacementText());
+ elem.xAlternatives = nullptr;
+ bHasReplaced = true;
+ }
+ else
+ bRet = true;
+ }
+ else if( elem.bIsGrammarError )
+ bRet = true;
+ }
+ return bRet;
+}
+
+SentenceEditWindow_Impl::SentenceEditWindow_Impl()
+ : m_pSpellDialog(nullptr)
+ , m_pToolbar(nullptr)
+ , m_nErrorStart(0)
+ , m_nErrorEnd(0)
+ , m_bIsUndoEditMode(false)
+{
+}
+
+void SentenceEditWindow_Impl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ Size aSize(pDrawingArea->get_approximate_digit_width() * 60,
+ pDrawingArea->get_text_height() * 6);
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+ WeldEditView::SetDrawingArea(pDrawingArea);
+ // tdf#132288 don't merge equal adjacent attributes
+ m_xEditEngine->DisableAttributeExpanding();
+}
+
+SentenceEditWindow_Impl::~SentenceEditWindow_Impl()
+{
+}
+
+namespace
+{
+ const EECharAttrib* FindCharAttrib(int nPosition, sal_uInt16 nWhich, std::vector<EECharAttrib>& rAttribList)
+ {
+ for (auto it = rAttribList.rbegin(); it != rAttribList.rend(); ++it)
+ {
+ const auto& rTextAtr = *it;
+ if (rTextAtr.pAttr->Which() != nWhich)
+ continue;
+ if (rTextAtr.nStart <= nPosition && rTextAtr.nEnd >= nPosition)
+ {
+ return &rTextAtr;
+ }
+ }
+
+ return nullptr;
+ }
+
+ void ExtractErrorDescription(const EECharAttrib& rEECharAttrib, SpellErrorDescription& rSpellErrorDescription)
+ {
+ css::uno::Sequence<css::uno::Any> aSequence;
+ static_cast<const SfxGrabBagItem*>(rEECharAttrib.pAttr)->GetGrabBag().find("SpellErrorDescription")->second >>= aSequence;
+ rSpellErrorDescription.fromSequence(aSequence);
+ }
+}
+
+/*-------------------------------------------------------------------------
+ The selection before inputting a key may have a range or not
+ and it may be inside or outside of field or error attributes.
+ A range may include the attribute partially, completely or together
+ with surrounding text. It may also contain more than one attribute
+ or no attribute at all.
+ Depending on this starting conditions some actions are necessary:
+ Attempts to delete a field are only allowed if the selection is the same
+ as the field's selection. Otherwise the field has to be selected and the key
+ input action has to be skipped.
+ Input of text at the start of the field requires the field attribute to be
+ corrected - it is not allowed to grow.
+
+ In case of errors the appending of text should grow the error attribute because
+ that is what the user usually wants to do.
+
+ Backspace at the start of the attribute requires to find out if a field ends
+ directly in front of the cursor position. In case of a field this attribute has to be
+ selected otherwise the key input method is allowed.
+
+ All changes outside of the error attributes switch the dialog mode to a "Undo edit" state that
+ removes all visible attributes and switches off further attribute checks.
+ Undo in this restarts the dialog with a current sentence newly presented.
+ All changes to the sentence are undone including the ones before the "Undo edit state" has been reached
+
+ We end up with 9 types of selection
+ 1 (LEFT_NO) - no range, start of attribute - can also be 3 at the same time
+ 2 (INSIDE_NO) - no range, inside of attribute
+ 3 (RIGHT_NO) - no range, end of attribute - can also be 1 at the same time
+ 4 (FULL) - range, same as attribute
+ 5 (INSIDE_YES) - range, inside of the attribute
+ 6 (BRACE)- range, from outside of the attribute to the inside or
+ including the complete attribute and something outside,
+ maybe more than one attribute
+ 7 (OUTSIDE_NO) - no range, not at an attribute
+ 8 (OUTSIDE_YES) - range, completely outside of all attributes
+
+ What has to be done depending on the attribute type involved
+ possible actions: UE - Undo edit mode
+ CO - Continue, no additional action is required
+ FS - Field has to be completely selected
+ EX - The attribute has to be expanded to include the added text
+
+ 1 - backspace delete any other
+ UE on field FS on error CO on field FS on error CO
+
+ 2 - on field FS on error C
+ 3 - backspace delete any other
+ on field FS on error CO UE on field UE on error EX
+
+ if 1 and 3 happen to apply both then backspace and other handling is 1 delete is 3
+
+ 4 - on field UE and on error CO
+ 5 - on field FS and on error CO
+ 6 - on field FS and on error UE
+ 7 - UE
+ 8 - UE
+ -----------------------------------------------------------------------*/
+#define INVALID 0
+#define LEFT_NO 1
+#define INSIDE_NO 2
+#define RIGHT_NO 3
+#define FULL 4
+#define INSIDE_YES 5
+#define BRACE 6
+#define OUTSIDE_NO 7
+#define OUTSIDE_YES 8
+
+#define ACTION_UNDOEDIT 0
+#define ACTION_CONTINUE 1
+#define ACTION_SELECTFIELD 2
+#define ACTION_EXPAND 3
+
+bool SentenceEditWindow_Impl::KeyInput(const KeyEvent& rKeyEvt)
+{
+ if (rKeyEvt.GetKeyCode().GetCode() == KEY_TAB)
+ return false;
+
+ bool bConsumed = false;
+
+ bool bChange = TextEngine::DoesKeyChangeText( rKeyEvt );
+ if (bChange && !IsUndoEditMode())
+ {
+ bConsumed = true;
+
+ ESelection aCurrentSelection(m_xEditView->GetSelection());
+ aCurrentSelection.Adjust();
+
+ //determine if the selection contains a field
+ bool bHasFieldLeft = false;
+ bool bHasErrorLeft = false;
+
+ bool bHasRange = aCurrentSelection.HasRange();
+ sal_uInt8 nSelectionType = 0; // invalid type!
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ auto nCursor = aCurrentSelection.nStartPos;
+ const EECharAttrib* pBackAttr = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ const EECharAttrib* pErrorAttr = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ const EECharAttrib* pBackAttrLeft = nullptr;
+ const EECharAttrib* pErrorAttrLeft = nullptr;
+
+ bool bHasField = pBackAttr != nullptr && (bHasRange || pBackAttr->nEnd > nCursor);
+ bool bHasError = pErrorAttr != nullptr && (bHasRange || pErrorAttr->nEnd > nCursor);
+ if (bHasRange)
+ {
+ if (pBackAttr &&
+ pBackAttr->nStart == aCurrentSelection.nStartPos &&
+ pBackAttr->nEnd == aCurrentSelection.nEndPos)
+ {
+ nSelectionType = FULL;
+ }
+ else if (pErrorAttr &&
+ pErrorAttr->nStart <= aCurrentSelection.nStartPos &&
+ pErrorAttr->nEnd >= aCurrentSelection.nEndPos)
+ {
+ nSelectionType = INSIDE_YES;
+ }
+ else
+ {
+ nSelectionType = bHasField||bHasError ? BRACE : OUTSIDE_NO;
+ while (nCursor < aCurrentSelection.nEndPos)
+ {
+ ++nCursor;
+ const EECharAttrib* pIntBackAttr = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ const EECharAttrib* pIntErrorAttr = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ //if any attr has been found then BRACE
+ if (pIntBackAttr || pIntErrorAttr)
+ nSelectionType = BRACE;
+ //the field has to be selected
+ if (pIntBackAttr && !pBackAttr)
+ pBackAttr = pIntBackAttr;
+ bHasField |= pIntBackAttr != nullptr;
+ }
+ }
+ }
+ else
+ {
+ //no range selection: then 1 2 3 and 8 are possible
+ const EECharAttrib* pCurAttr = pBackAttr ? pBackAttr : pErrorAttr;
+ if (pCurAttr)
+ {
+ nSelectionType = pCurAttr->nStart == aCurrentSelection.nStartPos ?
+ LEFT_NO : pCurAttr->nEnd == aCurrentSelection.nEndPos ? RIGHT_NO : INSIDE_NO;
+ }
+ else
+ nSelectionType = OUTSIDE_NO;
+
+ bHasFieldLeft = pBackAttr && pBackAttr->nEnd == nCursor;
+ if(bHasFieldLeft)
+ {
+ pBackAttrLeft = pBackAttr;
+ pBackAttr = nullptr;
+ }
+ bHasErrorLeft = pErrorAttr && pErrorAttr->nEnd == nCursor;
+ if(bHasErrorLeft)
+ {
+ pErrorAttrLeft = pErrorAttr;
+ pErrorAttr = nullptr;
+ }
+
+ //check previous position if this exists
+ //that is a redundant in the case the attribute found above already is on the left cursor side
+ //but it's o.k. for two errors/fields side by side
+ if (nCursor)
+ {
+ --nCursor;
+ pBackAttrLeft = FindCharAttrib(nCursor, EE_CHAR_BKGCOLOR, aAttribList);
+ pErrorAttrLeft = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ bHasFieldLeft = pBackAttrLeft !=nullptr;
+ bHasErrorLeft = pErrorAttrLeft != nullptr;
+ ++nCursor;
+ }
+ }
+ //Here we have to determine if the error found is the one currently active
+ bool bIsErrorActive = (pErrorAttr && pErrorAttr->nStart == m_nErrorStart) ||
+ (pErrorAttrLeft && pErrorAttrLeft->nStart == m_nErrorStart);
+
+ SAL_WARN_IF(
+ nSelectionType == INVALID, "cui.dialogs",
+ "selection type not set");
+
+ const vcl::KeyCode& rKeyCode = rKeyEvt.GetKeyCode();
+ bool bDelete = rKeyCode.GetCode() == KEY_DELETE;
+ bool bBackspace = rKeyCode.GetCode() == KEY_BACKSPACE;
+
+ sal_Int8 nAction = ACTION_CONTINUE;
+ switch(nSelectionType)
+ {
+// 1 - backspace delete any other
+// UE on field FS on error CO on field FS on error CO
+ case LEFT_NO :
+ if(bBackspace)
+ {
+ nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
+ //to force the use of pBackAttrLeft
+ pBackAttr = nullptr;
+ }
+ else if(bDelete)
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ else
+ nAction = bHasError && !nCursor ? ACTION_CONTINUE :
+ bHasError ? ACTION_EXPAND : bHasErrorLeft ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ break;
+// 2 - on field FS on error C
+ case INSIDE_NO :
+ nAction = bHasField ? ACTION_SELECTFIELD :
+ bIsErrorActive ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ break;
+// 3 - backspace delete any other
+// on field FS on error CO UE on field UE on error EX
+ case RIGHT_NO :
+ if(bBackspace)
+ nAction = bHasFieldLeft ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ else if(bDelete)
+ nAction = bHasFieldLeft && bHasError ? ACTION_CONTINUE : ACTION_UNDOEDIT;
+ else
+ nAction = bHasFieldLeft && bHasError ? ACTION_EXPAND :
+ bHasError ? ACTION_CONTINUE : bHasErrorLeft ? ACTION_EXPAND :ACTION_UNDOEDIT;
+ break;
+// 4 - on field UE and on error CO
+ case FULL :
+ nAction = ACTION_UNDOEDIT;
+ break;
+// 5 - on field FS and on error CO
+ case INSIDE_YES :
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_CONTINUE;
+ break;
+// 6 - on field FS and on error UE
+ case BRACE :
+ nAction = bHasField ? ACTION_SELECTFIELD : ACTION_UNDOEDIT;
+ break;
+// 7 - UE
+// 8 - UE
+ case OUTSIDE_NO :
+ case OUTSIDE_YES:
+ nAction = ACTION_UNDOEDIT;
+ break;
+ }
+ //save the current paragraph
+ sal_Int32 nCurrentLen = m_xEditEngine->GetText().getLength();
+ if (nAction != ACTION_SELECTFIELD)
+ {
+ m_xEditView->PostKeyEvent(rKeyEvt);
+ }
+ else
+ {
+ const EECharAttrib* pCharAttr = pBackAttr ? pBackAttr : pBackAttrLeft;
+ if (pCharAttr)
+ m_xEditView->SetSelection(ESelection(0, pCharAttr->nStart, 0, pCharAttr->nEnd));
+ }
+ if(nAction == ACTION_EXPAND)
+ {
+ DBG_ASSERT(pErrorAttrLeft || pErrorAttr, "where is the error");
+ //text has been added on the right and only the 'error attribute has to be corrected
+ if (pErrorAttrLeft)
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ ExtractErrorDescription(*pErrorAttrLeft, aSpellErrorDescription);
+
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrLeft->pAttr->Clone());
+ sal_Int32 nStart = pErrorAttrLeft->nStart;
+ sal_Int32 nEnd = pErrorAttrLeft->nEnd + 1;
+ m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
+ SetAttrib(*xNewError, nStart, nEnd);
+ //only active errors move the mark
+ if (bIsErrorActive)
+ {
+ bool bGrammar = aSpellErrorDescription.bIsGrammarError;
+ MoveErrorMarkTo(nStart, nEnd, bGrammar);
+ }
+ }
+ //text has been added on the left then the error attribute has to be expanded and the
+ //field attribute on the right - if any - has to be contracted
+ else if (pErrorAttr)
+ {
+ SpellErrorDescription aSpellErrorDescription;
+ ExtractErrorDescription(*pErrorAttr, aSpellErrorDescription);
+
+ //determine the change
+ sal_Int32 nAddedChars = m_xEditEngine->GetText().getLength() - nCurrentLen;
+
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttr->pAttr->Clone());
+ sal_Int32 nStart = pErrorAttr->nStart + nAddedChars;
+ sal_Int32 nEnd = pErrorAttr->nEnd + nAddedChars;
+ m_xEditEngine->RemoveAttribs(ESelection(0, nStart, 0, nEnd), false, EE_CHAR_GRABBAG);
+ nStart = pErrorAttr->nStart;
+ SetAttrib(*xNewError, nStart, nEnd);
+ //only if the error is active the mark is moved here
+ if (bIsErrorActive)
+ {
+ bool bGrammar = aSpellErrorDescription.bIsGrammarError;
+ MoveErrorMarkTo(nStart, nEnd, bGrammar);
+ }
+ xNewError.reset();
+
+ if (pBackAttrLeft)
+ {
+ std::unique_ptr<SfxPoolItem> xNewBack(pBackAttrLeft->pAttr->Clone());
+ sal_Int32 _nStart = pBackAttrLeft->nStart + nAddedChars;
+ sal_Int32 _nEnd = pBackAttrLeft->nEnd + nAddedChars;
+ m_xEditEngine->RemoveAttribs(ESelection(0, _nStart, 0, _nEnd), false, EE_CHAR_BKGCOLOR);
+ _nStart = pBackAttrLeft->nStart;
+ SetAttrib(*xNewBack, _nStart, _nEnd);
+ }
+ }
+ }
+ else if(nAction == ACTION_UNDOEDIT)
+ {
+ SetUndoEditMode(true);
+ }
+ //make sure the error positions are correct after text changes
+ //the old attribute may have been deleted
+ //all changes inside of the current error leave the error attribute at the current
+ //start position
+ if (!IsUndoEditMode() && bIsErrorActive)
+ {
+ const EECharAttrib* pFontColor = FindCharAttrib(nCursor, EE_CHAR_COLOR, aAttribList);
+ const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
+ if (pFontColor && pErrorAttrib)
+ {
+ m_nErrorStart = pFontColor->nStart;
+ m_nErrorEnd = pFontColor->nEnd;
+ if (pErrorAttrib->nStart != m_nErrorStart || pErrorAttrib->nEnd != m_nErrorEnd)
+ {
+ std::unique_ptr<SfxPoolItem> xNewError(pErrorAttrib->pAttr->Clone());
+ assert(pErrorAttr);
+ m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttr->nStart, 0, pErrorAttr->nEnd), false, EE_CHAR_GRABBAG);
+ SetAttrib(*xNewError, m_nErrorStart, m_nErrorEnd);
+ }
+ }
+ }
+ //this is not a modification anymore
+ if(nAction != ACTION_SELECTFIELD && !m_bIsUndoEditMode)
+ CallModifyLink();
+ }
+ else
+ bConsumed = m_xEditView->PostKeyEvent(rKeyEvt);
+
+ return bConsumed;
+}
+
+void SentenceEditWindow_Impl::Init(weld::Toolbar* pToolbar)
+{
+ m_pToolbar = pToolbar;
+ m_pToolbar->connect_clicked(LINK(this,SentenceEditWindow_Impl,ToolbarHdl));
+}
+
+IMPL_LINK(SentenceEditWindow_Impl, ToolbarHdl, const OString&, rCurItemId, void)
+{
+ if (rCurItemId == "paste")
+ {
+ m_xEditView->Paste();
+ CallModifyLink();
+ }
+ else if (rCurItemId == "insert")
+ {
+ if (vcl::GetGetSpecialCharsFunction())
+ {
+ OUString aChars = vcl::GetGetSpecialCharsFunction()(GetDrawingArea(), m_xEditEngine->GetStandardFont(0));
+ if (!aChars.isEmpty())
+ {
+ ESelection aCurrentSelection(m_xEditView->GetSelection());
+ m_xEditEngine->QuickInsertText(aChars, aCurrentSelection);
+ CallModifyLink();
+ }
+ }
+ }
+}
+
+bool SentenceEditWindow_Impl::MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& xSpell )
+{
+ if (bIgnoreCurrentError)
+ m_aIgnoreErrorsAt.insert( m_nErrorStart );
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ if (m_nErrorEnd >= nTextLen - 1)
+ return false;
+ //if it's not already modified the modified flag has to be reset at the end of the marking
+ bool bModified = IsModified();
+ bool bRet = false;
+ const sal_Int32 nOldErrorStart = m_nErrorStart;
+ const sal_Int32 nOldErrorEnd = m_nErrorEnd;
+
+ //create a cursor behind the end of the last error
+ //- or at 0 at the start of the sentence
+ sal_Int32 nCursor(m_nErrorEnd ? m_nErrorEnd + 1 : 0);
+
+ //search for SpellErrorDescription
+ SpellErrorDescription aSpellErrorDescription;
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ //iterate over the text and search for the next error that maybe has
+ //to be replace by a ChangeAllList replacement
+ bool bGrammarError = false;
+ while (nCursor < nTextLen)
+ {
+ const SpellErrorDescription* pSpellErrorDescription = nullptr;
+ const EECharAttrib* pEECharAttrib = nullptr;
+
+ sal_Int32 nMinPos = nTextLen + 1;
+ for (const auto& rTextAtr : aAttribList)
+ {
+ if (rTextAtr.pAttr->Which() != EE_CHAR_GRABBAG)
+ continue;
+ if (rTextAtr.nEnd > nCursor && rTextAtr.nStart < nMinPos)
+ {
+ nMinPos = rTextAtr.nStart;
+ pEECharAttrib = &rTextAtr;
+ }
+ }
+
+ if (pEECharAttrib)
+ {
+ ExtractErrorDescription(*pEECharAttrib, aSpellErrorDescription);
+
+ bGrammarError = aSpellErrorDescription.bIsGrammarError;
+ m_nErrorStart = pEECharAttrib->nStart;
+ m_nErrorEnd = pEECharAttrib->nEnd;
+
+ pSpellErrorDescription = &aSpellErrorDescription;
+ }
+
+ nCursor = std::max(nCursor, nMinPos); // move forward if possible
+
+ // maybe the error found here is already in the ChangeAllList and has to be replaced
+ Reference<XDictionary> xChangeAll = LinguMgr::GetChangeAllList();
+ Reference<XDictionaryEntry> xEntry;
+
+ if (xChangeAll->getCount() && pSpellErrorDescription &&
+ (xEntry = xChangeAll->getEntry( pSpellErrorDescription->sErrorText )).is())
+ {
+ OUString sReplacement(getDotReplacementString(GetErrorText(), xEntry->getReplacementText()));
+
+ int nLenChange = ChangeMarkedWord(sReplacement, LanguageTag::convertToLanguageType(pSpellErrorDescription->aLocale));
+
+ nCursor += sReplacement.getLength();
+
+ if (nLenChange)
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+ // maybe the error found here is already added to the dictionary and has to be ignored
+ }
+ else if(pSpellErrorDescription && !bGrammarError &&
+ xSpell->isValid(GetErrorText(),
+ static_cast<sal_uInt16>(LanguageTag::convertToLanguageType( pSpellErrorDescription->aLocale )),
+ Sequence< PropertyValue >() ))
+ {
+ ++nCursor;
+ }
+ else
+ break;
+ }
+
+ //if an attrib has been found search for the end of the error string
+ if (nCursor < nTextLen)
+ {
+ MoveErrorMarkTo(nCursor, m_nErrorEnd, bGrammarError);
+ bRet = true;
+ //add an undo action
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_CHANGE_NEXTERROR, GetSpellDialog()->aDialogUndoLink));
+ pAction->SetErrorMove(nOldErrorStart, nOldErrorEnd);
+
+ if (GetErrorDescription(aSpellErrorDescription, nOldErrorStart))
+ {
+ pAction->SetErrorLanguageSelected(aSpellErrorDescription.aSuggestions.hasElements() &&
+ LanguageTag(aSpellErrorDescription.aLocale).getLanguageType() == GetSpellDialog()->m_xLanguageLB->get_active_id());
+ }
+ else
+ pAction->SetErrorLanguageSelected(false);
+
+ AddUndoAction(std::move(pAction));
+ }
+ else
+ m_nErrorStart = m_nErrorEnd = nTextLen;
+ if( !bModified )
+ ClearModifyFlag();
+ SpellDialog* pSpellDialog = GetSpellDialog();
+ pSpellDialog->m_xIgnorePB->set_sensitive(bRet);
+ pSpellDialog->m_xIgnoreAllPB->set_sensitive(bRet);
+ pSpellDialog->m_xAutoCorrPB->set_sensitive(bRet);
+ pSpellDialog->m_xAddToDictMB->set_sensitive(bRet);
+ pSpellDialog->m_xAddToDictPB->set_sensitive(bRet);
+ return bRet;
+}
+
+void SentenceEditWindow_Impl::MoveErrorMarkTo(sal_Int32 nStart, sal_Int32 nEnd, bool bGrammarError)
+{
+ ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
+
+ SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
+ aSet.Put(SvxColorItem(bGrammarError ? COL_LIGHTBLUE : COL_LIGHTRED, EE_CHAR_COLOR));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CJK));
+ aSet.Put(SvxWeightItem(WEIGHT_BOLD, EE_CHAR_WEIGHT_CTL));
+
+ m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
+
+ // Set the selection so the editview will autoscroll to make this visible
+ // unless (tdf#133958) the selection already overlaps this range
+ ESelection aCurrentSelection = m_xEditView->GetSelection();
+ aCurrentSelection.Adjust();
+ bool bCurrentSelectionInRange = nStart <= aCurrentSelection.nEndPos && aCurrentSelection.nStartPos <= nEnd;
+ if (!bCurrentSelectionInRange)
+ {
+ m_xEditView->SetSelection(ESelection(0, nStart));
+ }
+
+ Invalidate();
+
+ m_nErrorStart = nStart;
+ m_nErrorEnd = nEnd;
+}
+
+int SentenceEditWindow_Impl::ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage)
+{
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ //calculate length changes
+ auto nDiffLen = rNewWord.getLength() - m_nErrorEnd + m_nErrorStart;
+ //Remove spell error attribute
+ m_xEditEngine->UndoActionStart(SPELLUNDO_MOVE_ERROREND);
+ const EECharAttrib* pErrorAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_GRABBAG, aAttribList);
+ DBG_ASSERT(pErrorAttrib, "no error attribute found");
+ bool bSpellErrorDescription = false;
+ SpellErrorDescription aSpellErrorDescription;
+ if (pErrorAttrib)
+ {
+ ExtractErrorDescription(*pErrorAttrib, aSpellErrorDescription);
+ m_xEditEngine->RemoveAttribs(ESelection(0, pErrorAttrib->nStart, 0, pErrorAttrib->nEnd), false, EE_CHAR_GRABBAG);
+ bSpellErrorDescription = true;
+ }
+
+ const EECharAttrib* pBackAttrib = FindCharAttrib(m_nErrorStart, EE_CHAR_BKGCOLOR, aAttribList);
+
+ ESelection aSel(0, m_nErrorStart, 0, m_nErrorEnd);
+ m_xEditEngine->QuickInsertText(rNewWord, aSel);
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ if (nDiffLen)
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (!m_nErrorStart)
+ {
+ //attributes following an error at the start of the text are not moved but expanded from the
+ //text engine - this is done to keep full-paragraph-attributes
+ //in the current case that handling is not desired
+ const EECharAttrib* pLangAttrib = FindCharAttrib(m_nErrorEnd, EE_CHAR_LANGUAGE, aAttribList);
+
+ if (pLangAttrib && !pLangAttrib->nStart && pLangAttrib->nEnd == nTextLen)
+ {
+ LanguageType eNewLanguage = static_cast<const SvxLanguageItem*>(pLangAttrib->pAttr)->GetLanguage();
+ m_xEditEngine->RemoveAttribs(ESelection(0, pLangAttrib->nStart, 0, pLangAttrib->nEnd), false, EE_CHAR_LANGUAGE);
+ SetAttrib(SvxLanguageItem(eNewLanguage, EE_CHAR_LANGUAGE), m_nErrorEnd + nDiffLen, nTextLen);
+ }
+ }
+
+ // undo expanded attributes!
+ if (pBackAttrib && pBackAttrib->nStart < m_nErrorStart && pBackAttrib->nEnd == m_nErrorEnd + nDiffLen)
+ {
+ std::unique_ptr<SfxPoolItem> xNewBackground(pBackAttrib->pAttr->Clone());
+ const sal_Int32 nStart = pBackAttrib->nStart;
+
+ m_xEditEngine->RemoveAttribs(ESelection(0, pBackAttrib->nStart, 0, pBackAttrib->nEnd), false, EE_CHAR_BKGCOLOR);
+
+ SetAttrib(*xNewBackground, nStart, m_nErrorStart);
+ }
+ m_xEditEngine->SetModified();
+
+ //adjust end position
+ long nEndTemp = m_nErrorEnd;
+ nEndTemp += nDiffLen;
+ m_nErrorEnd = static_cast<sal_Int32>(nEndTemp);
+
+ std::unique_ptr<SpellUndoAction_Impl> pAction(new SpellUndoAction_Impl(
+ SPELLUNDO_MOVE_ERROREND, GetSpellDialog()->aDialogUndoLink));
+ pAction->SetOffset(nDiffLen);
+ AddUndoAction(std::move(pAction));
+ if (bSpellErrorDescription)
+ {
+ SfxGrabBagItem aSpellErrorDescriptionItem(EE_CHAR_GRABBAG);
+ aSpellErrorDescriptionItem.GetGrabBag()["SpellErrorDescription"] <<= aSpellErrorDescription.toSequence();
+ SetAttrib(aSpellErrorDescriptionItem, m_nErrorStart, m_nErrorEnd);
+ }
+ SetAttrib(SvxLanguageItem(eLanguage, EE_CHAR_LANGUAGE), m_nErrorStart, m_nErrorEnd);
+ m_xEditEngine->UndoActionEnd();
+
+ Invalidate();
+
+ return nDiffLen;
+}
+
+OUString SentenceEditWindow_Impl::GetErrorText() const
+{
+ return m_xEditEngine->GetText(ESelection(0, m_nErrorStart, 0, m_nErrorEnd));
+}
+
+bool SentenceEditWindow_Impl::GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition)
+{
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (const EECharAttrib* pEECharAttrib = FindCharAttrib(nPosition, EE_CHAR_GRABBAG, aAttribList))
+ {
+ ExtractErrorDescription(*pEECharAttrib, rSpellErrorDescription);
+ return true;
+ }
+
+ return false;
+}
+
+bool SentenceEditWindow_Impl::GetAlternatives(SpellErrorDescription& rSpellErrorDescription)
+{
+ return GetErrorDescription(rSpellErrorDescription, m_nErrorStart);
+}
+
+void SentenceEditWindow_Impl::RestoreCurrentError()
+{
+ SpellErrorDescription aSpellErrorDescription;
+ if (GetErrorDescription(aSpellErrorDescription, m_nErrorStart))
+ {
+ if (aSpellErrorDescription.sErrorText != GetErrorText() )
+ ChangeMarkedWord(aSpellErrorDescription.sErrorText, LanguageTag::convertToLanguageType(aSpellErrorDescription.aLocale));
+ }
+}
+
+void SentenceEditWindow_Impl::SetAlternatives( const Reference< XSpellAlternatives>& xAlt )
+{
+ OUString aWord;
+ lang::Locale aLocale;
+ uno::Sequence< OUString > aAlts;
+ OUString sServiceName;
+ if (xAlt.is())
+ {
+ aWord = xAlt->getWord();
+ aLocale = xAlt->getLocale();
+ aAlts = xAlt->getAlternatives();
+ uno::Reference< container::XNamed > xNamed( xAlt, uno::UNO_QUERY );
+ if (xNamed.is())
+ sServiceName = xNamed->getName();
+ }
+ SpellErrorDescription aDesc( false, aWord, aLocale, aAlts, nullptr);
+ SfxGrabBagItem aSpellErrorDescription(EE_CHAR_GRABBAG);
+ aSpellErrorDescription.GetGrabBag()["SpellErrorDescription"] <<= aDesc.toSequence();
+ SetAttrib(aSpellErrorDescription, m_nErrorStart, m_nErrorEnd);
+}
+
+void SentenceEditWindow_Impl::SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd)
+{
+ SfxItemSet aSet(m_xEditEngine->GetEmptyItemSet());
+ aSet.Put(rItem);
+ m_xEditEngine->QuickSetAttribs(aSet, ESelection(0, nStart, 0, nEnd));
+ Invalidate();
+}
+
+void SentenceEditWindow_Impl::SetText( const OUString& rStr )
+{
+ m_nErrorStart = m_nErrorEnd = 0;
+ m_xEditEngine->SetText(rStr);
+}
+
+namespace {
+
+struct LanguagePosition_Impl
+{
+ sal_Int32 nPosition;
+ LanguageType eLanguage;
+
+ LanguagePosition_Impl(sal_Int32 nPos, LanguageType eLang) :
+ nPosition(nPos),
+ eLanguage(eLang)
+ {}
+};
+
+}
+
+typedef std::vector<LanguagePosition_Impl> LanguagePositions_Impl;
+
+static void lcl_InsertBreakPosition_Impl(
+ LanguagePositions_Impl& rBreakPositions, sal_Int32 nInsert, LanguageType eLanguage)
+{
+ LanguagePositions_Impl::iterator aStart = rBreakPositions.begin();
+ while(aStart != rBreakPositions.end())
+ {
+ if(aStart->nPosition == nInsert)
+ {
+ //the language of following starts has to overwrite
+ //the one of previous ends
+ aStart->eLanguage = eLanguage;
+ return;
+ }
+ else if(aStart->nPosition > nInsert)
+ {
+
+ rBreakPositions.insert(aStart, LanguagePosition_Impl(nInsert, eLanguage));
+ return;
+ }
+ else
+ ++aStart;
+ }
+ rBreakPositions.emplace_back(nInsert, eLanguage);
+}
+
+/*-------------------------------------------------------------------------
+ Returns the text in spell portions. Each portion contains text with an
+ equal language and attribute. The spell alternatives are empty.
+ -----------------------------------------------------------------------*/
+svx::SpellPortions SentenceEditWindow_Impl::CreateSpellPortions() const
+{
+ svx::SpellPortions aRet;
+
+ const sal_Int32 nTextLen = m_xEditEngine->GetTextLen(0);
+
+ std::vector<EECharAttrib> aAttribList;
+ m_xEditEngine->GetCharAttribs(0, aAttribList);
+
+ if (nTextLen)
+ {
+ int nCursor(0);
+ LanguagePositions_Impl aBreakPositions;
+ const EECharAttrib* pLastLang = nullptr;
+ const EECharAttrib* pLastError = nullptr;
+ LanguageType eLang = LANGUAGE_DONTKNOW;
+ const EECharAttrib* pError = nullptr;
+ while (nCursor < nTextLen)
+ {
+ const EECharAttrib* pLang = FindCharAttrib(nCursor, EE_CHAR_LANGUAGE, aAttribList);
+ if(pLang && pLang != pLastLang)
+ {
+ eLang = static_cast<const SvxLanguageItem*>(pLang->pAttr)->GetLanguage();
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nStart, eLang);
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pLang->nEnd, eLang);
+ pLastLang = pLang;
+ }
+ pError = FindCharAttrib(nCursor, EE_CHAR_GRABBAG, aAttribList);
+ if (pError && pLastError != pError)
+ {
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nStart, eLang);
+ lcl_InsertBreakPosition_Impl(aBreakPositions, pError->nEnd, eLang);
+ pLastError = pError;
+
+ }
+ ++nCursor;
+ }
+
+ if (aBreakPositions.empty())
+ {
+ //if all content has been overwritten the attributes may have been removed, too
+ svx::SpellPortion aPortion1;
+ aPortion1.eLanguage = GetSpellDialog()->GetSelectedLang_Impl();
+
+ aPortion1.sText = m_xEditEngine->GetText(ESelection(0, 0, 0, nTextLen));
+
+ aRet.push_back(aPortion1);
+ }
+ else
+ {
+ LanguagePositions_Impl::iterator aStart = aBreakPositions.begin();
+ //start should always be Null
+ eLang = aStart->eLanguage;
+ sal_Int32 nStart = aStart->nPosition;
+ DBG_ASSERT(!nStart, "invalid start position - language attribute missing?");
+ ++aStart;
+
+ while(aStart != aBreakPositions.end())
+ {
+ svx::SpellPortion aPortion1;
+ aPortion1.eLanguage = eLang;
+
+ aPortion1.sText = m_xEditEngine->GetText(ESelection(0, nStart, 0, aStart->nPosition));
+
+ bool bIsIgnoreError = m_aIgnoreErrorsAt.find( nStart ) != m_aIgnoreErrorsAt.end();
+ if( bIsIgnoreError )
+ {
+ aPortion1.bIgnoreThisError = true;
+ }
+ aRet.push_back(aPortion1);
+ nStart = aStart->nPosition;
+ eLang = aStart->eLanguage;
+ ++aStart;
+ }
+ }
+
+ // quick partly fix of #i71318. Correct fix needs to patch the EditEngine itself...
+ // this one will only prevent text from disappearing. It may to not have the
+ // correct language and will probably not spell checked...
+ const sal_uInt32 nPara = m_xEditEngine->GetParagraphCount();
+ if (nPara > 1)
+ {
+ OUStringBuffer aLeftOverText;
+ for (sal_uInt32 i = 1; i < nPara; ++i)
+ {
+ aLeftOverText.append("\x0a"); // the manual line break...
+ aLeftOverText.append(m_xEditEngine->GetText(i));
+ }
+ if (pError)
+ { // we need to add a new portion containing the left-over text
+ svx::SpellPortion aPortion2;
+ aPortion2.eLanguage = eLang;
+ aPortion2.sText = aLeftOverText.makeStringAndClear();
+ aRet.push_back( aPortion2 );
+ }
+ else
+ { // we just need to append the left-over text to the last portion (which had no errors)
+ aRet[ aRet.size() - 1 ].sText += aLeftOverText;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+void SentenceEditWindow_Impl::Undo()
+{
+ SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
+ DBG_ASSERT(GetUndoActionCount(), "no undo actions available" );
+ if(!GetUndoActionCount())
+ return;
+ bool bSaveUndoEdit = IsUndoEditMode();
+ SpellUndoAction_Impl* pUndoAction;
+ //if the undo edit mode is active then undo all changes until the UNDO_EDIT_MODE action has been found
+ do
+ {
+ pUndoAction = static_cast<SpellUndoAction_Impl*>(rUndoMgr.GetUndoAction());
+ rUndoMgr.Undo();
+ }while(bSaveUndoEdit && SPELLUNDO_UNDO_EDIT_MODE != pUndoAction->GetId() && GetUndoActionCount());
+
+ if(bSaveUndoEdit || SPELLUNDO_CHANGE_GROUP == pUndoAction->GetId())
+ GetSpellDialog()->UpdateBoxes_Impl();
+}
+
+void SentenceEditWindow_Impl::ResetUndo()
+{
+ SfxUndoManager& rUndo = m_xEditEngine->GetUndoManager();
+ rUndo.Clear();
+}
+
+void SentenceEditWindow_Impl::AddUndoAction( std::unique_ptr<SfxUndoAction> pAction )
+{
+ SfxUndoManager& rUndoMgr = m_xEditEngine->GetUndoManager();
+ rUndoMgr.AddUndoAction(std::move(pAction));
+ GetSpellDialog()->m_xUndoPB->set_sensitive(true);
+}
+
+size_t SentenceEditWindow_Impl::GetUndoActionCount() const
+{
+ return m_xEditEngine->GetUndoManager().GetUndoActionCount();
+}
+
+void SentenceEditWindow_Impl::UndoActionStart( sal_uInt16 nId )
+{
+ m_xEditEngine->UndoActionStart(nId);
+}
+
+void SentenceEditWindow_Impl::UndoActionEnd()
+{
+ m_xEditEngine->UndoActionEnd();
+}
+
+void SentenceEditWindow_Impl::MoveErrorEnd(long nOffset)
+{
+ // Shouldn't we always add the real signed value instead???
+ if(nOffset > 0)
+ m_nErrorEnd = m_nErrorEnd - static_cast<sal_Int32>(nOffset);
+ else
+ m_nErrorEnd = m_nErrorEnd - static_cast<sal_Int32>(-nOffset);
+}
+
+
+void SentenceEditWindow_Impl::SetUndoEditMode(bool bSet)
+{
+ DBG_ASSERT(!bSet || m_bIsUndoEditMode != bSet, "SetUndoEditMode with equal values?");
+ m_bIsUndoEditMode = bSet;
+ //disable all buttons except the Change
+ SpellDialog* pSpellDialog = GetSpellDialog();
+ weld::Widget* aControls[] =
+ {
+ pSpellDialog->m_xChangeAllPB.get(),
+ pSpellDialog->m_xExplainFT.get(),
+ pSpellDialog->m_xIgnoreAllPB.get(),
+ pSpellDialog->m_xIgnoreRulePB.get(),
+ pSpellDialog->m_xIgnorePB.get(),
+ pSpellDialog->m_xSuggestionLB.get(),
+ pSpellDialog->m_xSuggestionFT.get(),
+ pSpellDialog->m_xLanguageFT.get(),
+ pSpellDialog->m_xLanguageLB->get_widget(),
+ pSpellDialog->m_xAddToDictMB.get(),
+ pSpellDialog->m_xAddToDictPB.get(),
+ pSpellDialog->m_xAutoCorrPB.get(),
+ nullptr
+ };
+ sal_Int32 nIdx = 0;
+ do
+ {
+ aControls[nIdx]->set_sensitive(false);
+ }
+ while(aControls[++nIdx]);
+
+ //remove error marks
+ ESelection aAll(0, 0, 0, EE_TEXTPOS_ALL);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_COLOR);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CJK);
+ m_xEditEngine->RemoveAttribs(aAll, false, EE_CHAR_WEIGHT_CTL);
+ Invalidate();
+
+ //put the appropriate action on the Undo-stack
+ AddUndoAction( std::make_unique<SpellUndoAction_Impl>(
+ SPELLUNDO_UNDO_EDIT_MODE, GetSpellDialog()->aDialogUndoLink) );
+ pSpellDialog->m_xChangePB->set_sensitive(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/about.cxx b/cui/source/dialogs/about.cxx
new file mode 100644
index 000000000..99245b94b
--- /dev/null
+++ b/cui/source/dialogs/about.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 <about.hxx>
+
+#include <osl/process.h> //osl_getProcessLocale
+#include <rtl/character.hxx> //rtl::isAsciiHexDigit
+#include <sal/log.hxx> //SAL_WARN
+#include <vcl/settings.hxx> //GetSettings
+#include <vcl/svapp.hxx> //Application::
+#include <vcl/virdev.hxx> //VirtualDevice
+#include <vcl/weld.hxx>
+
+#include <config_buildid.h> //EXTRA_BUILDID
+#include <dialmgr.hxx> //CuiResId
+#include <i18nlangtag/languagetag.hxx>
+#include <sfx2/app.hxx> //SfxApplication::loadBrandSvg
+#include <strings.hrc>
+#include <svtools/langhelp.hxx>
+#include <unotools/bootstrap.hxx> //utl::Bootstrap::getBuildIdData
+#include <unotools/configmgr.hxx> //ConfigManager::
+
+#include <com/sun/star/datatransfer/clipboard/SystemClipboard.hpp>
+#include <vcl/unohelp2.hxx>
+
+#include <config_feature_opencl.h>
+#if HAVE_FEATURE_OPENCL
+#include <opencl/openclwrapper.hxx>
+#endif
+#include <officecfg/Office/Calc.hxx>
+#include <officecfg/Office/Common.hxx>
+
+using namespace ::com::sun::star::uno;
+
+AboutDialog::AboutDialog(weld::Window *pParent)
+ : GenericDialogController(pParent, "cui/ui/aboutdialog.ui", "AboutDialog"),
+ m_pCreditsButton(m_xBuilder->weld_link_button("btnCredits")),
+ m_pWebsiteButton(m_xBuilder->weld_link_button("btnWebsite")),
+ m_pReleaseNotesButton(m_xBuilder->weld_link_button("btnReleaseNotes")),
+ m_pCloseButton(m_xBuilder->weld_button("btnClose")),
+ m_pCopyButton(m_xBuilder->weld_button("btnCopyVersion")),
+ m_pBrandImage(m_xBuilder->weld_image("imBrand")),
+ m_pAboutImage(m_xBuilder->weld_image("imAbout")),
+ m_pVersionLabel(m_xBuilder->weld_label("lbVersionString")),
+ m_pBuildCaption(m_xBuilder->weld_label("lbBuild")),
+ m_pBuildLabel(m_xBuilder->weld_link_button("lbBuildString")),
+ m_pEnvLabel(m_xBuilder->weld_label("lbEnvString")),
+ m_pUILabel(m_xBuilder->weld_label("lbUIString")),
+ m_pLocaleLabel(m_xBuilder->weld_label("lbLocaleString")),
+ m_pMiscLabel(m_xBuilder->weld_label("lbMiscString")),
+ m_pCopyrightLabel(m_xBuilder->weld_label("lbCopyright")) {
+
+ // Labels
+ m_pVersionLabel->set_label(GetVersionString());
+
+ OUString sbuildId = GetBuildString();
+ const long nMaxChar = 25;
+ if (IsStringValidGitHash(sbuildId)) {
+ m_pBuildLabel->set_uri("https://gerrit.libreoffice.org/gitweb?p=core.git;a=log;h="
+ + sbuildId);
+ m_pBuildLabel->set_label(sbuildId.getLength() > nMaxChar ? sbuildId.replaceAt(
+ nMaxChar, sbuildId.getLength() - nMaxChar, "...")
+ : sbuildId);
+ } else {
+ m_pBuildCaption->hide();
+ m_pBuildLabel->hide();
+ }
+
+ m_pEnvLabel->set_label(Application::GetHWOSConfInfo(1));
+ m_pUILabel->set_label(Application::GetHWOSConfInfo(2));
+ m_pLocaleLabel->set_label(GetLocaleString());
+ m_pMiscLabel->set_label(GetMiscString());
+ m_pCopyrightLabel->set_label(GetCopyrightString());
+
+ // Images
+ const long nWidth(m_pCopyrightLabel->get_preferred_size().getWidth());
+ BitmapEx aBackgroundBitmap;
+
+ if (SfxApplication::loadBrandSvg(Application::GetSettings()
+ .GetStyleSettings()
+ .GetDialogColor()
+ .IsDark()
+ ? "shell/logo_inverted"
+ : "shell/logo",
+ aBackgroundBitmap, nWidth * 0.8)) {
+ ScopedVclPtr<VirtualDevice> m_pVirDev =
+ m_pBrandImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
+ m_pBrandImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+ if (SfxApplication::loadBrandSvg("shell/about", aBackgroundBitmap, nWidth * 0.9)) {
+ ScopedVclPtr<VirtualDevice> m_pVirDev =
+ m_pAboutImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aBackgroundBitmap.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aBackgroundBitmap);
+ m_pAboutImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+
+ // Links
+ m_pCreditsButton->set_uri(CuiResId(RID_SVXSTR_ABOUT_CREDITS_URL));
+
+ OUString sURL(officecfg::Office::Common::Help::StartCenter::InfoURL::get());
+ localizeWebserviceURI(sURL);
+ m_pWebsiteButton->set_uri(sURL);
+
+ sURL = officecfg::Office::Common::Menus::ReleaseNotesURL::get() +
+ "?LOvers=" + utl::ConfigManager::getProductVersion() + "&LOlocale=" +
+ LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
+ m_pReleaseNotesButton->set_uri(sURL);
+
+ // Handler
+ m_pCopyButton->connect_clicked(LINK(this, AboutDialog, HandleClick));
+ m_pCloseButton->grab_focus();
+}
+
+AboutDialog::~AboutDialog() {}
+
+bool AboutDialog::IsStringValidGitHash(const OUString &hash) {
+ for (int i = 0; i < hash.getLength(); i++) {
+ if (!std::isxdigit(hash[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+OUString AboutDialog::GetVersionString() {
+ OUString sVersion = CuiResId("%ABOUTBOXPRODUCTVERSION%ABOUTBOXPRODUCTVERSIONSUFFIX");
+
+#ifdef _WIN64
+ sVersion += " (x64)";
+#elif defined(_WIN32)
+ sVersion += " (x86)";
+#endif
+ return sVersion;
+}
+
+OUString AboutDialog::GetBuildString()
+{
+ OUString sBuildId(utl::Bootstrap::getBuildIdData(""));
+ SAL_WARN_IF(sBuildId.isEmpty(), "cui.dialogs", "No BUILDID in bootstrap file");
+
+ return sBuildId;
+}
+
+OUString AboutDialog::GetLocaleString() {
+
+ OUString sLocaleStr;
+
+ rtl_Locale *pLocale;
+ osl_getProcessLocale(&pLocale);
+ if (pLocale && pLocale->Language) {
+ if (pLocale->Country && rtl_uString_getLength(pLocale->Country) > 0)
+ sLocaleStr = OUString::unacquired(&pLocale->Language) + "_" +
+ OUString::unacquired(&pLocale->Country);
+ else
+ sLocaleStr = OUString(pLocale->Language);
+ if (pLocale->Variant && rtl_uString_getLength(pLocale->Variant) > 0)
+ sLocaleStr += OUString(pLocale->Variant);
+ }
+
+ sLocaleStr = Application::GetSettings().GetLanguageTag().getBcp47() + " (" +
+ sLocaleStr + ")";
+
+ OUString aUILocaleStr =
+ Application::GetSettings().GetUILanguageTag().getBcp47();
+ OUString sUILocaleStr(CuiResId(RID_SVXSTR_ABOUT_UILOCALE));
+ if (sUILocaleStr.indexOf("$LOCALE") == -1) {
+ SAL_WARN("cui.dialogs", "translated uilocale string in translations "
+ "doesn't contain $LOCALE placeholder");
+ sUILocaleStr += " $LOCALE";
+ }
+ sUILocaleStr = sUILocaleStr.replaceAll("$LOCALE", aUILocaleStr);
+
+ return sLocaleStr + "; " + sUILocaleStr;
+}
+
+OUString AboutDialog::GetMiscString() {
+
+ OUString sMisc;
+
+ bool const extra = EXTRA_BUILDID[0] != '\0';
+ // extracted from the 'if' to avoid Clang -Wunreachable-code
+ if (extra) {
+ sMisc = EXTRA_BUILDID "\n";
+ }
+
+ OUString aCalcMode = "Calc: "; // Calc calculation mode
+
+#if HAVE_FEATURE_OPENCL
+ bool bOpenCL = openclwrapper::GPUEnv::isOpenCLEnabled();
+ if (bOpenCL)
+ aCalcMode += "CL";
+#else
+ const bool bOpenCL = false;
+#endif
+
+ static const bool bThreadingProhibited =
+ std::getenv("SC_NO_THREADED_CALCULATION");
+ bool bThreadedCalc = officecfg::Office::Calc::Formula::Calculation::
+ UseThreadedCalculationForFormulaGroups::get();
+
+ if (!bThreadingProhibited && !bOpenCL && bThreadedCalc) {
+ if (!aCalcMode.endsWith(" "))
+ aCalcMode += " ";
+ aCalcMode += "threaded";
+ }
+
+ sMisc += aCalcMode;
+
+ return sMisc;
+}
+
+OUString AboutDialog::GetCopyrightString() {
+ OUString sVendorTextStr(CuiResId(RID_SVXSTR_ABOUT_VENDOR));
+ OUString aCopyrightString =
+ sVendorTextStr + "\n" + CuiResId(RID_SVXSTR_ABOUT_COPYRIGHT) + "\n";
+
+ if (utl::ConfigManager::getProductName() == "LibreOffice")
+ aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_BASED_ON);
+ else
+ aCopyrightString += CuiResId(RID_SVXSTR_ABOUT_DERIVED);
+
+ return aCopyrightString;
+}
+
+//special labels to comply with previous version info
+IMPL_LINK_NOARG(AboutDialog, HandleClick, weld::Button &, void) {
+ css::uno::Reference<css::datatransfer::clipboard::XClipboard> xClipboard =
+ css::datatransfer::clipboard::SystemClipboard::create(
+ comphelper::getProcessComponentContext());
+
+ OUString sInfo = "Version: " + m_pVersionLabel->get_label() + "\n" // version
+ "Build ID: " + GetBuildString() + "\n" + // build id
+ Application::GetHWOSConfInfo(0,false) + "\n" // env+UI
+ "Locale: " + m_pLocaleLabel->get_label() + "\n" + // locale
+ m_pMiscLabel->get_label(); // misc
+
+ vcl::unohelper::TextDataObject::CopyStringTo(sInfo, xClipboard);
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ \ No newline at end of file
diff --git a/cui/source/dialogs/colorpicker.cxx b/cui/source/dialogs/colorpicker.cxx
new file mode 100644
index 000000000..65f03fb3a
--- /dev/null
+++ b/cui/source/dialogs/colorpicker.cxx
@@ -0,0 +1,1334 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
+#include <com/sun/star/beans/XPropertyAccess.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/awt/XWindow.hpp>
+#include <cppuhelper/compbase.hxx>
+#include <cppuhelper/supportsservice.hxx>
+#include <cppuhelper/basemutex.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <svx/hexcolorcontrol.hxx>
+#include <basegfx/color/bcolortools.hxx>
+#include <colorpicker.hxx>
+#include <cmath>
+#include <o3tl/typed_flags_set.hxx>
+
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::beans;
+using namespace ::basegfx;
+
+namespace {
+
+enum class UpdateFlags
+{
+ NONE = 0x00,
+ RGB = 0x01,
+ CMYK = 0x02,
+ HSB = 0x04,
+ ColorChooser = 0x08,
+ ColorSlider = 0x10,
+ Hex = 0x20,
+ All = 0x3f,
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<UpdateFlags> : is_typed_flags<UpdateFlags, 0x3f> {};
+}
+
+
+namespace cui
+{
+
+namespace {
+
+enum class ColorComponent {
+ Red,
+ Green,
+ Blue,
+ Hue,
+ Saturation,
+ Brightness,
+ Cyan,
+ Yellow,
+ Magenta,
+ Key,
+};
+
+}
+
+// color space conversion helpers
+
+static void RGBtoHSV( double dR, double dG, double dB, double& dH, double& dS, double& dV )
+{
+ BColor result = basegfx::utils::rgb2hsv( BColor( dR, dG, dB ) );
+
+ dH = result.getX();
+ dS = result.getY();
+ dV = result.getZ();
+}
+
+static void HSVtoRGB(double dH, double dS, double dV, double& dR, double& dG, double& dB )
+{
+ BColor result = basegfx::utils::hsv2rgb( BColor( dH, dS, dV ) );
+
+ dR = result.getRed();
+ dG = result.getGreen();
+ dB = result.getBlue();
+}
+
+// CMYK values from 0 to 1
+static void CMYKtoRGB( double fCyan, double fMagenta, double fYellow, double fKey, double& dR, double& dG, double& dB )
+{
+ fCyan = (fCyan * ( 1.0 - fKey )) + fKey;
+ fMagenta = (fMagenta * ( 1.0 - fKey )) + fKey;
+ fYellow = (fYellow * ( 1.0 - fKey )) + fKey;
+
+ dR = std::max( std::min( ( 1.0 - fCyan ), 1.0), 0.0 );
+ dG = std::max( std::min( ( 1.0 - fMagenta ), 1.0), 0.0 );
+ dB = std::max( std::min( ( 1.0 - fYellow ), 1.0), 0.0 );
+}
+
+// CMY results from 0 to 1
+static void RGBtoCMYK( double dR, double dG, double dB, double& fCyan, double& fMagenta, double& fYellow, double& fKey )
+{
+ fCyan = 1 - dR;
+ fMagenta = 1 - dG;
+ fYellow = 1 - dB;
+
+ //CMYK and CMY values from 0 to 1
+ fKey = 1.0;
+ if( fCyan < fKey ) fKey = fCyan;
+ if( fMagenta < fKey ) fKey = fMagenta;
+ if( fYellow < fKey ) fKey = fYellow;
+
+ if( fKey >= 1.0 )
+ {
+ //Black
+ fCyan = 0.0;
+ fMagenta = 0.0;
+ fYellow = 0.0;
+ }
+ else
+ {
+ fCyan = ( fCyan - fKey ) / ( 1.0 - fKey );
+ fMagenta = ( fMagenta - fKey ) / ( 1.0 - fKey );
+ fYellow = ( fYellow - fKey ) / ( 1.0 - fKey );
+ }
+}
+
+namespace {
+
+class ColorPreviewControl : public weld::CustomWidgetController
+{
+private:
+ Color m_aColor;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+public:
+ ColorPreviewControl()
+ {
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 10,
+ pDrawingArea->get_text_height() * 2);
+ }
+
+ void SetColor(const Color& rCol)
+ {
+ if (rCol != m_aColor)
+ {
+ m_aColor = rCol;
+ Invalidate();
+ }
+ }
+};
+
+}
+
+void ColorPreviewControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.SetFillColor(m_aColor);
+ rRenderContext.SetLineColor(m_aColor);
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), GetOutputSizePixel()));
+}
+
+namespace {
+
+enum ColorMode { HUE, SATURATION, BRIGHTNESS, RED, GREEN, BLUE };
+
+}
+
+const ColorMode DefaultMode = HUE;
+
+namespace {
+
+class ColorFieldControl : public weld::CustomWidgetController
+{
+public:
+ ColorFieldControl()
+ : meMode( DefaultMode )
+ , mdX( -1.0 )
+ , mdY( -1.0 )
+ , mbMouseCaptured(false)
+ {
+ }
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 40,
+ pDrawingArea->get_text_height() * 10);
+ }
+
+ virtual ~ColorFieldControl() override
+ {
+ mxBitmap.disposeAndClear();
+ }
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+
+ void UpdateBitmap();
+ void ShowPosition( const Point& rPos, bool bUpdate );
+ void UpdatePosition();
+ void Modify();
+
+ void SetValues(Color aColor, ColorMode eMode, double x, double y);
+ double GetX() const { return mdX;}
+ double GetY() const { return mdY;}
+
+ void SetModifyHdl(const Link<ColorFieldControl&,void>& rLink) { maModifyHdl = rLink; }
+
+private:
+ ColorMode meMode;
+ Color maColor;
+ double mdX;
+ double mdY;
+ bool mbMouseCaptured;
+ Point maPosition;
+ VclPtr<VirtualDevice> mxBitmap;
+ Link<ColorFieldControl&,void> maModifyHdl;
+ std::vector<sal_uInt8> maRGB_Horiz;
+ std::vector<sal_uInt16> maGrad_Horiz;
+ std::vector<sal_uInt16> maPercent_Horiz;
+ std::vector<sal_uInt8> maRGB_Vert;
+ std::vector<sal_uInt16> maPercent_Vert;
+};
+
+}
+
+void ColorFieldControl::UpdateBitmap()
+{
+ const Size aSize(GetOutputSizePixel());
+
+ if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
+ mxBitmap.disposeAndClear();
+
+ const sal_Int32 nWidth = aSize.Width();
+ const sal_Int32 nHeight = aSize.Height();
+
+ if (nWidth == 0 || nHeight == 0)
+ return;
+
+ if (!mxBitmap)
+ {
+ mxBitmap = VclPtr<VirtualDevice>::Create();
+ mxBitmap->SetOutputSizePixel(aSize);
+
+ maRGB_Horiz.resize( nWidth );
+ maGrad_Horiz.resize( nWidth );
+ maPercent_Horiz.resize( nWidth );
+
+ sal_uInt8* pRGB = maRGB_Horiz.data();
+ sal_uInt16* pGrad = maGrad_Horiz.data();
+ sal_uInt16* pPercent = maPercent_Horiz.data();
+
+ for( sal_Int32 x = 0; x < nWidth; x++ )
+ {
+ *pRGB++ = static_cast<sal_uInt8>((x * 256) / nWidth);
+ *pGrad++ = static_cast<sal_uInt16>((x * 359) / nWidth);
+ *pPercent++ = static_cast<sal_uInt16>((x * 100) / nWidth);
+ }
+
+ maRGB_Vert.resize(nHeight);
+ maPercent_Vert.resize(nHeight);
+
+ pRGB = maRGB_Vert.data();
+ pPercent = maPercent_Vert.data();
+
+ sal_Int32 y = nHeight;
+ while (y--)
+ {
+ *pRGB++ = static_cast<sal_uInt8>((y * 256) / nHeight);
+ *pPercent++ = static_cast<sal_uInt16>((y * 100) / nHeight);
+ }
+ }
+
+ sal_uInt8* pRGB_Horiz = maRGB_Horiz.data();
+ sal_uInt16* pGrad_Horiz = maGrad_Horiz.data();
+ sal_uInt16* pPercent_Horiz = maPercent_Horiz.data();
+ sal_uInt8* pRGB_Vert = maRGB_Vert.data();
+ sal_uInt16* pPercent_Vert = maPercent_Vert.data();
+
+ Color aBitmapColor(maColor);
+
+ sal_uInt16 nHue, nSat, nBri;
+ maColor.RGBtoHSB(nHue, nSat, nBri);
+
+ // this has been unlooped for performance reason, please do not merge back!
+
+ sal_uInt16 y = nHeight,x;
+
+ switch(meMode)
+ {
+ case HUE:
+ while (y--)
+ {
+ nBri = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ nSat = pPercent_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ }
+ break;
+ case SATURATION:
+ while (y--)
+ {
+ nBri = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ nHue = pGrad_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ }
+ break;
+ case BRIGHTNESS:
+ while (y--)
+ {
+ nSat = pPercent_Vert[y];
+ x = nWidth;
+ while (x--)
+ {
+ nHue = pGrad_Horiz[x];
+ mxBitmap->DrawPixel(Point(x,y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ }
+ break;
+ case RED:
+ while (y--)
+ {
+ aBitmapColor.SetGreen(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetBlue(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ case GREEN:
+ while (y--)
+ {
+ aBitmapColor.SetRed(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetBlue(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ case BLUE:
+ while (y--)
+ {
+ aBitmapColor.SetGreen(pRGB_Vert[y]);
+ x = nWidth;
+ while (x--)
+ {
+ aBitmapColor.SetRed(pRGB_Horiz[x]);
+ mxBitmap->DrawPixel(Point(x,y), aBitmapColor);
+ }
+ }
+ break;
+ }
+}
+
+void ColorFieldControl::ShowPosition( const Point& rPos, bool bUpdate )
+{
+ if (!mxBitmap)
+ {
+ UpdateBitmap();
+ Invalidate();
+ }
+
+ if (!mxBitmap)
+ return;
+
+ const Size aSize(mxBitmap->GetOutputSizePixel());
+
+ long nX = rPos.X();
+ long nY = rPos.Y();
+ if (nX < 0)
+ nX = 0;
+ else if (nX >= aSize.Width())
+ nX = aSize.Width() - 1;
+
+ if (nY < 0)
+ nY = 0;
+ else if (nY >= aSize.Height())
+ nY = aSize.Height() - 1;
+
+ Point aPos = maPosition;
+ maPosition.setX( nX - 5 );
+ maPosition.setY( nY - 5 );
+ Invalidate(tools::Rectangle(aPos, Size(11, 11)));
+ Invalidate(tools::Rectangle(maPosition, Size(11, 11)));
+
+ if (bUpdate)
+ {
+ mdX = double(nX) / double(aSize.Width() - 1.0);
+ mdY = double(aSize.Height() - 1.0 - nY) / double(aSize.Height() - 1.0);
+
+ maColor = mxBitmap->GetPixel(Point(nX, nY));
+ }
+}
+
+bool ColorFieldControl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ CaptureMouse();
+ mbMouseCaptured = true;
+ ShowPosition(rMEvt.GetPosPixel(), true);
+ Modify();
+ return true;
+}
+
+bool ColorFieldControl::MouseMove(const MouseEvent& rMEvt)
+{
+ if (mbMouseCaptured)
+ {
+ ShowPosition(rMEvt.GetPosPixel(), true);
+ Modify();
+ }
+ return true;
+}
+
+bool ColorFieldControl::MouseButtonUp(const MouseEvent&)
+{
+ ReleaseMouse();
+ mbMouseCaptured = false;
+ return true;
+}
+
+void ColorFieldControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ if (!mxBitmap)
+ UpdateBitmap();
+
+ if (mxBitmap)
+ {
+ Size aSize(GetOutputSizePixel());
+ rRenderContext.DrawOutDev(Point(0, 0), aSize, Point(0, 0), aSize, *mxBitmap);
+ }
+
+ // draw circle around current color
+ if (maColor.IsDark())
+ rRenderContext.SetLineColor( COL_WHITE );
+ else
+ rRenderContext.SetLineColor( COL_BLACK );
+
+ rRenderContext.SetFillColor();
+
+ rRenderContext.DrawEllipse(::tools::Rectangle(maPosition, Size(11, 11)));
+}
+
+void ColorFieldControl::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdateBitmap();
+ UpdatePosition();
+}
+
+void ColorFieldControl::Modify()
+{
+ maModifyHdl.Call( *this );
+}
+
+void ColorFieldControl::SetValues( Color aColor, ColorMode eMode, double x, double y )
+{
+ bool bUpdateBitmap = (maColor!= aColor) || (meMode != eMode);
+ if( !(bUpdateBitmap || (mdX != x) || (mdY != y)) )
+ return;
+
+ maColor = aColor;
+ meMode = eMode;
+ mdX = x;
+ mdY = y;
+
+ if (bUpdateBitmap)
+ UpdateBitmap();
+ UpdatePosition();
+ if (bUpdateBitmap)
+ Invalidate();
+}
+
+void ColorFieldControl::UpdatePosition()
+{
+ Size aSize(GetOutputSizePixel());
+ ShowPosition(Point(static_cast<long>(mdX * aSize.Width()), static_cast<long>((1.0 - mdY) * aSize.Height())), false);
+}
+
+namespace {
+
+class ColorSliderControl : public weld::CustomWidgetController
+{
+public:
+ ColorSliderControl();
+ virtual ~ColorSliderControl() override;
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual void Resize() override;
+
+ void UpdateBitmap();
+ void ChangePosition( long nY );
+ void Modify();
+
+ void SetValue( const Color& rColor, ColorMode eMode, double dValue );
+ double GetValue() const { return mdValue; }
+
+ void SetModifyHdl( const Link<ColorSliderControl&,void>& rLink ) { maModifyHdl = rLink; }
+
+ sal_Int16 GetLevel() const { return mnLevel; }
+
+private:
+ Link<ColorSliderControl&,void> maModifyHdl;
+ Color maColor;
+ ColorMode meMode;
+ VclPtr<VirtualDevice> mxBitmap;
+ sal_Int16 mnLevel;
+ double mdValue;
+};
+
+}
+
+ColorSliderControl::ColorSliderControl()
+ : meMode( DefaultMode )
+ , mnLevel( 0 )
+ , mdValue( -1.0 )
+{
+}
+
+void ColorSliderControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(pDrawingArea->get_approximate_digit_width() * 3, -1);
+}
+
+ColorSliderControl::~ColorSliderControl()
+{
+ mxBitmap.disposeAndClear();
+}
+
+void ColorSliderControl::UpdateBitmap()
+{
+ Size aSize(1, GetOutputSizePixel().Height());
+
+ if (mxBitmap && mxBitmap->GetOutputSizePixel() != aSize)
+ mxBitmap.disposeAndClear();
+
+ if (!mxBitmap)
+ {
+ mxBitmap = VclPtr<VirtualDevice>::Create();
+ mxBitmap->SetOutputSizePixel(aSize);
+ }
+
+ const long nY = aSize.Height() - 1;
+
+ Color aBitmapColor(maColor);
+
+ sal_uInt16 nHue, nSat, nBri;
+ maColor.RGBtoHSB(nHue, nSat, nBri);
+
+ // this has been unlooped for performance reason, please do not merge back!
+
+ switch (meMode)
+ {
+ case HUE:
+ nSat = 100;
+ nBri = 100;
+ for (long y = 0; y <= nY; y++)
+ {
+ nHue = static_cast<sal_uInt16>((359 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case SATURATION:
+ nBri = std::max(sal_uInt16(32), nBri);
+ for (long y = 0; y <= nY; y++)
+ {
+ nSat = static_cast<sal_uInt16>((100 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case BRIGHTNESS:
+ for (long y = 0; y <= nY; y++)
+ {
+ nBri = static_cast<sal_uInt16>((100 * y) / nY);
+ mxBitmap->DrawPixel(Point(0, nY - y), Color::HSBtoRGB(nHue, nSat, nBri));
+ }
+ break;
+
+ case RED:
+ for (long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetRed(sal_uInt8((long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+
+ case GREEN:
+ for (long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetGreen(sal_uInt8((long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+
+ case BLUE:
+ for (long y = 0; y <= nY; y++)
+ {
+ aBitmapColor.SetBlue(sal_uInt8((long(255) * y) / nY));
+ mxBitmap->DrawPixel(Point(0, nY - y), aBitmapColor);
+ }
+ break;
+ }
+}
+
+void ColorSliderControl::ChangePosition(long nY)
+{
+ const long nHeight = GetOutputSizePixel().Height() - 1;
+
+ if (nY < 0)
+ nY = 0;
+ else if (nY > nHeight)
+ nY = nHeight;
+
+ mnLevel = nY;
+ mdValue = double(nHeight - nY) / double(nHeight);
+}
+
+bool ColorSliderControl::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ CaptureMouse();
+ ChangePosition(rMEvt.GetPosPixel().Y());
+ Modify();
+ return true;
+}
+
+bool ColorSliderControl::MouseMove(const MouseEvent& rMEvt)
+{
+ if (IsMouseCaptured())
+ {
+ ChangePosition(rMEvt.GetPosPixel().Y());
+ Modify();
+ }
+ return true;
+}
+
+bool ColorSliderControl::MouseButtonUp(const MouseEvent&)
+{
+ ReleaseMouse();
+ return true;
+}
+
+void ColorSliderControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ if (!mxBitmap)
+ UpdateBitmap();
+
+ const Size aSize(GetOutputSizePixel());
+
+ Point aPos;
+ int x = aSize.Width();
+ while (x--)
+ {
+ rRenderContext.DrawOutDev(aPos, aSize, Point(0,0), aSize, *mxBitmap);
+ aPos.AdjustX(1);
+ }
+}
+
+void ColorSliderControl::Resize()
+{
+ CustomWidgetController::Resize();
+ UpdateBitmap();
+}
+
+void ColorSliderControl::Modify()
+{
+ maModifyHdl.Call(*this);
+}
+
+void ColorSliderControl::SetValue(const Color& rColor, ColorMode eMode, double dValue)
+{
+ bool bUpdateBitmap = (rColor != maColor) || (eMode != meMode);
+ if( bUpdateBitmap || (mdValue != dValue))
+ {
+ maColor = rColor;
+ mdValue = dValue;
+ mnLevel = static_cast<sal_Int16>((1.0-dValue) * GetOutputSizePixel().Height());
+ meMode = eMode;
+ if (bUpdateBitmap)
+ UpdateBitmap();
+ Invalidate();
+ }
+}
+
+namespace {
+
+class ColorPickerDialog : public weld::GenericDialogController
+{
+private:
+ ColorFieldControl m_aColorField;
+ ColorSliderControl m_aColorSlider;
+ ColorPreviewControl m_aColorPreview;
+ ColorPreviewControl m_aColorPrevious;
+
+ std::unique_ptr<weld::CustomWeld> m_xColorField;
+ std::unique_ptr<weld::CustomWeld> m_xColorSlider;
+ std::unique_ptr<weld::CustomWeld> m_xColorPreview;
+ std::unique_ptr<weld::CustomWeld> m_xColorPrevious;
+
+ std::unique_ptr<weld::Widget> m_xFISliderLeft;
+ std::unique_ptr<weld::Widget> m_xFISliderRight;
+ std::unique_ptr<weld::RadioButton> m_xRBRed;
+ std::unique_ptr<weld::RadioButton> m_xRBGreen;
+ std::unique_ptr<weld::RadioButton> m_xRBBlue;
+ std::unique_ptr<weld::RadioButton> m_xRBHue;
+ std::unique_ptr<weld::RadioButton> m_xRBSaturation;
+ std::unique_ptr<weld::RadioButton> m_xRBBrightness;
+
+ std::unique_ptr<weld::SpinButton> m_xMFRed;
+ std::unique_ptr<weld::SpinButton> m_xMFGreen;
+ std::unique_ptr<weld::SpinButton> m_xMFBlue;
+ std::unique_ptr<weld::HexColorControl> m_xEDHex;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMFHue;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFSaturation;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFBrightness;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMFCyan;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFMagenta;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFYellow;
+ std::unique_ptr<weld::MetricSpinButton> m_xMFKey;
+
+public:
+ ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nMode);
+
+ void update_color(UpdateFlags n = UpdateFlags::All);
+
+ DECL_LINK(ColorFieldControlModifydl, ColorFieldControl&, void);
+ DECL_LINK(ColorSliderControlModifyHdl, ColorSliderControl&, void);
+ DECL_LINK(ColorModifyMetricHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ColorModifySpinHdl, weld::SpinButton&, void);
+ DECL_LINK(ColorModifyEditHdl, weld::Entry&, void);
+ DECL_LINK(ModeModifyHdl, weld::ToggleButton&, void);
+
+ Color GetColor() const;
+
+ void setColorComponent(ColorComponent nComp, double dValue);
+
+private:
+ ColorMode meMode;
+
+ double mdRed, mdGreen, mdBlue;
+ double mdHue, mdSat, mdBri;
+ double mdCyan, mdMagenta, mdYellow, mdKey;
+};
+
+}
+
+ColorPickerDialog::ColorPickerDialog(weld::Window* pParent, Color nColor, sal_Int16 nDialogMode)
+ : GenericDialogController(pParent, "cui/ui/colorpickerdialog.ui", "ColorPicker")
+ , m_xColorField(new weld::CustomWeld(*m_xBuilder, "colorField", m_aColorField))
+ , m_xColorSlider(new weld::CustomWeld(*m_xBuilder, "colorSlider", m_aColorSlider))
+ , m_xColorPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aColorPreview))
+ , m_xColorPrevious(new weld::CustomWeld(*m_xBuilder, "previous", m_aColorPrevious))
+ , m_xFISliderLeft(m_xBuilder->weld_widget("leftImage"))
+ , m_xFISliderRight(m_xBuilder->weld_widget("rightImage"))
+ , m_xRBRed(m_xBuilder->weld_radio_button("redRadiobutton"))
+ , m_xRBGreen(m_xBuilder->weld_radio_button("greenRadiobutton"))
+ , m_xRBBlue(m_xBuilder->weld_radio_button("blueRadiobutton"))
+ , m_xRBHue(m_xBuilder->weld_radio_button("hueRadiobutton"))
+ , m_xRBSaturation(m_xBuilder->weld_radio_button("satRadiobutton"))
+ , m_xRBBrightness(m_xBuilder->weld_radio_button("brightRadiobutton"))
+ , m_xMFRed(m_xBuilder->weld_spin_button("redSpinbutton"))
+ , m_xMFGreen(m_xBuilder->weld_spin_button("greenSpinbutton"))
+ , m_xMFBlue(m_xBuilder->weld_spin_button("blueSpinbutton"))
+ , m_xEDHex(new weld::HexColorControl(m_xBuilder->weld_entry("hexEntry")))
+ , m_xMFHue(m_xBuilder->weld_metric_spin_button("hueSpinbutton", FieldUnit::DEGREE))
+ , m_xMFSaturation(m_xBuilder->weld_metric_spin_button("satSpinbutton", FieldUnit::PERCENT))
+ , m_xMFBrightness(m_xBuilder->weld_metric_spin_button("brightSpinbutton", FieldUnit::PERCENT))
+ , m_xMFCyan(m_xBuilder->weld_metric_spin_button("cyanSpinbutton", FieldUnit::PERCENT))
+ , m_xMFMagenta(m_xBuilder->weld_metric_spin_button("magSpinbutton", FieldUnit::PERCENT))
+ , m_xMFYellow(m_xBuilder->weld_metric_spin_button("yellowSpinbutton", FieldUnit::PERCENT))
+ , m_xMFKey(m_xBuilder->weld_metric_spin_button("keySpinbutton", FieldUnit::PERCENT))
+ , meMode( DefaultMode )
+{
+ m_aColorField.SetModifyHdl( LINK( this, ColorPickerDialog, ColorFieldControlModifydl ) );
+ m_aColorSlider.SetModifyHdl( LINK( this, ColorPickerDialog, ColorSliderControlModifyHdl ) );
+
+ int nMargin = (m_xFISliderLeft->get_preferred_size().Height() + 1) / 2;
+ m_xColorSlider->set_margin_top(nMargin);
+ m_xColorSlider->set_margin_bottom(nMargin);
+
+ Link<weld::MetricSpinButton&,void> aLink3( LINK( this, ColorPickerDialog, ColorModifyMetricHdl ) );
+ m_xMFCyan->connect_value_changed( aLink3 );
+ m_xMFMagenta->connect_value_changed( aLink3 );
+ m_xMFYellow->connect_value_changed( aLink3 );
+ m_xMFKey->connect_value_changed( aLink3 );
+
+ m_xMFHue->connect_value_changed( aLink3 );
+ m_xMFSaturation->connect_value_changed( aLink3 );
+ m_xMFBrightness->connect_value_changed( aLink3 );
+
+ Link<weld::SpinButton&,void> aLink4(LINK(this, ColorPickerDialog, ColorModifySpinHdl));
+ m_xMFRed->connect_value_changed(aLink4);
+ m_xMFGreen->connect_value_changed(aLink4);
+ m_xMFBlue->connect_value_changed(aLink4);
+
+ m_xEDHex->connect_changed(LINK(this, ColorPickerDialog, ColorModifyEditHdl));
+
+ Link<weld::ToggleButton&,void> aLink2 = LINK( this, ColorPickerDialog, ModeModifyHdl );
+ m_xRBRed->connect_toggled( aLink2 );
+ m_xRBGreen->connect_toggled( aLink2 );
+ m_xRBBlue->connect_toggled( aLink2 );
+ m_xRBHue->connect_toggled( aLink2 );
+ m_xRBSaturation->connect_toggled( aLink2 );
+ m_xRBBrightness->connect_toggled( aLink2 );
+
+ Color aColor(nColor);
+
+ // modify
+ if (nDialogMode == 2)
+ {
+ m_aColorPrevious.SetColor(aColor);
+ m_xColorPrevious->show();
+ }
+
+ mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
+ mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
+ mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
+
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+
+ update_color();
+}
+
+static int toInt( double dValue, double dRange )
+{
+ return static_cast< int >( std::floor((dValue * dRange) + 0.5 ) );
+}
+
+Color ColorPickerDialog::GetColor() const
+{
+ return Color( toInt(mdRed,255.0), toInt(mdGreen,255.0), toInt(mdBlue,255.0) );
+}
+
+void ColorPickerDialog::update_color( UpdateFlags n )
+{
+ sal_uInt8 nRed = toInt(mdRed,255.0);
+ sal_uInt8 nGreen = toInt(mdGreen,255.0);
+ sal_uInt8 nBlue = toInt(mdBlue,255.0);
+
+ Color aColor(nRed, nGreen, nBlue);
+
+ if (n & UpdateFlags::RGB) // update RGB
+ {
+ m_xMFRed->set_value(nRed);
+ m_xMFGreen->set_value(nGreen);
+ m_xMFBlue->set_value(nBlue);
+ }
+
+ if (n & UpdateFlags::CMYK) // update CMYK
+ {
+ m_xMFCyan->set_value(toInt(mdCyan, 100.0), FieldUnit::PERCENT);
+ m_xMFMagenta->set_value(toInt(mdMagenta, 100.0), FieldUnit::PERCENT);
+ m_xMFYellow->set_value(toInt(mdYellow, 100.0), FieldUnit::PERCENT);
+ m_xMFKey->set_value(toInt(mdKey, 100.0), FieldUnit::PERCENT);
+ }
+
+ if (n & UpdateFlags::HSB ) // update HSB
+ {
+ m_xMFHue->set_value(toInt(mdHue, 1.0), FieldUnit::DEGREE);
+ m_xMFSaturation->set_value(toInt( mdSat, 100.0), FieldUnit::PERCENT);
+ m_xMFBrightness->set_value(toInt( mdBri, 100.0), FieldUnit::PERCENT);
+ }
+
+ if (n & UpdateFlags::ColorChooser ) // update Color Chooser 1
+ {
+ switch( meMode )
+ {
+ case HUE:
+ m_aColorField.SetValues(aColor, meMode, mdSat, mdBri);
+ break;
+ case SATURATION:
+ m_aColorField.SetValues(aColor, meMode, mdHue / 360.0, mdBri);
+ break;
+ case BRIGHTNESS:
+ m_aColorField.SetValues(aColor, meMode, mdHue / 360.0, mdSat);
+ break;
+ case RED:
+ m_aColorField.SetValues(aColor, meMode, mdBlue, mdGreen);
+ break;
+ case GREEN:
+ m_aColorField.SetValues(aColor, meMode, mdBlue, mdRed);
+ break;
+ case BLUE:
+ m_aColorField.SetValues(aColor, meMode, mdRed, mdGreen);
+ break;
+ }
+ }
+
+ if (n & UpdateFlags::ColorSlider) // update Color Chooser 2
+ {
+ switch (meMode)
+ {
+ case HUE:
+ m_aColorSlider.SetValue(aColor, meMode, mdHue / 360.0);
+ break;
+ case SATURATION:
+ m_aColorSlider.SetValue(aColor, meMode, mdSat);
+ break;
+ case BRIGHTNESS:
+ m_aColorSlider.SetValue(aColor, meMode, mdBri);
+ break;
+ case RED:
+ m_aColorSlider.SetValue(aColor, meMode, mdRed);
+ break;
+ case GREEN:
+ m_aColorSlider.SetValue(aColor, meMode, mdGreen);
+ break;
+ case BLUE:
+ m_aColorSlider.SetValue(aColor, meMode, mdBlue);
+ break;
+ }
+ }
+
+ if (n & UpdateFlags::Hex) // update hex
+ {
+ m_xFISliderLeft->set_margin_top(m_aColorSlider.GetLevel());
+ m_xFISliderRight->set_margin_top(m_aColorSlider.GetLevel());
+ m_xEDHex->SetColor(aColor);
+ }
+ m_aColorPreview.SetColor(aColor);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorFieldControlModifydl, ColorFieldControl&, void)
+{
+ double x = m_aColorField.GetX();
+ double y = m_aColorField.GetY();
+
+ switch( meMode )
+ {
+ case HUE:
+ mdSat = x;
+ setColorComponent( ColorComponent::Brightness, y );
+ break;
+ case SATURATION:
+ mdHue = x * 360.0;
+ setColorComponent( ColorComponent::Brightness, y );
+ break;
+ case BRIGHTNESS:
+ mdHue = x * 360.0;
+ setColorComponent( ColorComponent::Saturation, y );
+ break;
+ case RED:
+ mdBlue = x;
+ setColorComponent( ColorComponent::Green, y );
+ break;
+ case GREEN:
+ mdBlue = x;
+ setColorComponent( ColorComponent::Red, y );
+ break;
+ case BLUE:
+ mdRed = x;
+ setColorComponent( ColorComponent::Green, y );
+ break;
+ }
+
+ update_color(UpdateFlags::All & ~UpdateFlags::ColorChooser);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorSliderControlModifyHdl, ColorSliderControl&, void)
+{
+ double dValue = m_aColorSlider.GetValue();
+ switch (meMode)
+ {
+ case HUE:
+ setColorComponent( ColorComponent::Hue, dValue * 360.0 );
+ break;
+ case SATURATION:
+ setColorComponent( ColorComponent::Saturation, dValue );
+ break;
+ case BRIGHTNESS:
+ setColorComponent( ColorComponent::Brightness, dValue );
+ break;
+ case RED:
+ setColorComponent( ColorComponent::Red, dValue );
+ break;
+ case GREEN:
+ setColorComponent( ColorComponent::Green, dValue );
+ break;
+ case BLUE:
+ setColorComponent( ColorComponent::Blue, dValue );
+ break;
+ }
+
+ update_color(UpdateFlags::All & ~UpdateFlags::ColorSlider);
+}
+
+IMPL_LINK(ColorPickerDialog, ColorModifyMetricHdl, weld::MetricSpinButton&, rEdit, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ if (&rEdit == m_xMFHue.get())
+ {
+ setColorComponent( ColorComponent::Hue, static_cast<double>(m_xMFHue->get_value(FieldUnit::DEGREE)) );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFSaturation.get())
+ {
+ setColorComponent( ColorComponent::Saturation, static_cast<double>(m_xMFSaturation->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFBrightness.get())
+ {
+ setColorComponent( ColorComponent::Brightness, static_cast<double>(m_xMFBrightness->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::HSB;
+ }
+ else if (&rEdit == m_xMFCyan.get())
+ {
+ setColorComponent( ColorComponent::Cyan, static_cast<double>(m_xMFCyan->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFMagenta.get())
+ {
+ setColorComponent( ColorComponent::Magenta, static_cast<double>(m_xMFMagenta->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFYellow.get())
+ {
+ setColorComponent( ColorComponent::Yellow, static_cast<double>(m_xMFYellow->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+ else if (&rEdit == m_xMFKey.get())
+ {
+ setColorComponent( ColorComponent::Key, static_cast<double>(m_xMFKey->get_value(FieldUnit::PERCENT)) / 100.0 );
+ n = UpdateFlags::All & ~UpdateFlags::CMYK;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+IMPL_LINK_NOARG(ColorPickerDialog, ColorModifyEditHdl, weld::Entry&, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ Color aColor = m_xEDHex->GetColor();
+
+ if (aColor != Color(0xffffffff) && aColor != GetColor())
+ {
+ mdRed = static_cast<double>(aColor.GetRed()) / 255.0;
+ mdGreen = static_cast<double>(aColor.GetGreen()) / 255.0;
+ mdBlue = static_cast<double>(aColor.GetBlue()) / 255.0;
+
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ n = UpdateFlags::All & ~UpdateFlags::Hex;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+IMPL_LINK(ColorPickerDialog, ColorModifySpinHdl, weld::SpinButton&, rEdit, void)
+{
+ UpdateFlags n = UpdateFlags::NONE;
+
+ if (&rEdit == m_xMFRed.get())
+ {
+ setColorComponent( ColorComponent::Red, static_cast<double>(m_xMFRed->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+ else if (&rEdit == m_xMFGreen.get())
+ {
+ setColorComponent( ColorComponent::Green, static_cast<double>(m_xMFGreen->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+ else if (&rEdit == m_xMFBlue.get())
+ {
+ setColorComponent( ColorComponent::Blue, static_cast<double>(m_xMFBlue->get_value()) / 255.0 );
+ n = UpdateFlags::All & ~UpdateFlags::RGB;
+ }
+
+ if (n != UpdateFlags::NONE)
+ update_color(n);
+}
+
+
+IMPL_LINK_NOARG(ColorPickerDialog, ModeModifyHdl, weld::ToggleButton&, void)
+{
+ ColorMode eMode = HUE;
+
+ if (m_xRBRed->get_active())
+ {
+ eMode = RED;
+ }
+ else if (m_xRBGreen->get_active())
+ {
+ eMode = GREEN;
+ }
+ else if (m_xRBBlue->get_active())
+ {
+ eMode = BLUE;
+ }
+ else if (m_xRBSaturation->get_active())
+ {
+ eMode = SATURATION;
+ }
+ else if (m_xRBBrightness->get_active())
+ {
+ eMode = BRIGHTNESS;
+ }
+
+ if (meMode != eMode)
+ {
+ meMode = eMode;
+ update_color(UpdateFlags::ColorChooser | UpdateFlags::ColorSlider);
+ }
+}
+
+void ColorPickerDialog::setColorComponent( ColorComponent nComp, double dValue )
+{
+ switch( nComp )
+ {
+ case ColorComponent::Red:
+ mdRed = dValue;
+ break;
+ case ColorComponent::Green:
+ mdGreen = dValue;
+ break;
+ case ColorComponent::Blue:
+ mdBlue = dValue;
+ break;
+ case ColorComponent::Hue:
+ mdHue = dValue;
+ break;
+ case ColorComponent::Saturation:
+ mdSat = dValue;
+ break;
+ case ColorComponent::Brightness:
+ mdBri = dValue;
+ break;
+ case ColorComponent::Cyan:
+ mdCyan = dValue;
+ break;
+ case ColorComponent::Yellow:
+ mdYellow = dValue;
+ break;
+ case ColorComponent::Magenta:
+ mdMagenta = dValue;
+ break;
+ case ColorComponent::Key:
+ mdKey = dValue;
+ break;
+ }
+
+ if (nComp == ColorComponent::Red || nComp == ColorComponent::Green || nComp == ColorComponent::Blue)
+ {
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ }
+ else if (nComp == ColorComponent::Hue || nComp == ColorComponent::Saturation || nComp == ColorComponent::Brightness)
+ {
+ HSVtoRGB( mdHue, mdSat, mdBri, mdRed, mdGreen, mdBlue );
+ RGBtoCMYK( mdRed, mdGreen, mdBlue, mdCyan, mdMagenta, mdYellow, mdKey );
+ }
+ else
+ {
+ CMYKtoRGB( mdCyan, mdMagenta, mdYellow, mdKey, mdRed, mdGreen, mdBlue );
+ RGBtoHSV( mdRed, mdGreen, mdBlue, mdHue, mdSat, mdBri );
+ }
+}
+
+typedef ::cppu::WeakComponentImplHelper< XServiceInfo, XExecutableDialog, XInitialization, XPropertyAccess > ColorPickerBase;
+
+namespace {
+
+class ColorPicker : protected ::cppu::BaseMutex, // Struct for right initialization of mutex member! Must be first of baseclasses.
+ public ColorPickerBase
+{
+public:
+ explicit ColorPicker();
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
+
+ // XInitialization
+ virtual OUString SAL_CALL getImplementationName( ) override;
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
+
+ // XPropertyAccess
+ virtual Sequence< PropertyValue > SAL_CALL getPropertyValues( ) override;
+ virtual void SAL_CALL setPropertyValues( const Sequence< PropertyValue >& aProps ) override;
+
+ // XExecutableDialog
+ virtual void SAL_CALL setTitle( const OUString& aTitle ) override;
+ virtual sal_Int16 SAL_CALL execute( ) override;
+
+private:
+ Color mnColor;
+ sal_Int16 mnMode;
+ Reference<css::awt::XWindow> mxParent;
+};
+
+}
+
+OUString ColorPicker_getImplementationName()
+{
+ return "com.sun.star.cui.ColorPicker";
+}
+
+Reference< XInterface > ColorPicker_createInstance( Reference< XComponentContext > const & )
+{
+ return static_cast<XWeak*>( new ColorPicker );
+}
+
+Sequence< OUString > ColorPicker_getSupportedServiceNames()
+{
+ Sequence< OUString > seq { "com.sun.star.ui.dialogs.ColorPicker" };
+ return seq;
+}
+
+static const OUStringLiteral gsColorKey( "Color" );
+static const OUStringLiteral gsModeKey( "Mode" );
+
+ColorPicker::ColorPicker()
+ : ColorPickerBase( m_aMutex )
+ , mnColor( 0 )
+ , mnMode( 0 )
+{
+}
+
+// XInitialization
+void SAL_CALL ColorPicker::initialize( const Sequence< Any >& aArguments )
+{
+ if( aArguments.getLength() == 1 )
+ {
+ aArguments[0] >>= mxParent;
+ }
+}
+
+// XInitialization
+OUString SAL_CALL ColorPicker::getImplementationName( )
+{
+ return ColorPicker_getImplementationName();
+}
+
+sal_Bool SAL_CALL ColorPicker::supportsService( const OUString& sServiceName )
+{
+ return cppu::supportsService(this, sServiceName);
+}
+
+Sequence< OUString > SAL_CALL ColorPicker::getSupportedServiceNames( )
+{
+ return ColorPicker_getSupportedServiceNames();
+}
+
+// XPropertyAccess
+Sequence< PropertyValue > SAL_CALL ColorPicker::getPropertyValues( )
+{
+ Sequence< PropertyValue > props(1);
+ props[0].Name = gsColorKey;
+ props[0].Value <<= mnColor;
+ return props;
+}
+
+void SAL_CALL ColorPicker::setPropertyValues( const Sequence< PropertyValue >& aProps )
+{
+ for ( const PropertyValue& rProp : aProps )
+ {
+ if( rProp.Name == gsColorKey )
+ {
+ rProp.Value >>= mnColor;
+ }
+ else if( rProp.Name == gsModeKey )
+ {
+ rProp.Value >>= mnMode;
+ }
+ }
+}
+
+// XExecutableDialog
+void SAL_CALL ColorPicker::setTitle( const OUString& )
+{
+}
+
+sal_Int16 SAL_CALL ColorPicker::execute()
+{
+ std::unique_ptr<ColorPickerDialog> xDlg(new ColorPickerDialog(Application::GetFrameWeld(mxParent), mnColor, mnMode));
+ sal_Int16 ret = xDlg->run();
+ if (ret)
+ mnColor = xDlg->GetColor();
+ return ret;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuicharmap.cxx b/cui/source/dialogs/cuicharmap.cxx
new file mode 100644
index 000000000..bcc1dd16a
--- /dev/null
+++ b/cui/source/dialogs/cuicharmap.cxx
@@ -0,0 +1,1250 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <stdio.h>
+
+#include <vcl/svapp.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/itempool.hxx>
+
+#include <rtl/textenc.h>
+#include <svx/ucsubset.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/fontcharmap.hxx>
+#include <vcl/virdev.hxx>
+#include <svl/stritem.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/dispatchcommand.hxx>
+
+#include <dialmgr.hxx>
+#include <cui/cuicharmap.hxx>
+#include <sfx2/app.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/editids.hrc>
+#include <editeng/fontitem.hxx>
+#include <strings.hrc>
+#include <unicode/uchar.h>
+#include <unicode/utypes.h>
+
+using namespace css;
+
+SvxCharacterMap::SvxCharacterMap(weld::Widget* pParent, const SfxItemSet* pSet,
+ const css::uno::Reference<css::frame::XFrame>& rFrame)
+ : SfxDialogController(pParent, "cui/ui/specialcharacters.ui", "SpecialCharactersDialog")
+ , m_xVirDev(VclPtr<VirtualDevice>::Create())
+ , isSearchMode(true)
+ , m_xFrame(rFrame)
+ , mxContext(comphelper::getProcessComponentContext())
+ , m_aRecentCharView{SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev)}
+ , m_aFavCharView{SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev),
+ SvxCharView(m_xVirDev)}
+ , m_aShowChar(m_xVirDev)
+ , m_xOKBtn(m_xFrame.is() ? m_xBuilder->weld_button("insert") : m_xBuilder->weld_button("ok"))
+ , m_xFontText(m_xBuilder->weld_label("fontft"))
+ , m_xFontLB(m_xBuilder->weld_combo_box("fontlb"))
+ , m_xSubsetText(m_xBuilder->weld_label("subsetft"))
+ , m_xSubsetLB(m_xBuilder->weld_combo_box("subsetlb"))
+ , m_xSearchText(m_xBuilder->weld_entry("search"))
+ , m_xHexCodeText(m_xBuilder->weld_entry("hexvalue"))
+ , m_xDecimalCodeText(m_xBuilder->weld_entry("decimalvalue"))
+ , m_xFavouritesBtn(m_xBuilder->weld_button("favbtn"))
+ , m_xCharName(m_xBuilder->weld_label("charname"))
+ , m_xRecentGrid(m_xBuilder->weld_widget("viewgrid"))
+ , m_xFavGrid(m_xBuilder->weld_widget("favgrid"))
+ , m_xShowChar(new weld::CustomWeld(*m_xBuilder, "showchar", m_aShowChar))
+ , m_xRecentCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar1", m_aRecentCharView[0]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar2", m_aRecentCharView[1]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar3", m_aRecentCharView[2]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar4", m_aRecentCharView[3]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar5", m_aRecentCharView[4]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar6", m_aRecentCharView[5]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar7", m_aRecentCharView[6]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar8", m_aRecentCharView[7]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar9", m_aRecentCharView[8]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar10", m_aRecentCharView[9]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar11", m_aRecentCharView[10]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar12", m_aRecentCharView[11]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar13", m_aRecentCharView[12]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar14", m_aRecentCharView[13]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar15", m_aRecentCharView[14]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "viewchar16", m_aRecentCharView[15])}
+ , m_xFavCharView{std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar1", m_aFavCharView[0]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar2", m_aFavCharView[1]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar3", m_aFavCharView[2]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar4", m_aFavCharView[3]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar5", m_aFavCharView[4]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar6", m_aFavCharView[5]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar7", m_aFavCharView[6]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar8", m_aFavCharView[7]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar9", m_aFavCharView[8]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar10", m_aFavCharView[9]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar11", m_aFavCharView[10]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar12", m_aFavCharView[11]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar13", m_aFavCharView[12]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar14", m_aFavCharView[13]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar15", m_aFavCharView[14]),
+ std::make_unique<weld::CustomWeld>(*m_xBuilder, "favchar16", m_aFavCharView[15])}
+ , m_xShowSet(new SvxShowCharSet(m_xBuilder->weld_scrolled_window("showscroll"), m_xVirDev))
+ , m_xShowSetArea(new weld::CustomWeld(*m_xBuilder, "showcharset", *m_xShowSet))
+ , m_xSearchSet(new SvxSearchCharSet(m_xBuilder->weld_scrolled_window("searchscroll"), m_xVirDev))
+ , m_xSearchSetArea(new weld::CustomWeld(*m_xBuilder, "searchcharset", *m_xSearchSet))
+{
+ m_aShowChar.SetCentered(true);
+ m_xFontLB->make_sorted();
+ //lock the size request of this widget to the width of all possible entries
+ fillAllSubsets(*m_xSubsetLB);
+ m_xSubsetLB->set_size_request(m_xSubsetLB->get_preferred_size().Width(), -1);
+ m_xCharName->set_size_request(m_aShowChar.get_preferred_size().Width(), m_xCharName->get_text_height() * 4);
+ //lock the size request of this widget to the width of the original .ui string
+ m_xHexCodeText->set_size_request(m_xHexCodeText->get_preferred_size().Width(), -1);
+ //so things don't jump around if all the children are hidden
+ m_xRecentGrid->set_size_request(-1, m_aRecentCharView[0].get_preferred_size().Height());
+ m_xFavGrid->set_size_request(-1, m_aFavCharView[0].get_preferred_size().Height());
+
+ init();
+
+ const SfxInt32Item* pCharItem = SfxItemSet::GetItem<SfxInt32Item>(pSet, SID_ATTR_CHAR, false);
+ if ( pCharItem )
+ SetChar( pCharItem->GetValue() );
+
+ const SfxBoolItem* pDisableItem = SfxItemSet::GetItem<SfxBoolItem>(pSet, FN_PARAM_2, false);
+ if ( pDisableItem && pDisableItem->GetValue() )
+ DisableFontSelection();
+
+ const SvxFontItem* pFontItem = SfxItemSet::GetItem<SvxFontItem>(pSet, SID_ATTR_CHAR_FONT, false);
+ const SfxStringItem* pFontNameItem = SfxItemSet::GetItem<SfxStringItem>(pSet, SID_FONT_NAME, false);
+ if ( pFontItem )
+ {
+ vcl::Font aTmpFont( pFontItem->GetFamilyName(), pFontItem->GetStyleName(), GetCharFont().GetFontSize() );
+ aTmpFont.SetCharSet( pFontItem->GetCharSet() );
+ aTmpFont.SetPitch( pFontItem->GetPitch() );
+ SetCharFont( aTmpFont );
+ }
+ else if ( pFontNameItem )
+ {
+ vcl::Font aTmpFont( GetCharFont() );
+ aTmpFont.SetFamilyName( pFontNameItem->GetValue() );
+ SetCharFont( aTmpFont );
+ }
+
+ m_xOutputSet.reset(new SfxAllItemSet(pSet ? *pSet->GetPool() : SfxGetpApp()->GetPool()));
+ m_xShowSet->Show();
+ m_xSearchSet->Hide();
+}
+
+short SvxCharacterMap::run()
+{
+ if( SvxShowCharSet::getSelectedChar() == ' ')
+ {
+ m_xOKBtn->set_sensitive(false);
+ setFavButtonState(OUString(), OUString());
+ }
+ else
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ m_aShowChar.SetText(aOUStr);
+
+ setFavButtonState(aOUStr, m_aShowChar.GetFont().GetFamilyName());
+ m_xOKBtn->set_sensitive(true);
+ }
+
+ return SfxDialogController::run();
+}
+
+void SvxCharacterMap::SetChar( sal_UCS4 c )
+{
+ m_xShowSet->SelectCharacter( c );
+ setFavButtonState(OUString(&c, 1), aFont.GetFamilyName());
+}
+
+sal_UCS4 SvxCharacterMap::GetChar() const
+{
+ return m_aShowChar.GetText().toChar();
+}
+
+void SvxCharacterMap::DisableFontSelection()
+{
+ m_xFontText->set_sensitive(false);
+ m_xFontLB->set_sensitive(false);
+}
+
+
+void SvxCharacterMap::getRecentCharacterList()
+{
+ //retrieve recent character list
+ const css::uno::Sequence< OUString > rRecentCharList( officecfg::Office::Common::RecentCharacters::RecentCharacterList::get() );
+ for (OUString const & s : rRecentCharList)
+ {
+ maRecentCharList.push_back(s);
+ }
+
+ //retrieve recent character font list
+ const css::uno::Sequence< OUString > rRecentCharFontList( officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::get() );
+ for (OUString const & s : rRecentCharFontList)
+ {
+ maRecentCharFontList.push_back(s);
+ }
+}
+
+
+void SvxCharacterMap::getFavCharacterList()
+{
+ maFavCharList.clear();
+ maFavCharFontList.clear();
+ //retrieve recent character list
+ const css::uno::Sequence< OUString > rFavCharList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::get() );
+ for (const OUString& s : rFavCharList)
+ {
+ maFavCharList.push_back(s);
+ }
+
+ //retrieve recent character font list
+ const css::uno::Sequence< OUString > rFavCharFontList( officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::get() );
+ for (const OUString& s : rFavCharFontList)
+ {
+ maFavCharFontList.push_back(s);
+ }
+}
+
+
+void SvxCharacterMap::updateRecentCharControl()
+{
+ int i = 0;
+ for ( std::deque< OUString >::iterator it = maRecentCharList.begin(), it2 = maRecentCharFontList.begin();
+ it != maRecentCharList.end() && it2 != maRecentCharFontList.end();
+ ++it, ++it2, i++)
+ {
+ m_aRecentCharView[i].SetText(*it);
+ vcl::Font rFont = m_aRecentCharView[i].GetFont();
+ rFont.SetFamilyName( *it2 );
+ m_aRecentCharView[i].SetFont(rFont);
+ m_aRecentCharView[i].Show();
+ }
+
+ for(; i < 16 ; i++)
+ {
+ m_aRecentCharView[i].SetText(OUString());
+ m_aRecentCharView[i].Hide();
+ }
+}
+
+void SvxCharacterMap::updateRecentCharacterList(const OUString& sTitle, const OUString& rFont)
+{
+ auto itChar = std::find(maRecentCharList.begin(), maRecentCharList.end(), sTitle);
+
+ auto itChar2 = std::find(maRecentCharFontList.begin(), maRecentCharFontList.end(), rFont);
+
+ // if recent char to be added is already in list, remove it
+ if( itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
+ {
+ maRecentCharList.erase( itChar );
+ maRecentCharFontList.erase( itChar2);
+ }
+
+ if (maRecentCharList.size() == 16)
+ {
+ maRecentCharList.pop_back();
+ maRecentCharFontList.pop_back();
+ }
+
+ maRecentCharList.push_front(sTitle);
+ maRecentCharFontList.push_front(rFont);
+
+ css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
+ css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
+
+ for (size_t i = 0; i < maRecentCharList.size(); ++i)
+ {
+ aRecentCharList[i] = maRecentCharList[i];
+ aRecentCharFontList[i] = maRecentCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+
+void SvxCharacterMap::updateFavCharacterList(const OUString& sTitle, const OUString& rFont)
+{
+ auto itChar = std::find(maFavCharList.begin(), maFavCharList.end(), sTitle);
+
+ auto itChar2 = std::find(maFavCharFontList.begin(), maFavCharFontList.end(), rFont);
+
+ // if Fav char to be added is already in list, remove it
+ if( itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
+ {
+ maFavCharList.erase( itChar );
+ maFavCharFontList.erase( itChar2);
+ }
+
+ if (maFavCharList.size() == 16)
+ {
+ maFavCharList.pop_back();
+ maFavCharFontList.pop_back();
+ }
+
+ maFavCharList.push_back(sTitle);
+ maFavCharFontList.push_back(rFont);
+
+ css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
+ css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
+
+ for (size_t i = 0; i < maFavCharList.size(); ++i)
+ {
+ aFavCharList[i] = maFavCharList[i];
+ aFavCharFontList[i] = maFavCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
+ batch->commit();
+}
+
+
+void SvxCharacterMap::updateFavCharControl()
+{
+ int i = 0;
+ for ( std::deque< OUString >::iterator it = maFavCharList.begin(), it2 = maFavCharFontList.begin();
+ it != maFavCharList.end() && it2 != maFavCharFontList.end();
+ ++it, ++it2, i++)
+ {
+ m_aFavCharView[i].SetText(*it);
+ vcl::Font rFont = m_aFavCharView[i].GetFont();
+ rFont.SetFamilyName( *it2 );
+ m_aFavCharView[i].SetFont(rFont);
+ m_aFavCharView[i].Show();
+ }
+
+ for(; i < 16 ; i++)
+ {
+ m_aFavCharView[i].SetText(OUString());
+ m_aFavCharView[i].Hide();
+ }
+ m_xShowSet->getFavCharacterList();
+ m_xSearchSet->getFavCharacterList();
+}
+
+void SvxCharacterMap::deleteFavCharacterFromList(const OUString& sTitle, const OUString& rFont)
+{
+ auto itChar = std::find(maFavCharList.begin(), maFavCharList.end(), sTitle);
+
+ auto itChar2 = std::find(maFavCharFontList.begin(), maFavCharFontList.end(), rFont);
+
+ // if Fav char to be added is already in list, remove it
+ if( itChar != maFavCharList.end() && itChar2 != maFavCharFontList.end() )
+ {
+ maFavCharList.erase( itChar );
+ maFavCharFontList.erase( itChar2);
+ }
+
+ css::uno::Sequence< OUString > aFavCharList(maFavCharList.size());
+ css::uno::Sequence< OUString > aFavCharFontList(maFavCharFontList.size());
+
+ for (size_t i = 0; i < maFavCharList.size(); ++i)
+ {
+ aFavCharList[i] = maFavCharList[i];
+ aFavCharFontList[i] = maFavCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
+ batch->commit();
+}
+
+void SvxCharacterMap::init()
+{
+ aFont = m_xVirDev->GetFont();
+ aFont.SetTransparent( true );
+ aFont.SetFamily( FAMILY_DONTKNOW );
+ aFont.SetPitch( PITCH_DONTKNOW );
+ aFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+
+ OUString aDefStr( aFont.GetFamilyName() );
+ OUString aLastName;
+ int nCount = m_xVirDev->GetDevFontCount();
+ std::vector<weld::ComboBoxEntry> aEntries;
+ aEntries.reserve(nCount);
+ for (int i = 0; i < nCount; ++i)
+ {
+ OUString aFontName( m_xVirDev->GetDevFont( i ).GetFamilyName() );
+ if (aFontName != aLastName)
+ {
+ aLastName = aFontName;
+ aEntries.emplace_back(aFontName, OUString::number(i));
+ }
+ }
+ m_xFontLB->insert_vector(aEntries, true);
+ // the font may not be in the list =>
+ // try to find a font name token in list and select found font,
+ // else select topmost entry
+ bool bFound = (m_xFontLB->find_text(aDefStr) == -1);
+ if (!bFound)
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ OUString aToken = aDefStr.getToken(0, ';', nIndex);
+ if (m_xFontLB->find_text(aToken) != -1)
+ {
+ aDefStr = aToken;
+ bFound = true;
+ break;
+ }
+ }
+ while ( nIndex >= 0 );
+ }
+
+ if (bFound)
+ m_xFontLB->set_active_text(aDefStr);
+ else if (m_xFontLB->get_count() )
+ m_xFontLB->set_active(0);
+ FontSelectHdl(*m_xFontLB);
+ if (m_xSubsetLB->get_count())
+ m_xSubsetLB->set_active(0);
+
+ m_xFontLB->connect_changed(LINK( this, SvxCharacterMap, FontSelectHdl));
+ m_xSubsetLB->connect_changed(LINK( this, SvxCharacterMap, SubsetSelectHdl));
+ m_xOKBtn->connect_clicked(LINK(this, SvxCharacterMap, InsertClickHdl));
+ m_xOKBtn->show();
+
+ m_xShowSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, CharDoubleClickHdl ) );
+ m_xShowSet->SetSelectHdl( LINK( this, SvxCharacterMap, CharSelectHdl ) );
+ m_xShowSet->SetHighlightHdl( LINK( this, SvxCharacterMap, CharHighlightHdl ) );
+ m_xShowSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, CharPreSelectHdl ) );
+ m_xShowSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
+
+ m_xSearchSet->SetDoubleClickHdl( LINK( this, SvxCharacterMap, SearchCharDoubleClickHdl ) );
+ m_xSearchSet->SetSelectHdl( LINK( this, SvxCharacterMap, SearchCharSelectHdl ) );
+ m_xSearchSet->SetHighlightHdl( LINK( this, SvxCharacterMap, SearchCharHighlightHdl ) );
+ m_xSearchSet->SetPreSelectHdl( LINK( this, SvxCharacterMap, SearchCharPreSelectHdl ) );
+ m_xSearchSet->SetFavClickHdl( LINK( this, SvxCharacterMap, FavClickHdl ) );
+
+ m_xDecimalCodeText->connect_changed( LINK( this, SvxCharacterMap, DecimalCodeChangeHdl ) );
+ m_xHexCodeText->connect_changed( LINK( this, SvxCharacterMap, HexCodeChangeHdl ) );
+ m_xFavouritesBtn->connect_clicked( LINK(this, SvxCharacterMap, FavSelectHdl));
+
+ // tdf#117038 set the buttons width to its max possible width so it doesn't
+ // make layout change when the label changes
+ m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES));
+ auto nMaxWidth = m_xFavouritesBtn->get_preferred_size().Width();
+ m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
+ nMaxWidth = std::max(nMaxWidth, m_xFavouritesBtn->get_preferred_size().Width());
+ m_xFavouritesBtn->set_size_request(nMaxWidth, -1);
+
+ if( SvxShowCharSet::getSelectedChar() == ' ')
+ {
+ m_xOKBtn->set_sensitive(false);
+ }
+ else
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ m_aShowChar.SetText(aOUStr);
+
+ setFavButtonState(aOUStr, aDefStr);
+ m_xOKBtn->set_sensitive(true);
+ }
+
+ getRecentCharacterList();
+ updateRecentCharControl();
+
+ getFavCharacterList();
+ updateFavCharControl();
+
+ bool bHasInsert = m_xFrame.is();
+
+ for(int i = 0; i < 16; i++)
+ {
+ m_aRecentCharView[i].SetHasInsert(bHasInsert);
+ m_aRecentCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl));
+ m_aRecentCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, RecentClearClickHdl));
+ m_aRecentCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, RecentClearAllClickHdl));
+ m_aFavCharView[i].SetHasInsert(bHasInsert);
+ m_aFavCharView[i].setMouseClickHdl(LINK(this,SvxCharacterMap, CharClickHdl));
+ m_aFavCharView[i].setClearClickHdl(LINK(this,SvxCharacterMap, FavClearClickHdl));
+ m_aFavCharView[i].setClearAllClickHdl(LINK(this,SvxCharacterMap, FavClearAllClickHdl));
+ }
+
+ setCharName(90);
+
+ m_xSearchText->connect_focus_in(LINK( this, SvxCharacterMap, SearchFieldGetFocusHdl ));
+ m_xSearchText->connect_changed(LINK(this, SvxCharacterMap, SearchUpdateHdl));
+}
+
+bool SvxCharacterMap::isFavChar(const OUString& sTitle, const OUString& rFont)
+{
+ auto isFavCharTitleExists = std::any_of(maFavCharList.begin(),
+ maFavCharList.end(),
+ [sTitle] (const OUString & a) { return a == sTitle; });
+
+ auto isFavCharFontExists = std::any_of(maFavCharFontList.begin(),
+ maFavCharFontList.end(),
+ [rFont] (const OUString & a) { return a == rFont; });
+
+ // if Fav char to be added is already in list, remove it
+ return isFavCharTitleExists && isFavCharFontExists;
+}
+
+
+void SvxCharacterMap::setFavButtonState(const OUString& sTitle, const OUString& rFont)
+{
+ if(sTitle.isEmpty() || rFont.isEmpty())
+ {
+ m_xFavouritesBtn->set_sensitive(false);
+ return;
+ }
+ else
+ m_xFavouritesBtn->set_sensitive(true);
+
+ if (isFavChar(sTitle, rFont))
+ {
+ m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_REMOVE_FAVORITES));
+ }
+ else
+ {
+ if(maFavCharList.size() == 16)
+ {
+ m_xFavouritesBtn->set_sensitive(false);
+ }
+
+ m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
+ }
+}
+
+
+void SvxCharacterMap::SetCharFont( const vcl::Font& rFont )
+{
+ // first get the underlying info in order to get font names
+ // like "Times New Roman;Times" resolved
+ vcl::Font aTmp(m_xVirDev->GetFontMetric(rFont));
+
+ if (aTmp.GetFamilyName() == "StarSymbol" && m_xFontLB->find_text(aTmp.GetFamilyName()) == -1)
+ {
+ //if for some reason, like font in an old document, StarSymbol is requested and it's not available, then
+ //try OpenSymbol instead
+ aTmp.SetFamilyName("OpenSymbol");
+ }
+
+ if (m_xFontLB->find_text(aTmp.GetFamilyName()) == -1)
+ return;
+
+ m_xFontLB->set_active_text(aTmp.GetFamilyName());
+ aFont = aTmp;
+ FontSelectHdl(*m_xFontLB);
+ if (m_xSubsetLB->get_count())
+ m_xSubsetLB->set_active(0);
+}
+
+void SvxCharacterMap::fillAllSubsets(weld::ComboBox& rListBox)
+{
+ SubsetMap aAll(nullptr);
+ std::vector<weld::ComboBoxEntry> aEntries;
+ for (auto & subset : aAll.GetSubsetMap())
+ aEntries.emplace_back(subset.GetName());
+ rListBox.insert_vector(aEntries, true);
+}
+
+void SvxCharacterMap::insertCharToDoc(const OUString& sGlyph)
+{
+ if(sGlyph.isEmpty())
+ return;
+
+ if (m_xFrame.is()) {
+ uno::Sequence<beans::PropertyValue> aArgs(2);
+ aArgs[0].Name = "Symbols";
+ aArgs[0].Value <<= sGlyph;
+
+ aArgs[1].Name = "FontName";
+ aArgs[1].Value <<= aFont.GetFamilyName();
+ comphelper::dispatchCommand(".uno:InsertSymbol", m_xFrame, aArgs);
+
+ updateRecentCharacterList(sGlyph, aFont.GetFamilyName());
+
+ } else {
+ sal_Int32 tmp = 0;
+ sal_UCS4 cChar = sGlyph.iterateCodePoints(&tmp);
+ const SfxItemPool* pPool = m_xOutputSet->GetPool();
+ m_xOutputSet->Put( SfxStringItem( pPool->GetWhich(SID_CHARMAP), sGlyph ) );
+ m_xOutputSet->Put( SvxFontItem( aFont.GetFamilyType(), aFont.GetFamilyName(),
+ aFont.GetStyleName(), aFont.GetPitch(), aFont.GetCharSet(), pPool->GetWhich(SID_ATTR_CHAR_FONT) ) );
+ m_xOutputSet->Put( SfxStringItem( pPool->GetWhich(SID_FONT_NAME), aFont.GetFamilyName() ) );
+ m_xOutputSet->Put( SfxInt32Item( pPool->GetWhich(SID_ATTR_CHAR), cChar ) );
+ }
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FontSelectHdl, weld::ComboBox&, void)
+{
+ const sal_uInt32 nFont = m_xFontLB->get_active_id().toUInt32();
+ aFont = m_xVirDev->GetDevFont(nFont);
+ aFont.SetWeight( WEIGHT_DONTKNOW );
+ aFont.SetItalic( ITALIC_NONE );
+ aFont.SetWidthType( WIDTH_DONTKNOW );
+ aFont.SetPitch( PITCH_DONTKNOW );
+ aFont.SetFamily( FAMILY_DONTKNOW );
+
+ // notify children using this font
+ m_xShowSet->SetFont( aFont );
+ m_xSearchSet->SetFont( aFont );
+ m_aShowChar.SetFont( aFont );
+
+ // setup unicode subset listbar with font specific subsets,
+ // hide unicode subset listbar for symbol fonts
+ // TODO: get info from the Font once it provides it
+ pSubsetMap.reset();
+ m_xSubsetLB->clear();
+
+ bool bNeedSubset = (aFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL);
+ if (bNeedSubset)
+ {
+ FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
+ pSubsetMap.reset(new SubsetMap( xFontCharMap ));
+
+ // update subset listbox for new font's unicode subsets
+ for (auto const& subset : pSubsetMap->GetSubsetMap())
+ {
+ m_xSubsetLB->append(OUString::number(reinterpret_cast<sal_uInt64>(&subset)), subset.GetName());
+ // NOTE: subset must live at least as long as the selected font
+ }
+
+ if (m_xSubsetLB->get_count() <= 1)
+ bNeedSubset = false;
+ }
+
+ m_xSubsetText->set_sensitive(bNeedSubset);
+ m_xSubsetLB->set_sensitive(bNeedSubset);
+
+ if (isSearchMode)
+ {
+ // tdf#137294 do this after modifying m_xSubsetLB sensitivity to
+ // restore insensitive for the search case
+ SearchUpdateHdl(*m_xSearchText);
+ SearchCharHighlightHdl(m_xSearchSet.get());
+ }
+
+ // tdf#118304 reselect current glyph to see if its still there in new font
+ selectCharByCode(Radix::hexadecimal);
+}
+
+void SvxCharacterMap::toggleSearchView(bool state)
+{
+ isSearchMode = state;
+ m_xHexCodeText->set_editable(!state);
+ m_xDecimalCodeText->set_editable(!state);
+ m_xSubsetLB->set_sensitive(!state);
+
+ if(state)
+ {
+ m_xSearchSet->Show();
+ m_xShowSet->Hide();
+ }
+ else
+ {
+ m_xSearchSet->Hide();
+ m_xShowSet->Show();
+ }
+}
+
+void SvxCharacterMap::setCharName(sal_UCS4 nDecimalValue)
+{
+ /* get the character name */
+ UErrorCode errorCode = U_ZERO_ERROR;
+ // icu has a private uprv_getMaxCharNameLength function which returns the max possible
+ // length of this property. Unicode 3.2 max char name length was 83
+ char buffer[100];
+ u_charName(nDecimalValue, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ m_xCharName->set_label(OUString::createFromAscii(buffer));
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SubsetSelectHdl, weld::ComboBox&, void)
+{
+ const sal_Int32 nPos = m_xSubsetLB->get_active();
+ const Subset* pSubset = reinterpret_cast<const Subset*>(m_xSubsetLB->get_active_id().toUInt64());
+
+ if( pSubset && !isSearchMode)
+ {
+ sal_UCS4 cFirst = pSubset->GetRangeMin();
+ m_xShowSet->SelectCharacter( cFirst );
+
+ setFavButtonState(OUString(&cFirst, 1), aFont.GetFamilyName());
+ m_xSubsetLB->set_active(nPos);
+ }
+ else if( pSubset && isSearchMode)
+ {
+ m_xSearchSet->SelectCharacter( pSubset );
+
+ const Subset* curSubset = nullptr;
+ if( pSubsetMap )
+ curSubset = pSubsetMap->GetSubsetByUnicode( m_xSearchSet->GetSelectCharacter() );
+ if( curSubset )
+ m_xSubsetLB->set_active_text(curSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+
+ sal_UCS4 sChar = m_xSearchSet->GetSelectCharacter();
+ setFavButtonState(OUString(&sChar, 1), aFont.GetFamilyName());
+ }
+}
+
+IMPL_LINK(SvxCharacterMap, RecentClearClickHdl, SvxCharView*, rView, void)
+{
+ const OUString& sTitle = rView->GetText();
+ auto itChar = std::find(maRecentCharList.begin(), maRecentCharList.end(), sTitle);
+
+ OUString sFont = rView->GetFont().GetFamilyName();
+ auto itChar2 = std::find(maRecentCharFontList.begin(), maRecentCharFontList.end(), sFont);
+
+ // if recent char to be added is already in list, remove it
+ if( itChar != maRecentCharList.end() && itChar2 != maRecentCharFontList.end() )
+ {
+ maRecentCharList.erase( itChar );
+ maRecentCharFontList.erase( itChar2);
+ }
+
+ css::uno::Sequence< OUString > aRecentCharList(maRecentCharList.size());
+ css::uno::Sequence< OUString > aRecentCharFontList(maRecentCharFontList.size());
+
+ for (size_t i = 0; i < maRecentCharList.size(); ++i)
+ {
+ aRecentCharList[i] = maRecentCharList[i];
+ aRecentCharFontList[i] = maRecentCharFontList[i];
+ }
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, RecentClearAllClickHdl, SvxCharView*, void)
+{
+ css::uno::Sequence< OUString > aRecentCharList(0);
+ css::uno::Sequence< OUString > aRecentCharFontList(0);
+
+ maRecentCharList.clear();
+ maRecentCharFontList.clear();
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::RecentCharacters::RecentCharacterList::set(aRecentCharList, batch);
+ officecfg::Office::Common::RecentCharacters::RecentCharacterFontList::set(aRecentCharFontList, batch);
+ batch->commit();
+
+ updateRecentCharControl();
+}
+
+IMPL_LINK(SvxCharacterMap, FavClearClickHdl, SvxCharView*, rView, void)
+{
+ deleteFavCharacterFromList(rView->GetText(), rView->GetFont().GetFamilyName());
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavClearAllClickHdl, SvxCharView*, void)
+{
+ css::uno::Sequence< OUString > aFavCharList(0);
+ css::uno::Sequence< OUString > aFavCharFontList(0);
+
+ maFavCharList.clear();
+ maFavCharFontList.clear();
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(mxContext));
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterList::set(aFavCharList, batch);
+ officecfg::Office::Common::FavoriteCharacters::FavoriteCharacterFontList::set(aFavCharFontList, batch);
+ batch->commit();
+
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchFieldGetFocusHdl, weld::Widget&, void)
+{
+ m_xOKBtn->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchUpdateHdl, weld::Entry&, void)
+{
+ if (!m_xSearchText->get_text().isEmpty())
+ {
+ m_xSearchSet->ClearPreviousData();
+ OUString aKeyword = m_xSearchText->get_text();
+
+ toggleSearchView(true);
+
+ FontCharMapRef xFontCharMap = m_xSearchSet->GetFontCharMap();
+
+ sal_UCS4 sChar = xFontCharMap->GetFirstChar();
+ while(sChar != xFontCharMap->GetLastChar())
+ {
+ UErrorCode errorCode = U_ZERO_ERROR;
+ char buffer[100];
+ u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ {
+ OUString sName = OUString::createFromAscii(buffer);
+ if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
+ m_xSearchSet->AppendCharToList(sChar);
+ }
+ sChar = xFontCharMap->GetNextChar(sChar);
+ }
+ //for last char
+ UErrorCode errorCode = U_ZERO_ERROR;
+ char buffer[100];
+ u_charName(sChar, U_UNICODE_CHAR_NAME, buffer, sizeof(buffer), &errorCode);
+ if (U_SUCCESS(errorCode))
+ {
+ OUString sName = OUString::createFromAscii(buffer);
+ if(!sName.isEmpty() && sName.toAsciiLowerCase().indexOf(aKeyword.toAsciiLowerCase()) >= 0)
+ m_xSearchSet->AppendCharToList(sChar);
+ }
+ }
+ else
+ {
+ toggleSearchView(false);
+ }
+}
+
+
+IMPL_LINK(SvxCharacterMap, CharClickHdl, SvxCharView*, rView, void)
+{
+ rView->GrabFocus();
+
+ m_aShowChar.SetText( rView->GetText() );
+ m_aShowChar.SetFont(rView->GetFont());
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(rView->GetText(), rView->GetFont().GetFamilyName());//check state
+
+ // Get the hexadecimal code
+ OUString charValue = rView->GetText();
+ sal_Int32 tmp = 1;
+ sal_UCS4 cChar = charValue.iterateCodePoints(&tmp, -1);
+ OUString aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+
+ // Get the decimal code
+ OUString aDecimalText = OUString::number(cChar);
+
+ m_xHexCodeText->set_text(aHexText);
+ m_xDecimalCodeText->set_text(aDecimalText);
+ setCharName(cChar);
+
+ rView->Invalidate();
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharDoubleClickHdl, SvxShowCharSet*, void)
+{
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ setFavButtonState(aOUStr, aFont.GetFamilyName());
+ insertCharToDoc(aOUStr);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharDoubleClickHdl, SvxShowCharSet*, void)
+{
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ setFavButtonState(aOUStr, aFont.GetFamilyName());
+ insertCharToDoc(aOUStr);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharSelectHdl, SvxShowCharSet*, void)
+{
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharSelectHdl, SvxShowCharSet*, void)
+{
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, InsertClickHdl, weld::Button&, void)
+{
+ OUString sChar = m_aShowChar.GetText();
+ insertCharToDoc(sChar);
+ // Need to update recent character list, when OK button does not insert
+ if(!m_xFrame.is())
+ updateRecentCharacterList(sChar, aFont.GetFamilyName());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavSelectHdl, weld::Button&, void)
+{
+ if (m_xFavouritesBtn->get_label().match(CuiResId(RID_SVXSTR_ADD_FAVORITES)))
+ {
+ updateFavCharacterList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ setFavButtonState(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ }
+ else
+ {
+ deleteFavCharacterFromList(m_aShowChar.GetText(), m_aShowChar.GetFont().GetFamilyName());
+ m_xFavouritesBtn->set_label(CuiResId(RID_SVXSTR_ADD_FAVORITES));
+ m_xFavouritesBtn->set_sensitive(false);
+ }
+
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, FavClickHdl, SvxShowCharSet*, void)
+{
+ getFavCharacterList();
+ updateFavCharControl();
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharHighlightHdl, SvxShowCharSet*, void)
+{
+ OUString aText;
+ OUString aHexText;
+ OUString aDecimalText;
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+ bool bSelect = (cChar > 0);
+
+ // show char sample
+ if ( bSelect )
+ {
+ // using the new UCS4 constructor
+ aText = OUString( &cChar, 1 );
+ // Get the hexadecimal code
+ aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+ // Get the decimal code
+ aDecimalText = OUString::number(cChar);
+ setCharName(cChar);
+
+ // Update the hex and decimal codes only if necessary
+ if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
+ m_xHexCodeText->set_text(aHexText);
+ if (m_xDecimalCodeText->get_text() != aDecimalText)
+ m_xDecimalCodeText->set_text( aDecimalText );
+
+ const Subset* pSubset = nullptr;
+ if( pSubsetMap )
+ pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+ }
+
+ m_aShowChar.SetText( aText );
+ m_aShowChar.SetFont( aFont );
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(aText, aFont.GetFamilyName());
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharHighlightHdl, SvxShowCharSet*, void)
+{
+ OUString aText;
+ OUString aHexText;
+ OUString aDecimalText;
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+ bool bSelect = (cChar > 0);
+
+ // show char sample
+ if ( bSelect )
+ {
+ aText = OUString( &cChar, 1 );
+ // Get the hexadecimal code
+ aHexText = OUString::number(cChar, 16).toAsciiUpperCase();
+ // Get the decimal code
+ aDecimalText = OUString::number(cChar);
+ setCharName(cChar);
+
+ // Update the hex and decimal codes only if necessary
+ if (!m_xHexCodeText->get_text().equalsIgnoreAsciiCase(aHexText))
+ m_xHexCodeText->set_text(aHexText);
+ if (m_xDecimalCodeText->get_text() != aDecimalText)
+ m_xDecimalCodeText->set_text( aDecimalText );
+
+ const Subset* pSubset = nullptr;
+ if( pSubsetMap )
+ pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ else
+ m_xSubsetLB->set_active(-1);
+ }
+
+ if(m_xSearchSet->HasFocus())
+ {
+ m_aShowChar.SetText( aText );
+ m_aShowChar.SetFont( aFont );
+ m_aShowChar.Invalidate();
+
+ setFavButtonState(aText, aFont.GetFamilyName());
+ }
+}
+
+void SvxCharacterMap::selectCharByCode(Radix radix)
+{
+ OUString aCodeString;
+ switch(radix)
+ {
+ case Radix::decimal:
+ aCodeString = m_xDecimalCodeText->get_text();
+ break;
+ case Radix::hexadecimal:
+ aCodeString = m_xHexCodeText->get_text();
+ break;
+ }
+ // Convert the code back to a character using the appropriate radix
+ sal_UCS4 cChar = aCodeString.toUInt32(static_cast<sal_Int16> (radix));
+ // Use FontCharMap::HasChar(sal_UCS4 cChar) to see if the desired character is in the font
+ FontCharMapRef xFontCharMap = m_xShowSet->GetFontCharMap();
+ if (xFontCharMap->HasChar(cChar))
+ // Select the corresponding character
+ SetChar(cChar);
+ else {
+ m_xCharName->set_label(CuiResId(RID_SVXSTR_MISSING_CHAR));
+ m_aShowChar.SetText(" ");
+ switch(radix)
+ {
+ case Radix::decimal:
+ m_xHexCodeText->set_text(OUString::number(cChar, 16));
+ break;
+ case Radix::hexadecimal:
+ m_xDecimalCodeText->set_text(OUString::number(cChar));
+ break;
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, DecimalCodeChangeHdl, weld::Entry&, void)
+{
+ selectCharByCode(Radix::decimal);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, HexCodeChangeHdl, weld::Entry&, void)
+{
+ selectCharByCode(Radix::hexadecimal);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, CharPreSelectHdl, SvxShowCharSet*, void)
+{
+ // adjust subset selection
+ if( pSubsetMap )
+ {
+ sal_UCS4 cChar = m_xShowSet->GetSelectCharacter();
+
+ setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
+ const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ }
+
+ m_xOKBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvxCharacterMap, SearchCharPreSelectHdl, SvxShowCharSet*, void)
+{
+ // adjust subset selection
+ if( pSubsetMap )
+ {
+ sal_UCS4 cChar = m_xSearchSet->GetSelectCharacter();
+
+ setFavButtonState(OUString(&cChar, 1), aFont.GetFamilyName());
+ const Subset* pSubset = pSubsetMap->GetSubsetByUnicode( cChar );
+ if( pSubset )
+ m_xSubsetLB->set_active_text(pSubset->GetName());
+ }
+
+ m_xOKBtn->set_sensitive(true);
+}
+
+// class SvxShowText =====================================================
+SvxShowText::SvxShowText(const VclPtr<VirtualDevice>& rVirDev)
+ : m_xVirDev(rVirDev)
+ , mnY(0)
+ , mbCenter(false)
+{
+}
+
+void SvxShowText::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ vcl::Font aFont = m_xVirDev->GetFont();
+ Size aFontSize(aFont.GetFontSize().Width() * 5, aFont.GetFontSize().Height() * 5);
+ aFont.SetFontSize(aFontSize);
+ m_xVirDev->Push(PUSH_ALLFONT);
+ m_xVirDev->SetFont(aFont);
+ pDrawingArea->set_size_request(m_xVirDev->approximate_digit_width() + 2 * 12,
+ m_xVirDev->LogicToPixel(aFontSize).Height() * 2);
+ m_xVirDev->Pop();
+}
+
+void SvxShowText::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ rRenderContext.SetFont(m_aFont);
+
+ Color aTextCol = rRenderContext.GetTextColor();
+ Color aFillCol = rRenderContext.GetFillColor();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ const Color aWindowTextColor(rStyleSettings.GetDialogTextColor());
+ const Color aWindowColor(rStyleSettings.GetWindowColor());
+ rRenderContext.SetTextColor(aWindowTextColor);
+ rRenderContext.SetFillColor(aWindowColor);
+
+ const OUString aText = GetText();
+
+ Size aSize(GetOutputSizePixel());
+ long nAvailWidth = aSize.Width();
+ long nWinHeight = aSize.Height();
+
+ bool bGotBoundary = true;
+ bool bShrankFont = false;
+ vcl::Font aOrigFont(rRenderContext.GetFont());
+ Size aFontSize(aOrigFont.GetFontSize());
+ ::tools::Rectangle aBoundRect;
+
+ for (long nFontHeight = aFontSize.Height(); nFontHeight > 0; nFontHeight -= 5)
+ {
+ if (!rRenderContext.GetTextBoundRect( aBoundRect, aText ) || aBoundRect.IsEmpty())
+ {
+ bGotBoundary = false;
+ break;
+ }
+ if (!mbCenter)
+ break;
+ //only shrink in the single glyph large view mode
+ long nTextWidth = aBoundRect.GetWidth();
+ if (nAvailWidth > nTextWidth)
+ break;
+ vcl::Font aFont(aOrigFont);
+ aFontSize.setHeight( nFontHeight );
+ aFont.SetFontSize(aFontSize);
+ rRenderContext.SetFont(aFont);
+ mnY = (nWinHeight - rRenderContext.GetTextHeight()) / 2;
+ bShrankFont = true;
+ }
+
+ Point aPoint(2, mnY);
+ // adjust position using ink boundary if possible
+ if (!bGotBoundary)
+ aPoint.setX( (aSize.Width() - rRenderContext.GetTextWidth(aText)) / 2 );
+ else
+ {
+ // adjust position before it gets out of bounds
+ aBoundRect += aPoint;
+
+ // shift back vertically if needed
+ int nYLDelta = aBoundRect.Top();
+ int nYHDelta = aSize.Height() - aBoundRect.Bottom();
+ if( nYLDelta <= 0 )
+ aPoint.AdjustY( -(nYLDelta - 1) );
+ else if( nYHDelta <= 0 )
+ aPoint.AdjustY(nYHDelta - 1 );
+
+ if (mbCenter)
+ {
+ // move glyph to middle of cell
+ aPoint.setX( -aBoundRect.Left() + (aSize.Width() - aBoundRect.GetWidth()) / 2 );
+ }
+ else
+ {
+ // shift back horizontally if needed
+ int nXLDelta = aBoundRect.Left();
+ int nXHDelta = aSize.Width() - aBoundRect.Right();
+ if( nXLDelta <= 0 )
+ aPoint.AdjustX( -(nXLDelta - 1) );
+ else if( nXHDelta <= 0 )
+ aPoint.AdjustX(nXHDelta - 1 );
+ }
+ }
+
+ rRenderContext.DrawRect(tools::Rectangle(Point(0, 0), aSize));
+ rRenderContext.DrawText(aPoint, aText);
+ rRenderContext.SetTextColor(aTextCol);
+ rRenderContext.SetFillColor(aFillCol);
+ if (bShrankFont)
+ rRenderContext.SetFont(aOrigFont);
+}
+
+void SvxShowText::SetFont( const vcl::Font& rFont )
+{
+ long nWinHeight = GetOutputSizePixel().Height();
+
+ m_aFont = rFont;
+ m_aFont.SetWeight(WEIGHT_NORMAL);
+ m_aFont.SetAlignment(ALIGN_TOP);
+ m_aFont.SetFontSize(m_xVirDev->PixelToLogic(Size(0, nWinHeight / 2)));
+ m_aFont.SetTransparent(true);
+
+ m_xVirDev->Push(PUSH_ALLFONT);
+ m_xVirDev->SetFont(m_aFont);
+ mnY = (nWinHeight - m_xVirDev->GetTextHeight()) / 2;
+ m_xVirDev->Pop();
+
+ Invalidate();
+}
+
+void SvxShowText::Resize()
+{
+ SetFont(GetFont()); //force recalculation of size
+}
+
+void SvxShowText::SetText(const OUString& rText)
+{
+ m_sText = rText;
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuifmsearch.cxx b/cui/source/dialogs/cuifmsearch.cxx
new file mode 100644
index 000000000..de7681fa7
--- /dev/null
+++ b/cui/source/dialogs/cuifmsearch.cxx
@@ -0,0 +1,754 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <vcl/stdtext.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/app.hxx>
+#include <svx/fmsrccfg.hxx>
+#include <svx/fmsrcimp.hxx>
+#include <strings.hrc>
+#include <cuifmsearch.hxx>
+#include <svl/cjkoptions.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <svx/svxdlg.hxx>
+
+using namespace css::uno;
+using namespace css::i18n;
+using namespace ::svxform;
+using namespace css::sdbc;
+using namespace css::util;
+
+#define MAX_HISTORY_ENTRIES 50
+
+void FmSearchDialog::initCommon( const Reference< XResultSet >& _rxCursor )
+{
+ // init the engine
+ DBG_ASSERT( m_pSearchEngine, "FmSearchDialog::initCommon: have no engine!" );
+ m_pSearchEngine->SetProgressHandler(LINK(this, FmSearchDialog, OnSearchProgress));
+
+ // some layout changes according to available CJK options
+ SvtCJKOptions aCJKOptions;
+ if (!aCJKOptions.IsJapaneseFindEnabled())
+ {
+ // hide the options for the japanese search
+ m_pSoundsLikeCJK->hide();
+ m_pSoundsLikeCJKSettings->hide();
+ }
+
+ if (!aCJKOptions.IsCJKFontEnabled())
+ {
+ m_pHalfFullFormsCJK->hide();
+
+ // never ignore the width (ignoring is expensive) if the option is not available at all
+ m_pSearchEngine->SetIgnoreWidthCJK( false );
+ }
+
+ // some initial record texts
+ m_pftRecord->set_label( OUString::number(_rxCursor->getRow()) );
+ m_pbClose->set_tooltip_text(OUString());
+}
+
+FmSearchDialog::FmSearchDialog(weld::Window* pParent, const OUString& sInitialText, const std::vector< OUString >& _rContexts, sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier)
+ : GenericDialogController(pParent, "cui/ui/fmsearchdialog.ui", "RecordSearchDialog")
+ , m_sCancel( GetStandardText( StandardButtonType::Cancel ) )
+ , m_lnkContextSupplier(lnkContextSupplier)
+ , m_prbSearchForText(m_xBuilder->weld_radio_button("rbSearchForText"))
+ , m_prbSearchForNull(m_xBuilder->weld_radio_button("rbSearchForNull"))
+ , m_prbSearchForNotNull(m_xBuilder->weld_radio_button("rbSearchForNotNull"))
+ , m_pcmbSearchText(m_xBuilder->weld_combo_box("cmbSearchText"))
+ , m_pftForm(m_xBuilder->weld_label("ftForm"))
+ , m_plbForm(m_xBuilder->weld_combo_box("lbForm"))
+ , m_prbAllFields(m_xBuilder->weld_radio_button("rbAllFields"))
+ , m_prbSingleField(m_xBuilder->weld_radio_button("rbSingleField"))
+ , m_plbField(m_xBuilder->weld_combo_box("lbField"))
+ , m_pftPosition(m_xBuilder->weld_label("ftPosition"))
+ , m_plbPosition(m_xBuilder->weld_combo_box("lbPosition"))
+ , m_pcbUseFormat(m_xBuilder->weld_check_button("cbUseFormat"))
+ , m_pcbCase(m_xBuilder->weld_check_button("cbCase"))
+ , m_pcbBackwards(m_xBuilder->weld_check_button("cbBackwards"))
+ , m_pcbStartOver(m_xBuilder->weld_check_button("cbStartOver"))
+ , m_pcbWildCard(m_xBuilder->weld_check_button("cbWildCard"))
+ , m_pcbRegular(m_xBuilder->weld_check_button("cbRegular"))
+ , m_pcbApprox(m_xBuilder->weld_check_button("cbApprox"))
+ , m_ppbApproxSettings(m_xBuilder->weld_button("pbApproxSettings"))
+ , m_pHalfFullFormsCJK(m_xBuilder->weld_check_button("HalfFullFormsCJK"))
+ , m_pSoundsLikeCJK(m_xBuilder->weld_check_button("SoundsLikeCJK"))
+ , m_pSoundsLikeCJKSettings(m_xBuilder->weld_button("SoundsLikeCJKSettings"))
+ , m_pftRecord(m_xBuilder->weld_label("ftRecord"))
+ , m_pftHint(m_xBuilder->weld_label("ftHint"))
+ , m_pbSearchAgain(m_xBuilder->weld_button("pbSearchAgain"))
+ , m_pbClose(m_xBuilder->weld_button("close"))
+{
+ m_pcmbSearchText->set_size_request(m_pcmbSearchText->get_approximate_digit_width() * 38, -1);
+ m_plbForm->set_size_request(m_plbForm->get_approximate_digit_width() * 38, -1);
+ m_sSearch = m_pbSearchAgain->get_label();
+
+ DBG_ASSERT(m_lnkContextSupplier.IsSet(), "FmSearchDialog::FmSearchDialog : have no ContextSupplier !");
+
+ FmSearchContext fmscInitial;
+ fmscInitial.nContext = nInitialContext;
+ m_lnkContextSupplier.Call(fmscInitial);
+ DBG_ASSERT(fmscInitial.xCursor.is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscInitial.strUsedFields, ';') == static_cast<sal_Int32>(fmscInitial.arrFields.size()),
+ "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplied !");
+#if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
+ for (const Reference<XInterface> & arrField : fmscInitial.arrFields)
+ {
+ DBG_ASSERT(arrField.is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
+ }
+#endif // (OSL_DEBUG_LEVEL > 1) || DBG_UTIL
+
+ for ( std::vector< OUString >::const_iterator context = _rContexts.begin();
+ context != _rContexts.end();
+ ++context
+ )
+ {
+ m_arrContextFields.emplace_back();
+ m_plbForm->append_text(*context);
+ }
+ m_plbForm->set_active(nInitialContext);
+
+ m_plbForm->connect_changed(LINK(this, FmSearchDialog, OnContextSelection));
+
+ if (m_arrContextFields.size() == 1)
+ {
+ // hide dispensable controls
+ m_pftForm->hide();
+ m_plbForm->hide();
+ }
+
+ m_pSearchEngine.reset( new FmSearchEngine(
+ ::comphelper::getProcessComponentContext(), fmscInitial.xCursor, fmscInitial.strUsedFields, fmscInitial.arrFields ) );
+ initCommon( fmscInitial.xCursor );
+
+ if ( !fmscInitial.sFieldDisplayNames.isEmpty() )
+ { // use the display names if supplied
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscInitial.sFieldDisplayNames, ';') == comphelper::string::getTokenCount(fmscInitial.strUsedFields, ';'),
+ "FmSearchDialog::FmSearchDialog : invalid initial context description !");
+ Init(fmscInitial.sFieldDisplayNames, sInitialText);
+ }
+ else
+ Init(fmscInitial.strUsedFields, sInitialText);
+}
+
+FmSearchDialog::~FmSearchDialog()
+{
+ SaveParams();
+
+ m_pConfig.reset();
+ m_pSearchEngine.reset();
+}
+
+void FmSearchDialog::Init(const OUString& strVisibleFields, const OUString& sInitialText)
+{
+ //the initialization of all the Controls
+ m_prbSearchForText->connect_clicked(LINK(this, FmSearchDialog, OnClickedFieldRadios));
+ m_prbSearchForNull->connect_clicked(LINK(this, FmSearchDialog, OnClickedFieldRadios));
+ m_prbSearchForNotNull->connect_clicked(LINK(this, FmSearchDialog, OnClickedFieldRadios));
+
+ m_prbAllFields->connect_clicked(LINK(this, FmSearchDialog, OnClickedFieldRadios));
+ m_prbSingleField->connect_clicked(LINK(this, FmSearchDialog, OnClickedFieldRadios));
+
+ m_pbSearchAgain->connect_clicked(LINK(this, FmSearchDialog, OnClickedSearchAgain));
+ m_ppbApproxSettings->connect_clicked(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
+ m_pSoundsLikeCJKSettings->connect_clicked(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
+
+ m_plbPosition->connect_changed(LINK(this, FmSearchDialog, OnPositionSelected));
+ m_plbField->connect_changed(LINK(this, FmSearchDialog, OnFieldSelected));
+
+ m_pcmbSearchText->connect_changed(LINK(this, FmSearchDialog, OnSearchTextModified));
+ m_pcmbSearchText->set_entry_completion(false);
+ m_pcmbSearchText->connect_focus_in(LINK(this, FmSearchDialog, OnFocusGrabbed));
+
+ m_pcbUseFormat->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbBackwards->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbStartOver->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbCase->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbWildCard->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbRegular->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pcbApprox->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pHalfFullFormsCJK->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+ m_pSoundsLikeCJK->connect_toggled(LINK(this, FmSearchDialog, OnCheckBoxToggled));
+
+ // fill the listboxes
+ // method of field comparison
+ const char* const aResIds[] = {
+ RID_STR_SEARCH_ANYWHERE,
+ RID_STR_SEARCH_BEGINNING,
+ RID_STR_SEARCH_END,
+ RID_STR_SEARCH_WHOLE
+ };
+ for (auto pResId : aResIds)
+ m_plbPosition->append_text(CuiResId(pResId));
+ m_plbPosition->set_active(MATCHING_ANYWHERE);
+
+ // the field listbox
+ if (!strVisibleFields.isEmpty())
+ {
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(strVisibleFields.getToken(0, ';', nPos));
+ } while (nPos>=0);
+ }
+
+
+ m_pConfig.reset( new FmSearchConfigItem );
+ LoadParams();
+
+ m_pcmbSearchText->set_entry_text(sInitialText);
+ // if the Edit-line has changed the text (e.g. because it contains
+ // control characters, as can be the case with memo fields), I use
+ // an empty OUString.
+ OUString sRealSetText = m_pcmbSearchText->get_active_text();
+ if (sRealSetText != sInitialText)
+ m_pcmbSearchText->set_entry_text(OUString());
+ OnSearchTextModified(*m_pcmbSearchText);
+
+ // initial
+ EnableSearchUI(true);
+
+ if ( m_prbSearchForText->get_active() )
+ m_pcmbSearchText->grab_focus();
+
+}
+
+short FmSearchDialog::run()
+{
+ short nRet = weld::GenericDialogController::run();
+ m_pSearchEngine->CancelSearch();
+ return nRet;
+}
+
+IMPL_LINK(FmSearchDialog, OnClickedFieldRadios, weld::Button&, rButton, void)
+{
+ if ((&rButton == m_prbSearchForText.get()) || (&rButton == m_prbSearchForNull.get()) || (&rButton == m_prbSearchForNotNull.get()))
+ {
+ EnableSearchForDependees(true);
+ }
+ else
+ // en- or disable field list box accordingly
+ if (&rButton == m_prbSingleField.get())
+ {
+ m_plbField->set_sensitive(true);
+ m_pSearchEngine->RebuildUsedFields(m_plbField->get_active());
+ }
+ else
+ {
+ m_plbField->set_sensitive(false);
+ m_pSearchEngine->RebuildUsedFields(-1);
+ }
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnClickedSearchAgain, weld::Button&, void)
+{
+ if (m_pbClose->get_sensitive())
+ { // the button has the function 'search'
+ OUString strThisRoundText = m_pcmbSearchText->get_active_text();
+ // to history
+ m_pcmbSearchText->remove_text(strThisRoundText);
+ m_pcmbSearchText->insert_text(0, strThisRoundText);
+ // the remove/insert makes sure that a) the OUString does not appear twice and
+ // that b) the last searched strings are at the beginning and limit the list length
+ while (m_pcmbSearchText->get_count() > MAX_HISTORY_ENTRIES)
+ m_pcmbSearchText->remove(m_pcmbSearchText->get_count()-1);
+
+ // take out the 'overflow' hint
+ m_pftHint->set_label(OUString());
+
+ if (m_pcbStartOver->get_active())
+ {
+ m_pcbStartOver->set_active(false);
+ EnableSearchUI(false);
+ if (m_prbSearchForText->get_active())
+ m_pSearchEngine->StartOver(strThisRoundText);
+ else
+ m_pSearchEngine->StartOverSpecial(m_prbSearchForNull->get_active());
+ }
+ else
+ {
+ EnableSearchUI(false);
+ if (m_prbSearchForText->get_active())
+ m_pSearchEngine->SearchNext(strThisRoundText);
+ else
+ m_pSearchEngine->SearchNextSpecial(m_prbSearchForNull->get_active());
+ }
+ }
+ else
+ { // the button has the function 'cancel'
+ // the CancelButton is usually only disabled, when working in a thread or with reschedule
+ m_pSearchEngine->CancelSearch();
+ // the ProgressHandler is called when it's really finished, here it's only a demand
+ }
+}
+
+IMPL_LINK(FmSearchDialog, OnClickedSpecialSettings, weld::Button&, rButton, void)
+{
+ if (m_ppbApproxSettings.get() == &rButton)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxSearchSimilarityDialog> pDlg(pFact->CreateSvxSearchSimilarityDialog(m_xDialog.get(), m_pSearchEngine->GetLevRelaxed(), m_pSearchEngine->GetLevOther(),
+ m_pSearchEngine->GetLevShorter(), m_pSearchEngine->GetLevLonger() ));
+ if (pDlg->Execute() == RET_OK)
+ {
+ m_pSearchEngine->SetLevRelaxed( pDlg->IsRelaxed() );
+ m_pSearchEngine->SetLevOther( pDlg->GetOther() );
+ m_pSearchEngine->SetLevShorter(pDlg->GetShorter() );
+ m_pSearchEngine->SetLevLonger( pDlg->GetLonger() );
+ }
+ }
+ else if (m_pSoundsLikeCJKSettings.get() == &rButton)
+ {
+ SfxItemSet aSet( SfxGetpApp()->GetPool() );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxJSearchOptionsDialog> aDlg(pFact->CreateSvxJSearchOptionsDialog(m_xDialog.get(), aSet, m_pSearchEngine->GetTransliterationFlags() ));
+ aDlg->Execute();
+
+ TransliterationFlags nFlags = aDlg->GetTransliterationFlags();
+ m_pSearchEngine->SetTransliterationFlags(nFlags);
+
+ m_pcbCase->set_active(m_pSearchEngine->GetCaseSensitive());
+ OnCheckBoxToggled( *m_pcbCase );
+ m_pHalfFullFormsCJK->set_active( !m_pSearchEngine->GetIgnoreWidthCJK() );
+ OnCheckBoxToggled( *m_pHalfFullFormsCJK );
+ }
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnSearchTextModified, weld::ComboBox&, void)
+{
+ if ((!m_pcmbSearchText->get_active_text().isEmpty()) || !m_prbSearchForText->get_active())
+ m_pbSearchAgain->set_sensitive(true);
+ else
+ m_pbSearchAgain->set_sensitive(false);
+
+ m_pSearchEngine->InvalidatePreviousLoc();
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnFocusGrabbed, weld::Widget&, void)
+{
+ m_pcmbSearchText->select_entry_region(0, -1);
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnPositionSelected, weld::ComboBox&, void)
+{
+ m_pSearchEngine->SetPosition(m_plbPosition->get_active());
+}
+
+IMPL_LINK_NOARG(FmSearchDialog, OnFieldSelected, weld::ComboBox&, void)
+{
+ m_pSearchEngine->RebuildUsedFields(m_prbAllFields->get_active() ? -1 : m_plbField->get_active());
+ // calls m_pSearchEngine->InvalidatePreviousLoc too
+
+ int nCurrentContext = m_plbForm->get_active();
+ if (nCurrentContext != -1)
+ m_arrContextFields[nCurrentContext] = m_plbField->get_active_text();
+}
+
+IMPL_LINK(FmSearchDialog, OnCheckBoxToggled, weld::ToggleButton&, rBox, void)
+{
+ bool bChecked = rBox.get_active();
+
+ // formatter or case -> pass on to the engine
+ if (&rBox == m_pcbUseFormat.get())
+ m_pSearchEngine->SetFormatterUsing(bChecked);
+ else if (&rBox == m_pcbCase.get())
+ m_pSearchEngine->SetCaseSensitive(bChecked);
+ // direction -> pass on and reset the checkbox-text for StartOver
+ else if (&rBox == m_pcbBackwards.get())
+ {
+ m_pcbStartOver->set_label( CuiResId( bChecked ? RID_STR_FROM_BOTTOM : RID_STR_FROM_TOP ) );
+ m_pSearchEngine->SetDirection(!bChecked);
+ }
+ // similarity-search or regular expression
+ else if ((&rBox == m_pcbApprox.get()) || (&rBox == m_pcbRegular.get()) || (&rBox == m_pcbWildCard.get()))
+ {
+ weld::CheckButton* pBoxes[] = { m_pcbWildCard.get(), m_pcbRegular.get(), m_pcbApprox.get() };
+ for (weld::CheckButton* pBoxe : pBoxes)
+ {
+ if (pBoxe != &rBox)
+ {
+ if (bChecked)
+ pBoxe->set_sensitive(false);
+ else
+ pBoxe->set_sensitive(true);
+ }
+ }
+
+ // pass on to the engine
+ m_pSearchEngine->SetWildcard(m_pcbWildCard->get_sensitive() && m_pcbWildCard->get_active());
+ m_pSearchEngine->SetRegular(m_pcbRegular->get_sensitive() && m_pcbRegular->get_active());
+ m_pSearchEngine->SetLevenshtein(m_pcbApprox->get_sensitive() && m_pcbApprox->get_active());
+ // (disabled boxes have to be passed to the engine as sal_False)
+
+ // adjust the Position-Listbox (which is not allowed during Wildcard-search)
+ if (&rBox == m_pcbWildCard.get())
+ {
+ if (bChecked)
+ {
+ m_pftPosition->set_sensitive(false);
+ m_plbPosition->set_sensitive(false);
+ }
+ else
+ {
+ m_pftPosition->set_sensitive(true);
+ m_plbPosition->set_sensitive(true);
+ }
+ }
+
+ // and the button for similarity-search
+ if (&rBox == m_pcbApprox.get())
+ {
+ if (bChecked)
+ m_ppbApproxSettings->set_sensitive(true);
+ else
+ m_ppbApproxSettings->set_sensitive(false);
+ }
+ }
+ else if (&rBox == m_pHalfFullFormsCJK.get())
+ {
+ // forward to the search engine
+ m_pSearchEngine->SetIgnoreWidthCJK( !bChecked );
+ }
+ else if (&rBox == m_pSoundsLikeCJK.get())
+ {
+ m_pSoundsLikeCJKSettings->set_sensitive(bChecked);
+
+ // two other buttons which depend on this one
+ bool bEnable = ( m_prbSearchForText->get_active()
+ && !m_pSoundsLikeCJK->get_active()
+ )
+ || !SvtCJKOptions().IsJapaneseFindEnabled();
+ m_pcbCase->set_sensitive(bEnable);
+ m_pHalfFullFormsCJK->set_sensitive(bEnable);
+
+ // forward to the search engine
+ m_pSearchEngine->SetTransliteration( bChecked );
+ }
+}
+
+void FmSearchDialog::InitContext(sal_Int16 nContext)
+{
+ FmSearchContext fmscContext;
+ fmscContext.nContext = nContext;
+
+ sal_uInt32 nResult = m_lnkContextSupplier.Call(fmscContext);
+ DBG_ASSERT(nResult > 0, "FmSearchDialog::InitContext : ContextSupplier didn't give me any controls !");
+
+ // put the field names into the respective listbox
+ m_plbField->clear();
+
+ if (!fmscContext.sFieldDisplayNames.isEmpty())
+ {
+ // use the display names if supplied
+ DBG_ASSERT(comphelper::string::getTokenCount(fmscContext.sFieldDisplayNames, ';') == comphelper::string::getTokenCount(fmscContext.strUsedFields, ';'),
+ "FmSearchDialog::InitContext : invalid context description supplied !");
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(fmscContext.sFieldDisplayNames.getToken(0, ';', nPos));
+ } while (nPos>=0);
+ }
+ else if (!fmscContext.strUsedFields.isEmpty())
+ {
+ // else use the field names
+ sal_Int32 nPos {0};
+ do {
+ m_plbField->append_text(fmscContext.strUsedFields.getToken(0, ';', nPos));
+ } while (nPos>=0);
+ }
+
+ if (nContext < static_cast<sal_Int32>(m_arrContextFields.size()) && !m_arrContextFields[nContext].isEmpty())
+ {
+ m_plbField->set_active_text(m_arrContextFields[nContext]);
+ }
+ else
+ {
+ m_plbField->set_active(0);
+ if (m_prbSingleField->get_active() && (m_plbField->get_count() > 1))
+ m_plbField->grab_focus();
+ }
+
+ m_pSearchEngine->SwitchToContext(fmscContext.xCursor, fmscContext.strUsedFields, fmscContext.arrFields,
+ m_prbAllFields->get_active() ? -1 : 0);
+
+ m_pftRecord->set_label(OUString::number(fmscContext.xCursor->getRow()));
+}
+
+IMPL_LINK(FmSearchDialog, OnContextSelection, weld::ComboBox&, rBox, void)
+{
+ InitContext(rBox.get_active());
+}
+
+void FmSearchDialog::EnableSearchUI(bool bEnable)
+{
+ // the search button has two functions -> adjust its text accordingly
+ OUString sButtonText( bEnable ? m_sSearch : m_sCancel );
+ m_pbSearchAgain->set_label(sButtonText);
+
+ m_prbSearchForText->set_sensitive(bEnable);
+ m_prbSearchForNull->set_sensitive(bEnable);
+ m_prbSearchForNotNull->set_sensitive(bEnable);
+ m_plbForm->set_sensitive(bEnable);
+ m_prbAllFields->set_sensitive(bEnable);
+ m_prbSingleField->set_sensitive(bEnable);
+ m_plbField->set_sensitive(bEnable && m_prbSingleField->get_active());
+ m_pcbBackwards->set_sensitive(bEnable);
+ m_pcbStartOver->set_sensitive(bEnable);
+ m_pbClose->set_sensitive(bEnable);
+ EnableSearchForDependees(bEnable);
+
+ if ( !bEnable )
+ { // this means we're preparing for starting a search
+ // In this case, EnableSearchForDependees disabled the search button
+ // But as we're about to use it for cancelling the search, we really need to enable it, again
+ m_pbSearchAgain->set_sensitive(true);
+ }
+}
+
+void FmSearchDialog::EnableSearchForDependees(bool bEnable)
+{
+ bool bSearchingForText = m_prbSearchForText->get_active();
+ m_pbSearchAgain->set_sensitive(bEnable && (!bSearchingForText || (!m_pcmbSearchText->get_active_text().isEmpty())));
+
+ bEnable = bEnable && bSearchingForText;
+
+ bool bEnableRedundants = !m_pSoundsLikeCJK->get_active() || !SvtCJKOptions().IsJapaneseFindEnabled();
+
+ m_pcmbSearchText->set_sensitive(bEnable);
+ m_pftPosition->set_sensitive(bEnable && !m_pcbWildCard->get_active());
+ m_pcbWildCard->set_sensitive(bEnable && !m_pcbRegular->get_active() && !m_pcbApprox->get_active());
+ m_pcbRegular->set_sensitive(bEnable && !m_pcbWildCard->get_active() && !m_pcbApprox->get_active());
+ m_pcbApprox->set_sensitive(bEnable && !m_pcbWildCard->get_active() && !m_pcbRegular->get_active());
+ m_ppbApproxSettings->set_sensitive(bEnable && m_pcbApprox->get_active());
+ m_pHalfFullFormsCJK->set_sensitive(bEnable && bEnableRedundants);
+ m_pSoundsLikeCJK->set_sensitive(bEnable);
+ m_pSoundsLikeCJKSettings->set_sensitive(bEnable && m_pSoundsLikeCJK->get_active());
+ m_plbPosition->set_sensitive(bEnable && !m_pcbWildCard->get_active());
+ m_pcbUseFormat->set_sensitive(bEnable);
+ m_pcbCase->set_sensitive(bEnable && bEnableRedundants);
+}
+
+void FmSearchDialog::OnFound(const css::uno::Any& aCursorPos, sal_Int16 nFieldPos)
+{
+ FmFoundRecordInformation friInfo;
+ friInfo.nContext = m_plbForm->get_active();
+ // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
+ friInfo.aPosition = aCursorPos;
+ if (m_prbAllFields->get_active())
+ friInfo.nFieldPos = nFieldPos;
+ else
+ friInfo.nFieldPos = m_plbField->get_active();
+ // this of course implies that I have really searched in the field that is selected in the listbox,
+ // which is made sure in RebuildUsedFields
+
+ m_lnkFoundHandler.Call(friInfo);
+
+ m_pcmbSearchText->grab_focus();
+}
+
+IMPL_LINK(FmSearchDialog, OnSearchProgress, const FmSearchProgress*, pProgress, void)
+{
+ SolarMutexGuard aGuard;
+ // make this single method thread-safe (it's an overkill to block the whole application for this,
+ // but we don't have another safety concept at the moment)
+
+ switch (pProgress->aSearchState)
+ {
+ case FmSearchProgress::State::Progress:
+ if (pProgress->bOverflow)
+ {
+ OUString sHint( CuiResId( m_pcbBackwards->get_active() ? RID_STR_OVERFLOW_BACKWARD : RID_STR_OVERFLOW_FORWARD ) );
+ m_pftHint->set_label( sHint );
+ }
+
+ m_pftRecord->set_label(OUString::number(1 + pProgress->nCurrentRecord));
+ break;
+
+ case FmSearchProgress::State::ProgressCounting:
+ m_pftHint->set_label(CuiResId(RID_STR_SEARCH_COUNTING));
+ m_pftRecord->set_label(OUString::number(pProgress->nCurrentRecord));
+ break;
+
+ case FmSearchProgress::State::Successful:
+ OnFound(pProgress->aBookmark, static_cast<sal_Int16>(pProgress->nFieldIndex));
+ EnableSearchUI(true);
+ break;
+
+ case FmSearchProgress::State::Error:
+ case FmSearchProgress::State::NothingFound:
+ {
+ const char* pErrorId = (FmSearchProgress::State::Error == pProgress->aSearchState)
+ ? RID_STR_SEARCH_GENERAL_ERROR
+ : RID_STR_SEARCH_NORECORD;
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, CuiResId(pErrorId)));
+ xBox->run();
+ [[fallthrough]];
+ }
+ case FmSearchProgress::State::Canceled:
+ EnableSearchUI(true);
+ if (m_lnkCanceledNotFoundHdl.IsSet())
+ {
+ FmFoundRecordInformation friInfo;
+ friInfo.nContext = m_plbForm->get_active();
+ // if I don't do a search in a context, this has an invalid value - but then it doesn't matter anyway
+ friInfo.aPosition = pProgress->aBookmark;
+ m_lnkCanceledNotFoundHdl.Call(friInfo);
+ }
+ break;
+ }
+
+ m_pftRecord->set_label(OUString::number(1 + pProgress->nCurrentRecord));
+}
+
+void FmSearchDialog::LoadParams()
+{
+ FmSearchParams aParams(m_pConfig->getParams());
+
+ const OUString* pHistory = aParams.aHistory.getConstArray();
+ const OUString* pHistoryEnd = pHistory + aParams.aHistory.getLength();
+ for (; pHistory != pHistoryEnd; ++pHistory)
+ m_pcmbSearchText->append_text( *pHistory );
+
+ // I do the settings at my UI-elements and then I simply call the respective change-handler,
+ // that way the data is handed on to the SearchEngine and all dependent settings are done
+
+ // current field
+ int nInitialField = m_plbField->find_text( aParams.sSingleSearchField );
+ if (nInitialField == -1)
+ nInitialField = 0;
+ m_plbField->set_active(nInitialField);
+ OnFieldSelected(*m_plbField);
+ // all fields/single field (AFTER selecting the field because OnClickedFieldRadios expects a valid value there)
+ if (aParams.bAllFields)
+ {
+ m_prbSingleField->set_active(false);
+ m_prbAllFields->set_active(true);
+ OnClickedFieldRadios(*m_prbAllFields);
+ // OnClickedFieldRadios also calls to RebuildUsedFields
+ }
+ else
+ {
+ m_prbAllFields->set_active(false);
+ m_prbSingleField->set_active(true);
+ OnClickedFieldRadios(*m_prbSingleField);
+ }
+
+ m_plbPosition->set_active(aParams.nPosition);
+ OnPositionSelected(*m_plbPosition);
+
+ // field formatting/case sensitivity/direction
+ m_pcbUseFormat->set_active(aParams.bUseFormatter);
+ m_pcbCase->set_active( aParams.isCaseSensitive() );
+ m_pcbBackwards->set_active(aParams.bBackwards);
+ OnCheckBoxToggled(*m_pcbUseFormat);
+ OnCheckBoxToggled(*m_pcbCase);
+ OnCheckBoxToggled(*m_pcbBackwards);
+
+ m_pHalfFullFormsCJK->set_active( !aParams.isIgnoreWidthCJK( ) ); // BEWARE: this checkbox has an inverse semantics!
+ m_pSoundsLikeCJK->set_active( aParams.bSoundsLikeCJK );
+ OnCheckBoxToggled(*m_pHalfFullFormsCJK);
+ OnCheckBoxToggled(*m_pSoundsLikeCJK);
+
+ m_pcbWildCard->set_active(false);
+ m_pcbRegular->set_active(false);
+ m_pcbApprox->set_active(false);
+ OnCheckBoxToggled(*m_pcbWildCard);
+ OnCheckBoxToggled(*m_pcbRegular);
+ OnCheckBoxToggled(*m_pcbApprox);
+
+ weld::CheckButton* pToCheck = nullptr;
+ if (aParams.bWildcard)
+ pToCheck = m_pcbWildCard.get();
+ if (aParams.bRegular)
+ pToCheck = m_pcbRegular.get();
+ if (aParams.bApproxSearch)
+ pToCheck = m_pcbApprox.get();
+ if (aParams.bSoundsLikeCJK)
+ pToCheck = m_pSoundsLikeCJK.get();
+ if (pToCheck)
+ {
+ pToCheck->set_active(true);
+ OnCheckBoxToggled(*pToCheck);
+ }
+
+ // set Levenshtein-parameters directly at the SearchEngine
+ m_pSearchEngine->SetLevRelaxed(aParams.bLevRelaxed);
+ m_pSearchEngine->SetLevOther(aParams.nLevOther);
+ m_pSearchEngine->SetLevShorter(aParams.nLevShorter);
+ m_pSearchEngine->SetLevLonger(aParams.nLevLonger);
+
+ m_pSearchEngine->SetTransliterationFlags( aParams.getTransliterationFlags( ) );
+
+ m_prbSearchForText->set_active(false);
+ m_prbSearchForNull->set_active(false);
+ m_prbSearchForNotNull->set_active(false);
+ switch (aParams.nSearchForType)
+ {
+ case 1: m_prbSearchForNull->set_active(true); break;
+ case 2: m_prbSearchForNotNull->set_active(true); break;
+ default: m_prbSearchForText->set_active(true); break;
+ }
+ OnClickedFieldRadios(*m_prbSearchForText);
+}
+
+void FmSearchDialog::SaveParams() const
+{
+ if (!m_pConfig)
+ return;
+
+ FmSearchParams aCurrentSettings;
+
+ int nCount = m_pcmbSearchText->get_count();
+ aCurrentSettings.aHistory.realloc(nCount);
+ OUString* pHistory = aCurrentSettings.aHistory.getArray();
+ for (int i = 0; i < nCount; ++i, ++pHistory)
+ *pHistory = m_pcmbSearchText->get_text(i);
+
+ aCurrentSettings.sSingleSearchField = m_plbField->get_active_text();
+ aCurrentSettings.bAllFields = m_prbAllFields->get_active();
+ aCurrentSettings.nPosition = m_pSearchEngine->GetPosition();
+ aCurrentSettings.bUseFormatter = m_pSearchEngine->GetFormatterUsing();
+ aCurrentSettings.setCaseSensitive ( m_pSearchEngine->GetCaseSensitive() );
+ aCurrentSettings.bBackwards = !m_pSearchEngine->GetDirection();
+ aCurrentSettings.bWildcard = m_pSearchEngine->GetWildcard();
+ aCurrentSettings.bRegular = m_pSearchEngine->GetRegular();
+ aCurrentSettings.bApproxSearch = m_pSearchEngine->GetLevenshtein();
+ aCurrentSettings.bLevRelaxed = m_pSearchEngine->GetLevRelaxed();
+ aCurrentSettings.nLevOther = m_pSearchEngine->GetLevOther();
+ aCurrentSettings.nLevShorter = m_pSearchEngine->GetLevShorter();
+ aCurrentSettings.nLevLonger = m_pSearchEngine->GetLevLonger();
+
+ aCurrentSettings.bSoundsLikeCJK = m_pSearchEngine->GetTransliteration();
+ aCurrentSettings.setTransliterationFlags ( m_pSearchEngine->GetTransliterationFlags() );
+
+ if (m_prbSearchForNull->get_active())
+ aCurrentSettings.nSearchForType = 1;
+ else if (m_prbSearchForNotNull->get_active())
+ aCurrentSettings.nSearchForType = 2;
+ else
+ aCurrentSettings.nSearchForType = 0;
+
+ m_pConfig->setParams( aCurrentSettings );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuigaldlg.cxx b/cui/source/dialogs/cuigaldlg.cxx
new file mode 100644
index 000000000..de0b0c166
--- /dev/null
+++ b/cui/source/dialogs/cuigaldlg.cxx
@@ -0,0 +1,1011 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+
+#include <sal/config.h>
+
+#include <algorithm>
+#include <cassert>
+
+#include <vcl/errinf.hxx>
+#include <ucbhelper/content.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <avmedia/mediawindow.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/opengrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/gallery1.hxx>
+#include <svx/galtheme.hxx>
+#include <cuigaldlg.hxx>
+#include <bitmaps.hlst>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/ContentCreationException.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+
+using namespace ::ucbhelper;
+using namespace ::cppu;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+
+SearchThread::SearchThread(SearchProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ const INetURLObject& rStartURL)
+ : Thread("cuiSearchThread")
+ , mpProgress(pProgress)
+ , mpBrowser(pBrowser)
+ , maStartURL(rStartURL)
+{
+}
+
+SearchThread::~SearchThread()
+{
+}
+
+void SearchThread::execute()
+{
+ const OUString aFileType(mpBrowser->m_xCbbFileType->get_active_text());
+
+ if (!aFileType.isEmpty())
+ {
+ const int nFileNumber = mpBrowser->m_xCbbFileType->find_text(aFileType);
+ sal_Int32 nBeginFormat, nEndFormat;
+ std::vector< OUString > aFormats;
+
+ if( !nFileNumber || nFileNumber == -1)
+ {
+ nBeginFormat = 1;
+ nEndFormat = mpBrowser->m_xCbbFileType->get_count() - 1;
+ }
+ else
+ nBeginFormat = nEndFormat = nFileNumber;
+
+ for (sal_Int32 i = nBeginFormat; i <= nEndFormat; ++i)
+ aFormats.push_back( mpBrowser->aFilterEntryList[ i ]->aFilterName.toAsciiLowerCase() );
+
+ ImplSearch( maStartURL, aFormats, mpBrowser->bSearchRecursive );
+ }
+
+ Application::PostUserEvent(LINK(mpProgress, SearchProgress, CleanUpHdl));
+}
+
+
+void SearchThread::ImplSearch( const INetURLObject& rStartURL,
+ const std::vector< OUString >& rFormats,
+ bool bRecursive )
+{
+ {
+ SolarMutexGuard aGuard;
+
+ mpProgress->SetDirectory( rStartURL );
+ }
+
+ try
+ {
+ css::uno::Reference< XCommandEnvironment > xEnv;
+ Content aCnt( rStartURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), xEnv, comphelper::getProcessComponentContext() );
+ Sequence< OUString > aProps( 2 );
+
+ aProps.getArray()[ 0 ] = "IsFolder";
+ aProps.getArray()[ 1 ] = "IsDocument";
+ css::uno::Reference< XResultSet > xResultSet(
+ aCnt.createCursor( aProps ) );
+
+ if( xResultSet.is() )
+ {
+ css::uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
+ css::uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
+
+ while( xResultSet->next() && schedule() )
+ {
+ INetURLObject aFoundURL( xContentAccess->queryContentIdentifierString() );
+ DBG_ASSERT( aFoundURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ bool bFolder = xRow->getBoolean( 1 ); // property "IsFolder"
+ if ( xRow->wasNull() )
+ bFolder = false;
+
+ if( bRecursive && bFolder )
+ ImplSearch( aFoundURL, rFormats, true );
+ else
+ {
+ bool bDocument = xRow->getBoolean( 2 ); // property "IsDocument"
+ if ( xRow->wasNull() )
+ bDocument = false;
+
+ if( bDocument )
+ {
+ GraphicDescriptor aDesc( aFoundURL );
+
+ if( ( aDesc.Detect() &&
+ std::find( rFormats.begin(),
+ rFormats.end(),
+ GraphicDescriptor::GetImportFormatShortName(
+ aDesc.GetFileFormat() ).toAsciiLowerCase() )
+ != rFormats.end() ) ||
+ std::find( rFormats.begin(),
+ rFormats.end(),
+ aFoundURL.GetFileExtension().toAsciiLowerCase())
+ != rFormats.end() )
+ {
+ SolarMutexGuard aGuard;
+
+ mpBrowser->aFoundList.push_back(
+ aFoundURL.GetMainURL( INetURLObject::DecodeMechanism::NONE )
+ );
+ mpBrowser->m_xLbxFound->insert_text(
+ mpBrowser->aFoundList.size() - 1,
+ GetReducedString(aFoundURL, 50));
+ }
+ }
+ }
+ }
+ }
+ }
+ catch (const ContentCreationException&)
+ {
+ }
+ catch (const css::uno::RuntimeException&)
+ {
+ }
+ catch (const css::uno::Exception&)
+ {
+ }
+}
+
+SearchProgress::SearchProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage, const INetURLObject& rStartURL)
+ : GenericDialogController(pParent, "cui/ui/gallerysearchprogress.ui", "GallerySearchProgress")
+ , startUrl_(rStartURL)
+ , m_pTabPage(pTabPage)
+ , m_xFtSearchDir(m_xBuilder->weld_label("dir"))
+ , m_xFtSearchType(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xFtSearchType->set_size_request(m_xFtSearchType->get_preferred_size().Width(), -1);
+ m_xBtnCancel->connect_clicked(LINK(this, SearchProgress, ClickCancelBtn));
+}
+
+SearchProgress::~SearchProgress()
+{
+}
+
+IMPL_LINK_NOARG(SearchProgress, ClickCancelBtn, weld::Button&, void)
+{
+ if (m_aSearchThread.is())
+ m_aSearchThread->terminate();
+}
+
+IMPL_LINK_NOARG(SearchProgress, CleanUpHdl, void*, void)
+{
+ if (m_aSearchThread.is())
+ m_aSearchThread->join();
+
+ m_xDialog->response(RET_OK);
+}
+
+void SearchProgress::LaunchThread()
+{
+ assert(!m_aSearchThread.is());
+ m_aSearchThread = new SearchThread(this, m_pTabPage, startUrl_);
+ m_aSearchThread->launch();
+}
+
+TakeThread::TakeThread(
+ TakeProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ TokenList_impl& rTakenList
+) :
+ Thread ( "cuiTakeThread" ),
+ mpProgress ( pProgress ),
+ mpBrowser ( pBrowser ),
+ mrTakenList ( rTakenList )
+{
+}
+
+
+TakeThread::~TakeThread()
+{
+}
+
+void TakeThread::execute()
+{
+ sal_Int32 nEntries;
+ GalleryTheme* pThm = mpBrowser->GetXChgData()->pTheme;
+ std::unique_ptr<GalleryProgress> pStatusProgress;
+
+ std::vector<int> aSelectedRows;
+
+ {
+ SolarMutexGuard aGuard;
+ pStatusProgress.reset(new GalleryProgress);
+ if (mpBrowser->bTakeAll)
+ nEntries = mpBrowser->m_xLbxFound->n_children();
+ else
+ {
+ aSelectedRows = mpBrowser->m_xLbxFound->get_selected_rows();
+ nEntries = aSelectedRows.size();
+ }
+ pThm->LockBroadcaster();
+ }
+
+ for( sal_Int32 i = 0; i < nEntries && schedule(); ++i )
+ {
+ const sal_Int32 nPos = mpBrowser->bTakeAll ? i : aSelectedRows[i];
+ const INetURLObject aURL( mpBrowser->aFoundList[ nPos ]);
+
+ mrTakenList.push_back( nPos );
+
+ {
+ SolarMutexGuard aGuard;
+
+ mpProgress->SetFile( aURL );
+ pStatusProgress->Update( i, nEntries - 1 );
+ pThm->InsertURL( aURL );
+ }
+ }
+
+ {
+ SolarMutexGuard aGuard;
+
+ pThm->UnlockBroadcaster();
+ pStatusProgress.reset();
+ }
+
+ Application::PostUserEvent(LINK(mpProgress, TakeProgress, CleanUpHdl));
+}
+
+TakeProgress::TakeProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage)
+ : GenericDialogController(pParent, "cui/ui/galleryapplyprogress.ui",
+ "GalleryApplyProgress")
+ , m_pParent(pParent)
+ , m_pTabPage(pTabPage)
+ , m_xFtTakeFile(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xBtnCancel->connect_clicked(LINK(this, TakeProgress, ClickCancelBtn));
+}
+
+TakeProgress::~TakeProgress()
+{
+}
+
+IMPL_LINK_NOARG(TakeProgress, ClickCancelBtn, weld::Button&, void)
+{
+ if (maTakeThread.is())
+ maTakeThread->terminate();
+}
+
+
+IMPL_LINK_NOARG(TakeProgress, CleanUpHdl, void*, void)
+{
+ if (maTakeThread.is())
+ maTakeThread->join();
+
+ std::vector<bool, std::allocator<bool> > aRemoveEntries(m_pTabPage->aFoundList.size(), false);
+ std::vector< OUString > aRemainingVector;
+ sal_uInt32 i, nCount;
+
+ std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(m_pParent));
+
+ m_pTabPage->m_xLbxFound->select(-1);
+ m_pTabPage->m_xLbxFound->freeze();
+
+ // mark all taken positions in aRemoveEntries
+ for( i = 0, nCount = maTakenList.size(); i < nCount; ++i )
+ aRemoveEntries[ maTakenList[ i ] ] = true;
+ maTakenList.clear();
+
+ // refill found list
+ for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
+ if( !aRemoveEntries[ i ] )
+ aRemainingVector.push_back( m_pTabPage->aFoundList[i] );
+
+ m_pTabPage->aFoundList.clear();
+
+ for( i = 0, nCount = aRemainingVector.size(); i < nCount; ++i )
+ m_pTabPage->aFoundList.push_back( aRemainingVector[ i ] );
+
+ aRemainingVector.clear();
+
+ // refill list box
+ for( i = 0, nCount = aRemoveEntries.size(); i < nCount; ++i )
+ if( !aRemoveEntries[ i ] )
+ aRemainingVector.push_back(m_pTabPage->m_xLbxFound->get_text(i));
+
+ m_pTabPage->m_xLbxFound->clear();
+
+ for( i = 0, nCount = aRemainingVector.size(); i < nCount; ++i )
+ m_pTabPage->m_xLbxFound->append_text(aRemainingVector[i]);
+
+ aRemainingVector.clear();
+
+ m_pTabPage->m_xLbxFound->thaw();
+ m_pTabPage->SelectFoundHdl( *m_pTabPage->m_xLbxFound );
+
+ xWait.reset();
+
+ m_xDialog->response(RET_OK);
+}
+
+void TakeProgress::LaunchThread()
+{
+ assert(!maTakeThread.is());
+ maTakeThread = new TakeThread(this, m_pTabPage, maTakenList);
+ maTakeThread->launch();
+}
+
+ActualizeProgress::ActualizeProgress(weld::Widget* pWindow, GalleryTheme* pThm)
+ : GenericDialogController(pWindow, "cui/ui/galleryupdateprogress.ui",
+ "GalleryUpdateProgress")
+ , pIdle(nullptr)
+ , pTheme(pThm)
+ , m_xFtActualizeFile(m_xBuilder->weld_label("file"))
+ , m_xBtnCancel(m_xBuilder->weld_button("cancel"))
+{
+ m_xBtnCancel->connect_clicked(LINK(this, ActualizeProgress, ClickCancelBtn));
+}
+
+ActualizeProgress::~ActualizeProgress()
+{
+}
+
+short ActualizeProgress::run()
+{
+ pIdle = new Idle("ActualizeProgressTimeout");
+ pIdle->SetInvokeHandler( LINK( this, ActualizeProgress, TimeoutHdl ) );
+ pIdle->SetPriority( TaskPriority::LOWEST );
+ pIdle->Start();
+
+ return GenericDialogController::run();
+}
+
+IMPL_LINK_NOARG(ActualizeProgress, ClickCancelBtn, weld::Button&, void)
+{
+ pTheme->AbortActualize();
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK( ActualizeProgress, TimeoutHdl, Timer*, _pTimer, void)
+{
+ if (_pTimer)
+ {
+ _pTimer->Stop();
+ delete _pTimer;
+ }
+
+ pTheme->Actualize(LINK(this, ActualizeProgress, ActualizeHdl), &aStatusProgress);
+ ClickCancelBtn(*m_xBtnCancel);
+}
+
+IMPL_LINK( ActualizeProgress, ActualizeHdl, const INetURLObject&, rURL, void )
+{
+ Application::Reschedule(true);
+ m_xFtActualizeFile->set_label(GetReducedString(rURL, 30));
+}
+
+TitleDialog::TitleDialog(weld::Widget* pParent, const OUString& rOldTitle)
+ : GenericDialogController(pParent, "cui/ui/gallerytitledialog.ui", "GalleryTitleDialog")
+ , m_xEdit(m_xBuilder->weld_entry("entry"))
+{
+ m_xEdit->set_text(rOldTitle);
+ m_xEdit->grab_focus();
+}
+
+TitleDialog::~TitleDialog()
+{
+}
+
+GalleryIdDialog::GalleryIdDialog(weld::Widget* pParent, GalleryTheme* _pThm)
+ : GenericDialogController(pParent, "cui/ui/gallerythemeiddialog.ui", "GalleryThemeIDDialog")
+ , m_pThm(_pThm)
+ , m_xBtnOk(m_xBuilder->weld_button("ok"))
+ , m_xLbResName(m_xBuilder->weld_combo_box("entry"))
+{
+ m_xLbResName->append_text("!!! No Id !!!");
+
+ GalleryTheme::InsertAllThemes(*m_xLbResName);
+
+ m_xLbResName->set_active(m_pThm->GetId());
+ m_xLbResName->grab_focus();
+
+ m_xBtnOk->connect_clicked(LINK(this, GalleryIdDialog, ClickOkHdl));
+}
+
+GalleryIdDialog::~GalleryIdDialog()
+{
+}
+
+IMPL_LINK_NOARG(GalleryIdDialog, ClickOkHdl, weld::Button&, void)
+{
+ Gallery* pGal = m_pThm->GetParent();
+ const sal_uInt32 nId = GetId();
+ bool bDifferentThemeExists = false;
+
+ for( size_t i = 0, nCount = pGal->GetThemeCount(); i < nCount && !bDifferentThemeExists; i++ )
+ {
+ const GalleryThemeEntry* pInfo = pGal->GetThemeInfo( i );
+
+ if ((pInfo->GetId() == nId) && (pInfo->GetThemeName() != m_pThm->GetName()))
+ {
+ OUString aStr = CuiResId( RID_SVXSTR_GALLERY_ID_EXISTS ) +
+ " (" + pInfo->GetThemeName() + ")";
+
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ aStr));
+ xInfoBox->run();
+ m_xLbResName->grab_focus();
+ bDifferentThemeExists = true;
+ }
+ }
+
+ if (!bDifferentThemeExists)
+ m_xDialog->response(RET_OK);
+}
+
+GalleryThemeProperties::GalleryThemeProperties(weld::Widget* pParent,
+ ExchangeData* _pData, SfxItemSet const * pItemSet)
+ : SfxTabDialogController(pParent, "cui/ui/gallerythemedialog.ui",
+ "GalleryThemeDialog", pItemSet)
+ , pData(_pData)
+{
+ AddTabPage("general", TPGalleryThemeGeneral::Create, nullptr);
+ AddTabPage("files", TPGalleryThemeProperties::Create, nullptr);
+ if (pData->pTheme->IsReadOnly())
+ RemoveTabPage("files");
+
+ OUString aText = m_xDialog->get_title().replaceFirst( "%1", pData->pTheme->GetName() );
+
+ if (pData->pTheme->IsReadOnly())
+ aText += " " + CuiResId( RID_SVXSTR_GALLERY_READONLY );
+
+ m_xDialog->set_title(aText);
+}
+
+void GalleryThemeProperties::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "general")
+ static_cast<TPGalleryThemeGeneral&>( rPage ).SetXChgData( pData );
+ else
+ static_cast<TPGalleryThemeProperties&>( rPage ).SetXChgData( pData );
+}
+
+TPGalleryThemeGeneral::TPGalleryThemeGeneral(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/gallerygeneralpage.ui", "GalleryGeneralPage", &rSet)
+ , pData(nullptr)
+ , m_xFiMSImage(m_xBuilder->weld_image("image"))
+ , m_xEdtMSName(m_xBuilder->weld_entry("name"))
+ , m_xFtMSShowType(m_xBuilder->weld_label("type"))
+ , m_xFtMSShowPath(m_xBuilder->weld_label("location"))
+ , m_xFtMSShowContent(m_xBuilder->weld_label("contents"))
+ , m_xFtMSShowChangeDate(m_xBuilder->weld_label("modified"))
+{
+}
+
+void TPGalleryThemeGeneral::SetXChgData( ExchangeData* _pData )
+{
+ pData = _pData;
+
+ GalleryTheme* pThm = pData->pTheme;
+ OUString aOutStr( OUString::number(pThm->GetObjectCount()) );
+ OUString aObjStr( CuiResId( RID_SVXSTR_GALLERYPROPS_OBJECT ) );
+ OUString aAccess;
+ OUString aType( SvxResId( RID_SVXSTR_GALLERYPROPS_GALTHEME ) );
+ bool bReadOnly = pThm->IsReadOnly();
+
+ m_xEdtMSName->set_text(pThm->GetName());
+ m_xEdtMSName->set_editable(!bReadOnly);
+ m_xEdtMSName->set_sensitive(!bReadOnly);
+
+ if( pThm->IsReadOnly() )
+ aType += CuiResId( RID_SVXSTR_GALLERY_READONLY );
+
+ m_xFtMSShowType->set_label(aType);
+ m_xFtMSShowPath->set_label(pThm->GetSdgURL().GetMainURL(INetURLObject::DecodeMechanism::Unambiguous));
+
+ // singular or plural?
+ if ( 1 == pThm->GetObjectCount() )
+ aObjStr = aObjStr.getToken( 0, ';' );
+ else
+ aObjStr = aObjStr.getToken( 1, ';' );
+
+ aOutStr += " " + aObjStr;
+
+ m_xFtMSShowContent->set_label(aOutStr);
+
+ // get locale wrapper (singleton)
+ const SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& aLocaleData = aSysLocale.GetLocaleData();
+
+ // ChangeDate/Time
+ aAccess = aLocaleData.getDate( pData->aThemeChangeDate ) + ", " + aLocaleData.getTime( pData->aThemeChangeTime );
+ m_xFtMSShowChangeDate->set_label(aAccess);
+
+ // set image
+ OUString sId;
+
+ if( pThm->IsReadOnly() )
+ sId = RID_SVXBMP_THEME_READONLY_BIG;
+ else if( pThm->IsDefault() )
+ sId = RID_SVXBMP_THEME_DEFAULT_BIG;
+ else
+ sId = RID_SVXBMP_THEME_NORMAL_BIG;
+
+ m_xFiMSImage->set_from_icon_name(sId);
+}
+
+bool TPGalleryThemeGeneral::FillItemSet( SfxItemSet* /*rSet*/ )
+{
+ pData->aEditedTitle = m_xEdtMSName->get_text();
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> TPGalleryThemeGeneral::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<TPGalleryThemeGeneral>(pPage, pController, *rSet);
+}
+
+TPGalleryThemeProperties::TPGalleryThemeProperties(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/galleryfilespage.ui", "GalleryFilesPage", &rSet)
+ , pData(nullptr)
+ , bEntriesFound(false)
+ , bInputAllowed(true)
+ , bTakeAll(false)
+ , bSearchRecursive(false)
+ , xDialogListener(new ::svt::DialogClosedListener())
+ , m_xCbbFileType(m_xBuilder->weld_combo_box("filetype"))
+ , m_xLbxFound(m_xBuilder->weld_tree_view("files"))
+ , m_xBtnSearch(m_xBuilder->weld_button("findfiles"))
+ , m_xBtnTake(m_xBuilder->weld_button("add"))
+ , m_xBtnTakeAll(m_xBuilder->weld_button("addall"))
+ , m_xCbxPreview(m_xBuilder->weld_check_button("preview"))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "image", m_aWndPreview))
+{
+ m_xLbxFound->set_size_request(m_xLbxFound->get_approximate_digit_width() * 35,
+ m_xLbxFound->get_height_rows(15));
+ m_xLbxFound->set_selection_mode(SelectionMode::Multiple);
+ xDialogListener->SetDialogClosedLink( LINK( this, TPGalleryThemeProperties, DialogClosedHdl ) );
+}
+
+void TPGalleryThemeProperties::SetXChgData( ExchangeData* _pData )
+{
+ pData = _pData;
+
+ aPreviewTimer.SetInvokeHandler( LINK( this, TPGalleryThemeProperties, PreviewTimerHdl ) );
+ aPreviewTimer.SetTimeout( 500 );
+ m_xBtnSearch->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickSearchHdl));
+ m_xBtnTake->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickTakeHdl));
+ m_xBtnTakeAll->connect_clicked(LINK(this, TPGalleryThemeProperties, ClickTakeAllHdl));
+ m_xCbxPreview->connect_toggled(LINK(this, TPGalleryThemeProperties, ClickPreviewHdl));
+ m_xCbbFileType->connect_changed(LINK(this, TPGalleryThemeProperties, SelectFileTypeHdl));
+ m_xLbxFound->connect_row_activated(LINK(this, TPGalleryThemeProperties, DClickFoundHdl));
+ m_xLbxFound->connect_changed(LINK(this, TPGalleryThemeProperties, SelectFoundHdl));
+ m_xLbxFound->append_text(CuiResId(RID_SVXSTR_GALLERY_NOFILES));
+ m_xLbxFound->show();
+
+ FillFilterList();
+
+ m_xBtnTake->set_sensitive(true);
+ m_xBtnTakeAll->set_sensitive(false);
+ m_xCbxPreview->set_sensitive(false);
+}
+
+void TPGalleryThemeProperties::StartSearchFiles( const OUString& _rFolderURL, short _nDlgResult )
+{
+ if ( RET_OK == _nDlgResult )
+ {
+ aURL = INetURLObject( _rFolderURL );
+ bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
+ SearchFiles();
+ }
+}
+
+TPGalleryThemeProperties::~TPGalleryThemeProperties()
+{
+ xMediaPlayer.clear();
+ xDialogListener.clear();
+ aFilterEntryList.clear();
+}
+
+std::unique_ptr<SfxTabPage> TPGalleryThemeProperties::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<TPGalleryThemeProperties>(pPage, pController, *rSet);
+}
+
+OUString TPGalleryThemeProperties::addExtension( const OUString& _rDisplayText, const OUString& _rExtension )
+{
+ OUString sRet = _rDisplayText;
+ if ( sRet.indexOf( "(*.*)" ) == -1 )
+ {
+ sRet += " (" + _rExtension + ")";
+ }
+ return sRet;
+}
+
+void TPGalleryThemeProperties::FillFilterList()
+{
+ GraphicFilter &rFilter = GraphicFilter::GetGraphicFilter();
+ OUString aExt;
+ OUString aName;
+ sal_uInt16 i, nKeyCount;
+
+ // graphic filters
+ for( i = 0, nKeyCount = rFilter.GetImportFormatCount(); i < nKeyCount; i++ )
+ {
+ aExt = rFilter.GetImportFormatShortName( i );
+ aName = rFilter.GetImportFormatName( i );
+ size_t entryIndex = 0;
+ FilterEntry* pTestEntry = aFilterEntryList.empty() ? nullptr : aFilterEntryList[ entryIndex ].get();
+ bool bInList = false;
+
+ OUString aExtensions;
+ int j = 0;
+ OUString sWildcard;
+ while( true )
+ {
+ sWildcard = rFilter.GetImportWildcard( i, j++ );
+ if ( sWildcard.isEmpty() )
+ break;
+ if ( aExtensions.indexOf( sWildcard ) == -1 )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+ aExtensions += sWildcard;
+ }
+ }
+ aName = addExtension( aName, aExtensions );
+
+ while( pTestEntry )
+ {
+ if ( pTestEntry->aFilterName == aExt )
+ {
+ bInList = true;
+ break;
+ }
+ pTestEntry = ( ++entryIndex < aFilterEntryList.size() )
+ ? aFilterEntryList[ entryIndex ].get() : nullptr;
+ }
+ if ( !bInList )
+ {
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = aExt;
+ m_xCbbFileType->append_text(aName);
+ aFilterEntryList.push_back(std::move(pFilterEntry));
+ }
+ }
+
+#if HAVE_FEATURE_AVMEDIA
+ // media filters
+ static const char aWildcard[] = "*.";
+ ::avmedia::FilterNameVector aFilters= ::avmedia::MediaWindow::getMediaFilters();
+
+ for(const std::pair<OUString,OUString> & aFilter : aFilters)
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ OUString aFilterWildcard( aWildcard );
+
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = aFilter.second.getToken( 0, ';', nIndex );
+ aFilterWildcard += pFilterEntry->aFilterName;
+ m_xCbbFileType->append_text(addExtension(aFilter.first, aFilterWildcard));
+ aFilterEntryList.push_back( std::move(pFilterEntry) );
+ }
+ }
+#endif
+
+ // 'All' filters
+ OUString aExtensions;
+
+ // graphic filters
+ for ( i = 0; i < nKeyCount; ++i )
+ {
+ int j = 0;
+ OUString sWildcard;
+ while( true )
+ {
+ sWildcard = rFilter.GetImportWildcard( i, j++ );
+ if ( sWildcard.isEmpty() )
+ break;
+ if ( aExtensions.indexOf( sWildcard ) == -1 )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+
+ aExtensions += sWildcard;
+ }
+ }
+ }
+
+#if HAVE_FEATURE_AVMEDIA
+ // media filters
+ for(const std::pair<OUString,OUString> & aFilter : aFilters)
+ {
+ for( sal_Int32 nIndex = 0; nIndex >= 0; )
+ {
+ if ( !aExtensions.isEmpty() )
+ aExtensions += ";";
+ aExtensions += aWildcard + aFilter.second.getToken( 0, ';', nIndex );
+ }
+ }
+#endif
+
+#if defined(_WIN32)
+ if (aExtensions.getLength() > 240)
+ aExtensions = "*.*";
+#endif
+
+ std::unique_ptr<FilterEntry> pFilterEntry(new FilterEntry);
+ pFilterEntry->aFilterName = CuiResId(RID_SVXSTR_GALLERY_ALLFILES);
+ pFilterEntry->aFilterName = addExtension(pFilterEntry->aFilterName, aExtensions);
+ m_xCbbFileType->insert_text(0, pFilterEntry->aFilterName);
+ m_xCbbFileType->set_active(0);
+ aFilterEntryList.insert(aFilterEntryList.begin(), std::move(pFilterEntry));
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFileTypeHdl, weld::ComboBox&, void)
+{
+ OUString aText(m_xCbbFileType->get_active_text());
+
+ if( bInputAllowed && ( aLastFilterName != aText ) )
+ {
+ aLastFilterName = aText;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryupdategalleryfilelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryUpdateFileListDialog"));
+ if (xQuery->run() == RET_YES)
+ SearchFiles();
+ }
+}
+
+void TPGalleryThemeProperties::SearchFiles()
+{
+ auto xProgress = std::make_shared<SearchProgress>(GetFrameWeld(), this, aURL);
+
+ aFoundList.clear();
+ m_xLbxFound->clear();
+
+ xProgress->SetFileType( m_xCbbFileType->get_active_text() );
+ xProgress->SetDirectory( INetURLObject() );
+
+ xProgress->LaunchThread();
+ weld::DialogController::runAsync(xProgress, [this](sal_Int32 nResult) {
+ EndSearchProgressHdl(nResult);
+ });
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickSearchHdl, weld::Button&, void)
+{
+ if( !bInputAllowed )
+ return;
+
+ try
+ {
+ // setup folder picker
+ css::uno::Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = FolderPicker::create(xContext);
+
+ OUString aDlgPathName( SvtPathOptions().GetGraphicPath() );
+ xFolderPicker->setDisplayDirectory(aDlgPathName);
+
+ aPreviewTimer.Stop();
+
+ css::uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener.get() );
+ else
+ {
+ if( xFolderPicker->execute() == RET_OK )
+ {
+ aURL = INetURLObject( xFolderPicker->getDirectory() );
+ bSearchRecursive = true; // UI choice no longer possible, windows file picker allows no user controls
+ SearchFiles();
+ }
+ }
+ }
+ catch (const IllegalArgumentException&)
+ {
+ OSL_FAIL( "Folder picker failed with illegal arguments" );
+ }
+}
+
+void TPGalleryThemeProperties::TakeFiles()
+{
+ if (m_xLbxFound->count_selected_rows() || (bTakeAll && bEntriesFound))
+ {
+ auto xTakeProgress = std::make_shared<TakeProgress>(GetFrameWeld(), this);
+ xTakeProgress->LaunchThread();
+ weld::DialogController::runAsync(xTakeProgress, [=](sal_Int32 /*nResult*/) {
+ /* no postprocessing needed, pTakeProgress
+ will be disposed in TakeProgress::CleanupHdl */
+ });
+
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickPreviewHdl, weld::ToggleButton&, void)
+{
+ if ( !bInputAllowed )
+ return;
+
+ aPreviewTimer.Stop();
+ aPreviewString.clear();
+
+ if (!m_xCbxPreview->get_active())
+ {
+ xMediaPlayer.clear();
+ m_aWndPreview.SetGraphic(Graphic());
+ m_aWndPreview.Invalidate();
+ }
+ else
+ DoPreview();
+}
+
+void TPGalleryThemeProperties::DoPreview()
+{
+ int nIndex = m_xLbxFound->get_selected_index();
+ OUString aString(m_xLbxFound->get_text(nIndex));
+
+ if (aString == aPreviewString)
+ return;
+
+ INetURLObject _aURL(aFoundList[nIndex]);
+ bInputAllowed = false;
+
+ if (!m_aWndPreview.SetGraphic(_aURL))
+ {
+ weld::WaitObject aWaitObject(GetFrameWeld());
+ ErrorHandler::HandleError(ERRCODE_IO_NOTEXISTSPATH, GetFrameWeld());
+ }
+#if HAVE_FEATURE_AVMEDIA
+ else if( ::avmedia::MediaWindow::isMediaURL( _aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ), "" ) )
+ {
+ xMediaPlayer = ::avmedia::MediaWindow::createPlayer( _aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" );
+ if( xMediaPlayer.is() )
+ xMediaPlayer->start();
+ }
+#endif
+ bInputAllowed = true;
+ aPreviewString = aString;
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeHdl, weld::Button&, void)
+{
+ if( !bInputAllowed )
+ return;
+
+ aPreviewTimer.Stop();
+
+ if (!m_xLbxFound->count_selected_rows() || !bEntriesFound)
+ {
+ SvxOpenGraphicDialog aDlg(CuiResId(RID_SVXSTR_KEY_GALLERY_DIR), GetFrameWeld());
+ aDlg.EnableLink(false);
+ aDlg.AsLink(false);
+
+ if( !aDlg.Execute() )
+ pData->pTheme->InsertURL( INetURLObject( aDlg.GetPath() ) );
+ }
+ else
+ {
+ bTakeAll = false;
+ TakeFiles();
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, ClickTakeAllHdl, weld::Button&, void)
+{
+ if( bInputAllowed )
+ {
+ aPreviewTimer.Stop();
+ bTakeAll = true;
+ TakeFiles();
+ }
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, SelectFoundHdl, weld::TreeView&, void)
+{
+ if (!bInputAllowed)
+ return;
+
+ bool bPreviewPossible = false;
+
+ aPreviewTimer.Stop();
+
+ if( bEntriesFound )
+ {
+ if (m_xLbxFound->count_selected_rows() == 1)
+ {
+ m_xCbxPreview->set_sensitive(true);
+ bPreviewPossible = true;
+ }
+ else
+ m_xCbxPreview->set_sensitive(false);
+
+ if( !aFoundList.empty() )
+ m_xBtnTakeAll->set_sensitive(true);
+ else
+ m_xBtnTakeAll->set_sensitive(false);
+ }
+
+ if (bPreviewPossible && m_xCbxPreview->get_active())
+ aPreviewTimer.Start();
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, DClickFoundHdl, weld::TreeView&, bool)
+{
+ if( bInputAllowed )
+ {
+ aPreviewTimer.Stop();
+
+ if (m_xLbxFound->count_selected_rows() == 1 && bEntriesFound)
+ ClickTakeHdl(*m_xBtnTake);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(TPGalleryThemeProperties, PreviewTimerHdl, Timer *, void)
+{
+ aPreviewTimer.Stop();
+ DoPreview();
+}
+
+void TPGalleryThemeProperties::EndSearchProgressHdl(sal_Int32 /*nResult*/)
+{
+ if( !aFoundList.empty() )
+ {
+ m_xLbxFound->select(0);
+ m_xBtnTakeAll->set_sensitive(true);
+ m_xCbxPreview->set_sensitive(true);
+ bEntriesFound = true;
+ }
+ else
+ {
+ m_xLbxFound->append_text(CuiResId(RID_SVXSTR_GALLERY_NOFILES));
+ m_xBtnTakeAll->set_sensitive(false);
+ m_xCbxPreview->set_sensitive(false);
+ bEntriesFound = false;
+ }
+}
+
+IMPL_LINK( TPGalleryThemeProperties, DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, pEvt, void )
+{
+ DBG_ASSERT( xFolderPicker.is(), "TPGalleryThemeProperties::DialogClosedHdl(): no folder picker" );
+
+ OUString sURL = xFolderPicker->getDirectory();
+ StartSearchFiles( sURL, pEvt->DialogResult );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuigrfflt.cxx b/cui/source/dialogs/cuigrfflt.cxx
new file mode 100644
index 000000000..baaa6603c
--- /dev/null
+++ b/cui/source/dialogs/cuigrfflt.cxx
@@ -0,0 +1,468 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/BitmapMosaicFilter.hxx>
+#include <vcl/BitmapSharpenFilter.hxx>
+#include <vcl/BitmapEmbossGreyFilter.hxx>
+#include <vcl/BitmapSepiaFilter.hxx>
+#include <vcl/BitmapSmoothenFilter.hxx>
+#include <vcl/BitmapSolarizeFilter.hxx>
+#include <vcl/BitmapColorQuantizationFilter.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/diagnose.h>
+#include <tools/helpers.hxx>
+#include <cuigrfflt.hxx>
+
+CuiGraphicPreviewWindow::CuiGraphicPreviewWindow()
+ : mpOrigGraphic(nullptr)
+ , mfScaleX(0.0)
+ , mfScaleY(0.0)
+{
+}
+
+void CuiGraphicPreviewWindow::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ OutputDevice &rDevice = pDrawingArea->get_ref_device();
+ maOutputSizePixel = rDevice.LogicToPixel(Size(81, 73), MapMode(MapUnit::MapAppFont));
+ pDrawingArea->set_size_request(maOutputSizePixel.Width(), maOutputSizePixel.Height());
+}
+
+void CuiGraphicPreviewWindow::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetDialogColor()));
+ rRenderContext.Erase();
+
+ const Size aOutputSize(GetOutputSizePixel());
+
+ if (maPreview.IsAnimated())
+ {
+ const Size aGraphicSize(rRenderContext.LogicToPixel(maPreview.GetPrefSize(), maPreview.GetPrefMapMode()));
+ const Point aGraphicPosition((aOutputSize.Width() - aGraphicSize.Width() ) >> 1,
+ (aOutputSize.Height() - aGraphicSize.Height() ) >> 1);
+ maPreview.StartAnimation(&rRenderContext, aGraphicPosition, aGraphicSize);
+ }
+ else
+ {
+ const Size aGraphicSize(maPreview.GetSizePixel());
+ const Point aGraphicPosition((aOutputSize.Width() - aGraphicSize.Width()) >> 1,
+ (aOutputSize.Height() - aGraphicSize.Height()) >> 1);
+ maPreview.Draw(&rRenderContext, aGraphicPosition, aGraphicSize);
+ }
+}
+
+void CuiGraphicPreviewWindow::SetPreview(const Graphic& rGraphic)
+{
+ maPreview = rGraphic;
+ Invalidate();
+}
+
+void CuiGraphicPreviewWindow::ScaleImageToFit()
+{
+ if (!mpOrigGraphic)
+ return;
+
+ maScaledOrig = *mpOrigGraphic;
+
+ const Size aPreviewSize(GetOutputSizePixel());
+ Size aGrfSize(maOrigGraphicSizePixel);
+
+ if( mpOrigGraphic->GetType() == GraphicType::Bitmap &&
+ aPreviewSize.Width() && aPreviewSize.Height() &&
+ aGrfSize.Width() && aGrfSize.Height() )
+ {
+ const double fGrfWH = static_cast<double>(aGrfSize.Width()) / aGrfSize.Height();
+ const double fPreWH = static_cast<double>(aPreviewSize.Width()) / aPreviewSize.Height();
+
+ if( fGrfWH < fPreWH )
+ {
+ aGrfSize.setWidth( static_cast<long>( aPreviewSize.Height() * fGrfWH ) );
+ aGrfSize.setHeight( aPreviewSize.Height() );
+ }
+ else
+ {
+ aGrfSize.setWidth( aPreviewSize.Width() );
+ aGrfSize.setHeight( static_cast<long>( aPreviewSize.Width() / fGrfWH ) );
+ }
+
+ mfScaleX = static_cast<double>(aGrfSize.Width()) / maOrigGraphicSizePixel.Width();
+ mfScaleY = static_cast<double>(aGrfSize.Height()) / maOrigGraphicSizePixel.Height();
+
+ if( !mpOrigGraphic->IsAnimated() )
+ {
+ BitmapEx aBmpEx( mpOrigGraphic->GetBitmapEx() );
+
+ if( aBmpEx.Scale( aGrfSize ) )
+ maScaledOrig = aBmpEx;
+ }
+ }
+
+ maModifyHdl.Call(nullptr);
+}
+
+void CuiGraphicPreviewWindow::Resize()
+{
+ maOutputSizePixel = GetOutputSizePixel();
+ ScaleImageToFit();
+}
+
+GraphicFilterDialog::GraphicFilterDialog(weld::Window* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const Graphic& rGraphic)
+ : GenericDialogController(pParent, rUIXMLDescription, rID)
+ , maModifyHdl(LINK(this, GraphicFilterDialog, ImplModifyHdl))
+ , mxPreview(new weld::CustomWeld(*m_xBuilder, "preview", maPreview))
+{
+ bIsBitmap = rGraphic.GetType() == GraphicType::Bitmap;
+
+ maTimer.SetInvokeHandler(LINK(this, GraphicFilterDialog, ImplPreviewTimeoutHdl));
+ maTimer.SetTimeout(5);
+
+ maPreview.init(&rGraphic, maModifyHdl);
+}
+
+IMPL_LINK_NOARG(GraphicFilterDialog, ImplPreviewTimeoutHdl, Timer *, void)
+{
+ maTimer.Stop();
+ maPreview.SetPreview(GetFilteredGraphic(maPreview.GetScaledOriginal(),
+ maPreview.GetScaleX(), maPreview.GetScaleY()));
+}
+
+IMPL_LINK_NOARG(GraphicFilterDialog, ImplModifyHdl, LinkParamNone*, void)
+{
+ if (bIsBitmap)
+ {
+ maTimer.Stop();
+ maTimer.Start();
+ }
+}
+
+GraphicFilterMosaic::GraphicFilterMosaic(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges)
+ : GraphicFilterDialog(pParent, "cui/ui/mosaicdialog.ui", "MosaicDialog", rGraphic)
+ , mxMtrWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PIXEL))
+ , mxMtrHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PIXEL))
+ , mxCbxEdges(m_xBuilder->weld_check_button("edges"))
+{
+ mxMtrWidth->set_value(nTileWidth, FieldUnit::PIXEL);
+ mxMtrWidth->set_max(GetGraphicSizePixel().Width(), FieldUnit::PIXEL);
+ mxMtrWidth->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
+
+ mxMtrHeight->set_value(nTileHeight, FieldUnit::PIXEL);
+ mxMtrHeight->set_max(GetGraphicSizePixel().Height(), FieldUnit::PIXEL);
+ mxMtrHeight->connect_value_changed(LINK(this, GraphicFilterMosaic, EditModifyHdl));
+
+ mxCbxEdges->set_active(bEnhanceEdges);
+ mxCbxEdges->connect_toggled(LINK(this, GraphicFilterMosaic, CheckBoxModifyHdl));
+
+ mxMtrWidth->grab_focus();
+}
+
+IMPL_LINK_NOARG(GraphicFilterMosaic, CheckBoxModifyHdl, weld::ToggleButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+IMPL_LINK_NOARG(GraphicFilterMosaic, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterMosaic::GetFilteredGraphic( const Graphic& rGraphic,
+ double fScaleX, double fScaleY )
+{
+ Graphic aRet;
+ long nTileWidth = static_cast<long>(mxMtrWidth->get_value(FieldUnit::PIXEL));
+ long nTileHeight = static_cast<long>(mxMtrHeight->get_value(FieldUnit::PIXEL));
+ const Size aSize( std::max( FRound( nTileWidth * fScaleX ), 1L ),
+ std::max( FRound( nTileHeight * fScaleY ), 1L ) );
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
+ {
+ if( IsEnhanceEdges() )
+ (void)BitmapFilter::Filter(aAnim, BitmapSharpenFilter());
+
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapMosaicFilter(aSize.getWidth(), aSize.getHeight())))
+ {
+ if( IsEnhanceEdges() )
+ BitmapFilter::Filter(aBmpEx, BitmapSharpenFilter());
+
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSmooth::GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius)
+ : GraphicFilterDialog(pParent, "cui/ui/smoothdialog.ui", "SmoothDialog", rGraphic)
+ , mxMtrRadius(m_xBuilder->weld_spin_button("radius"))
+{
+ mxMtrRadius->set_value(nRadius * 10);
+ mxMtrRadius->connect_value_changed(LINK(this, GraphicFilterSmooth, EditModifyHdl));
+ mxMtrRadius->grab_focus();
+}
+
+IMPL_LINK_NOARG(GraphicFilterSmooth, EditModifyHdl, weld::SpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSmooth::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ double nRadius = mxMtrRadius->get_value() / 10.0;
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSmoothenFilter(nRadius)))
+ {
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSmoothenFilter(nRadius)))
+ {
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSolarize::GraphicFilterSolarize(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt8 cGreyThreshold, bool bInvert)
+ : GraphicFilterDialog(pParent, "cui/ui/solarizedialog.ui", "SolarizeDialog", rGraphic)
+ , mxMtrThreshold(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
+ , mxCbxInvert(m_xBuilder->weld_check_button("invert"))
+{
+ mxMtrThreshold->set_value(FRound(cGreyThreshold / 2.55), FieldUnit::PERCENT);
+ mxMtrThreshold->connect_value_changed(LINK(this, GraphicFilterSolarize, EditModifyHdl));
+
+ mxCbxInvert->set_active(bInvert);
+ mxCbxInvert->connect_toggled(LINK(this, GraphicFilterSolarize, CheckBoxModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterSolarize, CheckBoxModifyHdl, weld::ToggleButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+IMPL_LINK_NOARG(GraphicFilterSolarize, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSolarize::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt8 nGreyThreshold = static_cast<sal_uInt8>(FRound(mxMtrThreshold->get_value(FieldUnit::PERCENT) * 2.55));
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSolarizeFilter(nGreyThreshold)))
+ {
+ if( IsInvert() )
+ aAnim.Invert();
+
+ aRet = aAnim;
+ }
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSolarizeFilter(nGreyThreshold)))
+ {
+ if( IsInvert() )
+ aBmpEx.Invert();
+
+ aRet = aBmpEx;
+ }
+ }
+
+ return aRet;
+}
+
+GraphicFilterSepia::GraphicFilterSepia(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nSepiaPercent)
+ : GraphicFilterDialog(pParent, "cui/ui/agingdialog.ui", "AgingDialog", rGraphic)
+ , mxMtrSepia(m_xBuilder->weld_metric_spin_button("value", FieldUnit::PERCENT))
+{
+ mxMtrSepia->set_value(nSepiaPercent, FieldUnit::PERCENT);
+ mxMtrSepia->connect_value_changed(LINK(this, GraphicFilterSepia, EditModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterSepia, EditModifyHdl, weld::MetricSpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterSepia::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt16 nSepiaPct = sal::static_int_cast< sal_uInt16 >(mxMtrSepia->get_value(FieldUnit::PERCENT));
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapSepiaFilter(nSepiaPct)))
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapSepiaFilter(nSepiaPct)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+GraphicFilterPoster::GraphicFilterPoster(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nPosterCount)
+ : GraphicFilterDialog(pParent, "cui/ui/posterdialog.ui", "PosterDialog", rGraphic)
+ , mxNumPoster(m_xBuilder->weld_spin_button("value"))
+{
+ mxNumPoster->set_range(2, rGraphic.GetBitmapEx().GetBitCount());
+ mxNumPoster->set_value(nPosterCount);
+ mxNumPoster->connect_value_changed(LINK(this, GraphicFilterPoster, EditModifyHdl));
+}
+
+IMPL_LINK_NOARG(GraphicFilterPoster, EditModifyHdl, weld::SpinButton&, void)
+{
+ GetModifyHdl().Call(nullptr);
+}
+
+Graphic GraphicFilterPoster::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ const sal_uInt16 nPosterCount = static_cast<sal_uInt16>(mxNumPoster->get_value());
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if( aAnim.ReduceColors( nPosterCount ) )
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapColorQuantizationFilter(nPosterCount)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+bool EmbossControl::MouseButtonDown( const MouseEvent& rEvt )
+{
+ const RectPoint eOldRP = GetActualRP();
+
+ SvxRectCtl::MouseButtonDown( rEvt );
+
+ if( GetActualRP() != eOldRP )
+ maModifyHdl.Call( nullptr );
+
+ return true;
+}
+
+void EmbossControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ SvxRectCtl::SetDrawingArea(pDrawingArea);
+ Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(77, 60), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+}
+
+GraphicFilterEmboss::GraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic, RectPoint eLightSource)
+ : GraphicFilterDialog(pParent, "cui/ui/embossdialog.ui", "EmbossDialog", rGraphic)
+ , mxCtlLight(new weld::CustomWeld(*m_xBuilder, "lightsource", maCtlLight))
+{
+ maCtlLight.SetActualRP(eLightSource);
+ maCtlLight.SetModifyHdl( GetModifyHdl() );
+ maCtlLight.GrabFocus();
+}
+
+GraphicFilterEmboss::~GraphicFilterEmboss()
+{
+}
+
+Graphic GraphicFilterEmboss::GetFilteredGraphic( const Graphic& rGraphic, double, double )
+{
+ Graphic aRet;
+ sal_uInt16 nAzim, nElev;
+
+ switch (maCtlLight.GetActualRP())
+ {
+ default: OSL_FAIL("svx::GraphicFilterEmboss::GetFilteredGraphic(), unknown Reference Point!" );
+ [[fallthrough]];
+ case RectPoint::LT: nAzim = 4500; nElev = 4500; break;
+ case RectPoint::MT: nAzim = 9000; nElev = 4500; break;
+ case RectPoint::RT: nAzim = 13500; nElev = 4500; break;
+ case RectPoint::LM: nAzim = 0; nElev = 4500; break;
+ case RectPoint::MM: nAzim = 0; nElev = 9000; break;
+ case RectPoint::RM: nAzim = 18000; nElev = 4500; break;
+ case RectPoint::LB: nAzim = 31500; nElev = 4500; break;
+ case RectPoint::MB: nAzim = 27000; nElev = 4500; break;
+ case RectPoint::RB: nAzim = 22500; nElev = 4500; break;
+ }
+
+ if( rGraphic.IsAnimated() )
+ {
+ Animation aAnim( rGraphic.GetAnimation() );
+
+ if (BitmapFilter::Filter(aAnim, BitmapEmbossGreyFilter(nAzim, nElev)))
+ aRet = aAnim;
+ }
+ else
+ {
+ BitmapEx aBmpEx( rGraphic.GetBitmapEx() );
+
+ if (BitmapFilter::Filter(aBmpEx, BitmapEmbossGreyFilter(nAzim, nElev)))
+ aRet = aBmpEx;
+ }
+
+ return aRet;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuihyperdlg.cxx b/cui/source/dialogs/cuihyperdlg.cxx
new file mode 100644
index 000000000..9ca722680
--- /dev/null
+++ b/cui/source/dialogs/cuihyperdlg.cxx
@@ -0,0 +1,293 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <osl/diagnose.h>
+#include <comphelper/lok.hxx>
+#include <unotools/viewoptions.hxx>
+#include <cuihyperdlg.hxx>
+#include <hlinettp.hxx>
+#include <hlmailtp.hxx>
+#include <hldoctp.hxx>
+#include <hldocntp.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/eitem.hxx>
+#include <svx/svxids.hrc>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <vector>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+
+//# #
+//# Childwindow-Wrapper-Class #
+//# #
+
+
+SvxHlinkCtrl::SvxHlinkCtrl( sal_uInt16 _nId, SfxBindings & rBindings, SvxHpLinkDlg* pDlg )
+ : SfxControllerItem ( _nId, rBindings )
+ , aRdOnlyForwarder ( SID_READONLY_MODE, *this )
+{
+ pParent = pDlg;
+}
+
+void SvxHlinkCtrl::dispose()
+{
+ pParent = nullptr;
+ aRdOnlyForwarder.dispose();
+ ::SfxControllerItem::dispose();
+}
+
+void SvxHlinkCtrl::StateChanged( sal_uInt16 nSID, SfxItemState eState,
+ const SfxPoolItem* pState )
+{
+ if (!(eState == SfxItemState::DEFAULT && pParent))
+ return;
+
+ switch ( nSID )
+ {
+ case SID_HYPERLINK_GETLINK :
+ {
+ pParent->SetPage( static_cast<const SvxHyperlinkItem*>(pState) );
+ }
+ break;
+ case SID_READONLY_MODE :
+ {
+ pParent->SetReadOnlyMode( static_cast<const SfxBoolItem*>(pState)->GetValue() );
+ }
+ break;
+ }
+}
+
+//# #
+//# Hyperlink - Dialog #
+//# #
+SvxHpLinkDlg::SvxHpLinkDlg(SfxBindings* pBindings, SfxChildWindow* pChild, weld::Window* pParent)
+ : SfxModelessDialogController(pBindings, pChild, pParent, "cui/ui/hyperlinkdialog.ui", "HyperlinkDialog")
+ , pSet ( nullptr )
+ , pExampleSet ( nullptr )
+ , maCtrl ( SID_HYPERLINK_GETLINK, *pBindings, this )
+ , mbIsHTMLDoc ( false )
+ , m_xIconCtrl(m_xBuilder->weld_notebook("tabcontrol"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xApplyBtn(m_xBuilder->weld_button("apply"))
+ , m_xCancelBtn(m_xBuilder->weld_button("cancel"))
+ , m_xHelpBtn(m_xBuilder->weld_button("help"))
+ , m_xResetBtn(m_xBuilder->weld_button("reset"))
+{
+ m_xIconCtrl->connect_enter_page( LINK ( this, SvxHpLinkDlg, ChosePageHdl_Impl ) );
+ m_xIconCtrl->show();
+
+ // ItemSet
+ if ( pSet )
+ {
+ pExampleSet = new SfxItemSet( *pSet );
+ pOutSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
+ }
+
+ // Buttons
+ m_xOKBtn->show();
+ m_xApplyBtn->show();
+ m_xCancelBtn->show();
+ m_xHelpBtn->show();
+ m_xResetBtn->show();
+
+ mbGrabFocus = true;
+
+ // set OK/Cancel - button
+ m_xCancelBtn->set_label(CuiResId(RID_SVXSTR_HYPDLG_CLOSEBUT));
+
+ // create itemset for tabpages
+ mpItemSet = std::make_unique<SfxItemSet>( SfxGetpApp()->GetPool(), svl::Items<SID_HYPERLINK_GETLINK,
+ SID_HYPERLINK_SETLINK>{} );
+
+ SvxHyperlinkItem aItem(SID_HYPERLINK_GETLINK);
+ mpItemSet->Put(aItem);
+
+ SetInputSet (mpItemSet.get());
+
+ // insert pages
+ AddTabPage("internet", SvxHyperlinkInternetTp::Create);
+ AddTabPage("mail", SvxHyperlinkMailTp::Create);
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ AddTabPage("document", SvxHyperlinkDocTp::Create);
+ AddTabPage("newdocument", SvxHyperlinkNewDocTp::Create);
+ }
+
+ SetCurPageId("internet");
+
+ // Init Dialog
+ Start();
+
+ GetBindings().Update(SID_READONLY_MODE);
+
+ m_xResetBtn->connect_clicked( LINK( this, SvxHpLinkDlg, ResetHdl ) );
+ m_xOKBtn->connect_clicked( LINK ( this, SvxHpLinkDlg, ClickOkHdl_Impl ) );
+ m_xApplyBtn->connect_clicked ( LINK ( this, SvxHpLinkDlg, ClickApplyHdl_Impl ) );
+}
+
+SvxHpLinkDlg::~SvxHpLinkDlg()
+{
+ // delete config item, so the base class (SfxModelessDialogController) can not load it on the next start
+ SvtViewOptions aViewOpt( EViewType::TabDialog, OUString::number(SID_HYPERLINK_DIALOG) );
+ aViewOpt.Delete();
+
+ mpItemSet.reset();
+
+ maCtrl.dispose();
+
+ maPageList.clear();
+
+ pRanges.reset();
+ pOutSet.reset();
+}
+
+void SvxHpLinkDlg::Close()
+{
+ if (IsClosing())
+ return;
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if (pViewFrame)
+ pViewFrame->ToggleChildWindow(SID_HYPERLINK_DIALOG);
+}
+
+void SvxHpLinkDlg::Apply()
+{
+ SfxItemSet aItemSet( SfxGetpApp()->GetPool(), svl::Items<SID_HYPERLINK_GETLINK,
+ SID_HYPERLINK_SETLINK>{} );
+
+ SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(
+ GetTabPage( GetCurPageId() ) );
+
+ if ( pCurrentPage->AskApply() )
+ {
+ pCurrentPage->FillItemSet( &aItemSet );
+
+ const SvxHyperlinkItem *aItem = aItemSet.GetItem(SID_HYPERLINK_SETLINK);
+ if ( !aItem->GetURL().isEmpty() )
+ GetDispatcher()->ExecuteList(SID_HYPERLINK_SETLINK,
+ SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { aItem });
+
+ static_cast<SvxHyperlinkTabPageBase*>( GetTabPage( GetCurPageId() ) )->DoApply();
+ }
+}
+
+/// Click on OK button
+IMPL_LINK_NOARG(SvxHpLinkDlg, ClickOkHdl_Impl, weld::Button&, void)
+{
+ Apply();
+ m_xDialog->response(RET_OK);
+}
+
+/*************************************************************************
+|*
+|* Click on Apply-button
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHpLinkDlg, ClickApplyHdl_Impl, weld::Button&, void)
+{
+ Apply();
+}
+
+/*************************************************************************
+|*
+|* Set Page
+|*
+|************************************************************************/
+void SvxHpLinkDlg::SetPage ( SvxHyperlinkItem const * pItem )
+{
+ OString sPageId("internet");
+
+ OUString aStrURL(pItem->GetURL());
+ INetURLObject aURL(aStrURL);
+ INetProtocol eProtocolTyp = aURL.GetProtocol();
+
+ switch ( eProtocolTyp )
+ {
+ case INetProtocol::Http :
+ case INetProtocol::Ftp :
+ sPageId = "internet";
+ break;
+ case INetProtocol::File :
+ sPageId = "document";
+ break;
+ case INetProtocol::Mailto :
+ sPageId = "mail";
+ break;
+ default :
+ if (aStrURL.startsWith("#"))
+ sPageId = "document";
+ else
+ {
+ // not valid
+ sPageId = GetCurPageId();
+ }
+ break;
+ }
+
+ ShowPage (sPageId);
+
+ SvxHyperlinkTabPageBase* pCurrentPage = static_cast<SvxHyperlinkTabPageBase*>(GetTabPage( sPageId ));
+
+ mbIsHTMLDoc = (pItem->GetInsertMode() & HLINK_HTMLMODE) != 0;
+
+ IconChoicePage* pPage = GetTabPage (sPageId);
+ if(pPage)
+ {
+ SfxItemSet& aPageSet = const_cast<SfxItemSet&>(pPage->GetItemSet ());
+ aPageSet.Put ( *pItem );
+
+ pCurrentPage->Reset( aPageSet );
+ if ( mbGrabFocus )
+ {
+ pCurrentPage->SetInitFocus(); // #92535# grab the focus only once at initialization
+ mbGrabFocus = false;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* Enable/Disable ReadOnly mode
+|*
+|************************************************************************/
+void SvxHpLinkDlg::SetReadOnlyMode( bool bRdOnly )
+{
+ m_xOKBtn->set_sensitive(!bRdOnly);
+}
+
+/*************************************************************************
+|*
+|* late-initialization of newly created pages
+|*
+|************************************************************************/
+void SvxHpLinkDlg::PageCreated(const OString& /*rId*/, IconChoicePage& rPage)
+{
+ SvxHyperlinkTabPageBase& rHyperlinkPage = dynamic_cast< SvxHyperlinkTabPageBase& >( rPage );
+ Reference< XFrame > xDocumentFrame = GetBindings().GetActiveFrame();
+ OSL_ENSURE( xDocumentFrame.is(), "SvxHpLinkDlg::PageCreated: macro assignment functionality won't work with a proper frame!" );
+ rHyperlinkPage.SetDocumentFrame( xDocumentFrame );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuiimapwnd.cxx b/cui/source/dialogs/cuiimapwnd.cxx
new file mode 100644
index 000000000..60346dc69
--- /dev/null
+++ b/cui/source/dialogs/cuiimapwnd.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuiimapwnd.hxx>
+
+/*************************************************************************
+|*
+|* URLDlg
+|*
+\************************************************************************/
+
+URLDlg::URLDlg(weld::Widget* pWindow, const OUString& rURL, const OUString& rAlternativeText,
+ const OUString& rDescription, const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList)
+ : GenericDialogController(pWindow, "cui/ui/cuiimapdlg.ui", "IMapDialog")
+ , m_xEdtURL(m_xBuilder->weld_entry("urlentry"))
+ , m_xCbbTargets(m_xBuilder->weld_combo_box("frameCB"))
+ , m_xEdtName(m_xBuilder->weld_entry("nameentry"))
+ , m_xEdtAlternativeText(m_xBuilder->weld_entry("textentry"))
+ , m_xEdtDescription(m_xBuilder->weld_text_view("descTV"))
+{
+ m_xEdtDescription->set_size_request(m_xEdtDescription->get_approximate_digit_width() * 51,
+ m_xEdtDescription->get_height_rows(5));
+
+ m_xEdtURL->set_text( rURL );
+ m_xEdtAlternativeText->set_text( rAlternativeText );
+ m_xEdtDescription->set_text( rDescription );
+ m_xEdtName->set_text( rName );
+
+ for (const OUString& a : rTargetList)
+ m_xCbbTargets->append_text(a);
+
+ if (rTarget.isEmpty())
+ m_xCbbTargets->set_entry_text("_self");
+ else
+ m_xCbbTargets->set_entry_text(rTarget);
+}
+
+URLDlg::~URLDlg()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/cuitbxform.cxx b/cui/source/dialogs/cuitbxform.cxx
new file mode 100644
index 000000000..eb0a76814
--- /dev/null
+++ b/cui/source/dialogs/cuitbxform.cxx
@@ -0,0 +1,33 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuitbxform.hxx>
+
+FmInputRecordNoDialog::FmInputRecordNoDialog(weld::Window * pParent)
+ : GenericDialogController(pParent, "cui/ui/recordnumberdialog.ui", "RecordNumberDialog")
+ , m_xRecordNo(m_xBuilder->weld_spin_button("entry"))
+{
+ m_xRecordNo->set_range(1, 0x7FFFFFFF);
+}
+
+FmInputRecordNoDialog::~FmInputRecordNoDialog()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/dlgname.cxx b/cui/source/dialogs/dlgname.cxx
new file mode 100644
index 000000000..d8044366b
--- /dev/null
+++ b/cui/source/dialogs/dlgname.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 <dlgname.hxx>
+
+/*************************************************************************
+|*
+|* Dialog for editing a name
+|*
+\************************************************************************/
+
+SvxNameDialog::SvxNameDialog(weld::Window* pParent, const OUString& rName, const OUString& rDesc)
+ : GenericDialogController(pParent, "cui/ui/namedialog.ui", "NameDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("name_entry"))
+ , m_xFtDescription(m_xBuilder->weld_label("description_label"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+{
+ m_xFtDescription->set_label(rDesc);
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+ ModifyHdl(*m_xEdtName);
+ m_xEdtName->connect_changed(LINK(this, SvxNameDialog, ModifyHdl));
+}
+
+IMPL_LINK_NOARG(SvxNameDialog, ModifyHdl, weld::Entry&, void)
+{
+ // Do not allow empty names
+ bool bEnable;
+ if (m_aCheckNameHdl.IsSet())
+ bEnable = !m_xEdtName->get_text().isEmpty() && m_aCheckNameHdl.Call(*this);
+ else
+ bEnable = !m_xEdtName->get_text().isEmpty();
+ m_xBtnOK->set_sensitive(bEnable);
+ // tdf#129032: feedback on reason to disabled controls
+ m_xEdtName->set_message_type(bEnable ? weld::EntryMessageType::Normal : weld::EntryMessageType::Error);
+ OUString rTip = "";
+ if (!bEnable && m_aCheckNameTooltipHdl.IsSet())
+ rTip = m_aCheckNameTooltipHdl.Call(*this);
+ m_xBtnOK->set_tooltip_text(rTip);
+ m_xEdtName->set_tooltip_text(rTip);
+}
+
+// #i68101#
+// Dialog for editing Object Name
+// plus uniqueness-callback-linkHandler
+
+SvxObjectNameDialog::SvxObjectNameDialog(weld::Window* pParent, const OUString& rName)
+ : GenericDialogController(pParent, "cui/ui/objectnamedialog.ui", "ObjectNameDialog")
+ , m_xEdtName(m_xBuilder->weld_entry("object_name_entry"))
+ , m_xBtnOK(m_xBuilder->weld_button("ok"))
+{
+ // set name
+ m_xEdtName->set_text(rName);
+ m_xEdtName->select_region(0, -1);
+
+ // activate name
+ ModifyHdl(*m_xEdtName);
+ m_xEdtName->connect_changed(LINK(this, SvxObjectNameDialog, ModifyHdl));
+}
+
+IMPL_LINK_NOARG(SvxObjectNameDialog, ModifyHdl, weld::Entry&, void)
+{
+ if (aCheckNameHdl.IsSet())
+ {
+ m_xBtnOK->set_sensitive(aCheckNameHdl.Call(*this));
+ }
+}
+
+// #i68101#
+// Dialog for editing Object Title and Description
+
+SvxObjectTitleDescDialog::SvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle,
+ const OUString& rDescription)
+ : GenericDialogController(pParent, "cui/ui/objecttitledescdialog.ui", "ObjectTitleDescDialog")
+ , m_xEdtTitle(m_xBuilder->weld_entry("object_title_entry"))
+ , m_xEdtDescription(m_xBuilder->weld_text_view("desc_entry"))
+{
+ //lock height to initial height
+ m_xEdtDescription->set_size_request(-1, m_xEdtDescription->get_text_height() * 5);
+ // set title & desc
+ m_xEdtTitle->set_text(rTitle);
+ m_xEdtDescription->set_text(rDescription);
+
+ // activate title
+ m_xEdtTitle->select_region(0, -1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hangulhanjadlg.cxx b/cui/source/dialogs/hangulhanjadlg.cxx
new file mode 100644
index 000000000..5e273b3b1
--- /dev/null
+++ b/cui/source/dialogs/hangulhanjadlg.cxx
@@ -0,0 +1,1505 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hangulhanjadlg.hxx>
+#include <dialmgr.hxx>
+
+#include <helpids.h>
+#include <strings.hrc>
+
+#include <algorithm>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <com/sun/star/lang/NoSupportException.hpp>
+#include <com/sun/star/linguistic2/ConversionDictionaryType.hpp>
+#include <com/sun/star/linguistic2/ConversionDirection.hpp>
+#include <com/sun/star/linguistic2/ConversionDictionaryList.hpp>
+#include <com/sun/star/i18n/TextConversionOption.hpp>
+#include <com/sun/star/util/XFlushable.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#define HHC editeng::HangulHanjaConversion
+#define LINE_CNT static_cast< sal_uInt16 >(2)
+#define MAXNUM_SUGGESTIONS 50
+
+
+namespace svx
+{
+
+ using namespace ::com::sun::star;
+ using namespace css::uno;
+ using namespace css::linguistic2;
+ using namespace css::lang;
+ using namespace css::container;
+
+
+ namespace
+ {
+ class FontSwitch
+ {
+ private:
+ OutputDevice& m_rDev;
+
+ public:
+ FontSwitch( OutputDevice& _rDev, const vcl::Font& _rTemporaryFont )
+ :m_rDev( _rDev )
+ {
+ m_rDev.Push( PushFlags::FONT );
+ m_rDev.SetFont( _rTemporaryFont );
+ }
+ ~FontSwitch() COVERITY_NOEXCEPT_FALSE
+ {
+ m_rDev.Pop();
+ }
+ };
+
+ /** a class which allows to draw two texts in a pseudo-ruby way (which basically
+ means one text above or below the other, and a little bit smaller)
+ */
+ class PseudoRubyText
+ {
+ public:
+ enum RubyPosition
+ {
+ eAbove, eBelow
+ };
+
+ protected:
+ OUString m_sPrimaryText;
+ OUString m_sSecondaryText;
+ RubyPosition m_ePosition;
+
+ public:
+ PseudoRubyText();
+ void init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition );
+ const OUString& getPrimaryText() const { return m_sPrimaryText; }
+ const OUString& getSecondaryText() const { return m_sSecondaryText; }
+
+ public:
+ void Paint( vcl::RenderContext& _rDevice, const ::tools::Rectangle& _rRect,
+ ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation );
+ };
+
+ }
+
+ PseudoRubyText::PseudoRubyText()
+ : m_ePosition(eAbove)
+ {
+ }
+
+ void PseudoRubyText::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const RubyPosition& rPosition )
+ {
+ m_sPrimaryText = rPrimaryText;
+ m_sSecondaryText = rSecondaryText;
+ m_ePosition = rPosition;
+ }
+
+
+ void PseudoRubyText::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& _rRect,
+ ::tools::Rectangle* _pPrimaryLocation, ::tools::Rectangle* _pSecondaryLocation )
+ {
+ // calculate the text flags for the painting
+ constexpr DrawTextFlags nTextStyle = DrawTextFlags::Mnemonic |
+ DrawTextFlags::Left |
+ DrawTextFlags::VCenter;
+
+ Size aPlaygroundSize(_rRect.GetSize());
+
+ // the font for the secondary text:
+ vcl::Font aSmallerFont(rRenderContext.GetFont());
+ // heuristic: 80% of the original size
+ aSmallerFont.SetFontHeight( static_cast<long>( 0.8 * aSmallerFont.GetFontHeight() ) );
+
+ // let's calculate the size of our two texts
+ ::tools::Rectangle aPrimaryRect = rRenderContext.GetTextRect( _rRect, m_sPrimaryText, nTextStyle );
+ ::tools::Rectangle aSecondaryRect;
+ {
+ FontSwitch aFontRestore(rRenderContext, aSmallerFont);
+ aSecondaryRect = rRenderContext.GetTextRect(_rRect, m_sSecondaryText, nTextStyle);
+ }
+
+ // position these rectangles properly
+ // x-axis:
+ sal_Int32 nCombinedWidth = std::max( aSecondaryRect.GetWidth(), aPrimaryRect.GetWidth() );
+ // the rectangle where both texts will reside is as high as possible, and as wide as the
+ // widest of both text rects
+ aPrimaryRect.SetLeft( _rRect.Left() );
+ aSecondaryRect.SetLeft( aPrimaryRect.Left() );
+ aPrimaryRect.SetRight( _rRect.Left() + nCombinedWidth );
+ aSecondaryRect.SetRight( aPrimaryRect.Right() );
+
+ // y-axis:
+ sal_Int32 nCombinedHeight = aPrimaryRect.GetHeight() + aSecondaryRect.GetHeight();
+ // align to the top, for the moment
+ aPrimaryRect.Move( 0, _rRect.Top() - aPrimaryRect.Top() );
+ aSecondaryRect.Move( 0, aPrimaryRect.Top() + aPrimaryRect.GetHeight() - aSecondaryRect.Top() );
+ // move the rects to the bottom
+ aPrimaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
+ aSecondaryRect.Move( 0, ( aPlaygroundSize.Height() - nCombinedHeight ) / 2 );
+
+ // 'til here, everything we did assumes that the secondary text is painted _below_ the primary
+ // text. If this isn't the case, we need to correct the rectangles
+ if (eAbove == m_ePosition)
+ {
+ sal_Int32 nVertDistance = aSecondaryRect.Top() - aPrimaryRect.Top();
+ aSecondaryRect.Move( 0, -nVertDistance );
+ aPrimaryRect.Move( 0, nCombinedHeight - nVertDistance );
+ }
+
+ // now draw the texts
+ // as we already calculated the precise rectangles for the texts, we don't want to
+ // use the alignment flags given - within it's rect, every text is centered
+ DrawTextFlags nDrawTextStyle( nTextStyle );
+ nDrawTextStyle &= ~DrawTextFlags( DrawTextFlags::Right | DrawTextFlags::Left | DrawTextFlags::Bottom | DrawTextFlags::Top );
+ nDrawTextStyle |= DrawTextFlags::Center | DrawTextFlags::VCenter;
+
+ rRenderContext.DrawText( aPrimaryRect, m_sPrimaryText, nDrawTextStyle );
+ {
+ FontSwitch aFontRestore(rRenderContext, aSmallerFont);
+ rRenderContext.DrawText( aSecondaryRect, m_sSecondaryText, nDrawTextStyle );
+ }
+
+ // outta here
+ if (_pPrimaryLocation)
+ *_pPrimaryLocation = aPrimaryRect;
+ if (_pSecondaryLocation)
+ *_pSecondaryLocation = aSecondaryRect;
+ }
+
+ class RubyRadioButton
+ {
+ public:
+ RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl);
+ void init(const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition);
+
+ void set_sensitive(bool sensitive) { m_xControl->set_sensitive(sensitive); }
+ void set_active(bool active) { m_xControl->set_active(active); }
+ bool get_active() const { return m_xControl->get_active(); }
+
+ void connect_clicked(const Link<weld::Button&, void>& rLink) { m_xControl->connect_clicked(rLink); }
+
+ private:
+ Size GetOptimalSize() const;
+ void Paint(vcl::RenderContext& rRenderContext);
+
+ ScopedVclPtr<VirtualDevice> m_xVirDev;
+ std::unique_ptr<weld::RadioButton> m_xControl;
+ PseudoRubyText m_aRubyText;
+ };
+
+ RubyRadioButton::RubyRadioButton(std::unique_ptr<weld::RadioButton> xControl)
+ : m_xVirDev(xControl->create_virtual_device())
+ , m_xControl(std::move(xControl))
+ {
+ // expand the point size of the desired font to the equivalent pixel size
+ if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
+ pDefaultDevice->SetPointFont(*m_xVirDev, m_xControl->get_font());
+ }
+
+ void RubyRadioButton::init( const OUString& rPrimaryText, const OUString& rSecondaryText, const PseudoRubyText::RubyPosition& rPosition )
+ {
+ m_aRubyText.init(rPrimaryText, rSecondaryText, rPosition);
+
+ m_xVirDev->SetOutputSizePixel(GetOptimalSize());
+
+ Paint(*m_xVirDev);
+
+ m_xControl->set_image(m_xVirDev.get());
+ }
+
+ void RubyRadioButton::Paint(vcl::RenderContext& rRenderContext)
+ {
+ ::tools::Rectangle aOverallRect(Point(0, 0), rRenderContext.GetOutputSizePixel());
+ // inflate the rect a little bit (because the VCL radio button does the same)
+ ::tools::Rectangle aTextRect( aOverallRect );
+ aTextRect.AdjustLeft( 1 ); aTextRect.AdjustRight( -1 );
+ aTextRect.AdjustTop( 1 ); aTextRect.AdjustBottom( -1 );
+
+ // paint the ruby text
+ ::tools::Rectangle aPrimaryTextLocation;
+ ::tools::Rectangle aSecondaryTextLocation;
+
+ m_aRubyText.Paint(rRenderContext, aTextRect, &aPrimaryTextLocation, &aSecondaryTextLocation);
+ }
+
+ Size RubyRadioButton::GetOptimalSize() const
+ {
+ vcl::Font aSmallerFont(m_xVirDev->GetFont());
+ aSmallerFont.SetFontHeight( static_cast<long>( 0.8 * aSmallerFont.GetFontHeight() ) );
+ ::tools::Rectangle rect( Point(), Size( SAL_MAX_INT32, SAL_MAX_INT32 ) );
+
+ Size aPrimarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getPrimaryText() ).GetSize();
+ Size aSecondarySize;
+ {
+ FontSwitch aFontRestore(*m_xVirDev, aSmallerFont);
+ aSecondarySize = m_xVirDev->GetTextRect( rect, m_aRubyText.getSecondaryText() ).GetSize();
+ }
+
+ Size minimumSize;
+ minimumSize.setHeight( aPrimarySize.Height() + aSecondarySize.Height() + 5 );
+ minimumSize.setWidth( aPrimarySize.Width() + aSecondarySize.Width() + 5 );
+ return minimumSize;
+ }
+
+ SuggestionSet::SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow)
+ : ValueSet(std::move(xScrolledWindow))
+
+ {
+ }
+
+ void SuggestionSet::UserDraw( const UserDrawEvent& rUDEvt )
+ {
+ vcl::RenderContext* pDev = rUDEvt.GetRenderContext();
+ ::tools::Rectangle aRect = rUDEvt.GetRect();
+ sal_uInt16 nItemId = rUDEvt.GetItemId();
+
+ OUString sText = *static_cast< OUString* >( GetItemData( nItemId ) );
+ pDev->DrawText( aRect, sText, DrawTextFlags::Center | DrawTextFlags::VCenter );
+ }
+
+ SuggestionDisplay::SuggestionDisplay(weld::Builder& rBuilder)
+ : m_bDisplayListBox( true )
+ , m_bInSelectionUpdate( false )
+ , m_xValueSet(new SuggestionSet(rBuilder.weld_scrolled_window("scrollwin")))
+ , m_xValueSetWin(new weld::CustomWeld(rBuilder, "valueset", *m_xValueSet))
+ , m_xListBox(rBuilder.weld_tree_view("listbox"))
+ {
+ m_xValueSet->SetSelectHdl( LINK( this, SuggestionDisplay, SelectSuggestionValueSetHdl ) );
+ m_xListBox->connect_changed( LINK( this, SuggestionDisplay, SelectSuggestionListBoxHdl ) );
+
+ m_xValueSet->SetLineCount( LINE_CNT );
+ m_xValueSet->SetStyle( m_xValueSet->GetStyle() | WB_ITEMBORDER | WB_VSCROLL );
+
+ OUString const aOneCharacter("AU");
+ auto nItemWidth = 2 * m_xListBox->get_pixel_size(aOneCharacter).Width();
+ m_xValueSet->SetItemWidth( nItemWidth );
+
+ Size aSize(m_xListBox->get_approximate_digit_width() * 42, m_xListBox->get_text_height() * 5);
+ m_xValueSet->set_size_request(aSize.Width(), aSize.Height());
+ m_xListBox->set_size_request(aSize.Width(), aSize.Height());
+
+ implUpdateDisplay();
+ }
+
+ void SuggestionDisplay::implUpdateDisplay()
+ {
+ m_xListBox->set_visible(m_bDisplayListBox);
+ if (!m_bDisplayListBox)
+ m_xValueSetWin->show();
+ else
+ m_xValueSetWin->hide();
+ }
+
+ weld::Widget& SuggestionDisplay::implGetCurrentControl()
+ {
+ if (m_bDisplayListBox)
+ return *m_xListBox;
+ return *m_xValueSet->GetDrawingArea();
+ }
+
+ void SuggestionDisplay::DisplayListBox( bool bDisplayListBox )
+ {
+ if( m_bDisplayListBox == bDisplayListBox )
+ return;
+
+ weld::Widget& rOldControl = implGetCurrentControl();
+ bool bHasFocus = rOldControl.has_focus();
+
+ m_bDisplayListBox = bDisplayListBox;
+
+ if( bHasFocus )
+ {
+ weld::Widget& rNewControl = implGetCurrentControl();
+ rNewControl.grab_focus();
+ }
+
+ implUpdateDisplay();
+ }
+
+ IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet*, void)
+ {
+ SelectSuggestionHdl(false);
+ }
+
+ IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionListBoxHdl, weld::TreeView&, void)
+ {
+ SelectSuggestionHdl(true);
+ }
+
+ void SuggestionDisplay::SelectSuggestionHdl(bool bListBox)
+ {
+ if( m_bInSelectionUpdate )
+ return;
+
+ m_bInSelectionUpdate = true;
+ if (bListBox)
+ {
+ sal_uInt16 nPos = m_xListBox->get_selected_index();
+ m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
+ }
+ else
+ {
+ sal_uInt16 nPos = m_xValueSet->GetSelectedItemId()-1; //itemid == pos+1 (id 0 has special meaning)
+ m_xListBox->select(nPos);
+ }
+ m_bInSelectionUpdate = false;
+ m_aSelectLink.Call( *this );
+ }
+
+ void SuggestionDisplay::SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink )
+ {
+ m_aSelectLink = rLink;
+ }
+
+ void SuggestionDisplay::Clear()
+ {
+ m_xListBox->clear();
+ m_xValueSet->Clear();
+ }
+
+ void SuggestionDisplay::InsertEntry( const OUString& rStr )
+ {
+ m_xListBox->append_text(rStr);
+ sal_uInt16 nItemId = m_xListBox->n_children(); //itemid == pos+1 (id 0 has special meaning)
+ m_xValueSet->InsertItem( nItemId );
+ OUString* pItemData = new OUString( rStr );
+ m_xValueSet->SetItemData( nItemId, pItemData );
+ }
+
+ void SuggestionDisplay::SelectEntryPos( sal_uInt16 nPos )
+ {
+ m_xListBox->select(nPos);
+ m_xValueSet->SelectItem( nPos+1 ); //itemid == pos+1 (id 0 has special meaning)
+ }
+
+ sal_uInt16 SuggestionDisplay::GetEntryCount() const
+ {
+ return m_xListBox->n_children();
+ }
+
+ OUString SuggestionDisplay::GetEntry( sal_uInt16 nPos ) const
+ {
+ return m_xListBox->get_text( nPos );
+ }
+
+ OUString SuggestionDisplay::GetSelectedEntry() const
+ {
+ return m_xListBox->get_selected_text();
+ }
+
+ void SuggestionDisplay::SetHelpIds()
+ {
+ m_xValueSet->SetHelpId(HID_HANGULDLG_SUGGESTIONS_GRID);
+ m_xListBox->set_help_id(HID_HANGULDLG_SUGGESTIONS_LIST);
+ }
+
+ HangulHanjaConversionDialog::HangulHanjaConversionDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaconversiondialog.ui", "HangulHanjaConversionDialog")
+ , m_bDocumentMode( true )
+ , m_xFind(m_xBuilder->weld_button("find"))
+ , m_xIgnore(m_xBuilder->weld_button("ignore"))
+ , m_xIgnoreAll(m_xBuilder->weld_button("ignoreall"))
+ , m_xReplace(m_xBuilder->weld_button("replace"))
+ , m_xReplaceAll(m_xBuilder->weld_button("replaceall"))
+ , m_xOptions(m_xBuilder->weld_button("options"))
+ , m_xSuggestions(new SuggestionDisplay(*m_xBuilder))
+ , m_xSimpleConversion(m_xBuilder->weld_radio_button("simpleconversion"))
+ , m_xHangulBracketed(m_xBuilder->weld_radio_button("hangulbracket"))
+ , m_xHanjaBracketed(m_xBuilder->weld_radio_button("hanjabracket"))
+ , m_xWordInput(m_xBuilder->weld_entry("wordinput"))
+ , m_xOriginalWord(m_xBuilder->weld_label("originalword"))
+ , m_xHanjaAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_above")))
+ , m_xHanjaBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hanja_below")))
+ , m_xHangulAbove(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_above")))
+ , m_xHangulBelow(new RubyRadioButton(m_xBuilder->weld_radio_button("hangul_below")))
+ , m_xHangulOnly(m_xBuilder->weld_check_button("hangulonly"))
+ , m_xHanjaOnly(m_xBuilder->weld_check_button("hanjaonly"))
+ , m_xReplaceByChar(m_xBuilder->weld_check_button("replacebychar"))
+ {
+ m_xSuggestions->set_size_request(m_xOriginalWord->get_approximate_digit_width() * 42,
+ m_xOriginalWord->get_text_height() * 5);
+
+ const OUString sHangul(CuiResId(RID_SVXSTR_HANGUL));
+ const OUString sHanja(CuiResId(RID_SVXSTR_HANJA));
+ m_xHanjaAbove->init( sHangul, sHanja, PseudoRubyText::eAbove );
+ m_xHanjaBelow->init( sHangul, sHanja, PseudoRubyText::eBelow );
+ m_xHangulAbove->init( sHanja, sHangul, PseudoRubyText::eAbove );
+ m_xHangulBelow->init( sHanja, sHangul, PseudoRubyText::eBelow );
+
+ m_xWordInput->connect_changed( LINK( this, HangulHanjaConversionDialog, OnSuggestionModified ) );
+ m_xSuggestions->SetSelectHdl( LINK( this, HangulHanjaConversionDialog, OnSuggestionSelected ) );
+ m_xReplaceByChar->connect_toggled( LINK( this, HangulHanjaConversionDialog, ClickByCharacterHdl ) );
+ m_xHangulOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
+ m_xHanjaOnly->connect_toggled( LINK( this, HangulHanjaConversionDialog, OnConversionDirectionClicked ) );
+ m_xOptions->connect_clicked(LINK(this, HangulHanjaConversionDialog, OnOption));
+
+ // initial focus
+ FocusSuggestion( );
+
+ // initial control values
+ m_xSimpleConversion->set_active(true);
+
+ m_xSuggestions->SetHelpIds();
+ }
+
+ HangulHanjaConversionDialog::~HangulHanjaConversionDialog()
+ {
+ }
+
+ void HangulHanjaConversionDialog::FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions )
+ {
+ m_xSuggestions->Clear();
+ for ( auto const & suggestion : _rSuggestions )
+ m_xSuggestions->InsertEntry( suggestion );
+
+ // select the first suggestion, and fill in the suggestion edit field
+ OUString sFirstSuggestion;
+ if ( m_xSuggestions->GetEntryCount() )
+ {
+ sFirstSuggestion = m_xSuggestions->GetEntry( 0 );
+ m_xSuggestions->SelectEntryPos( 0 );
+ }
+ m_xWordInput->set_text( sFirstSuggestion );
+ m_xWordInput->save_value();
+ OnSuggestionModified( *m_xWordInput );
+ }
+
+ void HangulHanjaConversionDialog::SetOptionsChangedHdl(const Link<LinkParamNone*,void>& rHdl)
+ {
+ m_aOptionsChangedLink = rHdl;
+ }
+
+ void HangulHanjaConversionDialog::SetIgnoreHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xIgnore->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetIgnoreAllHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xIgnoreAll->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetChangeHdl(const Link<weld::Button&,void>& rHdl )
+ {
+ m_xReplace->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetChangeAllHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xReplaceAll->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetFindHdl(const Link<weld::Button&,void>& rHdl)
+ {
+ m_xFind->connect_clicked(rHdl);
+ }
+
+ void HangulHanjaConversionDialog::SetConversionFormatChangedHdl( const Link<weld::Button&,void>& rHdl )
+ {
+ m_xSimpleConversion->connect_clicked( rHdl );
+ m_xHangulBracketed->connect_clicked( rHdl );
+ m_xHanjaBracketed->connect_clicked( rHdl );
+ m_xHanjaAbove->connect_clicked( rHdl );
+ m_xHanjaBelow->connect_clicked( rHdl );
+ m_xHangulAbove->connect_clicked( rHdl );
+ m_xHangulBelow->connect_clicked( rHdl );
+ }
+
+ void HangulHanjaConversionDialog::SetClickByCharacterHdl( const Link<weld::ToggleButton&,void>& _rHdl )
+ {
+ m_aClickByCharacterLink = _rHdl;
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionSelected, SuggestionDisplay&, void )
+ {
+ m_xWordInput->set_text(m_xSuggestions->GetSelectedEntry());
+ OnSuggestionModified( *m_xWordInput );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaConversionDialog, OnSuggestionModified, weld::Entry&, void )
+ {
+ m_xFind->set_sensitive(m_xWordInput->get_value_changed_from_saved());
+
+ bool bSameLen = m_xWordInput->get_text().getLength() == m_xOriginalWord->get_label().getLength();
+ m_xReplace->set_sensitive( m_bDocumentMode && bSameLen );
+ m_xReplaceAll->set_sensitive( m_bDocumentMode && bSameLen );
+ }
+
+ IMPL_LINK(HangulHanjaConversionDialog, ClickByCharacterHdl, weld::ToggleButton&, rBox, void)
+ {
+ m_aClickByCharacterLink.Call(rBox);
+ bool bByCharacter = rBox.get_active();
+ m_xSuggestions->DisplayListBox( !bByCharacter );
+ }
+
+ IMPL_LINK(HangulHanjaConversionDialog, OnConversionDirectionClicked, weld::ToggleButton&, rBox, void)
+ {
+ weld::CheckButton* pOtherBox = nullptr;
+ if (&rBox == m_xHangulOnly.get())
+ pOtherBox = m_xHanjaOnly.get();
+ else
+ pOtherBox = m_xHangulOnly.get();
+ bool bBoxChecked = rBox.get_active();
+ if (bBoxChecked)
+ pOtherBox->set_active(false);
+ pOtherBox->set_sensitive(!bBoxChecked);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaConversionDialog, OnOption, weld::Button&, void)
+ {
+ HangulHanjaOptionsDialog aOptDlg(m_xDialog.get());
+ aOptDlg.run();
+ m_aOptionsChangedLink.Call( nullptr );
+ }
+
+ OUString HangulHanjaConversionDialog::GetCurrentString( ) const
+ {
+ return m_xOriginalWord->get_label();
+ }
+
+ void HangulHanjaConversionDialog::FocusSuggestion( )
+ {
+ m_xWordInput->grab_focus();
+ }
+
+ void HangulHanjaConversionDialog::SetCurrentString( const OUString& _rNewString,
+ const Sequence< OUString >& _rSuggestions, bool _bOriginatesFromDocument )
+ {
+ m_xOriginalWord->set_label(_rNewString);
+
+ bool bOldDocumentMode = m_bDocumentMode;
+ m_bDocumentMode = _bOriginatesFromDocument; // before FillSuggestions!
+ FillSuggestions( _rSuggestions );
+
+ m_xIgnoreAll->set_sensitive( m_bDocumentMode );
+
+ // switch the def button depending if we're working for document text
+ if (bOldDocumentMode == m_bDocumentMode)
+ return;
+
+ weld::Widget* pOldDefButton = nullptr;
+ weld::Widget* pNewDefButton = nullptr;
+ if (m_bDocumentMode)
+ {
+ pOldDefButton = m_xFind.get();
+ pNewDefButton = m_xReplace.get();
+ }
+ else
+ {
+ pOldDefButton = m_xReplace.get();
+ pNewDefButton = m_xFind.get();
+ }
+
+ pOldDefButton->set_has_default(false);
+ pNewDefButton->set_has_default(true);
+ }
+
+ OUString HangulHanjaConversionDialog::GetCurrentSuggestion( ) const
+ {
+ return m_xWordInput->get_text();
+ }
+
+ void HangulHanjaConversionDialog::SetByCharacter( bool _bByCharacter )
+ {
+ m_xReplaceByChar->set_active( _bByCharacter );
+ m_xSuggestions->DisplayListBox( !_bByCharacter );
+ }
+
+ void HangulHanjaConversionDialog::SetConversionDirectionState(
+ bool _bTryBothDirections,
+ HHC::ConversionDirection ePrimaryConversionDirection )
+ {
+ // default state: try both direction
+ m_xHangulOnly->set_active( false );
+ m_xHangulOnly->set_sensitive(true);
+ m_xHanjaOnly->set_active( false );
+ m_xHanjaOnly->set_sensitive(true);
+
+ if (!_bTryBothDirections)
+ {
+ weld::CheckButton* pBox = ePrimaryConversionDirection == HHC::eHangulToHanja ?
+ m_xHangulOnly.get() : m_xHanjaOnly.get();
+ pBox->set_active(true);
+ OnConversionDirectionClicked(*pBox);
+ }
+ }
+
+ bool HangulHanjaConversionDialog::GetUseBothDirections( ) const
+ {
+ return !m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active();
+ }
+
+ HHC::ConversionDirection HangulHanjaConversionDialog::GetDirection(
+ HHC::ConversionDirection eDefaultDirection ) const
+ {
+ HHC::ConversionDirection eDirection = eDefaultDirection;
+ if (m_xHangulOnly->get_active() && !m_xHanjaOnly->get_active())
+ eDirection = HHC::eHangulToHanja;
+ else if (!m_xHangulOnly->get_active() && m_xHanjaOnly->get_active())
+ eDirection = HHC::eHanjaToHangul;
+ return eDirection;
+ }
+
+ void HangulHanjaConversionDialog::SetConversionFormat( HHC::ConversionFormat _eType )
+ {
+ switch ( _eType )
+ {
+ case HHC::eSimpleConversion: m_xSimpleConversion->set_active(true); break;
+ case HHC::eHangulBracketed: m_xHangulBracketed->set_active(true); break;
+ case HHC::eHanjaBracketed: m_xHanjaBracketed->set_active(true); break;
+ case HHC::eRubyHanjaAbove: m_xHanjaAbove->set_active(true); break;
+ case HHC::eRubyHanjaBelow: m_xHanjaBelow->set_active(true); break;
+ case HHC::eRubyHangulAbove: m_xHangulAbove->set_active(true); break;
+ case HHC::eRubyHangulBelow: m_xHangulBelow->set_active(true); break;
+ default:
+ OSL_FAIL( "HangulHanjaConversionDialog::SetConversionFormat: unknown type!" );
+ }
+ }
+
+ HHC::ConversionFormat HangulHanjaConversionDialog::GetConversionFormat( ) const
+ {
+ if ( m_xSimpleConversion->get_active() )
+ return HHC::eSimpleConversion;
+ if ( m_xHangulBracketed->get_active() )
+ return HHC::eHangulBracketed;
+ if ( m_xHanjaBracketed->get_active() )
+ return HHC::eHanjaBracketed;
+ if ( m_xHanjaAbove->get_active() )
+ return HHC::eRubyHanjaAbove;
+ if ( m_xHanjaBelow->get_active() )
+ return HHC::eRubyHanjaBelow;
+ if ( m_xHangulAbove->get_active() )
+ return HHC::eRubyHangulAbove;
+ if ( m_xHangulBelow->get_active() )
+ return HHC::eRubyHangulBelow;
+
+ OSL_FAIL( "HangulHanjaConversionDialog::GetConversionFormat: no radio checked?" );
+ return HHC::eSimpleConversion;
+ }
+
+ void HangulHanjaConversionDialog::EnableRubySupport( bool bVal )
+ {
+ m_xHanjaAbove->set_sensitive( bVal );
+ m_xHanjaBelow->set_sensitive( bVal );
+ m_xHangulAbove->set_sensitive( bVal );
+ m_xHangulBelow->set_sensitive( bVal );
+ }
+
+ void HangulHanjaOptionsDialog::Init()
+ {
+ if( !m_xConversionDictionaryList.is() )
+ {
+ m_xConversionDictionaryList = ConversionDictionaryList::create( ::comphelper::getProcessComponentContext() );
+ }
+
+ m_aDictList.clear();
+ m_xDictsLB->clear();
+
+ Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
+ if( xNameCont.is() )
+ {
+ Sequence< OUString > aDictNames( xNameCont->getElementNames() );
+
+ const OUString* pDic = aDictNames.getConstArray();
+ sal_Int32 nCount = aDictNames.getLength();
+
+ sal_Int32 i;
+ for( i = 0 ; i < nCount ; ++i )
+ {
+ Any aAny( xNameCont->getByName( pDic[ i ] ) );
+ Reference< XConversionDictionary > xDic;
+ if( ( aAny >>= xDic ) && xDic.is() )
+ {
+ if( LANGUAGE_KOREAN == LanguageTag( xDic->getLocale() ).getLanguageType() )
+ {
+ m_aDictList.push_back( xDic );
+ AddDict( xDic->getName(), xDic->isActive() );
+ }
+ }
+ }
+ }
+ if (m_xDictsLB->n_children())
+ m_xDictsLB->select(0);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, OkHdl, weld::Button&, void)
+ {
+ sal_uInt32 nCnt = m_aDictList.size();
+ sal_uInt32 n = 0;
+ sal_uInt32 nActiveDics = 0;
+ Sequence< OUString > aActiveDics;
+
+ aActiveDics.realloc( nCnt );
+ OUString* pActActiveDic = aActiveDics.getArray();
+
+ while( nCnt )
+ {
+ Reference< XConversionDictionary > xDict = m_aDictList[ n ];
+
+ DBG_ASSERT( xDict.is(), "-HangulHanjaOptionsDialog::OkHdl(): someone is evaporated..." );
+
+ bool bActive = m_xDictsLB->get_toggle(n, 0) == TRISTATE_TRUE;
+ xDict->setActive( bActive );
+ Reference< util::XFlushable > xFlush( xDict, uno::UNO_QUERY );
+ if( xFlush.is() )
+ xFlush->flush();
+
+ if( bActive )
+ {
+ pActActiveDic[ nActiveDics ] = xDict->getName();
+ ++nActiveDics;
+ }
+
+ ++n;
+ --nCnt;
+ }
+
+ // save configuration
+ aActiveDics.realloc( nActiveDics );
+ Any aTmp;
+ SvtLinguConfig aLngCfg;
+ aTmp <<= aActiveDics;
+ aLngCfg.SetProperty( UPH_ACTIVE_CONVERSION_DICTIONARIES, aTmp );
+
+ aTmp <<= m_xIgnorepostCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD, aTmp );
+
+ aTmp <<= m_xShowrecentlyfirstCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST, aTmp );
+
+ aTmp <<= m_xAutoreplaceuniqueCB->get_active();
+ aLngCfg.SetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES, aTmp );
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DictsLB_SelectHdl, weld::TreeView&, void)
+ {
+ bool bSel = m_xDictsLB->get_selected_index() != -1;
+
+ m_xEditPB->set_sensitive(bSel);
+ m_xDeletePB->set_sensitive(bSel);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, NewDictHdl, weld::Button&, void)
+ {
+ OUString aName;
+ HangulHanjaNewDictDialog aNewDlg(m_xDialog.get());
+ aNewDlg.run();
+ if (!aNewDlg.GetName(aName))
+ return;
+
+ if( !m_xConversionDictionaryList.is() )
+ return;
+
+ try
+ {
+ Reference< XConversionDictionary > xDic =
+ m_xConversionDictionaryList->addNewDictionary( aName, LanguageTag::convertToLocale( LANGUAGE_KOREAN ), ConversionDictionaryType::HANGUL_HANJA );
+
+ if( xDic.is() )
+ {
+ //adapt local caches:
+ m_aDictList.push_back( xDic );
+ AddDict( xDic->getName(), xDic->isActive() );
+ }
+ }
+ catch( const ElementExistException& )
+ {
+ }
+ catch( const NoSupportException& )
+ {
+ }
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, EditDictHdl, weld::Button&, void)
+ {
+ int nEntry = m_xDictsLB->get_selected_index();
+ DBG_ASSERT(nEntry != -1, "+HangulHanjaEditDictDialog::EditDictHdl(): call of edit should not be possible with no selection!");
+ if (nEntry != -1)
+ {
+ HangulHanjaEditDictDialog aEdDlg(m_xDialog.get(), m_aDictList, nEntry);
+ aEdDlg.run();
+ }
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaOptionsDialog, DeleteDictHdl, weld::Button&, void)
+ {
+ int nSelPos = m_xDictsLB->get_selected_index();
+ if (nSelPos == -1)
+ return;
+
+ Reference< XConversionDictionary > xDic( m_aDictList[ nSelPos ] );
+ if( !(m_xConversionDictionaryList.is() && xDic.is()) )
+ return;
+
+ Reference< XNameContainer > xNameCont = m_xConversionDictionaryList->getDictionaryContainer();
+ if( !xNameCont.is() )
+ return;
+
+ try
+ {
+ xNameCont->removeByName( xDic->getName() );
+
+ //adapt local caches:
+ m_aDictList.erase(m_aDictList.begin()+nSelPos );
+ m_xDictsLB->remove(nSelPos);
+ }
+ catch( const ElementExistException& )
+ {
+ }
+ catch( const NoSupportException& )
+ {
+ }
+ }
+
+ HangulHanjaOptionsDialog::HangulHanjaOptionsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaoptdialog.ui", "HangulHanjaOptDialog")
+ , m_xDictsLB(m_xBuilder->weld_tree_view("dicts"))
+ , m_xIgnorepostCB(m_xBuilder->weld_check_button("ignorepost"))
+ , m_xShowrecentlyfirstCB(m_xBuilder->weld_check_button("showrecentfirst"))
+ , m_xAutoreplaceuniqueCB(m_xBuilder->weld_check_button("autoreplaceunique"))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ , m_xOkPB(m_xBuilder->weld_button("ok"))
+ {
+ m_xDictsLB->set_size_request(m_xDictsLB->get_approximate_digit_width() * 32,
+ m_xDictsLB->get_height_rows(5));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xDictsLB->get_checkbox_column_width());
+ m_xDictsLB->set_column_fixed_widths(aWidths);
+
+ m_xDictsLB->connect_changed( LINK( this, HangulHanjaOptionsDialog, DictsLB_SelectHdl ) );
+
+ m_xOkPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, OkHdl ) );
+ m_xNewPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, NewDictHdl ) );
+ m_xEditPB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, EditDictHdl ) );
+ m_xDeletePB->connect_clicked( LINK( this, HangulHanjaOptionsDialog, DeleteDictHdl ) );
+
+ SvtLinguConfig aLngCfg;
+ Any aTmp;
+ bool bVal = bool();
+ aTmp = aLngCfg.GetProperty( UPH_IS_IGNORE_POST_POSITIONAL_WORD );
+ if( aTmp >>= bVal )
+ m_xIgnorepostCB->set_active( bVal );
+
+ aTmp = aLngCfg.GetProperty( UPH_IS_SHOW_ENTRIES_RECENTLY_USED_FIRST );
+ if( aTmp >>= bVal )
+ m_xShowrecentlyfirstCB->set_active( bVal );
+
+ aTmp = aLngCfg.GetProperty( UPH_IS_AUTO_REPLACE_UNIQUE_ENTRIES );
+ if( aTmp >>= bVal )
+ m_xAutoreplaceuniqueCB->set_active( bVal );
+
+ Init();
+ }
+
+ HangulHanjaOptionsDialog::~HangulHanjaOptionsDialog()
+ {
+ }
+
+ void HangulHanjaOptionsDialog::AddDict(const OUString& rName, bool bChecked)
+ {
+ m_xDictsLB->append();
+ int nRow = m_xDictsLB->n_children() - 1;
+ m_xDictsLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xDictsLB->set_text(nRow, rName, 1);
+ m_xDictsLB->set_id(nRow, rName);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaNewDictDialog, OKHdl, weld::Button&, void)
+ {
+ OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
+
+ m_bEntered = !aName.isEmpty();
+ if (m_bEntered)
+ m_xDictNameED->set_text(aName); // do this in case of trailing chars have been deleted
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(HangulHanjaNewDictDialog, ModifyHdl, weld::Entry&, void)
+ {
+ OUString aName(comphelper::string::stripEnd(m_xDictNameED->get_text(), ' '));
+
+ m_xOkBtn->set_sensitive(!aName.isEmpty());
+ }
+
+ HangulHanjaNewDictDialog::HangulHanjaNewDictDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaadddialog.ui", "HangulHanjaAddDialog")
+ , m_bEntered(false)
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_xDictNameED(m_xBuilder->weld_entry("entry"))
+ {
+ m_xOkBtn->connect_clicked( LINK( this, HangulHanjaNewDictDialog, OKHdl ) );
+ m_xDictNameED->connect_changed( LINK( this, HangulHanjaNewDictDialog, ModifyHdl ) );
+ }
+
+ HangulHanjaNewDictDialog::~HangulHanjaNewDictDialog()
+ {
+ }
+
+ bool HangulHanjaNewDictDialog::GetName( OUString& _rRetName ) const
+ {
+ if( m_bEntered )
+ _rRetName = comphelper::string::stripEnd(m_xDictNameED->get_text(), ' ');
+
+ return m_bEntered;
+ }
+
+ class SuggestionList
+ {
+ private:
+ protected:
+ std::vector<OUString> m_vElements;
+ sal_uInt16 m_nNumOfEntries;
+ // index of the internal iterator, used for First() and Next() methods
+ sal_uInt16 m_nAct;
+
+ const OUString* Next_();
+ public:
+ SuggestionList();
+ ~SuggestionList();
+
+ void Set( const OUString& _rElement, sal_uInt16 _nNumOfElement );
+ void Reset( sal_uInt16 _nNumOfElement );
+ const OUString & Get( sal_uInt16 _nNumOfElement ) const;
+ void Clear();
+
+ const OUString* First();
+ const OUString* Next();
+
+ sal_uInt16 GetCount() const { return m_nNumOfEntries; }
+ };
+
+ SuggestionList::SuggestionList() :
+ m_vElements(MAXNUM_SUGGESTIONS)
+ {
+ m_nAct = m_nNumOfEntries = 0;
+ }
+
+ SuggestionList::~SuggestionList()
+ {
+ Clear();
+ }
+
+ void SuggestionList::Set( const OUString& _rElement, sal_uInt16 _nNumOfElement )
+ {
+ m_vElements[_nNumOfElement] = _rElement;
+ ++m_nNumOfEntries;
+ }
+
+ void SuggestionList::Reset( sal_uInt16 _nNumOfElement )
+ {
+ m_vElements[_nNumOfElement].clear();
+ --m_nNumOfEntries;
+ }
+
+ const OUString& SuggestionList::Get( sal_uInt16 _nNumOfElement ) const
+ {
+ return m_vElements[_nNumOfElement];
+ }
+
+ void SuggestionList::Clear()
+ {
+ if( m_nNumOfEntries )
+ {
+ for (auto & vElement : m_vElements)
+ vElement.clear();
+ m_nNumOfEntries = m_nAct = 0;
+ }
+ }
+
+ const OUString* SuggestionList::Next_()
+ {
+ while( m_nAct < m_vElements.size() )
+ {
+ auto & s = m_vElements[ m_nAct ];
+ if (!s.isEmpty())
+ return &s;
+ ++m_nAct;
+ }
+
+ return nullptr;
+ }
+
+ const OUString* SuggestionList::First()
+ {
+ m_nAct = 0;
+ return Next_();
+ }
+
+ const OUString* SuggestionList::Next()
+ {
+ const OUString* pRet;
+
+ if( m_nAct < m_nNumOfEntries )
+ {
+ ++m_nAct;
+ pRet = Next_();
+ }
+ else
+ pRet = nullptr;
+
+ return pRet;
+ }
+
+
+ bool SuggestionEdit::ShouldScroll( bool _bUp ) const
+ {
+ bool bRet = false;
+
+ if( _bUp )
+ {
+ if( !m_pPrev )
+ bRet = m_pScrollBar->vadjustment_get_value() > m_pScrollBar->vadjustment_get_lower();
+ }
+ else
+ {
+ if( !m_pNext )
+ bRet = m_pScrollBar->vadjustment_get_value() < ( m_pScrollBar->vadjustment_get_upper() - 4 );
+ }
+
+ return bRet;
+ }
+
+ void SuggestionEdit::DoJump( bool _bUp )
+ {
+ m_pScrollBar->vadjustment_set_value( m_pScrollBar->vadjustment_get_value() + ( _bUp? -1 : 1 ) );
+ m_pParent->UpdateScrollbar();
+ }
+
+ SuggestionEdit::SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent)
+ : m_pParent(pParent)
+ , m_pPrev(nullptr)
+ , m_pNext(nullptr)
+ , m_pScrollBar(nullptr)
+ , m_xEntry(std::move(xEntry))
+ {
+ m_xEntry->connect_key_press(LINK(this, SuggestionEdit, KeyInputHdl));
+ }
+
+ IMPL_LINK(SuggestionEdit, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+ {
+ bool bHandled = false;
+
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ sal_uInt16 nMod = rKeyCode.GetModifier();
+ sal_uInt16 nCode = rKeyCode.GetCode();
+ if( nCode == KEY_TAB && ( !nMod || KEY_SHIFT == nMod ) )
+ {
+ bool bUp = KEY_SHIFT == nMod;
+ if( ShouldScroll( bUp ) )
+ {
+ DoJump( bUp );
+ m_xEntry->select_region(0, -1);
+ // Tab-travel doesn't really happen, so emulate it by setting a selection manually
+ bHandled = true;
+ }
+ }
+ else if( KEY_UP == nCode || KEY_DOWN == nCode )
+ {
+ bool bUp = KEY_UP == nCode;
+ if( ShouldScroll( bUp ) )
+ {
+ DoJump( bUp );
+ bHandled = true;
+ }
+ else if( bUp )
+ {
+ if( m_pPrev )
+ {
+ m_pPrev->grab_focus();
+ bHandled = true;
+ }
+ }
+ else if( m_pNext )
+ {
+ m_pNext->grab_focus();
+ bHandled = true;
+ }
+ }
+
+ return bHandled;
+ }
+
+ void SuggestionEdit::init(weld::ScrolledWindow* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext)
+ {
+ m_pScrollBar = pScrollBar;
+ m_pPrev = pPrev;
+ m_pNext = pNext;
+ }
+
+ namespace
+ {
+ bool GetConversions( const Reference< XConversionDictionary >& _xDict,
+ const OUString& _rOrg,
+ Sequence< OUString >& _rEntries )
+ {
+ bool bRet = false;
+ if( _xDict.is() && !_rOrg.isEmpty() )
+ {
+ try
+ {
+ _rEntries = _xDict->getConversions( _rOrg,
+ 0,
+ _rOrg.getLength(),
+ ConversionDirection_FROM_LEFT,
+ css::i18n::TextConversionOption::NONE );
+ bRet = _rEntries.hasElements();
+ }
+ catch( const IllegalArgumentException& )
+ {
+ }
+ }
+
+ return bRet;
+ }
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, ScrollHdl, weld::ScrolledWindow&, void )
+ {
+ UpdateScrollbar();
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, OriginalModifyHdl, weld::ComboBox&, void )
+ {
+ m_bModifiedOriginal = true;
+ m_aOriginal = comphelper::string::stripEnd( m_xOriginalLB->get_active_text(), ' ' );
+
+ UpdateSuggestions();
+ UpdateButtonStates();
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl1, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 0 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl2, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 1 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl3, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 2 );
+ }
+
+ IMPL_LINK( HangulHanjaEditDictDialog, EditModifyHdl4, weld::Entry&, rEdit, void )
+ {
+ EditModify( &rEdit, 3 );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, BookLBSelectHdl, weld::ComboBox&, void )
+ {
+ InitEditDictDialog( m_xBookLB->get_active() );
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, NewPBPushHdl, weld::Button&, void )
+ {
+ DBG_ASSERT( m_xSuggestions, "-HangulHanjaEditDictDialog::NewPBPushHdl(): no suggestions... search in hell..." );
+ Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
+ if( xDict.is() && m_xSuggestions )
+ {
+ //delete old entry
+ bool bRemovedSomething = DeleteEntryFromDictionary( xDict );
+
+ OUString aLeft( m_aOriginal );
+ const OUString* pRight = m_xSuggestions->First();
+ bool bAddedSomething = false;
+ while( pRight )
+ {
+ try
+ {
+ //add new entry
+ xDict->addEntry( aLeft, *pRight );
+ bAddedSomething = true;
+ }
+ catch( const IllegalArgumentException& )
+ {
+ }
+ catch( const ElementExistException& )
+ {
+ }
+
+ pRight = m_xSuggestions->Next();
+ }
+
+ if( bAddedSomething || bRemovedSomething )
+ InitEditDictDialog( m_nCurrentDict );
+ }
+ else
+ {
+ SAL_INFO( "cui.dialogs", "dictionary faded away..." );
+ }
+ }
+
+ bool HangulHanjaEditDictDialog::DeleteEntryFromDictionary( const Reference< XConversionDictionary >& xDict )
+ {
+ bool bRemovedSomething = false;
+ if( xDict.is() )
+ {
+ OUString aOrg( m_aOriginal );
+ Sequence< OUString > aEntries;
+ GetConversions( xDict, m_aOriginal, aEntries );
+
+ sal_uInt32 n = aEntries.getLength();
+ OUString* pEntry = aEntries.getArray();
+ while( n )
+ {
+ try
+ {
+ xDict->removeEntry( aOrg, *pEntry );
+ bRemovedSomething = true;
+ }
+ catch( const NoSuchElementException& )
+ { // can not be...
+ }
+
+ ++pEntry;
+ --n;
+ }
+ }
+ return bRemovedSomething;
+ }
+
+ IMPL_LINK_NOARG( HangulHanjaEditDictDialog, DeletePBPushHdl, weld::Button&, void )
+ {
+ if( DeleteEntryFromDictionary( m_rDictList[ m_nCurrentDict ] ) )
+ {
+ m_aOriginal.clear();
+ m_bModifiedOriginal = true;
+ InitEditDictDialog( m_nCurrentDict );
+ }
+ }
+
+ void HangulHanjaEditDictDialog::InitEditDictDialog( sal_uInt32 nSelDict )
+ {
+ if( m_xSuggestions )
+ m_xSuggestions->Clear();
+
+ if( m_nCurrentDict != nSelDict )
+ {
+ m_nCurrentDict = nSelDict;
+ m_aOriginal.clear();
+ m_bModifiedOriginal = true;
+ }
+
+ UpdateOriginalLB();
+
+ m_xOriginalLB->set_entry_text( !m_aOriginal.isEmpty() ? m_aOriginal : m_aEditHintText);
+ m_xOriginalLB->select_entry_region(0, -1);
+ m_xOriginalLB->grab_focus();
+
+ UpdateSuggestions();
+ UpdateButtonStates();
+ }
+
+ void HangulHanjaEditDictDialog::UpdateOriginalLB()
+ {
+ m_xOriginalLB->clear();
+ Reference< XConversionDictionary > xDict = m_rDictList[ m_nCurrentDict ];
+ if( xDict.is() )
+ {
+ Sequence< OUString > aEntries = xDict->getConversionEntries( ConversionDirection_FROM_LEFT );
+ sal_uInt32 n = aEntries.getLength();
+ OUString* pEntry = aEntries.getArray();
+ while( n )
+ {
+ m_xOriginalLB->append_text( *pEntry );
+
+ ++pEntry;
+ --n;
+ }
+ }
+ else
+ {
+ SAL_INFO( "cui.dialogs", "dictionary faded away..." );
+ }
+ }
+
+ void HangulHanjaEditDictDialog::UpdateButtonStates()
+ {
+ bool bHaveValidOriginalString = !m_aOriginal.isEmpty() && m_aOriginal != m_aEditHintText;
+ bool bNew = bHaveValidOriginalString && m_xSuggestions && m_xSuggestions->GetCount() > 0;
+ bNew = bNew && ( m_bModifiedSuggestions || m_bModifiedOriginal );
+
+ m_xNewPB->set_sensitive( bNew );
+ m_xDeletePB->set_sensitive(!m_bModifiedOriginal && bHaveValidOriginalString);
+ }
+
+ void HangulHanjaEditDictDialog::UpdateSuggestions()
+ {
+ Sequence< OUString > aEntries;
+ bool bFound = GetConversions( m_rDictList[ m_nCurrentDict ], m_aOriginal, aEntries );
+ if( bFound )
+ {
+ m_bModifiedOriginal = false;
+
+ if( m_xSuggestions )
+ m_xSuggestions->Clear();
+
+ //fill found entries into boxes
+ sal_uInt32 nCnt = aEntries.getLength();
+ if( nCnt )
+ {
+ if( !m_xSuggestions )
+ m_xSuggestions.reset(new SuggestionList);
+
+ const OUString* pSugg = aEntries.getConstArray();
+ sal_uInt32 n = 0;
+ while( nCnt )
+ {
+ m_xSuggestions->Set( pSugg[ n ], sal_uInt16( n ) );
+ ++n;
+ --nCnt;
+ }
+ }
+ m_bModifiedSuggestions = false;
+ }
+
+ m_xScrollSB->vadjustment_set_value( 0 );
+ UpdateScrollbar(); // will force edits to be filled new
+ }
+
+ void HangulHanjaEditDictDialog::SetEditText(SuggestionEdit& rEdit, sal_uInt16 nEntryNum)
+ {
+ OUString aStr;
+ if( m_xSuggestions )
+ {
+ aStr = m_xSuggestions->Get(nEntryNum);
+ }
+
+ rEdit.set_text(aStr);
+ }
+
+ void HangulHanjaEditDictDialog::EditModify(const weld::Entry* pEdit, sal_uInt8 _nEntryOffset)
+ {
+ m_bModifiedSuggestions = true;
+
+ OUString aTxt( pEdit->get_text() );
+ sal_uInt16 nEntryNum = m_nTopPos + _nEntryOffset;
+ if( aTxt.isEmpty() )
+ {
+ //reset suggestion
+ if( m_xSuggestions )
+ m_xSuggestions->Reset( nEntryNum );
+ }
+ else
+ {
+ //set suggestion
+ if( !m_xSuggestions )
+ m_xSuggestions.reset(new SuggestionList);
+ m_xSuggestions->Set( aTxt, nEntryNum );
+ }
+
+ UpdateButtonStates();
+ }
+
+ HangulHanjaEditDictDialog::HangulHanjaEditDictDialog(weld::Window* pParent, HHDictList& _rDictList, sal_uInt32 nSelDict)
+ : GenericDialogController(pParent, "cui/ui/hangulhanjaeditdictdialog.ui", "HangulHanjaEditDictDialog")
+ , m_aEditHintText ( CuiResId(RID_SVXSTR_EDITHINT) )
+ , m_rDictList ( _rDictList )
+ , m_nCurrentDict ( 0xFFFFFFFF )
+ , m_nTopPos ( 0 )
+ , m_bModifiedSuggestions ( false )
+ , m_bModifiedOriginal ( false )
+ , m_xBookLB(m_xBuilder->weld_combo_box("book"))
+ , m_xOriginalLB(m_xBuilder->weld_combo_box("original"))
+ , m_xEdit1(new SuggestionEdit(m_xBuilder->weld_entry("edit1"), this))
+ , m_xEdit2(new SuggestionEdit(m_xBuilder->weld_entry("edit2"), this))
+ , m_xEdit3(new SuggestionEdit(m_xBuilder->weld_entry("edit3"), this))
+ , m_xEdit4(new SuggestionEdit(m_xBuilder->weld_entry("edit4"), this))
+ , m_xContents(m_xBuilder->weld_widget("box"))
+ , m_xScrollSB(m_xBuilder->weld_scrolled_window("scrollbar"))
+ , m_xNewPB(m_xBuilder->weld_button("new"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+ {
+ m_xScrollSB->set_user_managed_scrolling();
+
+ Size aSize(m_xContents->get_preferred_size());
+ m_xScrollSB->set_size_request(-1, aSize.Height());
+
+ m_xEdit1->init( m_xScrollSB.get(), nullptr, m_xEdit2.get() );
+ m_xEdit2->init( m_xScrollSB.get(), m_xEdit1.get(), m_xEdit3.get() );
+ m_xEdit3->init( m_xScrollSB.get(), m_xEdit2.get(), m_xEdit4.get() );
+ m_xEdit4->init( m_xScrollSB.get(), m_xEdit3.get(), nullptr );
+
+ m_xOriginalLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, OriginalModifyHdl ) );
+
+ m_xNewPB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, NewPBPushHdl ) );
+ m_xNewPB->set_sensitive( false );
+
+ m_xDeletePB->connect_clicked( LINK( this, HangulHanjaEditDictDialog, DeletePBPushHdl ) );
+ m_xDeletePB->set_sensitive( false );
+
+ static_assert(MAXNUM_SUGGESTIONS >= 5, "number of suggestions should not under-run the value of 5");
+
+ // 4 here, because we have 4 edits / page
+ m_xScrollSB->vadjustment_configure(0, 0, MAXNUM_SUGGESTIONS, 1, 4, 4);
+ m_xScrollSB->connect_vadjustment_changed(LINK(this, HangulHanjaEditDictDialog, ScrollHdl));
+
+ m_xEdit1->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl1 ) );
+ m_xEdit2->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl2 ) );
+ m_xEdit3->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl3 ) );
+ m_xEdit4->connect_changed( LINK( this, HangulHanjaEditDictDialog, EditModifyHdl4 ) );
+
+ m_xBookLB->connect_changed( LINK( this, HangulHanjaEditDictDialog, BookLBSelectHdl ) );
+ sal_uInt32 nDictCnt = m_rDictList.size();
+ for( sal_uInt32 n = 0 ; n < nDictCnt ; ++n )
+ {
+ Reference< XConversionDictionary > xDic( m_rDictList[n] );
+ OUString aName;
+ if( xDic.is() )
+ aName = xDic->getName();
+ m_xBookLB->append_text( aName );
+ }
+ m_xBookLB->set_active(nSelDict);
+
+ InitEditDictDialog(nSelDict);
+ }
+
+ HangulHanjaEditDictDialog::~HangulHanjaEditDictDialog()
+ {
+ }
+
+ void HangulHanjaEditDictDialog::UpdateScrollbar()
+ {
+ sal_uInt16 nPos = m_xScrollSB->vadjustment_get_value();
+ m_nTopPos = nPos;
+
+ SetEditText( *m_xEdit1, nPos++ );
+ SetEditText( *m_xEdit2, nPos++ );
+ SetEditText( *m_xEdit3, nPos++ );
+ SetEditText( *m_xEdit4, nPos );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hldocntp.cxx b/cui/source/dialogs/hldocntp.cxx
new file mode 100644
index 000000000..50d7131ad
--- /dev/null
+++ b/cui/source/dialogs/hldocntp.cxx
@@ -0,0 +1,479 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hldocntp.hxx>
+#include <osl/file.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/docfilt.hxx>
+#include <svl/stritem.hxx>
+#include <com/sun/star/awt/XTopWindow.hpp>
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/uno/Sequence.h>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Exception.hpp>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/dynamicmenuoptions.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <unotools/ucbhelper.hxx>
+
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <cuihyperdlg.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* Data-struct for documenttypes in listbox
+|*
+|************************************************************************/
+
+namespace {
+
+struct DocumentTypeData
+{
+ OUString aStrURL;
+ OUString aStrExt;
+ DocumentTypeData (const OUString& aURL, const OUString& aExt) : aStrURL(aURL), aStrExt(aExt)
+ {}
+};
+
+}
+
+bool SvxHyperlinkNewDocTp::ImplGetURLObject( const OUString& rPath, const OUString& rBase, INetURLObject& aURLObject ) const
+{
+ bool bIsValidURL = !rPath.isEmpty();
+ if ( bIsValidURL )
+ {
+ aURLObject.SetURL( rPath );
+ if ( aURLObject.GetProtocol() == INetProtocol::NotValid ) // test if the source is already a valid url
+ { // if not we have to create a url from a physical file name
+ bool wasAbs;
+ INetURLObject base(rBase);
+ base.setFinalSlash();
+ aURLObject = base.smartRel2Abs(
+ rPath, wasAbs, true, INetURLObject::EncodeMechanism::All,
+ RTL_TEXTENCODING_UTF8, true);
+ }
+ bIsValidURL = aURLObject.GetProtocol() != INetProtocol::NotValid;
+ if ( bIsValidURL )
+ {
+ OUString aBase( aURLObject.getName( INetURLObject::LAST_SEGMENT, false ) );
+ if ( aBase.isEmpty() || ( aBase[0] == '.' ) )
+ bIsValidURL = false;
+ }
+ if ( bIsValidURL )
+ {
+ sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ if (nPos != -1)
+ aURLObject.SetExtension(reinterpret_cast<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos).toInt64())->aStrExt);
+ }
+
+ }
+ return bIsValidURL;
+}
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+
+SvxHyperlinkNewDocTp::SvxHyperlinkNewDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinknewdocpage.ui", "HyperlinkNewDocPage", pItemSet)
+ , m_xRbtEditNow(xBuilder->weld_radio_button("editnow"))
+ , m_xRbtEditLater(xBuilder->weld_radio_button("editlater"))
+ , m_xCbbPath(new SvxHyperURLBox(xBuilder->weld_combo_box("path")))
+ , m_xBtCreate(xBuilder->weld_button("create"))
+ , m_xLbDocTypes(xBuilder->weld_tree_view("types"))
+{
+ m_xCbbPath->SetSmartProtocol(INetProtocol::File);
+ m_xLbDocTypes->set_size_request(-1, m_xLbDocTypes->get_height_rows(5));
+
+ InitStdControls();
+
+ SetExchangeSupport ();
+
+ m_xCbbPath->show();
+ m_xCbbPath->SetBaseURL(SvtPathOptions().GetWorkPath());
+
+ // set defaults
+ m_xRbtEditNow->set_active(true);
+
+ m_xBtCreate->connect_clicked(LINK(this, SvxHyperlinkNewDocTp, ClickNewHdl_Impl));
+
+ FillDocumentList ();
+}
+
+SvxHyperlinkNewDocTp::~SvxHyperlinkNewDocTp ()
+{
+ if (m_xLbDocTypes)
+ {
+ for (sal_Int32 n = 0, nEntryCount = m_xLbDocTypes->n_children(); n < nEntryCount; ++n)
+ delete reinterpret_cast<DocumentTypeData*>(m_xLbDocTypes->get_id(n).toInt64());
+ m_xLbDocTypes = nullptr;
+ }
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+
+
+void SvxHyperlinkNewDocTp::FillDlgFields(const OUString& /*rStrURL*/)
+{
+}
+
+void SvxHyperlinkNewDocTp::FillDocumentList()
+{
+ weld::WaitObject aWaitObj(mpDialog->getDialog());
+
+ uno::Sequence< uno::Sequence< beans::PropertyValue > >
+ aDynamicMenuEntries( SvtDynamicMenuOptions().GetMenu( EDynamicMenuType::NewMenu ) );
+
+ sal_uInt32 i, nCount = aDynamicMenuEntries.getLength();
+ for ( i = 0; i < nCount; i++ )
+ {
+ const uno::Sequence< beans::PropertyValue >& rDynamicMenuEntry = aDynamicMenuEntries[ i ];
+
+ OUString aDocumentUrl, aTitle;
+
+ for ( const beans::PropertyValue& e : rDynamicMenuEntry )
+ {
+ if ( e.Name == DYNAMICMENU_PROPERTYNAME_URL )
+ e.Value >>= aDocumentUrl;
+ else if ( e.Name == DYNAMICMENU_PROPERTYNAME_TITLE )
+ e.Value >>= aTitle;
+ }
+ //#i96822# business cards, labels and database should not be inserted here
+ if( aDocumentUrl == "private:factory/swriter?slot=21051" ||
+ aDocumentUrl == "private:factory/swriter?slot=21052" ||
+ aDocumentUrl == "private:factory/sdatabase?Interactive" )
+ continue;
+
+ // Insert into listbox
+ if ( !aDocumentUrl.isEmpty() )
+ {
+ if ( aDocumentUrl == "private:factory/simpress?slot=6686" ) // SJ: #106216# do not start
+ aDocumentUrl = "private:factory/simpress"; // the AutoPilot for impress
+
+ // insert private-url and default-extension as user-data
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetDefaultFilterFromFactory( aDocumentUrl );
+ if ( pFilter )
+ {
+ // insert doc-name and image
+ OUString aTitleName = aTitle.replaceFirst( "~", "" );
+
+ OUString aStrDefExt(pFilter->GetDefaultExtension());
+ DocumentTypeData *pTypeData = new DocumentTypeData(aDocumentUrl, aStrDefExt.copy(2));
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pTypeData)));
+ m_xLbDocTypes->append(sId, aTitleName);
+ }
+ }
+ }
+ m_xLbDocTypes->select(0);
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+
+void SvxHyperlinkNewDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ // get data from dialog-controls
+ rStrURL = m_xCbbPath->get_active_text();
+ INetURLObject aURL;
+ if ( ImplGetURLObject( rStrURL, m_xCbbPath->GetBaseURL(), aURL ) )
+ {
+ rStrURL = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkNewDocTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkNewDocTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkNewDocTp::SetInitFocus()
+{
+ m_xCbbPath->grab_focus();
+}
+
+/*************************************************************************
+|*
+|* Ask page whether an insert is possible
+|*
+\************************************************************************/
+bool SvxHyperlinkNewDocTp::AskApply()
+{
+ INetURLObject aINetURLObject;
+ bool bRet = ImplGetURLObject(m_xCbbPath->get_active_text(), m_xCbbPath->GetBaseURL(), aINetURLObject);
+ if ( !bRet )
+ {
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(mpDialog->getDialog(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_HYPDLG_NOVALIDFILENAME)));
+ xWarn->run();
+ }
+ return bRet;
+}
+
+namespace
+{
+ struct ExecuteInfo
+ {
+ bool bRbtEditLater;
+ bool bRbtEditNow;
+ INetURLObject aURL;
+ OUString aStrDocName;
+ // current document
+ css::uno::Reference<css::frame::XFrame> xFrame;
+ SfxDispatcher* pDispatcher;
+ };
+}
+
+IMPL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void*, p, void)
+{
+ std::unique_ptr<ExecuteInfo> xExecuteInfo(static_cast<ExecuteInfo*>(p));
+ if (!xExecuteInfo->xFrame.is())
+ return;
+ try
+ {
+ //if it throws dispatcher is invalid
+ css::uno::Reference<css::awt::XTopWindow>(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY_THROW);
+
+ SfxViewFrame *pViewFrame = nullptr;
+
+ // create items
+ SfxStringItem aName( SID_FILE_NAME, xExecuteInfo->aStrDocName );
+ SfxStringItem aReferer( SID_REFERER, "private:user" );
+ SfxStringItem aFrame( SID_TARGETNAME, "_blank");
+
+ OUString aStrFlags('S');
+ if (xExecuteInfo->bRbtEditLater)
+ {
+ aStrFlags += "H";
+ }
+ SfxStringItem aFlags (SID_OPTIONS, aStrFlags);
+
+ // open url
+ const SfxPoolItem* pReturn = xExecuteInfo->pDispatcher->ExecuteList(
+ SID_OPENDOC, SfxCallMode::SYNCHRON,
+ { &aName, &aFlags, &aFrame, &aReferer });
+
+ // save new doc
+ const SfxViewFrameItem *pItem = dynamic_cast<const SfxViewFrameItem*>( pReturn ); // SJ: pReturn is NULL if the Hyperlink
+ if ( pItem ) // creation is cancelled #106216#
+ {
+ pViewFrame = pItem->GetFrame();
+ if (pViewFrame)
+ {
+ SfxStringItem aNewName( SID_FILE_NAME, xExecuteInfo->aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ SfxUnoFrameItem aDocFrame( SID_FILLFRAME, pViewFrame->GetFrame().GetFrameInterface() );
+ fprintf(stderr, "is there a frame int %p\n", pViewFrame->GetFrame().GetFrameInterface().get() );
+ pViewFrame->GetDispatcher()->ExecuteList(
+ SID_SAVEASDOC, SfxCallMode::SYNCHRON,
+ { &aNewName }, { &aDocFrame });
+ }
+ }
+
+ if (xExecuteInfo->bRbtEditNow)
+ {
+ css::uno::Reference<css::awt::XTopWindow> xWindow(xExecuteInfo->xFrame->getContainerWindow(), css::uno::UNO_QUERY);
+ if (xWindow.is()) //will be false if the frame was exited while the document was loading (e.g. we waited for warning dialogs)
+ xWindow->toFront();
+ }
+
+ if (pViewFrame && xExecuteInfo->bRbtEditLater)
+ {
+ SfxObjectShell* pObjShell = pViewFrame->GetObjectShell();
+ pObjShell->DoClose();
+ }
+ }
+ catch (...)
+ {
+ }
+}
+
+/*************************************************************************
+|*
+|* Any action to do after apply-button is pressed
+|*
+\************************************************************************/
+void SvxHyperlinkNewDocTp::DoApply()
+{
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ // get data from dialog-controls
+ OUString aStrNewName = m_xCbbPath->get_active_text();
+
+ if ( aStrNewName.isEmpty() )
+ aStrNewName = maStrInitURL;
+
+ // create a real URL-String
+ INetURLObject aURL;
+ if ( !ImplGetURLObject( aStrNewName, m_xCbbPath->GetBaseURL(), aURL ) )
+ return;
+
+ // create Document
+ aStrNewName = aURL.GetURLPath( INetURLObject::DecodeMechanism::NONE );
+ bool bCreate = true;
+ try
+ {
+ // check if file exists, warn before we overwrite it
+ std::unique_ptr<SvStream> pIStm = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ );
+
+ bool bOk = pIStm && ( pIStm->GetError() == ERRCODE_NONE);
+
+ pIStm.reset();
+
+ if( bOk )
+ {
+ std::unique_ptr<weld::MessageDialog> xWarn(Application::CreateMessageDialog(mpDialog->getDialog(),
+ VclMessageType::Warning, VclButtonsType::YesNo,
+ CuiResId(RID_SVXSTR_HYPERDLG_QUERYOVERWRITE)));
+ bCreate = xWarn->run() == RET_YES;
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ if (!(bCreate && !aStrNewName.isEmpty()))
+ return;
+
+ ExecuteInfo* pExecuteInfo = new ExecuteInfo;
+
+ pExecuteInfo->bRbtEditLater = m_xRbtEditLater->get_active();
+ pExecuteInfo->bRbtEditNow = m_xRbtEditNow->get_active();
+ // get private-url
+ sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ if (nPos == -1)
+ nPos = 0;
+ pExecuteInfo->aURL = aURL;
+ pExecuteInfo->aStrDocName = reinterpret_cast<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos).toInt64())->aStrURL;
+
+ // current document
+ pExecuteInfo->xFrame = GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface();
+ pExecuteInfo->pDispatcher = GetDispatcher();
+
+ Application::PostUserEvent(LINK(nullptr, SvxHyperlinkNewDocTp, DispatchDocument), pExecuteInfo);
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : new
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkNewDocTp, ClickNewHdl_Impl, weld::Button&, void)
+{
+ DisableClose( true );
+ uno::Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
+
+ OUString aStrURL;
+ OUString aTempStrURL( m_xCbbPath->get_active_text() );
+ osl::FileBase::getFileURLFromSystemPath( aTempStrURL, aStrURL );
+
+ OUString aStrPath = aStrURL;
+ bool bZeroPath = aStrPath.isEmpty();
+ bool bHandleFileName = bZeroPath; // when path has length of 0, then the rest should always be handled
+ // as file name, otherwise we do not yet know
+
+ if( bZeroPath )
+ aStrPath = SvtPathOptions().GetWorkPath();
+ else if( !::utl::UCBContentHelper::IsFolder( aStrURL ) )
+ bHandleFileName = true;
+
+ xFolderPicker->setDisplayDirectory( aStrPath );
+ sal_Int16 nResult = xFolderPicker->execute();
+ DisableClose( false );
+ if( ExecutableDialogResults::OK != nResult )
+ return;
+
+ char const sSlash[] = "/";
+
+ INetURLObject aURL( aStrURL, INetProtocol::File );
+ OUString aStrName;
+ if( bHandleFileName )
+ aStrName = bZeroPath? aTempStrURL : aURL.getName();
+
+ m_xCbbPath->SetBaseURL( xFolderPicker->getDirectory() );
+ OUString aStrTmp( xFolderPicker->getDirectory() );
+
+ if( aStrTmp[ aStrTmp.getLength() - 1 ] != sSlash[0] )
+ aStrTmp += sSlash;
+
+ // append old file name
+ if( bHandleFileName )
+ aStrTmp += aStrName;
+
+ INetURLObject aNewURL( aStrTmp );
+
+ if (!aStrName.isEmpty() && !aNewURL.getExtension().isEmpty() &&
+ m_xLbDocTypes->get_selected_index() != -1)
+ {
+ // get private-url
+ const sal_Int32 nPos = m_xLbDocTypes->get_selected_index();
+ aNewURL.setExtension(reinterpret_cast<DocumentTypeData*>(m_xLbDocTypes->get_id(nPos).toInt64())->aStrExt);
+ }
+
+ if( aNewURL.GetProtocol() == INetProtocol::File )
+ {
+ osl::FileBase::getSystemPathFromFileURL(aNewURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aStrTmp);
+ }
+ else
+ {
+ aStrTmp = aNewURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+ }
+
+ m_xCbbPath->set_entry_text( aStrTmp );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hldoctp.cxx b/cui/source/dialogs/hldoctp.cxx
new file mode 100644
index 000000000..8bfe89465
--- /dev/null
+++ b/cui/source/dialogs/hldoctp.cxx
@@ -0,0 +1,318 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cuihyperdlg.hxx>
+#include <osl/file.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <hldoctp.hxx>
+#include <hlmarkwn_def.hxx>
+
+char const sHash[] = "#";
+char const sFileScheme[] = INET_FILE_SCHEME;
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+
+SvxHyperlinkDocTp::SvxHyperlinkDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkdocpage.ui", "HyperlinkDocPage", pItemSet)
+ , m_xCbbPath(new SvxHyperURLBox(xBuilder->weld_combo_box("path")))
+ , m_xBtFileopen(xBuilder->weld_button("fileopen"))
+ , m_xEdTarget(xBuilder->weld_entry("target"))
+ , m_xFtFullURL(xBuilder->weld_label("url"))
+ , m_xBtBrowse(xBuilder->weld_button("browse"))
+ , m_bMarkWndOpen(false)
+{
+ m_xCbbPath->SetSmartProtocol(INetProtocol::File);
+
+ InitStdControls();
+
+ m_xCbbPath->show();
+ m_xCbbPath->SetBaseURL(INET_FILE_SCHEME);
+
+ SetExchangeSupport();
+
+ // set handlers
+ m_xBtFileopen->connect_clicked( LINK ( this, SvxHyperlinkDocTp, ClickFileopenHdl_Impl ) );
+ m_xBtBrowse->connect_clicked( LINK ( this, SvxHyperlinkDocTp, ClickTargetHdl_Impl ) );
+ m_xCbbPath->connect_changed( LINK ( this, SvxHyperlinkDocTp, ModifiedPathHdl_Impl ) );
+ m_xEdTarget->connect_changed( LINK ( this, SvxHyperlinkDocTp, ModifiedTargetHdl_Impl ) );
+
+ m_xCbbPath->connect_focus_out( LINK ( this, SvxHyperlinkDocTp, LostFocusPathHdl_Impl ) );
+
+ maTimer.SetInvokeHandler ( LINK ( this, SvxHyperlinkDocTp, TimeoutHdl_Impl ) );
+}
+
+SvxHyperlinkDocTp::~SvxHyperlinkDocTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::FillDlgFields(const OUString& rStrURL)
+{
+ sal_Int32 nPos = rStrURL.indexOf(sHash);
+ // path
+ m_xCbbPath->set_entry_text( rStrURL.copy( 0, ( nPos == -1 ? rStrURL.getLength() : nPos ) ) );
+
+ // set target in document at editfield
+ OUString aStrMark;
+ if ( nPos != -1 && nPos < rStrURL.getLength()-1 )
+ aStrMark = rStrURL.copy( nPos+1 );
+ m_xEdTarget->set_text( aStrMark );
+
+ ModifiedPathHdl_Impl(*m_xCbbPath->getWidget());
+}
+
+/*************************************************************************
+|*
+|* retrieve current url-string
+|*
+|************************************************************************/
+OUString SvxHyperlinkDocTp::GetCurrentURL () const
+{
+ // get data from dialog-controls
+ OUString aStrURL;
+ OUString aStrPath( m_xCbbPath->get_active_text() );
+ OUString aStrMark( m_xEdTarget->get_text() );
+
+ if ( !aStrPath.isEmpty() )
+ {
+ INetURLObject aURL( aStrPath );
+ if ( aURL.GetProtocol() != INetProtocol::NotValid ) // maybe the path is already a valid
+ aStrURL = aStrPath; // hyperlink, then we can use this path directly
+ else
+ {
+ osl::FileBase::getFileURLFromSystemPath( aStrPath, aStrURL );
+ aStrURL = INetURLObject::decode(aStrURL, INetURLObject::DecodeMechanism::ToIUri, RTL_TEXTENCODING_UTF8);
+ }
+
+ //#105788# always create a URL even if it is not valid
+ if( aStrURL.isEmpty() )
+ aStrURL = aStrPath;
+ }
+
+ if( !aStrMark.isEmpty() )
+ {
+ aStrURL += sHash + aStrMark;
+ }
+
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ // get data from standard-fields
+ rStrURL = GetCurrentURL();
+
+ if( rStrURL.equalsIgnoreAsciiCase( sFileScheme ) )
+ rStrURL.clear();
+
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+std::unique_ptr<IconChoicePage> SvxHyperlinkDocTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkDocTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::SetInitFocus()
+{
+ m_xCbbPath->grab_focus();
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : fileopen
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ClickFileopenHdl_Impl, weld::Button&, void)
+{
+ DisableClose( true );
+ // Open Fileopen-Dialog
+ sfx2::FileDialogHelper aDlg(
+ css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE,
+ mpDialog->getDialog() );
+ OUString aOldURL( GetCurrentURL() );
+ if( aOldURL.startsWithIgnoreAsciiCase( sFileScheme ) )
+ {
+ OUString aPath;
+ osl::FileBase::getSystemPathFromFileURL(aOldURL, aPath);
+ aDlg.SetDisplayFolder( aPath );
+ }
+
+ ErrCode nError = aDlg.Execute();
+ DisableClose( false );
+
+ if ( ERRCODE_NONE != nError )
+ return;
+
+ OUString aURL( aDlg.GetPath() );
+ OUString aPath;
+
+ osl::FileBase::getSystemPathFromFileURL(aURL, aPath);
+
+ m_xCbbPath->SetBaseURL( aURL );
+ m_xCbbPath->set_entry_text(aPath);
+
+ if ( aOldURL != GetCurrentURL() )
+ ModifiedPathHdl_Impl(*m_xCbbPath->getWidget());
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : target
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ClickTargetHdl_Impl, weld::Button&, void)
+{
+ ShowMarkWnd();
+
+ if ( GetPathType ( maStrURL ) == EPathType::ExistsFile ||
+ maStrURL.isEmpty() ||
+ maStrURL.equalsIgnoreAsciiCase( sFileScheme ) ||
+ maStrURL.startsWith( sHash ) )
+ {
+ mxMarkWnd->SetError( LERR_NOERROR );
+
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ if ( maStrURL.equalsIgnoreAsciiCase( sFileScheme ) )
+ mxMarkWnd->RefreshTree ( "" );
+ else
+ mxMarkWnd->RefreshTree ( maStrURL );
+ }
+ else
+ mxMarkWnd->SetError( LERR_DOCNOTOPEN );
+}
+
+/*************************************************************************
+|*
+|* Contents of combobox "Path" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ModifiedPathHdl_Impl, weld::ComboBox&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ maTimer.SetTimeout( 2500 );
+ maTimer.Start();
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* If path-field was modify, to browse the new doc after timeout
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, TimeoutHdl_Impl, Timer *, void)
+{
+ if ( IsMarkWndVisible() && ( GetPathType( maStrURL )== EPathType::ExistsFile ||
+ maStrURL.isEmpty() ||
+ maStrURL.equalsIgnoreAsciiCase( sFileScheme ) ) )
+ {
+ weld::WaitObject aWait(mpDialog->getDialog());
+
+ if ( maStrURL.equalsIgnoreAsciiCase( sFileScheme ) )
+ mxMarkWnd->RefreshTree ( "" );
+ else
+ mxMarkWnd->RefreshTree ( maStrURL );
+ }
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Target" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, ModifiedTargetHdl_Impl, weld::Entry&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ if (IsMarkWndVisible())
+ mxMarkWnd->SelectEntry(m_xEdTarget->get_text());
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* editfield "Target" lost focus
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkDocTp, LostFocusPathHdl_Impl, weld::Widget&, void)
+{
+ maStrURL = GetCurrentURL();
+
+ m_xFtFullURL->set_label( maStrURL );
+}
+
+/*************************************************************************
+|*
+|* Get String from Bookmark-Wnd
+|*
+|************************************************************************/
+void SvxHyperlinkDocTp::SetMarkStr ( const OUString& aStrMark )
+{
+ m_xEdTarget->set_text(aStrMark);
+
+ ModifiedTargetHdl_Impl ( *m_xEdTarget );
+}
+
+/*************************************************************************
+|*
+|* retrieve kind of pathstr
+|*
+|************************************************************************/
+SvxHyperlinkDocTp::EPathType SvxHyperlinkDocTp::GetPathType ( const OUString& rStrPath )
+{
+ INetURLObject aURL( rStrPath, INetProtocol::File );
+
+ if( aURL.HasError() )
+ return EPathType::Invalid;
+ else
+ return EPathType::ExistsFile;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlinettp.cxx b/cui/source/dialogs/hlinettp.cxx
new file mode 100644
index 000000000..f2deeb9b3
--- /dev/null
+++ b/cui/source/dialogs/hlinettp.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 <unotools/useroptions.hxx>
+#include <svl/adrparse.hxx>
+
+#include <hlinettp.hxx>
+#include <hlmarkwn_def.hxx>
+
+char const sAnonymous[] = "anonymous";
+char const sFTPScheme[] = INET_FTP_SCHEME;
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+SvxHyperlinkInternetTp::SvxHyperlinkInternetTp(weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkinternetpage.ui", "HyperlinkInternetPage",
+ pItemSet)
+ , m_bMarkWndOpen(false)
+ , m_xRbtLinktypInternet(xBuilder->weld_radio_button("linktyp_internet"))
+ , m_xRbtLinktypFTP(xBuilder->weld_radio_button("linktyp_ftp"))
+ , m_xCbbTarget(new SvxHyperURLBox(xBuilder->weld_combo_box("target")))
+ , m_xFtTarget(xBuilder->weld_label("target_label"))
+ , m_xFtLogin(xBuilder->weld_label("login_label"))
+ , m_xEdLogin(xBuilder->weld_entry("login"))
+ , m_xFtPassword(xBuilder->weld_label("password_label"))
+ , m_xEdPassword(xBuilder->weld_entry("password"))
+ , m_xCbAnonymous(xBuilder->weld_check_button("anonymous"))
+{
+ // gtk_size_group_set_ignore_hidden, "Measuring the size of hidden widgets
+ // ... they will report a size of 0 nowadays, and thus, their size will
+ // not affect the other size group members", which is unfortunate. So here
+ // before we hide the labels, take the size group width and set it as
+ // explicit preferred size on a label that won't be hidden
+ auto nLabelWidth = m_xFtTarget->get_preferred_size().Width();
+ m_xFtTarget->set_size_request(nLabelWidth, -1);
+
+ m_xCbbTarget->SetSmartProtocol(INetProtocol::Http);
+
+ InitStdControls();
+
+ m_xCbbTarget->show();
+
+ SetExchangeSupport ();
+
+ // set defaults
+ m_xRbtLinktypInternet->set_active(true);
+
+ // set handlers
+ Link<weld::Button&, void> aLink( LINK ( this, SvxHyperlinkInternetTp, Click_SmartProtocol_Impl ) );
+ m_xRbtLinktypInternet->connect_clicked( aLink );
+ m_xRbtLinktypFTP->connect_clicked( aLink );
+ m_xCbAnonymous->connect_clicked( LINK ( this, SvxHyperlinkInternetTp, ClickAnonymousHdl_Impl ) );
+ m_xEdLogin->connect_changed( LINK ( this, SvxHyperlinkInternetTp, ModifiedLoginHdl_Impl ) );
+ m_xCbbTarget->connect_focus_out( LINK ( this, SvxHyperlinkInternetTp, LostFocusTargetHdl_Impl ) );
+ m_xCbbTarget->connect_changed( LINK ( this, SvxHyperlinkInternetTp, ModifiedTargetHdl_Impl ) );
+ maTimer.SetInvokeHandler ( LINK ( this, SvxHyperlinkInternetTp, TimeoutHdl_Impl ) );
+}
+
+SvxHyperlinkInternetTp::~SvxHyperlinkInternetTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::FillDlgFields(const OUString& rStrURL)
+{
+ INetURLObject aURL(rStrURL);
+ OUString aStrScheme(GetSchemeFromURL(rStrURL));
+
+ // set additional controls for FTP: Username / Password
+ if (aStrScheme.startsWith(sFTPScheme))
+ {
+ if ( aURL.GetUser().toAsciiLowerCase().startsWith( sAnonymous ) )
+ setAnonymousFTPUser();
+ else
+ setFTPUser(aURL.GetUser(), aURL.GetPass());
+
+ //do not show password and user in url
+ if(!aURL.GetUser().isEmpty() || !aURL.GetPass().isEmpty() )
+ aURL.SetUserAndPass("", "");
+ }
+
+ // set URL-field
+ // Show the scheme, #72740
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ m_xCbbTarget->set_entry_text( aURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous ) );
+ else
+ m_xCbbTarget->set_entry_text(rStrURL);
+
+ SetScheme(aStrScheme);
+}
+
+void SvxHyperlinkInternetTp::setAnonymousFTPUser()
+{
+ m_xEdLogin->set_text(sAnonymous);
+ SvAddressParser aAddress(SvtUserOptions().GetEmail());
+ m_xEdPassword->set_text(aAddress.Count() ? aAddress.GetEmailAddress(0) : OUString());
+
+ m_xFtLogin->set_sensitive(false);
+ m_xFtPassword->set_sensitive(false);
+ m_xEdLogin->set_sensitive(false);
+ m_xEdPassword->set_sensitive(false);
+ m_xCbAnonymous->set_active(true);
+}
+
+void SvxHyperlinkInternetTp::setFTPUser(const OUString& rUser, const OUString& rPassword)
+{
+ m_xEdLogin->set_text(rUser);
+ m_xEdPassword->set_text(rPassword);
+
+ m_xFtLogin->set_sensitive(true);
+ m_xFtPassword->set_sensitive(true);
+ m_xEdLogin->set_sensitive(true);
+ m_xEdPassword->set_sensitive(true);
+ m_xCbAnonymous->set_active(false);
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+
+void SvxHyperlinkInternetTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ rStrURL = CreateAbsoluteURL();
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+OUString SvxHyperlinkInternetTp::CreateAbsoluteURL() const
+{
+ // erase leading and trailing whitespaces
+ OUString aStrURL(m_xCbbTarget->get_active_text().trim());
+
+ INetURLObject aURL(aStrURL);
+
+ if( aURL.GetProtocol() == INetProtocol::NotValid )
+ {
+ aURL.SetSmartProtocol( GetSmartProtocolFromButtons() );
+ aURL.SetSmartURL(aStrURL);
+ }
+
+ // username and password for ftp-url
+ if( aURL.GetProtocol() == INetProtocol::Ftp && !m_xEdLogin->get_text().isEmpty() )
+ aURL.SetUserAndPass ( m_xEdLogin->get_text(), m_xEdPassword->get_text() );
+
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ return aURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
+ else //#105788# always create a URL even if it is not valid
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkInternetTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkInternetTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::SetInitFocus()
+{
+ m_xCbbTarget->grab_focus();
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Target" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ModifiedTargetHdl_Impl, weld::ComboBox&, void)
+{
+ OUString aScheme = GetSchemeFromURL( m_xCbbTarget->get_active_text() );
+ if( !aScheme.isEmpty() )
+ SetScheme( aScheme );
+
+ // start timer
+ maTimer.SetTimeout( 2500 );
+ maTimer.Start();
+}
+
+/*************************************************************************
+|*
+|* If target-field was modify, to browse the new doc after timeout
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, TimeoutHdl_Impl, Timer *, void)
+{
+ RefreshMarkWindow();
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "Login" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ModifiedLoginHdl_Impl, weld::Entry&, void)
+{
+ OUString aStrLogin ( m_xEdLogin->get_text() );
+ if ( aStrLogin.equalsIgnoreAsciiCase( sAnonymous ) )
+ {
+ m_xCbAnonymous->set_active(true);
+ ClickAnonymousHdl_Impl(*m_xCbAnonymous);
+ }
+}
+
+void SvxHyperlinkInternetTp::SetScheme(const OUString& rScheme)
+{
+ //if rScheme is empty or unknown the default behaviour is like it where HTTP
+ bool bFTP = rScheme.startsWith(sFTPScheme);
+ bool bInternet = !bFTP;
+
+ //update protocol button selection:
+ m_xRbtLinktypFTP->set_active(bFTP);
+ m_xRbtLinktypInternet->set_active(bInternet);
+
+ //update target:
+ RemoveImproperProtocol(rScheme);
+ m_xCbbTarget->SetSmartProtocol( GetSmartProtocolFromButtons() );
+
+ //show/hide special fields for FTP:
+ m_xFtLogin->set_visible( bFTP );
+ m_xFtPassword->set_visible( bFTP );
+ m_xEdLogin->set_visible( bFTP );
+ m_xEdPassword->set_visible( bFTP );
+ m_xCbAnonymous->set_visible( bFTP );
+
+ //update 'link target in document'-window and opening-button
+ if (rScheme.startsWith(INET_HTTP_SCHEME) || rScheme.isEmpty())
+ {
+ if ( m_bMarkWndOpen )
+ ShowMarkWnd ();
+ }
+ else
+ {
+ //disable for https and ftp
+ if ( m_bMarkWndOpen )
+ HideMarkWnd ();
+ }
+}
+
+/*************************************************************************
+|*
+|* Remove protocol if it does not fit to the current button selection
+|*
+|************************************************************************/
+
+void SvxHyperlinkInternetTp::RemoveImproperProtocol(const OUString& aProperScheme)
+{
+ OUString aStrURL ( m_xCbbTarget->get_active_text() );
+ if ( !aStrURL.isEmpty() )
+ {
+ OUString aStrScheme(GetSchemeFromURL(aStrURL));
+ if ( !aStrScheme.isEmpty() && aStrScheme != aProperScheme )
+ {
+ aStrURL = aStrURL.copy( aStrScheme.getLength() );
+ m_xCbbTarget->set_entry_text( aStrURL );
+ }
+ }
+}
+
+OUString SvxHyperlinkInternetTp::GetSchemeFromButtons() const
+{
+ if( m_xRbtLinktypFTP->get_active() )
+ return INET_FTP_SCHEME;
+ return INET_HTTP_SCHEME;
+}
+
+INetProtocol SvxHyperlinkInternetTp::GetSmartProtocolFromButtons() const
+{
+ if( m_xRbtLinktypFTP->get_active() )
+ {
+ return INetProtocol::Ftp;
+ }
+ return INetProtocol::Http;
+}
+
+/*************************************************************************
+|*
+|* Click on Radiobutton : Internet or FTP
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, Click_SmartProtocol_Impl, weld::Button&, void)
+{
+ OUString aScheme = GetSchemeFromButtons();
+ SetScheme(aScheme);
+}
+
+/*************************************************************************
+|*
+|* Click on Checkbox : Anonymous user
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, ClickAnonymousHdl_Impl, weld::Button&, void)
+{
+ // disable login-editfields if checked
+ if ( m_xCbAnonymous->get_active() )
+ {
+ if ( m_xEdLogin->get_text().toAsciiLowerCase().startsWith( sAnonymous ) )
+ {
+ maStrOldUser.clear();
+ maStrOldPassword.clear();
+ }
+ else
+ {
+ maStrOldUser = m_xEdLogin->get_text();
+ maStrOldPassword = m_xEdPassword->get_text();
+ }
+
+ setAnonymousFTPUser();
+ }
+ else
+ setFTPUser(maStrOldUser, maStrOldPassword);
+}
+
+/*************************************************************************
+|*
+|* Combobox Target lost the focus
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkInternetTp, LostFocusTargetHdl_Impl, weld::Widget&, void)
+{
+ RefreshMarkWindow();
+}
+
+void SvxHyperlinkInternetTp::RefreshMarkWindow()
+{
+ if (m_xRbtLinktypInternet->get_active() && IsMarkWndVisible())
+ {
+ weld::WaitObject aWait(mpDialog->getDialog());
+ OUString aStrURL( CreateAbsoluteURL() );
+ if ( !aStrURL.isEmpty() )
+ mxMarkWnd->RefreshTree ( aStrURL );
+ else
+ mxMarkWnd->SetError( LERR_DOCNOTOPEN );
+ }
+}
+
+/*************************************************************************
+|*
+|* Get String from Bookmark-Wnd
+|*
+|************************************************************************/
+void SvxHyperlinkInternetTp::SetMarkStr ( const OUString& aStrMark )
+{
+ OUString aStrURL(m_xCbbTarget->get_active_text());
+
+ const sal_Unicode sUHash = '#';
+ sal_Int32 nPos = aStrURL.lastIndexOf( sUHash );
+
+ if( nPos != -1 )
+ aStrURL = aStrURL.copy(0, nPos);
+
+ aStrURL += OUStringChar(sUHash) + aStrMark;
+
+ m_xCbbTarget->set_entry_text(aStrURL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlmailtp.cxx b/cui/source/dialogs/hlmailtp.cxx
new file mode 100644
index 000000000..4e2e111fc
--- /dev/null
+++ b/cui/source/dialogs/hlmailtp.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 <sfx2/request.hxx>
+
+#include <sfx2/viewfrm.hxx>
+#include <unotools/moduleoptions.hxx>
+
+#include <hlmailtp.hxx>
+
+#include <comphelper/lok.hxx>
+
+using namespace ::com::sun::star;
+
+/*************************************************************************
+|*
+|* Constructor / Destructor
+|*
+|************************************************************************/
+SvxHyperlinkMailTp::SvxHyperlinkMailTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+ : SvxHyperlinkTabPageBase(pParent, pDlg, "cui/ui/hyperlinkmailpage.ui", "HyperlinkMailPage", pItemSet)
+ , m_xCbbReceiver(new SvxHyperURLBox(xBuilder->weld_combo_box("receiver")))
+ , m_xBtAdrBook(xBuilder->weld_button("adressbook"))
+ , m_xFtSubject(xBuilder->weld_label("subject_label"))
+ , m_xEdSubject(xBuilder->weld_entry("subject"))
+{
+ m_xCbbReceiver->SetSmartProtocol(INetProtocol::Mailto);
+
+ InitStdControls();
+
+ m_xCbbReceiver->show();
+
+ SetExchangeSupport ();
+
+ // set handlers
+ m_xBtAdrBook->connect_clicked( LINK ( this, SvxHyperlinkMailTp, ClickAdrBookHdl_Impl ) );
+ m_xCbbReceiver->connect_changed( LINK ( this, SvxHyperlinkMailTp, ModifiedReceiverHdl_Impl) );
+
+ if ( !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::DATABASE ) ||
+ comphelper::LibreOfficeKit::isActive() )
+ m_xBtAdrBook->hide();
+}
+
+SvxHyperlinkMailTp::~SvxHyperlinkMailTp()
+{
+}
+
+/*************************************************************************
+|*
+|* Fill the all dialog-controls except controls in groupbox "more..."
+|*
+|************************************************************************/
+
+void SvxHyperlinkMailTp::FillDlgFields(const OUString& rStrURL)
+{
+ OUString aStrScheme = GetSchemeFromURL(rStrURL);
+
+ // set URL-field and additional controls
+ OUString aStrURLc (rStrURL);
+ // set additional controls for EMail:
+ if ( aStrScheme.startsWith( INET_MAILTO_SCHEME ) )
+ {
+ // Find mail-subject
+ OUString aStrSubject, aStrTmp( aStrURLc );
+
+ sal_Int32 nPos = aStrTmp.toAsciiLowerCase().indexOf( "subject" );
+
+ if ( nPos != -1 )
+ nPos = aStrTmp.indexOf( '=', nPos );
+
+ if ( nPos != -1 )
+ aStrSubject = aStrURLc.copy( nPos+1 );
+
+ nPos = aStrURLc.indexOf( '?' );
+
+ if ( nPos != -1 )
+ aStrURLc = aStrURLc.copy( 0, nPos );
+
+ m_xEdSubject->set_text( aStrSubject );
+ }
+ else
+ {
+ m_xEdSubject->set_text("");
+ }
+
+ m_xCbbReceiver->set_entry_text(aStrURLc);
+
+ SetScheme( aStrScheme );
+}
+
+/*************************************************************************
+|*
+|* retrieve and prepare data from dialog-fields
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ rStrURL = CreateAbsoluteURL();
+ GetDataFromCommonFields( aStrName, aStrIntName, aStrFrame, eMode );
+}
+
+OUString SvxHyperlinkMailTp::CreateAbsoluteURL() const
+{
+ OUString aStrURL = m_xCbbReceiver->get_active_text();
+ INetURLObject aURL(aStrURL);
+
+ if( aURL.GetProtocol() == INetProtocol::NotValid )
+ {
+ aURL.SetSmartProtocol( INetProtocol::Mailto );
+ aURL.SetSmartURL(aStrURL);
+ }
+
+ // subject for EMail-url
+ if( aURL.GetProtocol() == INetProtocol::Mailto )
+ {
+ if (!m_xEdSubject->get_text().isEmpty())
+ {
+ OUString aQuery = "subject=" + m_xEdSubject->get_text();
+ aURL.SetParam(aQuery);
+ }
+ }
+
+ if ( aURL.GetProtocol() != INetProtocol::NotValid )
+ return aURL.GetMainURL( INetURLObject::DecodeMechanism::WithCharset );
+ else //#105788# always create a URL even if it is not valid
+ return aStrURL;
+}
+
+/*************************************************************************
+|*
+|* static method to create Tabpage
+|*
+|************************************************************************/
+
+std::unique_ptr<IconChoicePage> SvxHyperlinkMailTp::Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet)
+{
+ return std::make_unique<SvxHyperlinkMailTp>(pWindow, pDlg, pItemSet);
+}
+
+/*************************************************************************
+|*
+|* Set initial focus
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::SetInitFocus()
+{
+ m_xCbbReceiver->grab_focus();
+}
+
+/*************************************************************************
+|************************************************************************/
+void SvxHyperlinkMailTp::SetScheme(const OUString& rScheme)
+{
+ //update target:
+ RemoveImproperProtocol(rScheme);
+ m_xCbbReceiver->SetSmartProtocol( INetProtocol::Mailto );
+
+ //show/hide special fields for MAIL:
+ m_xBtAdrBook->set_sensitive(true);
+ m_xEdSubject->set_sensitive(true);
+}
+
+/*************************************************************************
+|*
+|* Remove protocol if it does not fit to the current button selection
+|*
+|************************************************************************/
+void SvxHyperlinkMailTp::RemoveImproperProtocol(const OUString& aProperScheme)
+{
+ OUString aStrURL(m_xCbbReceiver->get_active_text());
+ if ( !aStrURL.isEmpty() )
+ {
+ OUString aStrScheme = GetSchemeFromURL( aStrURL );
+ if ( !aStrScheme.isEmpty() && aStrScheme != aProperScheme )
+ {
+ aStrURL = aStrURL.copy( aStrScheme.getLength() );
+ m_xCbbReceiver->set_entry_text(aStrURL);
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* Contents of editfield "receiver" modified
+|*
+|************************************************************************/
+IMPL_LINK_NOARG(SvxHyperlinkMailTp, ModifiedReceiverHdl_Impl, weld::ComboBox&, void)
+{
+ OUString aScheme = GetSchemeFromURL( m_xCbbReceiver->get_active_text() );
+ if(!aScheme.isEmpty())
+ SetScheme( aScheme );
+}
+
+/*************************************************************************
+|*
+|* Click on imagebutton : addressbook
+|*
+|************************************************************************/
+IMPL_STATIC_LINK_NOARG(SvxHyperlinkMailTp, ClickAdrBookHdl_Impl, weld::Button&, void)
+{
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if( pViewFrame )
+ {
+ SfxItemPool &rPool = pViewFrame->GetPool();
+ SfxRequest aReq(SID_VIEW_DATA_SOURCE_BROWSER, SfxCallMode::SLOT, rPool);
+ pViewFrame->ExecuteSlot( aReq, true );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hlmarkwn.cxx b/cui/source/dialogs/hlmarkwn.cxx
new file mode 100644
index 000000000..3b985b2b0
--- /dev/null
+++ b/cui/source/dialogs/hlmarkwn.cxx
@@ -0,0 +1,473 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <unotools/viewoptions.hxx>
+#include <vcl/graph.hxx>
+
+// UNO-Stuff
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/document/XLinkTargetSupplier.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/io/IOException.hpp>
+
+#include <toolkit/helper/vclunohelper.hxx>
+
+#include <strings.hrc>
+#include <hlmarkwn.hxx>
+#include <hltpbase.hxx>
+#include <hlmarkwn_def.hxx>
+
+using namespace ::com::sun::star;
+
+namespace {
+
+// Userdata-struct for tree-entries
+struct TargetData
+{
+ OUString aUStrLinkname;
+ bool bIsTarget;
+
+ TargetData (const OUString& aUStrLName, bool bTarget)
+ : bIsTarget(bTarget)
+ {
+ if (bIsTarget)
+ aUStrLinkname = aUStrLName;
+ }
+};
+
+}
+
+//*** Window-Class ***
+// Constructor / Destructor
+SvxHlinkDlgMarkWnd::SvxHlinkDlgMarkWnd(weld::Window* pParentDialog, SvxHyperlinkTabPageBase *pParentPage)
+ : GenericDialogController(pParentDialog, "cui/ui/hyperlinkmarkdialog.ui", "HyperlinkMark")
+ , mpParent(pParentPage)
+ , mnError(LERR_NOERROR)
+ , mxBtApply(m_xBuilder->weld_button("ok"))
+ , mxBtClose(m_xBuilder->weld_button("close"))
+ , mxLbTree(m_xBuilder->weld_tree_view("TreeListBox"))
+ , mxError(m_xBuilder->weld_label("error"))
+{
+ mxLbTree->set_size_request(mxLbTree->get_approximate_digit_width() * 25,
+ mxLbTree->get_height_rows(12));
+ mxBtApply->connect_clicked( LINK ( this, SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl ) );
+ mxBtClose->connect_clicked( LINK ( this, SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl ) );
+ mxLbTree->connect_row_activated( LINK ( this, SvxHlinkDlgMarkWnd, DoubleClickApplyHdl_Impl ) );
+}
+
+SvxHlinkDlgMarkWnd::~SvxHlinkDlgMarkWnd()
+{
+ ClearTree();
+}
+
+void SvxHlinkDlgMarkWnd::ErrorChanged()
+{
+ if (mnError == LERR_NOENTRIES)
+ {
+ OUString aStrMessage = CuiResId( RID_SVXSTR_HYPDLG_ERR_LERR_NOENTRIES );
+ mxError->set_label(aStrMessage);
+ mxError->show();
+ mxLbTree->hide();
+ }
+ else if (mnError == LERR_DOCNOTOPEN)
+ {
+ OUString aStrMessage = CuiResId( RID_SVXSTR_HYPDLG_ERR_LERR_DOCNOTOPEN );
+ mxError->set_label(aStrMessage);
+ mxError->show();
+ mxLbTree->hide();
+ }
+ else
+ {
+ mxLbTree->show();
+ mxError->hide();
+ }
+}
+
+// Set an errorstatus
+sal_uInt16 SvxHlinkDlgMarkWnd::SetError( sal_uInt16 nError)
+{
+ sal_uInt16 nOldError = mnError;
+ mnError = nError;
+
+ if( mnError != LERR_NOERROR )
+ ClearTree();
+
+ ErrorChanged();
+
+ return nOldError;
+}
+
+// Move window
+void SvxHlinkDlgMarkWnd::MoveTo(const Point& rNewPos)
+{
+ m_xDialog->window_move(rNewPos.X(), rNewPos.Y());
+}
+
+namespace
+{
+ void SelectPath(weld::TreeIter* pEntry, weld::TreeView& rLbTree,
+ std::deque<OUString> &rLastSelectedPath)
+ {
+ OUString sTitle(rLastSelectedPath.front());
+ rLastSelectedPath.pop_front();
+ if (sTitle.isEmpty())
+ return;
+ while (pEntry)
+ {
+ if (sTitle == rLbTree.get_text(*pEntry))
+ {
+ rLbTree.select(*pEntry);
+ rLbTree.scroll_to_row(*pEntry);
+ if (!rLastSelectedPath.empty())
+ {
+ rLbTree.expand_row(*pEntry);
+ if (!rLbTree.iter_children(*pEntry))
+ pEntry = nullptr;
+ SelectPath(pEntry, rLbTree, rLastSelectedPath);
+ }
+ break;
+ }
+ if (!rLbTree.iter_next_sibling(*pEntry))
+ pEntry = nullptr;
+ }
+ }
+}
+
+#define TG_SETTING_MANAGER "TargetInDocument"
+#define TG_SETTING_LASTMARK "LastSelectedMark"
+#define TG_SETTING_LASTPATH "LastSelectedPath"
+
+void SvxHlinkDlgMarkWnd::RestoreLastSelection()
+{
+ bool bSelectedEntry = false;
+
+ OUString sLastSelectedMark;
+ std::deque<OUString> aLastSelectedPath;
+ SvtViewOptions aViewSettings( EViewType::Dialog, TG_SETTING_MANAGER );
+ if (aViewSettings.Exists())
+ {
+ //Maybe we might want to have some sort of mru list and keep a mapping
+ //per document, rather than the current reuse of "the last thing
+ //selected, regardless of the document"
+ aViewSettings.GetUserItem(TG_SETTING_LASTMARK) >>= sLastSelectedMark;
+ uno::Sequence<OUString> aTmp;
+ aViewSettings.GetUserItem(TG_SETTING_LASTPATH) >>= aTmp;
+ aLastSelectedPath = comphelper::sequenceToContainer< std::deque<OUString> >(aTmp);
+ }
+ //fallback to previous entry selected the last time we executed this dialog.
+ //First see if the exact mark exists and re-use that
+ if (!sLastSelectedMark.isEmpty())
+ bSelectedEntry = SelectEntry(sLastSelectedMark);
+ //Otherwise just select the closest path available
+ //now to what was available at dialog close time
+ if (!bSelectedEntry && !aLastSelectedPath.empty())
+ {
+ std::deque<OUString> aTmpSelectedPath(aLastSelectedPath);
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ if (!mxLbTree->get_iter_first(*xEntry))
+ xEntry.reset();
+ SelectPath(xEntry.get(), *mxLbTree, aTmpSelectedPath);
+ }
+}
+
+// Interface to refresh tree
+void SvxHlinkDlgMarkWnd::RefreshTree (const OUString& aStrURL)
+{
+ OUString aUStrURL;
+
+ weld::WaitObject aWait(m_xDialog.get());
+
+ ClearTree();
+
+ sal_Int32 nPos = aStrURL.indexOf('#');
+
+ if (nPos != 0)
+ aUStrURL = aStrURL;
+
+ if (!RefreshFromDoc(aUStrURL))
+ ErrorChanged();
+
+ bool bSelectedEntry = false;
+
+ if ( nPos != -1 )
+ {
+ OUString aStrMark = aStrURL.copy(nPos+1);
+ bSelectedEntry = SelectEntry(aStrMark);
+ }
+
+ if (!bSelectedEntry)
+ RestoreLastSelection();
+}
+
+// get links from document
+bool SvxHlinkDlgMarkWnd::RefreshFromDoc(const OUString& aURL)
+{
+ mnError = LERR_NOERROR;
+
+ uno::Reference< frame::XDesktop2 > xDesktop = frame::Desktop::create( ::comphelper::getProcessComponentContext() );
+ uno::Reference< lang::XComponent > xComp;
+
+ if( !aURL.isEmpty() )
+ {
+ // load from url
+ if( xDesktop.is() )
+ {
+ try
+ {
+ uno::Sequence< beans::PropertyValue > aArg(1);
+ aArg.getArray()[0].Name = "Hidden";
+ aArg.getArray()[0].Value <<= true;
+ xComp = xDesktop->loadComponentFromURL( aURL, "_blank", 0, aArg );
+ }
+ catch( const io::IOException& )
+ {
+
+ }
+ catch( const lang::IllegalArgumentException& )
+ {
+
+ }
+ }
+ }
+ else
+ {
+ // the component with user focus ( current document )
+ xComp = xDesktop->getCurrentComponent();
+ }
+
+ if( xComp.is() )
+ {
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xComp, uno::UNO_QUERY );
+
+ if( xLTS.is() )
+ {
+ if( FillTree( xLTS->getLinks() ) == 0 )
+ mnError = LERR_NOENTRIES;
+ }
+ else
+ mnError = LERR_DOCNOTOPEN;
+
+ if ( !aURL.isEmpty() )
+ xComp->dispose();
+ }
+ else
+ {
+ if( !aURL.isEmpty() )
+ mnError=LERR_DOCNOTOPEN;
+ }
+ return (mnError==0);
+}
+
+// Fill Tree-Control
+int SvxHlinkDlgMarkWnd::FillTree( const uno::Reference< container::XNameAccess >& xLinks, const weld::TreeIter* pParentEntry )
+{
+ int nEntries=0;
+ const uno::Sequence< OUString > aNames( xLinks->getElementNames() );
+ const sal_uLong nLinks = aNames.getLength();
+ const OUString* pNames = aNames.getConstArray();
+
+ const OUString aProp_LinkDisplayName( "LinkDisplayName" );
+ const OUString aProp_LinkTarget( "com.sun.star.document.LinkTarget" );
+ const OUString aProp_LinkDisplayBitmap( "LinkDisplayBitmap" );
+ for( sal_uLong i = 0; i < nLinks; i++ )
+ {
+ uno::Any aAny;
+ OUString aLink( *pNames++ );
+
+ bool bError = false;
+ try
+ {
+ aAny = xLinks->getByName( aLink );
+ }
+ catch(const uno::Exception&)
+ {
+ // if the name of the target was invalid (like empty headings)
+ // no object can be provided
+ bError = true;
+ }
+ if(bError)
+ continue;
+
+ uno::Reference< beans::XPropertySet > xTarget;
+
+ if( aAny >>= xTarget )
+ {
+ try
+ {
+ // get name to display
+ aAny = xTarget->getPropertyValue( aProp_LinkDisplayName );
+ OUString aDisplayName;
+ aAny >>= aDisplayName;
+ OUString aStrDisplayname ( aDisplayName );
+
+ // is it a target ?
+ uno::Reference< lang::XServiceInfo > xSI( xTarget, uno::UNO_QUERY );
+ bool bIsTarget = xSI->supportsService( aProp_LinkTarget );
+
+ // create userdata
+ TargetData *pData = new TargetData ( aLink, bIsTarget );
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pData)));
+
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ mxLbTree->insert(pParentEntry, -1, &aStrDisplayname, &sId, nullptr, nullptr, nullptr, false, xEntry.get());
+
+ try
+ {
+ // get bitmap for the tree-entry
+ uno::Reference< awt::XBitmap >
+ aXBitmap( xTarget->getPropertyValue( aProp_LinkDisplayBitmap ), uno::UNO_QUERY );
+ if (aXBitmap.is())
+ {
+ Graphic aBmp(Graphic(VCLUnoHelper::GetBitmap(aXBitmap)));
+ // insert Displayname into treelist with bitmaps
+ mxLbTree->set_image(*xEntry, aBmp.GetXGraphic(), -1);
+ }
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+
+ nEntries++;
+
+ uno::Reference< document::XLinkTargetSupplier > xLTS( xTarget, uno::UNO_QUERY );
+ if( xLTS.is() )
+ nEntries += FillTree( xLTS->getLinks(), xEntry.get() );
+ }
+ catch(const css::uno::Exception&)
+ {
+ }
+ }
+ }
+
+ return nEntries;
+}
+
+// Clear Tree
+void SvxHlinkDlgMarkWnd::ClearTree()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = mxLbTree->make_iterator();
+ bool bEntry = mxLbTree->get_iter_first(*xEntry);
+
+ while (bEntry)
+ {
+ TargetData* pUserData = reinterpret_cast<TargetData*>(mxLbTree->get_id(*xEntry).toInt64());
+ delete pUserData;
+
+ bEntry = mxLbTree->iter_next(*xEntry);
+ }
+
+ mxLbTree->clear();
+}
+
+// Find Entry for String
+std::unique_ptr<weld::TreeIter> SvxHlinkDlgMarkWnd::FindEntry (const OUString& aStrName)
+{
+ bool bFound=false;
+ std::unique_ptr<weld::TreeIter> xEntry = mxLbTree->make_iterator();
+ bool bEntry = mxLbTree->get_iter_first(*xEntry);
+
+ while (bEntry && !bFound)
+ {
+ TargetData* pUserData = reinterpret_cast<TargetData*>(mxLbTree->get_id(*xEntry).toInt64());
+ if (aStrName == pUserData->aUStrLinkname)
+ bFound = true;
+ else
+ bEntry = mxLbTree->iter_next(*xEntry);
+ }
+
+ if (!bFound)
+ xEntry.reset();
+
+ return xEntry;
+}
+
+// Select Entry
+bool SvxHlinkDlgMarkWnd::SelectEntry(const OUString& aStrMark)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = FindEntry(aStrMark);
+ if (!xEntry)
+ return false;
+ mxLbTree->select(*xEntry);
+ mxLbTree->scroll_to_row(*xEntry);
+ return true;
+}
+
+// Click on Apply-Button / Double-click on item in tree
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, DoubleClickApplyHdl_Impl, weld::TreeView&, bool)
+{
+ ClickApplyHdl_Impl(*mxBtApply);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, ClickApplyHdl_Impl, weld::Button&, void)
+{
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ bool bEntry = mxLbTree->get_cursor(xEntry.get());
+ if (bEntry)
+ {
+ TargetData* pData = reinterpret_cast<TargetData*>(mxLbTree->get_id(*xEntry).toInt64());
+ if (pData->bIsTarget)
+ {
+ mpParent->SetMarkStr(pData->aUStrLinkname);
+ }
+ }
+}
+
+// Click on Close-Button
+IMPL_LINK_NOARG(SvxHlinkDlgMarkWnd, ClickCloseHdl_Impl, weld::Button&, void)
+{
+ std::unique_ptr<weld::TreeIter> xEntry(mxLbTree->make_iterator());
+ bool bEntry = mxLbTree->get_cursor(xEntry.get());
+ if (bEntry)
+ {
+ TargetData* pUserData = reinterpret_cast<TargetData*>(mxLbTree->get_id(*xEntry).toInt64());
+ OUString sLastSelectedMark = pUserData->aUStrLinkname;
+
+ std::deque<OUString> aLastSelectedPath;
+ //If the bottommost entry is expanded but nothing
+ //underneath it is selected leave a dummy entry
+ if (mxLbTree->get_row_expanded(*xEntry))
+ aLastSelectedPath.push_front(OUString());
+ while (bEntry)
+ {
+ aLastSelectedPath.push_front(mxLbTree->get_text(*xEntry));
+ bEntry = mxLbTree->iter_parent(*xEntry);
+ }
+
+ uno::Sequence< beans::NamedValue > aSettings
+ {
+ { TG_SETTING_LASTMARK, css::uno::Any(sLastSelectedMark) },
+ { TG_SETTING_LASTPATH, css::uno::Any(comphelper::containerToSequence(aLastSelectedPath)) }
+ };
+
+ // write
+ SvtViewOptions aViewSettings( EViewType::Dialog, TG_SETTING_MANAGER );
+ aViewSettings.SetUserData( aSettings );
+ }
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hltpbase.cxx b/cui/source/dialogs/hltpbase.cxx
new file mode 100644
index 000000000..b3c7b076f
--- /dev/null
+++ b/cui/source/dialogs/hltpbase.cxx
@@ -0,0 +1,545 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sal/config.h>
+
+#include <comphelper/lok.hxx>
+#include <osl/file.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/event.hxx>
+#include <sfx2/frame.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sot/formats.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <svl/macitem.hxx>
+#include <ucbhelper/content.hxx>
+#include <cuihyperdlg.hxx>
+#include <hltpbase.hxx>
+#include <macroass.hxx>
+#include <svx/svxdlg.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+#include <bitmaps.hlst>
+
+using namespace ::ucbhelper;
+
+namespace {
+
+OUString CreateUiNameFromURL( const OUString& aStrURL )
+{
+ OUString aStrUiURL;
+ INetURLObject aURLObj( aStrURL );
+
+ switch(aURLObj.GetProtocol())
+ {
+ case INetProtocol::File:
+ osl::FileBase::getSystemPathFromFileURL(aURLObj.GetMainURL(INetURLObject::DecodeMechanism::NONE), aStrUiURL);
+ break;
+ case INetProtocol::Ftp :
+ {
+ //remove password from name
+ INetURLObject aTmpURL(aURLObj);
+ aTmpURL.SetPass("");
+ aStrUiURL = aTmpURL.GetMainURL( INetURLObject::DecodeMechanism::Unambiguous );
+ }
+ break;
+ default :
+ {
+ aStrUiURL = aURLObj.GetMainURL(INetURLObject::DecodeMechanism::Unambiguous);
+ }
+ }
+ if(aStrUiURL.isEmpty())
+ return aStrURL;
+ return aStrUiURL;
+}
+
+}
+
+// ComboBox-Control for URL's with History and Autocompletion
+SvxHyperURLBox::SvxHyperURLBox(std::unique_ptr<weld::ComboBox> xControl)
+ : SvtURLBox(std::move(xControl))
+ , DropTargetHelper(getWidget()->get_drop_target())
+{
+ SetSmartProtocol(INetProtocol::Http);
+}
+
+sal_Int8 SvxHyperURLBox::AcceptDrop( const AcceptDropEvent& /* rEvt */ )
+{
+ return IsDropFormatSupported( SotClipboardFormatId::STRING ) ? DND_ACTION_COPY : DND_ACTION_NONE;
+}
+
+sal_Int8 SvxHyperURLBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
+{
+ TransferableDataHelper aDataHelper( rEvt.maDropEvent.Transferable );
+ OUString aString;
+ sal_Int8 nRet = DND_ACTION_NONE;
+
+ if( aDataHelper.GetString( SotClipboardFormatId::STRING, aString ) )
+ {
+ set_entry_text(aString);
+ nRet = DND_ACTION_COPY;
+ }
+
+ return nRet;
+}
+
+//# Hyperlink-Dialog: Tabpages-Baseclass #
+
+SvxHyperlinkTabPageBase::SvxHyperlinkTabPageBase(weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const OUString& rUIXMLDescription,
+ const OString& rID,
+ const SfxItemSet* pItemSet)
+ : IconChoicePage(pParent, rUIXMLDescription, rID, pItemSet)
+ , mxCbbFrame(xBuilder->weld_combo_box("frame"))
+ , mxLbForm(xBuilder->weld_combo_box("form"))
+ , mxEdIndication(xBuilder->weld_entry("indication"))
+ , mxEdText(xBuilder->weld_entry("name"))
+ , mxBtScript(xBuilder->weld_button("script"))
+ , mxFormLabel(xBuilder->weld_label("form_label"))
+ , mxFrameLabel(xBuilder->weld_label("frame_label"))
+ , mbIsCloseDisabled( false )
+ , mpDialog( pDlg )
+ , mbStdControlsInit( false )
+{
+ // create bookmark-window
+}
+
+SvxHyperlinkTabPageBase::~SvxHyperlinkTabPageBase()
+{
+ maTimer.Stop();
+
+ HideMarkWnd();
+}
+
+bool SvxHyperlinkTabPageBase::QueryClose()
+{
+ return !mbIsCloseDisabled;
+}
+
+void SvxHyperlinkTabPageBase::InitStdControls ()
+{
+ if ( !mbStdControlsInit )
+ {
+ SfxDispatcher* pDispatch = GetDispatcher();
+ SfxViewFrame* pViewFrame = pDispatch ? pDispatch->GetFrame() : nullptr;
+ SfxFrame* pFrame = pViewFrame ? &pViewFrame->GetFrame() : nullptr;
+ if ( pFrame )
+ {
+ std::unique_ptr<TargetList> pList(new TargetList);
+ SfxFrame::GetDefaultTargetList(*pList);
+ if( !pList->empty() )
+ {
+ size_t nCount = pList->size();
+ size_t i;
+ for ( i = 0; i < nCount; i++ )
+ {
+ mxCbbFrame->append_text( pList->at( i ) );
+ }
+ }
+ }
+
+ mxBtScript->set_from_icon_name(RID_SVXBMP_SCRIPT);
+
+ mxBtScript->connect_clicked ( LINK ( this, SvxHyperlinkTabPageBase, ClickScriptHdl_Impl ) );
+ }
+
+ mbStdControlsInit = true;
+}
+
+// Move Extra-Window
+void SvxHyperlinkTabPageBase::MoveToExtraWnd( Point aNewPos )
+{
+ mxMarkWnd->MoveTo(aNewPos);
+}
+
+// Show Extra-Window
+void SvxHyperlinkTabPageBase::ShowMarkWnd()
+{
+ if (mxMarkWnd)
+ {
+ mxMarkWnd->getDialog()->present();
+ return;
+ }
+
+ weld::Dialog* pDialog = mpDialog->getDialog();
+
+ mxMarkWnd = std::make_shared<SvxHlinkDlgMarkWnd>(pDialog, this);
+
+ // Size of dialog-window in screen pixels
+ Point aDlgPos(pDialog->get_position());
+ Size aDlgSize(pDialog->get_size());
+
+ // Absolute size of the screen
+ ::tools::Rectangle aScreen(pDialog->get_monitor_workarea());
+
+ // Size of Extrawindow
+ Size aExtraWndSize(mxMarkWnd->getDialog()->get_preferred_size());
+
+ // mxMarkWnd is a child of mpDialog, so coordinates for positioning must be relative to mpDialog
+ if( aDlgPos.X()+(1.05*aDlgSize.Width())+aExtraWndSize.Width() > aScreen.Right() )
+ {
+ if( aDlgPos.X() - ( 0.05*aDlgSize.Width() ) - aExtraWndSize.Width() < 0 )
+ {
+ // Pos Extrawindow anywhere
+ MoveToExtraWnd( Point(10,10) ); // very unlikely
+ }
+ else
+ {
+ // Pos Extrawindow on the left side of Dialog
+ MoveToExtraWnd( Point(0,0) - Point( long(0.05*aDlgSize.Width()), 0 ) - Point( aExtraWndSize.Width(), 0 ) );
+ }
+ }
+ else
+ {
+ // Pos Extrawindow on the right side of Dialog
+ MoveToExtraWnd ( Point( long(1.05*aDlgSize.getWidth()), 0 ) );
+ }
+
+ // Set size of Extra-Window
+ mxMarkWnd->getDialog()->set_size_request(aExtraWndSize.Width(), aDlgSize.Height());
+
+ weld::DialogController::runAsync(mxMarkWnd, [this](sal_Int32 /*nResult*/) { mxMarkWnd.reset(); } );
+}
+
+void SvxHyperlinkTabPageBase::HideMarkWnd()
+{
+ if (mxMarkWnd)
+ {
+ mxMarkWnd->response(RET_CANCEL);
+ mxMarkWnd.reset();
+ }
+}
+
+// Fill Dialogfields
+void SvxHyperlinkTabPageBase::FillStandardDlgFields ( const SvxHyperlinkItem* pHyperlinkItem )
+{
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ // Frame
+ sal_Int32 nPos = mxCbbFrame->find_text(pHyperlinkItem->GetTargetFrame());
+ if (nPos != -1)
+ mxCbbFrame->set_active(nPos);
+
+ // Form
+ OUString aStrFormText = CuiResId( RID_SVXSTR_HYPERDLG_FROM_TEXT );
+
+ OUString aStrFormButton = CuiResId( RID_SVXSTR_HYPERDLG_FORM_BUTTON );
+
+ if( pHyperlinkItem->GetInsertMode() & HLINK_HTMLMODE )
+ {
+ mxLbForm->clear();
+ mxLbForm->append_text( aStrFormText );
+ mxLbForm->set_active( 0 );
+ }
+ else
+ {
+ mxLbForm->clear();
+ mxLbForm->append_text( aStrFormText );
+ mxLbForm->append_text( aStrFormButton );
+ mxLbForm->set_active( pHyperlinkItem->GetInsertMode() == HLINK_BUTTON ? 1 : 0 );
+ }
+ }
+ else
+ {
+ mxCbbFrame->hide();
+ mxLbForm->hide();
+ mxFormLabel->hide();
+ mxFrameLabel->hide();
+ }
+
+ // URL
+ mxEdIndication->set_text( pHyperlinkItem->GetName() );
+
+ // Name
+ mxEdText->set_text( pHyperlinkItem->GetIntName() );
+
+ // Script-button
+ if (!comphelper::LibreOfficeKit::isActive())
+ {
+ if ( pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE )
+ mxBtScript->set_sensitive(false);
+ else
+ mxBtScript->set_sensitive(true);
+ }
+ else
+ {
+ mxBtScript->hide();
+ }
+}
+
+// Any action to do after apply-button is pressed
+void SvxHyperlinkTabPageBase::DoApply ()
+{
+ // default-implementation : do nothing
+}
+
+// Ask page whether an insert is possible
+bool SvxHyperlinkTabPageBase::AskApply ()
+{
+ // default-implementation
+ return true;
+}
+
+// This method would be called from bookmark-window to set new mark-string
+void SvxHyperlinkTabPageBase::SetMarkStr ( const OUString& /*aStrMark*/ )
+{
+ // default-implementation : do nothing
+}
+
+// Set initial focus
+void SvxHyperlinkTabPageBase::SetInitFocus()
+{
+ xContainer->grab_focus();
+}
+
+// retrieve dispatcher
+SfxDispatcher* SvxHyperlinkTabPageBase::GetDispatcher() const
+{
+ return mpDialog->GetDispatcher();
+}
+
+void SvxHyperlinkTabPageBase::DisableClose(bool _bDisable)
+{
+ mbIsCloseDisabled = _bDisable;
+ if (mbIsCloseDisabled)
+ maBusy.incBusy(mpDialog->getDialog());
+ else
+ maBusy.decBusy();
+}
+
+// Click on imagebutton : Script
+IMPL_LINK_NOARG(SvxHyperlinkTabPageBase, ClickScriptHdl_Impl, weld::Button&, void)
+{
+ SvxHyperlinkItem *pHyperlinkItem = const_cast<SvxHyperlinkItem*>(static_cast<const SvxHyperlinkItem *>(
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK)));
+
+ if ( pHyperlinkItem->GetMacroEvents() == HyperDialogEvent::NONE )
+ return;
+
+ // get macros from itemset
+ const SvxMacroTableDtor* pMacroTbl = pHyperlinkItem->GetMacroTable();
+ SvxMacroItem aItem ( SID_ATTR_MACROITEM );
+ if( pMacroTbl )
+ aItem.SetMacroTable( *pMacroTbl );
+
+ // create empty itemset for macro-dlg
+ std::unique_ptr<SfxItemSet> pItemSet( new SfxItemSet(SfxGetpApp()->GetPool(),
+ svl::Items<SID_ATTR_MACROITEM,
+ SID_ATTR_MACROITEM>{} ) );
+ pItemSet->Put ( aItem );
+
+ DisableClose( true );
+
+ SfxMacroAssignDlg aDlg(mpDialog->getDialog(), mxDocumentFrame, *pItemSet);
+
+ // add events
+ SfxMacroTabPage *pMacroPage = aDlg.GetTabPage();
+
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOverObject )
+ pMacroPage->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT1),
+ SvMacroItemId::OnMouseOver );
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseClickObject )
+ pMacroPage->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT2),
+ SvMacroItemId::OnClick);
+ if ( pHyperlinkItem->GetMacroEvents() & HyperDialogEvent::MouseOutObject )
+ pMacroPage->AddEvent( CuiResId(RID_SVXSTR_HYPDLG_MACROACT3),
+ SvMacroItemId::OnMouseOut);
+ // execute dlg
+ short nRet = aDlg.run();
+ DisableClose( false );
+ if ( RET_OK == nRet )
+ {
+ const SfxItemSet* pOutSet = aDlg.GetOutputItemSet();
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == pOutSet->GetItemState( SID_ATTR_MACROITEM, false, &pItem ))
+ {
+ pHyperlinkItem->SetMacroTable( static_cast<const SvxMacroItem*>(pItem)->GetMacroTable() );
+ }
+ }
+}
+
+// Get Macro-Infos
+HyperDialogEvent SvxHyperlinkTabPageBase::GetMacroEvents() const
+{
+ const SvxHyperlinkItem *pHyperlinkItem = static_cast<const SvxHyperlinkItem *>(
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK));
+
+ return pHyperlinkItem->GetMacroEvents();
+}
+
+SvxMacroTableDtor* SvxHyperlinkTabPageBase::GetMacroTable()
+{
+ const SvxHyperlinkItem *pHyperlinkItem = static_cast<const SvxHyperlinkItem *>(
+ GetItemSet().GetItem (SID_HYPERLINK_GETLINK));
+
+ return const_cast<SvxMacroTableDtor*>(pHyperlinkItem->GetMacroTable());
+}
+
+// try to detect the current protocol that is used in rStrURL
+OUString SvxHyperlinkTabPageBase::GetSchemeFromURL( const OUString& rStrURL )
+{
+ OUString aStrScheme;
+
+ INetURLObject aURL( rStrURL );
+ INetProtocol aProtocol = aURL.GetProtocol();
+
+ // our new INetUrlObject now has the ability
+ // to detect if a Url is valid or not :-(
+ if ( aProtocol == INetProtocol::NotValid )
+ {
+ if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTP_SCHEME ) )
+ {
+ aStrScheme = INET_HTTP_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_HTTPS_SCHEME ) )
+ {
+ aStrScheme = INET_HTTPS_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_FTP_SCHEME ) )
+ {
+ aStrScheme = INET_FTP_SCHEME;
+ }
+ else if ( rStrURL.startsWithIgnoreAsciiCase( INET_MAILTO_SCHEME ) )
+ {
+ aStrScheme = INET_MAILTO_SCHEME;
+ }
+ }
+ else
+ aStrScheme = INetURLObject::GetScheme( aProtocol );
+ return aStrScheme;
+}
+
+void SvxHyperlinkTabPageBase::GetDataFromCommonFields( OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode )
+{
+ aStrIntName = mxEdText->get_text();
+ aStrName = mxEdIndication->get_text();
+ aStrFrame = mxCbbFrame->get_active_text();
+
+ sal_Int32 nPos = mxLbForm->get_active();
+ if (nPos == -1)
+ // This happens when FillStandardDlgFields() hides mpLbForm.
+ nPos = 0;
+ eMode = static_cast<SvxLinkInsertMode>(nPos + 1);
+
+ // Ask dialog whether the current doc is a HTML-doc
+ if (mpDialog->IsHTMLDoc())
+ eMode = static_cast<SvxLinkInsertMode>( sal_uInt16(eMode) | HLINK_HTMLMODE );
+}
+
+// reset dialog-fields
+void SvxHyperlinkTabPageBase::Reset( const SfxItemSet& rItemSet)
+{
+
+ // Set dialog-fields from create-itemset
+ maStrInitURL.clear();
+
+ const SvxHyperlinkItem *pHyperlinkItem = static_cast<const SvxHyperlinkItem *>(
+ rItemSet.GetItem (SID_HYPERLINK_GETLINK));
+
+ if ( pHyperlinkItem )
+ {
+ // set dialog-fields
+ FillStandardDlgFields (pHyperlinkItem);
+
+ // set all other fields
+ FillDlgFields ( pHyperlinkItem->GetURL() );
+
+ // Store initial URL
+ maStrInitURL = pHyperlinkItem->GetURL();
+ }
+}
+
+// Fill output-ItemSet
+bool SvxHyperlinkTabPageBase::FillItemSet( SfxItemSet* rOut)
+{
+ OUString aStrURL, aStrName, aStrIntName, aStrFrame;
+ SvxLinkInsertMode eMode;
+
+ GetCurentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
+ if ( aStrName.isEmpty() ) //automatically create a visible name if the link is created without name
+ aStrName = CreateUiNameFromURL(aStrURL);
+
+ HyperDialogEvent nEvents = GetMacroEvents();
+ SvxMacroTableDtor* pTable = GetMacroTable();
+
+ SvxHyperlinkItem aItem( SID_HYPERLINK_SETLINK, aStrName, aStrURL, aStrFrame,
+ aStrIntName, eMode, nEvents, pTable );
+ rOut->Put (aItem);
+
+ return true;
+}
+
+// Activate / Deactivate Tabpage
+void SvxHyperlinkTabPageBase::ActivatePage( const SfxItemSet& rItemSet )
+{
+
+ // Set dialog-fields from input-itemset
+ const SvxHyperlinkItem *pHyperlinkItem = static_cast<const SvxHyperlinkItem *>(
+ rItemSet.GetItem (SID_HYPERLINK_GETLINK));
+
+ if ( pHyperlinkItem )
+ {
+ // standard-fields
+ FillStandardDlgFields (pHyperlinkItem);
+ }
+
+ // show mark-window if it was open before
+ if ( ShouldOpenMarkWnd () )
+ ShowMarkWnd ();
+}
+
+DeactivateRC SvxHyperlinkTabPageBase::DeactivatePage( SfxItemSet* _pSet)
+{
+ // hide mark-wnd
+ SetMarkWndShouldOpen( IsMarkWndVisible () );
+ HideMarkWnd ();
+
+ // retrieve data of dialog
+ OUString aStrURL, aStrName, aStrIntName, aStrFrame;
+ SvxLinkInsertMode eMode;
+
+ GetCurentItemData ( aStrURL, aStrName, aStrIntName, aStrFrame, eMode);
+
+ HyperDialogEvent nEvents = GetMacroEvents();
+ SvxMacroTableDtor* pTable = GetMacroTable();
+
+ if( _pSet )
+ {
+ SvxHyperlinkItem aItem( SID_HYPERLINK_GETLINK, aStrName, aStrURL, aStrFrame,
+ aStrIntName, eMode, nEvents, pTable );
+ _pSet->Put( aItem );
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxHyperlinkTabPageBase::ShouldOpenMarkWnd()
+{
+ return false;
+}
+
+void SvxHyperlinkTabPageBase::SetMarkWndShouldOpen(bool)
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/hyphen.cxx b/cui/source/dialogs/hyphen.cxx
new file mode 100644
index 000000000..f7b6549fc
--- /dev/null
+++ b/cui/source/dialogs/hyphen.cxx
@@ -0,0 +1,471 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <hyphen.hxx>
+
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+
+#include <editeng/splwrap.hxx>
+#include <editeng/unolingu.hxx>
+#include <svtools/langtab.hxx>
+#include <sal/log.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <tools/debug.hxx>
+
+#define HYPH_POS_CHAR '='
+
+#define CUR_HYPH_POS_CHAR '-'
+
+using namespace css;
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CursorChangeHdl_Impl, weld::Entry&, void)
+{
+ int nStart, nEnd;
+ m_xWordEdit->get_selection_bounds(nStart, nEnd);
+ if (nStart == m_nOldPos && nEnd == m_nOldPos + 1)
+ return;
+ bool bReSelect;
+ if (nStart <= m_nOldPos)
+ bReSelect = !SelLeft();
+ else
+ bReSelect = !SelRight();
+ if (bReSelect)
+ select_region(m_nOldPos, m_nOldPos + 1);
+}
+
+void SvxHyphenWordDialog::EnableLRBtn_Impl()
+{
+ const sal_Int32 nLen = m_aEditWord.getLength();
+
+ m_xRightBtn->set_sensitive(false);
+ for ( sal_Int32 i = m_nOldPos + 2; i < nLen; ++i )
+ {
+ if ( m_aEditWord[ i ] == sal_Unicode( HYPH_POS_CHAR ) )
+ {
+ m_xRightBtn->set_sensitive(true);
+ break;
+ }
+ }
+
+ DBG_ASSERT(m_nOldPos < nLen, "nOldPos out of range");
+ if (m_nOldPos >= nLen)
+ m_nOldPos = nLen - 1;
+ m_xLeftBtn->set_sensitive(false);
+ for ( sal_Int32 i = m_nOldPos; i-- > 0; )
+ {
+ if ( m_aEditWord[ i ] == sal_Unicode( HYPH_POS_CHAR ) )
+ {
+ m_xLeftBtn->set_sensitive(true);
+ break;
+ }
+ }
+}
+
+OUString SvxHyphenWordDialog::EraseUnusableHyphens_Impl()
+{
+ // returns a String showing only those hyphen positions which will result
+ // in a line break if hyphenation is done there
+ // 1) we will need to discard all hyphenation positions at the end that
+ // will not result in a line break where the text to the left still fits
+ // on the line.
+ // 2) since as from OOo 3.2 '-' are part of a word and thus text like
+ // 'multi-line-editor' is regarded as single word we also need to discard those
+ // hyphenation positions to the left of the rightmost '-' that is still left of
+ // the rightmost valid hyphenation position according to 1)
+
+ // Example:
+ // If the possible hyphenation position in 'multi-line-editor' are to be marked
+ // by '=' then the text will look like this: 'mul=ti-line-ed=it=or'.
+ // If now the first line is only large enough for 'multi-line-edi' we need to discard
+ // the last possible hyphenation point because of 1). The right most valid
+ // hyphenation position is "ed=itor". The first '-' left of this position is
+ // "line-ed", thus because of 2) we now need to discard all possible hyphenation
+ // positions to the left of that as well. Thus in the end leaving us with just
+ // 'multi-line-ed=itor' as return value for this function. (Just one valid hyphenation
+ // position for the user to choose from. However ALL the '-' characters in the word
+ // will ALWAYS be valid implicit hyphenation positions for the core to choose from!
+ // And thus even if this word is skipped in the hyphenation dialog it will still be broken
+ // right after 'multi-line-' (actually it might already be broken up that way before
+ // the hyphenation dialog is called!).
+ // Thus rule 2) just eliminates those positions which will not be used by the core at all
+ // even if the user were to select one of them.
+
+ OUString aTxt;
+ DBG_ASSERT(m_xPossHyph.is(), "missing possible hyphens");
+ if (m_xPossHyph.is())
+ {
+ DBG_ASSERT( m_aActWord == m_xPossHyph->getWord(), "word mismatch" );
+
+ aTxt = m_xPossHyph->getPossibleHyphens();
+
+ m_nHyphenationPositionsOffset = 0;
+ uno::Sequence< sal_Int16 > aHyphenationPositions(
+ m_xPossHyph->getHyphenationPositions() );
+ sal_Int32 nLen = aHyphenationPositions.getLength();
+ const sal_Int16 *pHyphenationPos = aHyphenationPositions.getConstArray();
+
+ // find position nIdx after which all hyphen positions are unusable
+ sal_Int32 nIdx = -1;
+ sal_Int32 nPos = 0, nPos1 = 0;
+ if (nLen)
+ {
+ sal_Int32 nStart = 0;
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ if (pHyphenationPos[i] > m_nMaxHyphenationPos)
+ break;
+ else
+ {
+ // find corresponding hyphen positions in string
+ nPos = aTxt.indexOf( sal_Unicode( HYPH_POS_CHAR ), nStart );
+
+ if (nPos == -1)
+ break;
+ else
+ {
+ nIdx = nPos;
+ nStart = nPos + 1;
+ }
+ }
+ }
+ }
+ DBG_ASSERT(nIdx != -1, "no usable hyphenation position");
+
+ // 1) remove all not usable hyphenation positions from the end of the string
+ nPos = nIdx == -1 ? 0 : nIdx + 1;
+ nPos1 = nPos; //save for later use in 2) below
+ const OUString aTmp( sal_Unicode( HYPH_POS_CHAR ) );
+ while (nPos != -1)
+ {
+ nPos++;
+ aTxt = aTxt.replaceFirst( aTmp, "", &nPos);
+ }
+
+ // 2) remove all hyphenation positions from the start that are not considered by the core
+ const OUString aSearchRange( aTxt.copy( 0, nPos1 ) );
+ sal_Int32 nPos2 = aSearchRange.lastIndexOf( '-' ); // the '-' position the core will use by default
+ if (nPos2 != -1 )
+ {
+ OUString aLeft( aSearchRange.copy( 0, nPos2 ) );
+ nPos = 0;
+ while (nPos != -1)
+ {
+ nPos++;
+ aLeft = aLeft.replaceFirst( aTmp, "", &nPos );
+ if (nPos != -1)
+ ++m_nHyphenationPositionsOffset;
+ }
+ aTxt = aTxt.replaceAt( 0, nPos2, aLeft );
+ }
+ }
+ return aTxt;
+}
+
+void SvxHyphenWordDialog::InitControls_Impl()
+{
+ m_xPossHyph = nullptr;
+ if (m_xHyphenator.is())
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale(m_nActLanguage) );
+ m_xPossHyph = m_xHyphenator->createPossibleHyphens( m_aActWord, aLocale,
+ uno::Sequence< beans::PropertyValue >() );
+ if (m_xPossHyph.is())
+ m_aEditWord = EraseUnusableHyphens_Impl();
+ }
+ m_xWordEdit->set_text(m_aEditWord);
+
+ m_nOldPos = m_aEditWord.getLength();
+ SelLeft();
+ EnableLRBtn_Impl();
+}
+
+void SvxHyphenWordDialog::ContinueHyph_Impl( sal_Int32 nInsPos )
+{
+ if ( nInsPos >= 0 && m_xPossHyph.is() )
+ {
+ if (nInsPos)
+ {
+ DBG_ASSERT(nInsPos <= m_aEditWord.getLength() - 2, "wrong hyphen position");
+
+ sal_Int32 nIdxPos = -1;
+ for (sal_Int32 i = 0; i <= nInsPos; ++i)
+ {
+ if (HYPH_POS_CHAR == m_aEditWord[ i ])
+ nIdxPos++;
+ }
+ // take the possible hyphenation positions that got removed from the
+ // start of the word into account:
+ nIdxPos += m_nHyphenationPositionsOffset;
+
+ uno::Sequence< sal_Int16 > aSeq = m_xPossHyph->getHyphenationPositions();
+ sal_Int32 nLen = aSeq.getLength();
+ DBG_ASSERT(nLen, "empty sequence");
+ DBG_ASSERT(0 <= nIdxPos && nIdxPos < nLen, "index out of range");
+ if (nLen && 0 <= nIdxPos && nIdxPos < nLen)
+ {
+ nInsPos = aSeq.getConstArray()[ nIdxPos ];
+ m_pHyphWrapper->InsertHyphen( nInsPos );
+ }
+ }
+ else
+ {
+ //! calling with 0 as argument will remove hyphens!
+ m_pHyphWrapper->InsertHyphen( nInsPos );
+ }
+ }
+
+ if ( m_pHyphWrapper->FindSpellError() )
+ {
+ uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( m_pHyphWrapper->GetLast(), uno::UNO_QUERY );
+
+ // adapt actual word and language to new found hyphenation result
+ if(xHyphWord.is())
+ {
+ m_aActWord = xHyphWord->getWord();
+ m_nActLanguage = LanguageTag( xHyphWord->getLocale() ).getLanguageType();
+ m_nMaxHyphenationPos = xHyphWord->getHyphenationPos();
+ InitControls_Impl();
+ SetWindowTitle( m_nActLanguage );
+ }
+ }
+ else
+ {
+ m_xCloseBtn->set_sensitive(false);
+ m_xDialog->response(RET_OK);
+ }
+}
+
+bool SvxHyphenWordDialog::SelLeft()
+{
+ bool bRet = false;
+ DBG_ASSERT( m_nOldPos > 0, "invalid hyphenation position" );
+ if (m_nOldPos > 0)
+ {
+ OUString aTxt( m_aEditWord );
+ for( sal_Int32 i = m_nOldPos - 1; i > 0; --i )
+ {
+ DBG_ASSERT(i <= aTxt.getLength(), "index out of range");
+ if (aTxt[ i ] == sal_Unicode( HYPH_POS_CHAR ))
+ {
+ aTxt = aTxt.replaceAt( i, 1, OUString( CUR_HYPH_POS_CHAR ) );
+
+ m_nOldPos = i;
+ m_xWordEdit->set_text(aTxt);
+ select_region(i, i + 1);
+ m_xWordEdit->grab_focus();
+ bRet = true;
+ break;
+ }
+ }
+ EnableLRBtn_Impl();
+ }
+ return bRet;
+}
+
+bool SvxHyphenWordDialog::SelRight()
+{
+ bool bRet = false;
+ OUString aTxt( m_aEditWord );
+ for ( sal_Int32 i = m_nOldPos + 1; i < aTxt.getLength(); ++i )
+ {
+ if (aTxt[ i ] == sal_Unicode( HYPH_POS_CHAR ))
+ {
+ aTxt = aTxt.replaceAt( i, 1, OUString( CUR_HYPH_POS_CHAR ) );
+
+ m_nOldPos = i;
+ m_xWordEdit->set_text(aTxt);
+ select_region(i, i + 1);
+ m_xWordEdit->grab_focus();
+ bRet = true;
+ break;
+ }
+ }
+ EnableLRBtn_Impl();
+ return bRet;
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CutHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl( /*m_nHyphPos*/m_nOldPos );
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, HyphenateAllHdl_Impl, weld::Button&, void)
+{
+ if( m_bBusy )
+ return;
+
+ try
+ {
+ uno::Reference< linguistic2::XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
+
+ xProp->setIsHyphAuto( true );
+
+ m_bBusy = true;
+ ContinueHyph_Impl( /*m_nHyphPos*/m_nOldPos );
+ m_bBusy = false;
+
+ xProp->setIsHyphAuto( false );
+ }
+ catch (uno::Exception &)
+ {
+ SAL_WARN( "cui.dialogs", "Hyphenate All failed" );
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl( 0 );
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, ContinueHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ ContinueHyph_Impl();
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, CancelHdl_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ m_xDialog->response(RET_CANCEL);
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, Left_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ SelLeft();
+ m_bBusy = false;
+ }
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, Right_Impl, weld::Button&, void)
+{
+ if( !m_bBusy )
+ {
+ m_bBusy = true;
+ SelRight();
+ m_bBusy = false;
+ }
+}
+
+void SvxHyphenWordDialog::select_region(int nStart, int nEnd)
+{
+ int nScrollPos = nStart + m_nWordEditWidth/2;
+ if (nScrollPos > m_aEditWord.getLength())
+ nScrollPos = m_aEditWord.getLength() - m_nWordEditWidth/2;
+ if (nScrollPos < 0)
+ nScrollPos = 0;
+ m_xWordEdit->set_position(nScrollPos);
+ m_xWordEdit->select_region(nStart, nEnd);
+}
+
+IMPL_LINK_NOARG(SvxHyphenWordDialog, GetFocusHdl_Impl, weld::Widget&, void)
+{
+ select_region(m_nOldPos, m_nOldPos + 1);
+}
+
+// class SvxHyphenWordDialog ---------------------------------------------
+
+SvxHyphenWordDialog::SvxHyphenWordDialog(
+ const OUString &rWord, LanguageType nLang,
+ weld::Window* pParent,
+ uno::Reference< linguistic2::XHyphenator > const &xHyphen,
+ SvxSpellWrapper* pWrapper)
+ : SfxDialogController(pParent, "cui/ui/hyphenate.ui", "HyphenateDialog")
+ , m_pHyphWrapper(pWrapper)
+ , m_aActWord(rWord)
+ , m_nActLanguage(nLang)
+ , m_nMaxHyphenationPos(0)
+ , m_nOldPos(0)
+ , m_nHyphenationPositionsOffset(0)
+ , m_bBusy(false)
+ , m_xWordEdit(m_xBuilder->weld_entry("worded"))
+ , m_xLeftBtn(m_xBuilder->weld_button("left"))
+ , m_xRightBtn(m_xBuilder->weld_button("right"))
+ , m_xOkBtn(m_xBuilder->weld_button("ok"))
+ , m_xContBtn(m_xBuilder->weld_button("continue"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+ , m_xHyphAll(m_xBuilder->weld_button("hyphall"))
+ , m_xCloseBtn(m_xBuilder->weld_button("close"))
+{
+ m_nWordEditWidth = m_xWordEdit->get_width_chars();
+ m_aLabel = m_xDialog->get_title();
+ m_xHyphenator = xHyphen;
+
+ uno::Reference< linguistic2::XHyphenatedWord > xHyphWord( m_pHyphWrapper ?
+ m_pHyphWrapper->GetLast() : nullptr, uno::UNO_QUERY );
+ DBG_ASSERT( xHyphWord.is(), "hyphenation result missing" );
+ if (xHyphWord.is())
+ {
+ DBG_ASSERT( m_aActWord == xHyphWord->getWord(), "word mismatch" );
+ DBG_ASSERT( m_nActLanguage == LanguageTag( xHyphWord->getLocale() ).getLanguageType(), "language mismatch" );
+ m_nMaxHyphenationPos = xHyphWord->getHyphenationPos();
+ }
+
+ InitControls_Impl();
+ m_xWordEdit->grab_focus();
+
+ m_xLeftBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, Left_Impl ) );
+ m_xRightBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, Right_Impl ) );
+ m_xOkBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, CutHdl_Impl ) );
+ m_xContBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, ContinueHdl_Impl ) );
+ m_xDelBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, DeleteHdl_Impl ) );
+ m_xHyphAll->connect_clicked( LINK( this, SvxHyphenWordDialog, HyphenateAllHdl_Impl ) );
+ m_xCloseBtn->connect_clicked( LINK( this, SvxHyphenWordDialog, CancelHdl_Impl ) );
+ m_xWordEdit->connect_focus_in( LINK( this, SvxHyphenWordDialog, GetFocusHdl_Impl ) );
+ m_xWordEdit->connect_cursor_position( LINK( this, SvxHyphenWordDialog, CursorChangeHdl_Impl ) );
+
+ SetWindowTitle( nLang );
+
+ // disable controls if service is not available
+ if (!m_xHyphenator.is())
+ m_xDialog->set_sensitive(false);
+}
+
+SvxHyphenWordDialog::~SvxHyphenWordDialog()
+{
+ if (m_xCloseBtn->get_sensitive())
+ m_pHyphWrapper->SpellEnd();
+}
+
+void SvxHyphenWordDialog::SetWindowTitle(LanguageType nLang)
+{
+ m_xDialog->set_title(m_aLabel + " (" + SvtLanguageTable::GetLanguageString(nLang) + ")");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/iconcdlg.cxx b/cui/source/dialogs/iconcdlg.cxx
new file mode 100644
index 000000000..bca5984f8
--- /dev/null
+++ b/cui/source/dialogs/iconcdlg.cxx
@@ -0,0 +1,311 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <iconcdlg.hxx>
+#include <cuihyperdlg.hxx>
+
+#include <cassert>
+#include <sal/log.hxx>
+#include <vcl/svapp.hxx>
+
+/**********************************************************************
+|
+| Ctor / Dtor
+|
+\**********************************************************************/
+
+IconChoicePage::IconChoicePage(weld::Container* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const SfxItemSet* pItemSet)
+ : xBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
+ , xContainer(xBuilder->weld_container(rID))
+ , pSet(pItemSet)
+ , bHasExchangeSupport(false)
+{
+}
+
+IconChoicePage::~IconChoicePage()
+{
+}
+
+/**********************************************************************
+|
+| Activate / Deactivate
+|
+\**********************************************************************/
+
+void IconChoicePage::ActivatePage( const SfxItemSet& )
+{
+}
+
+
+DeactivateRC IconChoicePage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool IconChoicePage::QueryClose()
+{
+ return true;
+}
+
+/**********************************************************************
+|
+| add new page
+|
+\**********************************************************************/
+void SvxHpLinkDlg::AddTabPage(const OString& rId, CreatePage pCreateFunc /* != 0 */)
+{
+ weld::Container* pPage = m_xIconCtrl->get_page(rId);
+ maPageList.emplace_back(new IconChoicePageData(rId, pCreateFunc(pPage, this, pSet)));
+ maPageList.back()->xPage->Reset(*pSet);
+ PageCreated(rId, *maPageList.back()->xPage);
+}
+
+/**********************************************************************
+|
+| Show / Hide page or button
+|
+\**********************************************************************/
+void SvxHpLinkDlg::ShowPage(const OString& rId)
+{
+ OString sOldPageId = GetCurPageId();
+ bool bInvalidate = sOldPageId != rId;
+ if (bInvalidate)
+ {
+ IconChoicePageData* pOldData = GetPageData(sOldPageId);
+ if (pOldData && pOldData->xPage)
+ {
+ DeActivatePageImpl();
+ }
+ }
+ SetCurPageId(rId);
+ ActivatePageImpl();
+}
+
+/**********************************************************************
+|
+| select a page
+|
+\**********************************************************************/
+IMPL_LINK(SvxHpLinkDlg, ChosePageHdl_Impl, const OString&, rId, void)
+{
+ if (rId != msCurrentPageId)
+ {
+ ShowPage(rId);
+ }
+}
+
+/**********************************************************************
+|
+| Button-handler
+|
+\**********************************************************************/
+IMPL_LINK_NOARG(SvxHpLinkDlg, ResetHdl, weld::Button&, void)
+{
+ ResetPageImpl ();
+
+ IconChoicePageData* pData = GetPageData ( msCurrentPageId );
+ assert( pData && "ID not known " );
+
+ pData->xPage->Reset( *pSet );
+}
+
+/**********************************************************************
+|
+| call page
+|
+\**********************************************************************/
+void SvxHpLinkDlg::ActivatePageImpl()
+{
+ assert( !maPageList.empty() && "no Pages registered " );
+ IconChoicePageData* pData = GetPageData ( msCurrentPageId );
+ assert( pData && "ID not known " );
+
+ if ( pData->bRefresh )
+ {
+ pData->xPage->Reset( *pSet );
+ pData->bRefresh = false;
+ }
+
+ if ( pExampleSet )
+ pData->xPage->ActivatePage( *pExampleSet );
+ m_xDialog->set_help_id(pData->xPage->GetHelpId());
+
+ m_xResetBtn->show();
+}
+
+void SvxHpLinkDlg::DeActivatePageImpl ()
+{
+ IconChoicePageData *pData = GetPageData ( msCurrentPageId );
+
+ DeactivateRC nRet = DeactivateRC::LeavePage;
+
+ if ( !pData )
+ return;
+
+ IconChoicePage * pPage = pData->xPage.get();
+
+ if ( !pExampleSet && pPage->HasExchangeSupport() && pSet )
+ pExampleSet = new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() );
+
+ if ( pSet )
+ {
+ SfxItemSet aTmp( *pSet->GetPool(), pSet->GetRanges() );
+
+ if ( pPage->HasExchangeSupport() )
+ nRet = pPage->DeactivatePage( &aTmp );
+
+ if ( ( DeactivateRC::LeavePage & nRet ) &&
+ aTmp.Count() )
+ {
+ if (pExampleSet)
+ pExampleSet->Put(aTmp);
+ pOutSet->Put( aTmp );
+ }
+ }
+ else
+ {
+ if ( pPage->HasExchangeSupport() ) //!!!
+ {
+ if ( !pExampleSet )
+ {
+ SfxItemPool* pPool = pPage->GetItemSet().GetPool();
+ pExampleSet =
+ new SfxItemSet( *pPool, GetInputRanges( *pPool ) );
+ }
+ nRet = pPage->DeactivatePage( pExampleSet );
+ }
+ else
+ nRet = pPage->DeactivatePage( nullptr );
+ }
+
+ if ( nRet & DeactivateRC::RefreshSet )
+ {
+ // TODO refresh input set
+ // flag all pages to be newly initialized
+ for (auto & pObj : maPageList)
+ {
+ if ( pObj->xPage.get() != pPage )
+ pObj->bRefresh = true;
+ else
+ pObj->bRefresh = false;
+ }
+ }
+}
+
+
+void SvxHpLinkDlg::ResetPageImpl ()
+{
+ IconChoicePageData *pData = GetPageData ( msCurrentPageId );
+
+ assert( pData && "ID not known " );
+
+ pData->xPage->Reset( *pSet );
+}
+
+/**********************************************************************
+|
+| handling itemsets
+|
+\**********************************************************************/
+
+const sal_uInt16* SvxHpLinkDlg::GetInputRanges( const SfxItemPool& )
+{
+ if ( pSet )
+ {
+ SAL_WARN( "cui.dialogs", "Set does already exist!" );
+ return pSet->GetRanges();
+ }
+
+ if ( pRanges )
+ return pRanges.get();
+
+ pRanges.reset(new sal_uInt16[1]);
+ pRanges[0] = 0;
+
+ return pRanges.get();
+}
+
+
+void SvxHpLinkDlg::SetInputSet( const SfxItemSet* pInSet )
+{
+ bool bSet = ( pSet != nullptr );
+
+ pSet = pInSet;
+
+ if ( !bSet && !pExampleSet && !pOutSet )
+ {
+ pExampleSet = new SfxItemSet( *pSet );
+ pOutSet.reset(new SfxItemSet( *pSet->GetPool(), pSet->GetRanges() ));
+ }
+}
+
+bool SvxHpLinkDlg::QueryClose()
+{
+ bool bRet = true;
+ for (auto & pData : maPageList)
+ {
+ if ( pData->xPage && !pData->xPage->QueryClose() )
+ {
+ bRet = false;
+ break;
+ }
+ }
+ return bRet;
+}
+
+void SvxHpLinkDlg::Start()
+{
+ SwitchPage(msCurrentPageId);
+ ActivatePageImpl();
+}
+
+/**********************************************************************
+|
+| tool-methods
+|
+\**********************************************************************/
+
+IconChoicePageData* SvxHpLinkDlg::GetPageData ( const OString& rId )
+{
+ IconChoicePageData *pRet = nullptr;
+ for (const auto & pData : maPageList)
+ {
+ if ( pData->sId == rId )
+ {
+ pRet = pData.get();
+ break;
+ }
+ }
+ return pRet;
+}
+
+/**********************************************************************
+|
+| OK-Status
+|
+\**********************************************************************/
+
+void SvxHpLinkDlg::SwitchPage( const OString& rId )
+{
+ m_xIconCtrl->set_current_page(rId);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/insdlg.cxx b/cui/source/dialogs/insdlg.cxx
new file mode 100644
index 000000000..4f34b461e
--- /dev/null
+++ b/cui/source/dialogs/insdlg.cxx
@@ -0,0 +1,583 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/embed/EmbedStates.hpp>
+#include <com/sun/star/embed/XInsertObjectDialog.hpp>
+#include <com/sun/star/embed/MSOLEObjectSystemCreator.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <insdlg.hxx>
+#include <dialmgr.hxx>
+#include <osl/diagnose.h>
+#include <svtools/imagemgr.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+
+#include <sal/log.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/debug.hxx>
+#include <tools/stream.hxx>
+#include <vcl/image.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/classids.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/frmdescr.hxx>
+#include <sfx2/viewsh.hxx>
+#include <comphelper/seqstream.hxx>
+
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::ui::dialogs;
+
+bool InsertObjectDialog_Impl::IsCreateNew() const
+{
+ return false;
+}
+
+uno::Reference< io::XInputStream > InsertObjectDialog_Impl::GetIconIfIconified( OUString* /*pGraphicMediaType*/ )
+{
+ return uno::Reference< io::XInputStream >();
+}
+
+InsertObjectDialog_Impl::InsertObjectDialog_Impl(weld::Window* pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const css::uno::Reference < css::embed::XStorage >& xStorage)
+ : GenericDialogController(pParent, rUIXMLDescription, rID)
+ , m_xStorage( xStorage )
+ , aCnt( m_xStorage )
+{
+}
+
+IMPL_LINK_NOARG(SvInsertOleDlg, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvInsertOleDlg, BrowseHdl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get());
+ const Reference< XFilePicker3 >& xFilePicker = aHelper.GetFilePicker();
+
+ // add filter
+ try
+ {
+ xFilePicker->appendFilter(CuiResId(RID_SVXSTR_FILTER_ALL), "*.*");
+ }
+ catch( const IllegalArgumentException& )
+ {
+ SAL_WARN( "cui.dialogs", "caught IllegalArgumentException when registering filter" );
+ }
+
+ if( xFilePicker->execute() == ExecutableDialogResults::OK )
+ {
+ Sequence< OUString > aPathSeq( xFilePicker->getSelectedFiles() );
+ INetURLObject aObj( aPathSeq[0] );
+ m_xEdFilepath->set_text(aObj.PathToFileName());
+ }
+}
+
+IMPL_LINK_NOARG(SvInsertOleDlg, RadioHdl, weld::Button&, void)
+{
+ if (m_xRbNewObject->get_active())
+ {
+ m_xObjectTypeFrame->show();
+ m_xFileFrame->hide();
+ }
+ else
+ {
+ m_xFileFrame->show();
+ m_xObjectTypeFrame->hide();
+ }
+}
+
+SvInsertOleDlg::SvInsertOleDlg(weld::Window* pParent, const Reference<embed::XStorage>& xStorage,
+ const SvObjectServerList* pServers)
+ : InsertObjectDialog_Impl( pParent, "cui/ui/insertoleobject.ui", "InsertOLEObjectDialog", xStorage)
+ , m_pServers( pServers )
+ , m_xRbNewObject(m_xBuilder->weld_radio_button("createnew"))
+ , m_xRbObjectFromfile(m_xBuilder->weld_radio_button("createfromfile"))
+ , m_xObjectTypeFrame(m_xBuilder->weld_frame("objecttypeframe"))
+ , m_xLbObjecttype(m_xBuilder->weld_tree_view("types"))
+ , m_xFileFrame(m_xBuilder->weld_frame("fileframe"))
+ , m_xEdFilepath(m_xBuilder->weld_entry("urled"))
+ , m_xBtnFilepath(m_xBuilder->weld_button("urlbtn"))
+ , m_xCbFilelink(m_xBuilder->weld_check_button("linktofile"))
+ , m_xCbAsIcon(m_xBuilder->weld_check_button("asicon"))
+{
+ m_xLbObjecttype->set_size_request(m_xLbObjecttype->get_approximate_digit_width() * 32,
+ m_xLbObjecttype->get_height_rows(6));
+ m_xLbObjecttype->connect_row_activated(LINK(this, SvInsertOleDlg, DoubleClickHdl));
+ m_xBtnFilepath->connect_clicked(LINK( this, SvInsertOleDlg, BrowseHdl));
+ Link<weld::Button&,void> aLink( LINK( this, SvInsertOleDlg, RadioHdl ) );
+ m_xRbNewObject->connect_clicked( aLink );
+ m_xRbObjectFromfile->connect_clicked( aLink );
+ m_xRbNewObject->set_active(true);
+}
+
+short SvInsertOleDlg::run()
+{
+ short nRet = RET_OK;
+ SvObjectServerList aObjS;
+ if ( !m_pServers )
+ {
+ // if no list was provided, take the complete one
+ aObjS.FillInsertObjects();
+ m_pServers = &aObjS;
+ }
+
+ // fill listbox and select default
+ m_xLbObjecttype->freeze();
+ for ( sal_uLong i = 0; i < m_pServers->Count(); i++ )
+ m_xLbObjecttype->append_text((*m_pServers)[i].GetHumanName());
+ m_xLbObjecttype->thaw();
+ m_xLbObjecttype->select(0);
+ OUString aName;
+
+ DBG_ASSERT( m_xStorage.is(), "No storage!");
+ if ( m_xStorage.is() && ( nRet = InsertObjectDialog_Impl::run() ) == RET_OK )
+ {
+ OUString aFileName;
+ bool bCreateNew = IsCreateNew();
+ if ( bCreateNew )
+ {
+ // create and insert new embedded object
+ OUString aServerName = m_xLbObjecttype->get_selected_text();
+ const SvObjectServer* pS = m_pServers->Get( aServerName );
+ if ( pS )
+ {
+ if( pS->GetClassName() == SvGlobalName( SO3_OUT_CLASSID ) )
+ {
+ try
+ {
+ uno::Reference < embed::XInsertObjectDialog > xDialogCreator(
+ embed::MSOLEObjectSystemCreator::create( ::comphelper::getProcessComponentContext() ),
+ uno::UNO_QUERY );
+
+ if ( xDialogCreator.is() )
+ {
+ aName = aCnt.CreateUniqueObjectName();
+ const embed::InsertedObjectInfo aNewInf = xDialogCreator->createInstanceByDialog(
+ m_xStorage,
+ aName,
+ uno::Sequence < beans::PropertyValue >() );
+
+ OSL_ENSURE( aNewInf.Object.is(), "The object must be created or an exception must be thrown!" );
+ m_xObj = aNewInf.Object;
+ for ( const auto& opt : aNewInf.Options )
+ if ( opt.Name == "Icon" )
+ {
+ opt.Value >>= m_aIconMetaFile;
+ }
+ else if ( opt.Name == "IconFormat" )
+ {
+ datatransfer::DataFlavor aFlavor;
+ if ( opt.Value >>= aFlavor )
+ m_aIconMediaType = aFlavor.MimeType;
+ }
+
+ }
+ }
+ catch( ucb::CommandAbortedException& )
+ {
+ // the user has pressed cancel
+ }
+ catch( uno::Exception& )
+ {
+ // TODO: Error handling
+ }
+ }
+ else
+ {
+ // create object with desired ClassId
+ m_xObj = aCnt.CreateEmbeddedObject( pS->GetClassName().GetByteSequence(), aName );
+ }
+
+ if ( !m_xObj.is() )
+ {
+ if( !aFileName.isEmpty() ) // from OLE Dialog
+ {
+ // object couldn't be created from file
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE));
+ aErr = aErr.replaceFirst( "%", aFileName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ else
+ {
+ // object couldn't be created
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE));
+ aErr = aErr.replaceFirst( "%", aServerName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ }
+ }
+ }
+ else
+ {
+ aFileName = m_xEdFilepath->get_text();
+ INetURLObject aURL;
+ aURL.SetSmartProtocol( INetProtocol::File );
+ aURL.SetSmartURL( aFileName );
+ aFileName = aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ bool bLink = m_xCbFilelink->get_active();
+
+ if ( !aFileName.isEmpty() )
+ {
+ // create MediaDescriptor for file to create object from
+ uno::Sequence < beans::PropertyValue > aMedium( 2 );
+ aMedium[0].Name = "URL";
+ aMedium[0].Value <<= aFileName;
+
+ uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ uno::Reference< task::XInteractionHandler2 > xInteraction(
+ task::InteractionHandler::createWithParent(xContext, nullptr) );
+
+ aMedium[1].Name = "InteractionHandler";
+ aMedium[1].Value <<= xInteraction;
+
+ // create object from media descriptor
+ if ( bLink )
+ m_xObj = aCnt.InsertEmbeddedLink( aMedium, aName );
+ else
+ m_xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
+ }
+
+ if ( !m_xObj.is() )
+ {
+ // object couldn't be created from file
+ // global Resource from svtools (former so3 resource)
+ OUString aErr(SvtResId(STR_ERROR_OBJNOCREATE_FROM_FILE));
+ aErr = aErr.replaceFirst( "%", aFileName );
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aErr));
+ xBox->run();
+ }
+ else
+ {
+ if (m_xCbAsIcon->get_active())
+ {
+ //something nice here I guess would be to write the filename into
+ //the image with this icon above it
+ Image aImage = SvFileInformationManager::GetImage(aURL, true);
+ SvMemoryStream aTemp;
+ WriteDIBBitmapEx(aImage.GetBitmapEx(), aTemp);
+ m_aIconMetaFile = Sequence<sal_Int8>(static_cast<const sal_Int8*>(aTemp.GetData()), aTemp.TellEnd());
+ m_aIconMediaType = "application/x-openoffice-bitmap;windows_formatname=\"Bitmap\"";
+ }
+ }
+ }
+ }
+
+ m_pServers = nullptr;
+ return nRet;
+}
+
+uno::Reference< io::XInputStream > SvInsertOleDlg::GetIconIfIconified( OUString* pGraphicMediaType )
+{
+ if ( m_aIconMetaFile.hasElements() )
+ {
+ if ( pGraphicMediaType )
+ *pGraphicMediaType = m_aIconMediaType;
+
+ return uno::Reference< io::XInputStream >( new ::comphelper::SequenceInputStream( m_aIconMetaFile ) );
+ }
+
+ return uno::Reference< io::XInputStream >();
+}
+
+
+SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const css::uno::Reference < css::embed::XStorage >& xStorage)
+ : InsertObjectDialog_Impl(pParent, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
+ xStorage)
+{
+ Init();
+}
+
+SfxInsertFloatingFrameDialog::SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const uno::Reference < embed::XEmbeddedObject >& xObj)
+ : InsertObjectDialog_Impl(pParent, "cui/ui/insertfloatingframe.ui", "InsertFloatingFrameDialog",
+ uno::Reference<embed::XStorage>())
+{
+ m_xObj = xObj;
+
+ Init();
+}
+
+void SfxInsertFloatingFrameDialog::Init()
+{
+ m_xEDName = m_xBuilder->weld_entry("edname");
+ m_xEDURL = m_xBuilder->weld_entry("edurl");
+ m_xBTOpen = m_xBuilder->weld_button("buttonbrowse");
+ m_xRBScrollingOn = m_xBuilder->weld_radio_button("scrollbaron");
+ m_xRBScrollingOff = m_xBuilder->weld_radio_button("scrollbaroff");
+ m_xRBScrollingAuto = m_xBuilder->weld_radio_button("scrollbarauto");
+ m_xRBFrameBorderOn = m_xBuilder->weld_radio_button("borderon");
+ m_xRBFrameBorderOff = m_xBuilder->weld_radio_button("borderoff");
+ m_xFTMarginWidth = m_xBuilder->weld_label("widthlabel");
+ m_xNMMarginWidth = m_xBuilder->weld_spin_button("width");
+ m_xCBMarginWidthDefault = m_xBuilder->weld_check_button("defaultwidth");
+ m_xFTMarginHeight = m_xBuilder->weld_label("heightlabel");
+ m_xNMMarginHeight = m_xBuilder->weld_spin_button("height");
+ m_xCBMarginHeightDefault = m_xBuilder->weld_check_button("defaultheight");
+
+ Link<weld::Button&, void> aLink(LINK(this, SfxInsertFloatingFrameDialog, CheckHdl));
+ m_xCBMarginWidthDefault->connect_clicked(aLink);
+ m_xCBMarginHeightDefault->connect_clicked(aLink);
+
+ m_xCBMarginWidthDefault->set_active(true);
+ m_xCBMarginHeightDefault->set_active(true);
+ m_xRBScrollingAuto->set_active(true);
+ m_xRBFrameBorderOn->set_active(true);
+
+ m_xBTOpen->connect_clicked(LINK(this, SfxInsertFloatingFrameDialog, OpenHdl));
+}
+
+short SfxInsertFloatingFrameDialog::run()
+{
+ short nRet = RET_OK;
+ bool bOK = false;
+ uno::Reference < beans::XPropertySet > xSet;
+ if ( m_xObj.is() )
+ {
+ try
+ {
+ if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+ xSet.set( m_xObj->getComponent(), uno::UNO_QUERY );
+ OUString aStr;
+ uno::Any aAny = xSet->getPropertyValue( "FrameURL" );
+ if ( aAny >>= aStr )
+ m_xEDURL->set_text( aStr );
+ aAny = xSet->getPropertyValue( "FrameName" );
+ if ( aAny >>= aStr )
+ m_xEDName->set_text(aStr);
+
+ sal_Int32 nSize = SIZE_NOT_SET;
+ aAny = xSet->getPropertyValue( "FrameMarginWidth" );
+ aAny >>= nSize;
+
+ if ( nSize == SIZE_NOT_SET )
+ {
+ m_xCBMarginWidthDefault->set_active(true);
+ m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH));
+ m_xFTMarginWidth->set_sensitive(false);
+ m_xNMMarginWidth->set_sensitive(false);
+ }
+ else
+ m_xNMMarginWidth->set_text(OUString::number(nSize));
+
+ aAny = xSet->getPropertyValue( "FrameMarginHeight" );
+ aAny >>= nSize;
+
+ if ( nSize == SIZE_NOT_SET )
+ {
+ m_xCBMarginHeightDefault->set_active(true);
+ m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT));
+ m_xFTMarginHeight->set_sensitive(false);
+ m_xNMMarginHeight->set_sensitive(false);
+ }
+ else
+ m_xNMMarginHeight->set_text(OUString::number(nSize));
+
+ bool bScrollOn = false;
+ bool bScrollOff = false;
+ bool bScrollAuto = false;
+
+ bool bSet = false;
+ aAny = xSet->getPropertyValue( "FrameIsAutoScroll" );
+ aAny >>= bSet;
+ if ( !bSet )
+ {
+ aAny = xSet->getPropertyValue( "FrameIsScrollingMode" );
+ aAny >>= bSet;
+ bScrollOn = bSet;
+ bScrollOff = !bSet;
+ }
+ else
+ bScrollAuto = true;
+
+ m_xRBScrollingOn->set_sensitive(bScrollOn);
+ m_xRBScrollingOff->set_sensitive(bScrollOff);
+ m_xRBScrollingAuto->set_sensitive(bScrollAuto);
+
+ bSet = false;
+ aAny = xSet->getPropertyValue( "FrameIsAutoBorder" );
+ aAny >>= bSet;
+ if ( !bSet )
+ {
+ aAny = xSet->getPropertyValue( "FrameIsBorder" );
+ aAny >>= bSet;
+ m_xRBFrameBorderOn->set_active(bSet);
+ m_xRBFrameBorderOff->set_active(!bSet);
+ }
+
+ bOK = true;
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL( "No IFrame!" );
+ }
+ }
+ else
+ {
+ DBG_ASSERT( m_xStorage.is(), "No storage!");
+ bOK = m_xStorage.is();
+ }
+
+ if (!bOK)
+ return RET_OK;
+
+ nRet = InsertObjectDialog_Impl::run();
+ if ( nRet == RET_OK )
+ {
+ OUString aURL;
+ if (!m_xEDURL->get_text().isEmpty())
+ {
+ // URL can be a valid and absolute URL or a system file name
+ INetURLObject aObj;
+ aObj.SetSmartProtocol( INetProtocol::File );
+ if ( aObj.SetSmartURL( m_xEDURL->get_text() ) )
+ aURL = aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ }
+
+ if ( !m_xObj.is() && !aURL.isEmpty() )
+ {
+ // create the object
+ OUString aName;
+ SvGlobalName aClassId( SO3_IFRAME_CLASSID );
+ m_xObj = aCnt.CreateEmbeddedObject( aClassId.GetByteSequence(), aName );
+ if ( m_xObj->getCurrentState() == embed::EmbedStates::LOADED )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+ xSet.set( m_xObj->getComponent(), uno::UNO_QUERY );
+ }
+
+ if ( m_xObj.is() )
+ {
+ try
+ {
+ bool bIPActive = m_xObj->getCurrentState() == embed::EmbedStates::INPLACE_ACTIVE;
+ if ( bIPActive )
+ m_xObj->changeState( embed::EmbedStates::RUNNING );
+
+ OUString aName = m_xEDName->get_text();
+ ScrollingMode eScroll = ScrollingMode::No;
+ if (m_xRBScrollingOn->get_active())
+ eScroll = ScrollingMode::Yes;
+ if (m_xRBScrollingOff->get_active())
+ eScroll = ScrollingMode::No;
+ if (m_xRBScrollingAuto->get_active())
+ eScroll = ScrollingMode::Auto;
+
+ bool bHasBorder = m_xRBFrameBorderOn->get_active();
+
+ long lMarginWidth;
+ if (!m_xCBMarginWidthDefault->get_active())
+ lMarginWidth = static_cast<long>(m_xNMMarginWidth->get_text().toInt32());
+ else
+ lMarginWidth = SIZE_NOT_SET;
+
+ long lMarginHeight;
+ if (!m_xCBMarginHeightDefault->get_active())
+ lMarginHeight = static_cast<long>(m_xNMMarginHeight->get_text().toInt32());
+ else
+ lMarginHeight = SIZE_NOT_SET;
+
+ xSet->setPropertyValue( "FrameURL", Any( aURL ) );
+ xSet->setPropertyValue( "FrameName", Any( aName ) );
+
+ if ( eScroll == ScrollingMode::Auto )
+ xSet->setPropertyValue( "FrameIsAutoScroll", Any( true ) );
+ else
+ xSet->setPropertyValue( "FrameIsScrollingMode", Any( eScroll == ScrollingMode::Yes ) );
+
+ xSet->setPropertyValue( "FrameIsBorder", Any( bHasBorder ) );
+ xSet->setPropertyValue( "FrameMarginWidth", Any( sal_Int32( lMarginWidth ) ) );
+ xSet->setPropertyValue( "FrameMarginHeight", Any( sal_Int32( lMarginHeight ) ) );
+
+ if ( bIPActive )
+ m_xObj->changeState( embed::EmbedStates::INPLACE_ACTIVE );
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL( "No IFrame!" );
+ }
+ }
+ }
+
+ return nRet;
+}
+
+IMPL_LINK(SfxInsertFloatingFrameDialog, CheckHdl, weld::Button&, rButton, void)
+{
+ weld::CheckButton& rCB = dynamic_cast<weld::CheckButton&>(rButton);
+ if (&rCB == m_xCBMarginWidthDefault.get())
+ {
+ if (rCB.get_active())
+ m_xNMMarginWidth->set_text(OUString::number(DEFAULT_MARGIN_WIDTH));
+ m_xFTMarginWidth->set_sensitive(!rCB.get_active());
+ m_xNMMarginWidth->set_sensitive(!rCB.get_active());
+ }
+
+ if (&rCB == m_xCBMarginHeightDefault.get())
+ {
+ if (rCB.get_active())
+ m_xNMMarginHeight->set_text(OUString::number(DEFAULT_MARGIN_HEIGHT));
+ m_xFTMarginHeight->set_sensitive(!rCB.get_active());
+ m_xNMMarginHeight->set_sensitive(!rCB.get_active());
+ }
+}
+
+IMPL_LINK_NOARG( SfxInsertFloatingFrameDialog, OpenHdl, weld::Button&, void)
+{
+ // create the file dialog
+ sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, OUString(),
+ SfxFilterFlags::NONE, SfxFilterFlags::NONE, m_xDialog.get());
+
+ // set the title
+ aFileDlg.SetTitle(CuiResId(RID_SVXSTR_SELECT_FILE_IFRAME));
+
+ // show the dialog
+ if ( aFileDlg.Execute() == ERRCODE_NONE )
+ m_xEDURL->set_text(INetURLObject(aFileDlg.GetPath()).GetMainURL(INetURLObject::DecodeMechanism::WithCharset));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/insrc.cxx b/cui/source/dialogs/insrc.cxx
new file mode 100644
index 000000000..862963275
--- /dev/null
+++ b/cui/source/dialogs/insrc.cxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <insrc.hxx>
+
+bool SvxInsRowColDlg::isInsertBefore() const
+{
+ return !m_xAfterBtn->get_active();
+}
+
+sal_uInt16 SvxInsRowColDlg::getInsertCount() const
+{
+ return m_xCountEdit->get_value();
+}
+
+SvxInsRowColDlg::SvxInsRowColDlg(weld::Window* pParent, bool bColumn, const OString& rHelpId)
+ : GenericDialogController(pParent, "cui/ui/insertrowcolumn.ui", "InsertRowColumnDialog")
+ , m_xCountEdit(m_xBuilder->weld_spin_button("insert_number"))
+ , m_xBeforeBtn(m_xBuilder->weld_radio_button("insert_before"))
+ , m_xAfterBtn(m_xBuilder->weld_radio_button("insert_after"))
+{
+ m_xDialog->set_title(bColumn ? CuiResId(RID_SVXSTR_COL) : CuiResId(RID_SVXSTR_ROW));
+
+ // tdf#119293
+ if (bColumn) {
+ m_xBeforeBtn->set_label(CuiResId(RID_SVXSTR_INSERTCOL_BEFORE));
+ m_xAfterBtn->set_label(CuiResId(RID_SVXSTR_INSERTCOL_AFTER));
+ } else {
+ m_xBeforeBtn->set_label(CuiResId(RID_SVXSTR_INSERTROW_BEFORE));
+ m_xAfterBtn->set_label(CuiResId(RID_SVXSTR_INSERTROW_AFTER));
+ }
+
+ m_xDialog->set_help_id(rHelpId);
+}
+
+short SvxInsRowColDlg::Execute()
+{
+ return run();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/linkdlg.cxx b/cui/source/dialogs/linkdlg.cxx
new file mode 100644
index 000000000..764d29e0c
--- /dev/null
+++ b/cui/source/dialogs/linkdlg.cxx
@@ -0,0 +1,636 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <linkdlg.hxx>
+#include <vcl/svapp.hxx>
+
+#include <tools/diagnose_ex.h>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/window.hxx>
+
+#include <strings.hrc>
+#include <sfx2/linkmgr.hxx>
+#include <sfx2/linksrc.hxx>
+#include <sfx2/lnkbase.hxx>
+#include <sfx2/objsh.hxx>
+
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <comphelper/processfactory.hxx>
+
+#include <dialmgr.hxx>
+
+
+using namespace sfx2;
+using namespace ::com::sun::star;
+
+namespace {
+
+class SvBaseLinkMemberList {
+private:
+ std::vector<SvBaseLink*> mLinks;
+
+public:
+ ~SvBaseLinkMemberList()
+ {
+ for (auto const& link : mLinks)
+ {
+ if( link )
+ link->ReleaseRef();
+ }
+ }
+
+ size_t size() const { return mLinks.size(); }
+
+ SvBaseLink *operator[](size_t i) const { return mLinks[i]; }
+
+ void push_back(SvBaseLink* p)
+ {
+ mLinks.push_back(p);
+ p->AddFirstRef();
+ }
+};
+
+}
+
+SvBaseLinksDlg::SvBaseLinksDlg(weld::Window * pParent, LinkManager* pMgr, bool bHtmlMode)
+ : GenericDialogController(pParent, "cui/ui/baselinksdialog.ui", "BaseLinksDialog")
+ , aStrAutolink( CuiResId( STR_AUTOLINK ) )
+ , aStrManuallink( CuiResId( STR_MANUALLINK ) )
+ , aStrBrokenlink( CuiResId( STR_BROKENLINK ) )
+ , aStrCloselinkmsg( CuiResId( STR_CLOSELINKMSG ) )
+ , aStrCloselinkmsgMulti( CuiResId( STR_CLOSELINKMSG_MULTI ) )
+ , aStrWaitinglink( CuiResId( STR_WAITINGLINK ) )
+ , pLinkMgr( nullptr )
+ , aUpdateIdle("cui SvBaseLinksDlg UpdateIdle")
+ , m_xTbLinks(m_xBuilder->weld_tree_view("TB_LINKS"))
+ , m_xFtFullFileName(m_xBuilder->weld_link_button("FULL_FILE_NAME"))
+ , m_xFtFullSourceName(m_xBuilder->weld_label("FULL_SOURCE_NAME"))
+ , m_xFtFullTypeName(m_xBuilder->weld_label("FULL_TYPE_NAME"))
+ , m_xRbAutomatic(m_xBuilder->weld_radio_button("AUTOMATIC"))
+ , m_xRbManual(m_xBuilder->weld_radio_button("MANUAL"))
+ , m_xPbUpdateNow(m_xBuilder->weld_button("UPDATE_NOW"))
+ , m_xPbChangeSource(m_xBuilder->weld_button("CHANGE_SOURCE"))
+ , m_xPbBreakLink(m_xBuilder->weld_button("BREAK_LINK"))
+ , m_xVirDev(VclPtr<VirtualDevice>::Create())
+{
+ // expand the point size of the desired font to the equivalent pixel size
+ if (vcl::Window* pDefaultDevice = dynamic_cast<vcl::Window*>(Application::GetDefaultDevice()))
+ pDefaultDevice->SetPointFont(*m_xVirDev, m_xTbLinks->get_font());
+ m_xTbLinks->set_size_request(m_xTbLinks->get_approximate_digit_width() * 90,
+ m_xTbLinks->get_height_rows(12));
+
+ m_xTbLinks->set_selection_mode(SelectionMode::Multiple);
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 30);
+ aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 20);
+ aWidths.push_back(m_xTbLinks->get_approximate_digit_width() * 20);
+ m_xTbLinks->set_column_fixed_widths(aWidths);
+
+ // UpdateTimer for DDE-/Grf-links, which are waited for
+ aUpdateIdle.SetInvokeHandler( LINK( this, SvBaseLinksDlg, UpdateWaitingHdl ) );
+ aUpdateIdle.SetPriority( TaskPriority::LOWEST );
+
+ m_xTbLinks->connect_changed( LINK( this, SvBaseLinksDlg, LinksSelectHdl ) );
+ m_xTbLinks->connect_row_activated( LINK( this, SvBaseLinksDlg, LinksDoubleClickHdl ) );
+ m_xRbAutomatic->connect_clicked( LINK( this, SvBaseLinksDlg, AutomaticClickHdl ) );
+ m_xRbManual->connect_clicked( LINK( this, SvBaseLinksDlg, ManualClickHdl ) );
+ m_xPbUpdateNow->connect_clicked( LINK( this, SvBaseLinksDlg, UpdateNowClickHdl ) );
+ m_xPbChangeSource->connect_clicked( LINK( this, SvBaseLinksDlg, ChangeSourceClickHdl ) );
+ if(!bHtmlMode)
+ m_xPbBreakLink->connect_clicked( LINK( this, SvBaseLinksDlg, BreakLinkClickHdl ) );
+ else
+ m_xPbBreakLink->hide();
+
+ SetManager( pMgr );
+}
+
+SvBaseLinksDlg::~SvBaseLinksDlg()
+{
+}
+
+/*************************************************************************
+|* SvBaseLinksDlg::Handler()
+*************************************************************************/
+IMPL_LINK(SvBaseLinksDlg, LinksSelectHdl, weld::TreeView&, rTreeView, void)
+{
+ LinksSelectHdl(&rTreeView);
+}
+
+void SvBaseLinksDlg::LinksSelectHdl(weld::TreeView* pSvTabListBox)
+{
+ const int nSelectionCount = pSvTabListBox ?
+ pSvTabListBox->count_selected_rows() : 0;
+ if (nSelectionCount > 1)
+ {
+ // possibly deselect old entries in case of multi-selection
+ int nSelEntry = pSvTabListBox->get_selected_index();
+ SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(pSvTabListBox->get_id(nSelEntry).toInt64());
+ SvBaseLinkObjectType nObjectType = pLink->GetObjType();
+ if(!isClientFileType(nObjectType))
+ {
+ pSvTabListBox->unselect_all();
+ pSvTabListBox->select(nSelEntry);
+ }
+ else
+ {
+ std::vector<int> aRows = pSvTabListBox->get_selected_rows();
+ for (auto nEntry : aRows)
+ {
+ pLink = reinterpret_cast<SvBaseLink*>(pSvTabListBox->get_id(nEntry).toInt64());
+ DBG_ASSERT(pLink, "Where is the Link?");
+ if (!pLink)
+ continue;
+ if( !isClientFileType(pLink->GetObjType()) )
+ pSvTabListBox->unselect(nEntry);
+ }
+ }
+
+ m_xPbUpdateNow->set_sensitive(true);
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_active(true);
+ m_xRbManual->set_sensitive(false);
+ }
+ else
+ {
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if( !pLink )
+ return;
+
+ m_xPbUpdateNow->set_sensitive(true);
+
+ OUString sType, sLink;
+ OUString *pLinkNm = &sLink, *pFilter = nullptr;
+
+ if( isClientFileType(pLink->GetObjType()) )
+ {
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_active(true);
+ m_xRbManual->set_sensitive(false);
+ if( SvBaseLinkObjectType::ClientGraphic == pLink->GetObjType() )
+ {
+ pLinkNm = nullptr;
+ pFilter = &sLink;
+ }
+ }
+ else
+ {
+ m_xRbAutomatic->set_sensitive(true);
+ m_xRbManual->set_sensitive(true);
+
+ if( SfxLinkUpdateMode::ALWAYS == pLink->GetUpdateMode() )
+ m_xRbAutomatic->set_active(true);
+ else
+ m_xRbManual->set_active(true);
+ }
+
+ OUString aFileName;
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &aFileName, pLinkNm, pFilter );
+ aFileName = INetURLObject::decode(aFileName, INetURLObject::DecodeMechanism::Unambiguous);
+ m_xFtFullFileName->set_label( aFileName );
+ m_xFtFullFileName->set_uri( aFileName );
+ m_xFtFullSourceName->set_label( sLink );
+ m_xFtFullTypeName->set_label( sType );
+ }
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, LinksDoubleClickHdl, weld::TreeView&, bool )
+{
+ ChangeSourceClickHdl(*m_xPbChangeSource);
+ return true;
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, AutomaticClickHdl, weld::Button&, void )
+{
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if( pLink && !isClientFileType( pLink->GetObjType() ) &&
+ SfxLinkUpdateMode::ALWAYS != pLink->GetUpdateMode() )
+ SetType( *pLink, nPos, SfxLinkUpdateMode::ALWAYS );
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, ManualClickHdl, weld::Button&, void )
+{
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if( pLink && !isClientFileType( pLink->GetObjType() ) &&
+ SfxLinkUpdateMode::ONCALL != pLink->GetUpdateMode())
+ SetType( *pLink, nPos, SfxLinkUpdateMode::ONCALL );
+}
+
+IMPL_LINK_NOARG(SvBaseLinksDlg, UpdateNowClickHdl, weld::Button&, void)
+{
+ std::vector< SvBaseLink* > aLnkArr;
+ std::vector< sal_Int16 > aPosArr;
+
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ for (int nFndPos : aRows)
+ {
+ aLnkArr.push_back( reinterpret_cast<SvBaseLink*>( m_xTbLinks->get_id(nFndPos).toInt64() ) );
+ aPosArr.push_back( nFndPos );
+ }
+
+ if( aLnkArr.empty() )
+ return;
+
+ for( size_t n = 0; n < aLnkArr.size(); ++n )
+ {
+ tools::SvRef<SvBaseLink> xLink = aLnkArr[ n ];
+
+ // first look for the entry in the array
+ for(const auto & i : pLinkMgr->GetLinks())
+ if( xLink == i )
+ {
+ SetType( *xLink, aPosArr[ n ], xLink->GetUpdateMode() );
+ break;
+ }
+ }
+
+ // if somebody is of the opinion to swap his links (SD)
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+
+
+ OUString sId = OUString::number(reinterpret_cast<sal_Int64>(aLnkArr[0]));
+ int nE = m_xTbLinks->find_id(sId);
+ if (nE == -1)
+ nE = m_xTbLinks->get_selected_index();
+ int nSelEntry = m_xTbLinks->get_selected_index();
+ if (nE != nSelEntry)
+ m_xTbLinks->unselect(nSelEntry);
+ m_xTbLinks->select(nE);
+ m_xTbLinks->scroll_to_row(nE);
+
+ pNewMgr->CloseCachedComps();
+}
+
+IMPL_LINK_NOARG(SvBaseLinksDlg, ChangeSourceClickHdl, weld::Button&, void)
+{
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ if (aRows.size() > 1)
+ {
+ try
+ {
+ uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = ui::dialogs::FolderPicker::create(comphelper::getProcessComponentContext());
+
+ OUString sType, sFile, sLinkName;
+ OUString sFilter;
+ SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(aRows[0]).toInt64());
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile );
+ INetURLObject aUrl(sFile);
+ if(aUrl.GetProtocol() == INetProtocol::File)
+ {
+ OUString sOldPath(aUrl.PathToFileName());
+ sal_Int32 nLen = aUrl.GetLastName().getLength();
+ sOldPath = sOldPath.copy(0, sOldPath.getLength() - nLen);
+ xFolderPicker->setDisplayDirectory(sOldPath);
+ }
+ if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ OUString aPath = xFolderPicker->getDirectory();
+
+ for (auto nRow : aRows)
+ {
+ pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nRow).toInt64());
+ DBG_ASSERT(pLink,"Where is the link?");
+ if (!pLink)
+ continue;
+ sfx2::LinkManager::GetDisplayNames( pLink, &sType, &sFile, &sLinkName, &sFilter );
+ INetURLObject aUrl_(sFile);
+ INetURLObject aUrl2(aPath, INetProtocol::File);
+ aUrl2.insertName( aUrl_.getName() );
+ OUString sNewLinkName;
+ MakeLnkName( sNewLinkName, nullptr ,
+ aUrl2.GetMainURL(INetURLObject::DecodeMechanism::ToIUri), sLinkName, &sFilter);
+ pLink->SetLinkSourceName( sNewLinkName );
+ pLink->Update();
+ }
+ if( pLinkMgr->GetPersist() )
+ pLinkMgr->GetPersist()->SetModified();
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "SvBaseLinksDlg");
+ }
+ }
+ else
+ {
+ int nPos;
+ SvBaseLink* pLink = GetSelEntry( &nPos );
+ if ( pLink && !pLink->GetLinkSourceName().isEmpty() )
+ pLink->Edit(m_xDialog.get(), LINK(this, SvBaseLinksDlg, EndEditHdl));
+ }
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, BreakLinkClickHdl, weld::Button&, void )
+{
+ bool bModified = false;
+ if (m_xTbLinks->count_selected_rows() <= 1)
+ {
+ int nPos;
+ tools::SvRef<SvBaseLink> xLink = GetSelEntry( &nPos );
+ if( !xLink.is() )
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ aStrCloselinkmsg));
+ xQueryBox->set_default_response(RET_YES);
+
+ if (RET_YES == xQueryBox->run())
+ {
+ m_xTbLinks->remove(nPos);
+
+ // close object, if it's still existing
+ bool bNewLnkMgr = SvBaseLinkObjectType::ClientFile == xLink->GetObjType();
+
+ // tell the link that it will be resolved!
+ xLink->Closed();
+
+ // if somebody has forgotten to deregister himself
+ if( xLink.is() )
+ pLinkMgr->Remove( xLink.get() );
+
+ if( bNewLnkMgr )
+ {
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ m_xTbLinks->set_cursor(nPos ? --nPos : 0);
+ }
+ bModified = true;
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ aStrCloselinkmsgMulti));
+ xQueryBox->set_default_response(RET_YES);
+
+ if (RET_YES == xQueryBox->run())
+ {
+ std::vector<int> aRows = m_xTbLinks->get_selected_rows();
+ SvBaseLinkMemberList aLinkList;
+ for (auto nRow : aRows)
+ {
+ SvBaseLink* pLink = reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nRow).toInt64());
+ if (pLink)
+ aLinkList.push_back(pLink);
+ }
+ std::sort(aRows.begin(), aRows.end());
+ for (auto it = aRows.rbegin(); it != aRows.rend(); ++it)
+ m_xTbLinks->remove(*it);
+ for (size_t i = 0; i < aLinkList.size(); ++i)
+ {
+ tools::SvRef<SvBaseLink> xLink = aLinkList[i];
+ // tell the link that it will be resolved!
+ xLink->Closed();
+
+ // if somebody has forgotten to deregister himself
+ pLinkMgr->Remove( xLink.get() );
+ bModified = true;
+ }
+ // then remove all selected entries
+ }
+ }
+ if(!bModified)
+ return;
+
+ if (!m_xTbLinks->n_children())
+ {
+ m_xRbAutomatic->set_sensitive(false);
+ m_xRbManual->set_sensitive(false);
+ m_xPbUpdateNow->set_sensitive(false);
+ m_xPbChangeSource->set_sensitive(false);
+ m_xPbBreakLink->set_sensitive(false);
+
+ m_xFtFullSourceName->set_label( "" );
+ m_xFtFullTypeName->set_label( "" );
+ }
+ if( pLinkMgr && pLinkMgr->GetPersist() )
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+IMPL_LINK_NOARG( SvBaseLinksDlg, UpdateWaitingHdl, Timer*, void )
+{
+ m_xTbLinks->freeze();
+ for (int nPos = m_xTbLinks->n_children(); nPos; --nPos)
+ {
+ tools::SvRef<SvBaseLink> xLink( reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nPos).toInt64()) );
+ if( xLink.is() )
+ {
+ OUString sCur( ImplGetStateStr( *xLink ) ),
+ sOld( m_xTbLinks->get_text(nPos, 3) );
+ if( sCur != sOld )
+ m_xTbLinks->set_text(nPos, sCur, 3);
+ }
+ }
+ m_xTbLinks->thaw();
+}
+
+IMPL_LINK( SvBaseLinksDlg, EndEditHdl, sfx2::SvBaseLink&, _rLink, void )
+{
+ int nPos;
+ GetSelEntry( &nPos );
+
+ if( !_rLink.WasLastEditOK() )
+ return;
+
+ // StarImpress/Draw swap the LinkObjects themselves!
+ // So search for the link in the manager; if it does not exist
+ // anymore, fill the list completely new. Otherwise only the
+ // edited link needs to be refreshed.
+ bool bLinkFnd = false;
+ for( size_t n = pLinkMgr->GetLinks().size(); n; )
+ if( &_rLink == &(*pLinkMgr->GetLinks()[ --n ]) )
+ {
+ bLinkFnd = true;
+ break;
+ }
+
+ if( bLinkFnd )
+ {
+ m_xTbLinks->remove(nPos);
+ int nToUnselect = m_xTbLinks->get_selected_index();
+ InsertEntry(_rLink, nPos, true);
+ if (nToUnselect != -1)
+ m_xTbLinks->unselect(nToUnselect);
+ }
+ else
+ {
+ LinkManager* pNewMgr = pLinkMgr;
+ pLinkMgr = nullptr;
+ SetManager( pNewMgr );
+ }
+ if (pLinkMgr && pLinkMgr->GetPersist())
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+OUString SvBaseLinksDlg::ImplGetStateStr( const SvBaseLink& rLnk )
+{
+ OUString sRet;
+ if( !rLnk.GetObj() )
+ sRet = aStrBrokenlink;
+ else if( rLnk.GetObj()->IsPending() )
+ {
+ sRet = aStrWaitinglink;
+ aUpdateIdle.Start();
+ }
+ else if( SfxLinkUpdateMode::ALWAYS == rLnk.GetUpdateMode() )
+ sRet = aStrAutolink;
+ else
+ sRet = aStrManuallink;
+
+ return sRet;
+}
+
+void SvBaseLinksDlg::SetManager( LinkManager* pNewMgr )
+{
+ if( pLinkMgr == pNewMgr )
+ return;
+
+ if (pNewMgr)
+ {
+ // update has to be stopped before clear
+ m_xTbLinks->freeze();
+ }
+
+ m_xTbLinks->clear();
+ pLinkMgr = pNewMgr;
+
+ if( !pLinkMgr )
+ return;
+
+ SvBaseLinks& rLnks = const_cast<SvBaseLinks&>(pLinkMgr->GetLinks());
+ for( size_t n = 0; n < rLnks.size(); ++n )
+ {
+ tools::SvRef<SvBaseLink>& rLinkRef = rLnks[ n ];
+ if( !rLinkRef.is() )
+ {
+ rLnks.erase( rLnks.begin() + n );
+ --n;
+ continue;
+ }
+ if( rLinkRef->IsVisible() )
+ InsertEntry( *rLinkRef );
+ }
+
+ m_xTbLinks->thaw();
+
+ if( !rLnks.empty() )
+ {
+ m_xTbLinks->set_cursor(0);
+ m_xTbLinks->select(0);
+ LinksSelectHdl( nullptr );
+ }
+}
+
+void SvBaseLinksDlg::InsertEntry(const SvBaseLink& rLink, int nPos, bool bSelect)
+{
+ OUString sFileNm, sLinkNm, sTypeNm, sFilter;
+
+ sfx2::LinkManager::GetDisplayNames( &rLink, &sTypeNm, &sFileNm, &sLinkNm, &sFilter );
+
+ auto nWidthPixel = m_xTbLinks->get_column_width(0);
+ OUString aTxt = m_xVirDev->GetEllipsisString(sFileNm, nWidthPixel, DrawTextFlags::PathEllipsis);
+ INetURLObject aPath( sFileNm, INetProtocol::File );
+ OUString aFileName = aPath.getName(
+ INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::Unambiguous);
+
+ if( aFileName.getLength() > aTxt.getLength() )
+ aTxt = aFileName;
+ else if (!aFileName.isEmpty() && aTxt.indexOf(aFileName, aTxt.getLength() - aFileName.getLength()) == -1)
+ // filename not in string
+ aTxt = aFileName;
+
+ if (nPos == -1)
+ nPos = m_xTbLinks->n_children();
+ m_xTbLinks->insert(nPos);
+ m_xTbLinks->set_text(nPos, aTxt, 0);
+ m_xTbLinks->set_id(nPos, OUString::number(reinterpret_cast<sal_Int64>(&rLink)));
+ if( SvBaseLinkObjectType::ClientGraphic == rLink.GetObjType() )
+ m_xTbLinks->set_text(nPos, sFilter, 1);
+ else
+ m_xTbLinks->set_text(nPos, sLinkNm, 1);
+ m_xTbLinks->set_text(nPos, sTypeNm, 2);
+ m_xTbLinks->set_text(nPos, ImplGetStateStr(rLink), 3);
+ if (bSelect)
+ m_xTbLinks->select(nPos);
+}
+
+SvBaseLink* SvBaseLinksDlg::GetSelEntry(int* pPos)
+{
+ int nPos = m_xTbLinks->get_selected_index();
+ if (nPos != -1)
+ {
+ if (pPos)
+ *pPos = nPos;
+ return reinterpret_cast<SvBaseLink*>(m_xTbLinks->get_id(nPos).toInt64());
+ }
+ return nullptr;
+}
+
+void SvBaseLinksDlg::SetType(SvBaseLink& rLink,
+ int nSelPos,
+ SfxLinkUpdateMode nType)
+{
+ rLink.SetUpdateMode( nType );
+ rLink.Update();
+ m_xTbLinks->set_text(nSelPos, ImplGetStateStr(rLink), 3);
+ if (pLinkMgr->GetPersist())
+ pLinkMgr->GetPersist()->SetModified();
+}
+
+void SvBaseLinksDlg::SetActLink( SvBaseLink const * pLink )
+{
+ if( !pLinkMgr )
+ return;
+
+ const SvBaseLinks& rLnks = pLinkMgr->GetLinks();
+ int nSelect = 0;
+ for(const auto & rLinkRef : rLnks)
+ {
+ // #109573# only visible links have been inserted into the TreeListBox,
+ // invisible ones have to be skipped here
+ if( rLinkRef->IsVisible() )
+ {
+ if( pLink == rLinkRef.get() )
+ {
+ m_xTbLinks->select(nSelect);
+ LinksSelectHdl( nullptr );
+ return ;
+ }
+ ++nSelect;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/multipat.cxx b/cui/source/dialogs/multipat.cxx
new file mode 100644
index 000000000..48dc545f9
--- /dev/null
+++ b/cui/source/dialogs/multipat.cxx
@@ -0,0 +1,320 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <multipat.hxx>
+#include <dialmgr.hxx>
+
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+
+#include <unotools/pathoptions.hxx>
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, SelectHdl_Impl, weld::TreeView&, void)
+{
+ auto nCount = m_xRadioLB->n_children();
+ bool bIsSelected = m_xRadioLB->get_selected_index() != -1;
+ bool bEnable = nCount > 1;
+ m_xDelBtn->set_sensitive(bEnable && bIsSelected);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, SelectHdl_Impl, weld::TreeView&, void)
+{
+ auto nCount = m_xPathLB->n_children();
+ bool bIsSelected = m_xPathLB->get_selected_index() != -1;
+ bool bEnable = nCount > 1;
+ m_xDelBtn->set_sensitive(bEnable && bIsSelected);
+}
+
+void SvxMultiPathDialog::HandleEntryChecked(int nRow)
+{
+ m_xRadioLB->select(nRow);
+ bool bChecked = m_xRadioLB->get_toggle(nRow, 0) == TRISTATE_TRUE;
+ if (bChecked)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ int nCount = m_xRadioLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (i != nRow)
+ m_xRadioLB->set_toggle(i, TRISTATE_FALSE, 0);
+ }
+ }
+}
+
+IMPL_LINK(SvxMultiPathDialog, CheckHdl_Impl, const row_col&, rRowCol, void)
+{
+ HandleEntryChecked(rRowCol.first);
+}
+
+void SvxMultiPathDialog::AppendEntry(const OUString& rText, const OUString& rId)
+{
+ m_xRadioLB->append();
+ const int nRow = m_xRadioLB->n_children() - 1;
+ m_xRadioLB->set_toggle(nRow, TRISTATE_FALSE, 0);
+ m_xRadioLB->set_text(nRow, rText, 1);
+ m_xRadioLB->set_id(nRow, rId);
+}
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, AddHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
+
+ if ( xFolderPicker->execute() != ExecutableDialogResults::OK )
+ return;
+
+ INetURLObject aPath( xFolderPicker->getDirectory() );
+ aPath.removeFinalSlash();
+ OUString aURL = aPath.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ OUString sInsPath;
+ osl::FileBase::getSystemPathFromFileURL(aURL, sInsPath);
+
+ if (m_xRadioLB->find_text(sInsPath) != -1)
+ {
+ OUString sMsg( CuiResId( RID_MULTIPATH_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sInsPath );
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xInfoBox->run();
+ }
+ else
+ {
+ AppendEntry(sInsPath, aURL);
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, AddHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
+
+ if ( xFolderPicker->execute() != ExecutableDialogResults::OK )
+ return;
+
+ INetURLObject aPath( xFolderPicker->getDirectory() );
+ aPath.removeFinalSlash();
+ OUString aURL = aPath.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+ OUString sInsPath;
+ osl::FileBase::getSystemPathFromFileURL(aURL, sInsPath);
+
+ if (m_xPathLB->find_text(sInsPath) != -1)
+ {
+ OUString sMsg( CuiResId( RID_MULTIPATH_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sInsPath );
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xInfoBox->run();
+ }
+ else
+ {
+ m_xPathLB->append(aURL, sInsPath);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+IMPL_LINK_NOARG(SvxMultiPathDialog, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xRadioLB->get_selected_index();
+ bool bChecked = m_xRadioLB->get_toggle(nPos, 0) == TRISTATE_TRUE;
+ m_xRadioLB->remove(nPos);
+ int nCnt = m_xRadioLB->n_children();
+ if (nCnt)
+ {
+ --nCnt;
+
+ if ( nPos > nCnt )
+ nPos = nCnt;
+ if (bChecked)
+ {
+ m_xRadioLB->set_toggle(nPos, TRISTATE_TRUE, 0);
+ HandleEntryChecked(nPos);
+ }
+ m_xRadioLB->select(nPos);
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+IMPL_LINK_NOARG(SvxPathSelectDialog, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xPathLB->get_selected_index();
+ m_xPathLB->remove(nPos);
+ int nCnt = m_xPathLB->n_children();
+
+ if (nCnt)
+ {
+ --nCnt;
+
+ if ( nPos > nCnt )
+ nPos = nCnt;
+ m_xPathLB->select(nPos);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+SvxMultiPathDialog::SvxMultiPathDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/multipathdialog.ui", "MultiPathDialog")
+ , m_xRadioLB(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+{
+ m_xRadioLB->set_size_request(m_xRadioLB->get_approximate_digit_width() * 60,
+ m_xRadioLB->get_text_height() * 10);
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xRadioLB->get_checkbox_column_width());
+ m_xRadioLB->set_column_fixed_widths(aWidths);
+
+ std::vector<int> aRadioColumns;
+ aRadioColumns.push_back(0);
+ m_xRadioLB->set_toggle_columns_as_radio(aRadioColumns);
+ m_xRadioLB->connect_toggled(LINK(this, SvxMultiPathDialog, CheckHdl_Impl));
+ m_xRadioLB->connect_changed(LINK(this, SvxMultiPathDialog, SelectHdl_Impl));
+ m_xAddBtn->connect_clicked(LINK(this, SvxMultiPathDialog, AddHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this, SvxMultiPathDialog, DelHdl_Impl));
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+SvxPathSelectDialog::SvxPathSelectDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/selectpathdialog.ui", "SelectPathDialog")
+ , m_xPathLB(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDelBtn(m_xBuilder->weld_button("delete"))
+{
+ m_xPathLB->set_size_request(m_xPathLB->get_approximate_digit_width() * 60,
+ m_xPathLB->get_text_height() * 10);
+
+ m_xPathLB->connect_changed(LINK(this, SvxPathSelectDialog, SelectHdl_Impl));
+ m_xAddBtn->connect_clicked(LINK(this, SvxPathSelectDialog, AddHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this, SvxPathSelectDialog, DelHdl_Impl));
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+SvxMultiPathDialog::~SvxMultiPathDialog()
+{
+}
+
+OUString SvxMultiPathDialog::GetPath() const
+{
+ OUStringBuffer sNewPath;
+ sal_Unicode cDelim = SVT_SEARCHPATH_DELIMITER;
+
+ OUString sWritable;
+ for (int i = 0, nCount = m_xRadioLB->n_children(); i < nCount; ++i)
+ {
+ if (m_xRadioLB->get_toggle(i, 0) == TRISTATE_TRUE)
+ sWritable = m_xRadioLB->get_id(i);
+ else
+ {
+ if (!sNewPath.isEmpty())
+ sNewPath.append(cDelim);
+ sNewPath.append(m_xRadioLB->get_id(i));
+ }
+ }
+ if (!sNewPath.isEmpty())
+ sNewPath.append(cDelim);
+ sNewPath.append(sWritable);
+
+ return sNewPath.makeStringAndClear();
+}
+
+OUString SvxPathSelectDialog::GetPath() const
+{
+ OUStringBuffer sNewPath;
+
+ for (int i = 0; i < m_xPathLB->n_children(); ++i)
+ {
+ if ( !sNewPath.isEmpty() )
+ sNewPath.append(SVT_SEARCHPATH_DELIMITER);
+ sNewPath.append( m_xPathLB->get_id(i));
+ }
+
+ return sNewPath.makeStringAndClear();
+}
+
+void SvxMultiPathDialog::SetPath( const OUString& rPath )
+{
+ if ( !rPath.isEmpty() )
+ {
+ const sal_Unicode cDelim = SVT_SEARCHPATH_DELIMITER;
+ int nCount = 0;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const OUString sPath = rPath.getToken( 0, cDelim, nIndex );
+ OUString sSystemPath;
+ bool bIsSystemPath =
+ osl::FileBase::getSystemPathFromFileURL(sPath, sSystemPath) == osl::FileBase::E_None;
+
+ const OUString sEntry((bIsSystemPath ? sSystemPath : sPath));
+ AppendEntry(sEntry, sPath);
+ ++nCount;
+ }
+ while (nIndex >= 0);
+
+ if (nCount)
+ {
+ m_xRadioLB->set_toggle(nCount - 1, TRISTATE_TRUE, 0);
+ HandleEntryChecked(nCount - 1);
+ }
+ }
+
+ SelectHdl_Impl(*m_xRadioLB);
+}
+
+void SvxPathSelectDialog::SetPath(const OUString& rPath)
+{
+ if ( !rPath.isEmpty() )
+ {
+ sal_Int32 nIndex = 0;
+ do
+ {
+ const OUString sPath = rPath.getToken( 0, SVT_SEARCHPATH_DELIMITER, nIndex );
+ OUString sSystemPath;
+ bool bIsSystemPath =
+ osl::FileBase::getSystemPathFromFileURL(sPath, sSystemPath) == osl::FileBase::E_None;
+
+ m_xPathLB->append(sPath, bIsSystemPath ? sSystemPath : sPath);
+ }
+ while (nIndex >= 0);
+ }
+
+ SelectHdl_Impl(*m_xPathLB);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/newtabledlg.cxx b/cui/source/dialogs/newtabledlg.cxx
new file mode 100644
index 000000000..16e81f8d9
--- /dev/null
+++ b/cui/source/dialogs/newtabledlg.cxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <newtabledlg.hxx>
+
+SvxNewTableDialog::SvxNewTableDialog(weld::Window* pWindow)
+ : GenericDialogController(pWindow, "cui/ui/newtabledialog.ui", "NewTableDialog")
+ , mxNumColumns(m_xBuilder->weld_spin_button("columns"))
+ , mxNumRows(m_xBuilder->weld_spin_button("rows"))
+{
+}
+
+sal_Int32 SvxNewTableDialog::getRows() const
+{
+ return sal::static_int_cast< sal_Int32 >( mxNumRows->get_value() );
+}
+
+sal_Int32 SvxNewTableDialog::getColumns() const
+{
+ return sal::static_int_cast< sal_Int32 >( mxNumColumns->get_value() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/passwdomdlg.cxx b/cui/source/dialogs/passwdomdlg.cxx
new file mode 100644
index 000000000..250f9e728
--- /dev/null
+++ b/cui/source/dialogs/passwdomdlg.cxx
@@ -0,0 +1,171 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <passwdomdlg.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+IMPL_LINK_NOARG(PasswordToOpenModifyDialog, OkBtnClickHdl, weld::Button&, void)
+{
+ bool bInvalidState = !m_xOpenReadonlyCB->get_active() &&
+ m_xPasswdToOpenED->get_text().isEmpty() &&
+ m_xPasswdToModifyED->get_text().isEmpty();
+ if (bInvalidState)
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ m_bIsPasswordToModify? m_aInvalidStateForOkButton : m_aInvalidStateForOkButton_v2));
+ xErrorBox->run();
+ }
+ else // check for mismatched passwords...
+ {
+ const bool bToOpenMatch = m_xPasswdToOpenED->get_text() == m_xReenterPasswdToOpenED->get_text();
+ const bool bToModifyMatch = m_xPasswdToModifyED->get_text() == m_xReenterPasswdToModifyED->get_text();
+ const int nMismatch = (bToOpenMatch? 0 : 1) + (bToModifyMatch? 0 : 1);
+ if (nMismatch > 0)
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ nMismatch == 1 ? m_aOneMismatch : m_aTwoMismatch));
+ xErrorBox->run();
+
+ weld::Entry* pEdit = !bToOpenMatch ? m_xPasswdToOpenED.get() : m_xPasswdToModifyED.get();
+ weld::Entry* pRepeatEdit = !bToOpenMatch? m_xReenterPasswdToOpenED.get() : m_xReenterPasswdToModifyED.get();
+ if (nMismatch == 1)
+ {
+ pEdit->set_text( "" );
+ pRepeatEdit->set_text( "" );
+ }
+ else if (nMismatch == 2)
+ {
+ m_xPasswdToOpenED->set_text( "" );
+ m_xReenterPasswdToOpenED->set_text( "" );
+ m_xPasswdToModifyED->set_text( "" );
+ m_xReenterPasswdToModifyED->set_text( "" );
+ }
+ pEdit->grab_focus();
+ }
+ else
+ {
+ m_xDialog->response(RET_OK);
+ }
+ }
+}
+
+IMPL_LINK(PasswordToOpenModifyDialog, ChangeHdl, weld::Entry&, rEntry, void)
+{
+ weld::Label* pIndicator = nullptr;
+ int nLength = rEntry.get_text().getLength();
+ if (&rEntry == m_xPasswdToOpenED.get())
+ pIndicator = m_xPasswdToOpenInd.get();
+ else if (&rEntry == m_xReenterPasswdToOpenED.get())
+ pIndicator = m_xReenterPasswdToOpenInd.get();
+ else if (&rEntry == m_xPasswdToModifyED.get())
+ pIndicator = m_xPasswdToModifyInd.get();
+ else if (&rEntry == m_xReenterPasswdToModifyED.get())
+ pIndicator = m_xReenterPasswdToModifyInd.get();
+ assert(pIndicator);
+ pIndicator->set_visible(nLength >= m_nMaxPasswdLen);
+}
+
+PasswordToOpenModifyDialog::PasswordToOpenModifyDialog(weld::Window * pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify)
+ : SfxDialogController(pParent, "cui/ui/password.ui", "PasswordDialog")
+ , m_xPasswdToOpenED(m_xBuilder->weld_entry("newpassEntry"))
+ , m_xPasswdToOpenInd(m_xBuilder->weld_label("newpassIndicator"))
+ , m_xReenterPasswdToOpenED(m_xBuilder->weld_entry("confirmpassEntry"))
+ , m_xReenterPasswdToOpenInd(m_xBuilder->weld_label("confirmpassIndicator"))
+ , m_xOptionsExpander(m_xBuilder->weld_expander("expander"))
+ , m_xOk(m_xBuilder->weld_button("ok"))
+ , m_xOpenReadonlyCB(m_xBuilder->weld_check_button("readonly"))
+ , m_xPasswdToModifyFT(m_xBuilder->weld_label("label7"))
+ , m_xPasswdToModifyED(m_xBuilder->weld_entry("newpassroEntry"))
+ , m_xPasswdToModifyInd(m_xBuilder->weld_label("newpassroIndicator"))
+ , m_xReenterPasswdToModifyFT(m_xBuilder->weld_label("label8"))
+ , m_xReenterPasswdToModifyED(m_xBuilder->weld_entry("confirmropassEntry"))
+ , m_xReenterPasswdToModifyInd(m_xBuilder->weld_label("confirmropassIndicator"))
+ , m_aOneMismatch( CuiResId( RID_SVXSTR_ONE_PASSWORD_MISMATCH ) )
+ , m_aTwoMismatch( CuiResId( RID_SVXSTR_TWO_PASSWORDS_MISMATCH ) )
+ , m_aInvalidStateForOkButton( CuiResId( RID_SVXSTR_INVALID_STATE_FOR_OK_BUTTON ) )
+ , m_aInvalidStateForOkButton_v2( CuiResId( RID_SVXSTR_INVALID_STATE_FOR_OK_BUTTON_V2 ) )
+ , m_aIndicatorTemplate(CuiResId(RID_SVXSTR_PASSWORD_LEN_INDICATOR).replaceFirst("%1", OUString::number(nMaxPasswdLen)))
+ , m_nMaxPasswdLen(nMaxPasswdLen)
+ , m_bIsPasswordToModify( bIsPasswordToModify )
+{
+ m_xOk->connect_clicked(LINK(this, PasswordToOpenModifyDialog, OkBtnClickHdl));
+
+ if (nMaxPasswdLen)
+ {
+ m_xPasswdToOpenED->set_max_length( nMaxPasswdLen );
+ m_xPasswdToOpenED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xPasswdToOpenInd->set_label(m_aIndicatorTemplate);
+ m_xReenterPasswdToOpenED->set_max_length( nMaxPasswdLen );
+ m_xReenterPasswdToOpenED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xReenterPasswdToOpenInd->set_label(m_aIndicatorTemplate);
+ m_xPasswdToModifyED->set_max_length( nMaxPasswdLen );
+ m_xPasswdToModifyED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xPasswdToModifyInd->set_label(m_aIndicatorTemplate);
+ m_xReenterPasswdToModifyED->set_max_length( nMaxPasswdLen );
+ m_xReenterPasswdToModifyED->connect_changed(LINK(this, PasswordToOpenModifyDialog, ChangeHdl));
+ m_xReenterPasswdToModifyInd->set_label(m_aIndicatorTemplate);
+ }
+
+ m_xPasswdToOpenED->grab_focus();
+
+ m_xOptionsExpander->set_sensitive(bIsPasswordToModify);
+ if (!bIsPasswordToModify)
+ m_xOptionsExpander->hide();
+
+ m_xOpenReadonlyCB->connect_clicked(LINK(this, PasswordToOpenModifyDialog, ReadonlyOnOffHdl));
+ ReadonlyOnOffHdl(*m_xOpenReadonlyCB);
+}
+
+OUString PasswordToOpenModifyDialog::GetPasswordToOpen() const
+{
+ const bool bPasswdOk =
+ !m_xPasswdToOpenED->get_text().isEmpty() &&
+ m_xPasswdToOpenED->get_text() == m_xReenterPasswdToOpenED->get_text();
+ return bPasswdOk ? m_xPasswdToOpenED->get_text() : OUString();
+}
+
+
+OUString PasswordToOpenModifyDialog::GetPasswordToModify() const
+{
+ const bool bPasswdOk =
+ !m_xPasswdToModifyED->get_text().isEmpty() &&
+ m_xPasswdToModifyED->get_text() == m_xReenterPasswdToModifyED->get_text();
+ return bPasswdOk ? m_xPasswdToModifyED->get_text() : OUString();
+}
+
+
+bool PasswordToOpenModifyDialog::IsRecommendToOpenReadonly() const
+{
+ return m_xOpenReadonlyCB->get_active();
+}
+
+IMPL_LINK_NOARG(PasswordToOpenModifyDialog, ReadonlyOnOffHdl, weld::Button&, void)
+{
+ bool bEnable = m_xOpenReadonlyCB->get_active();
+ m_xPasswdToModifyED->set_sensitive(bEnable);
+ m_xPasswdToModifyFT->set_sensitive(bEnable);
+ m_xReenterPasswdToModifyED->set_sensitive(bEnable);
+ m_xReenterPasswdToModifyFT->set_sensitive(bEnable);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/pastedlg.cxx b/cui/source/dialogs/pastedlg.cxx
new file mode 100644
index 000000000..375a966c7
--- /dev/null
+++ b/cui/source/dialogs/pastedlg.cxx
@@ -0,0 +1,339 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+
+#include <pastedlg.hxx>
+#include <svtools/insdlg.hxx>
+#include <sot/exchange.hxx>
+#include <sot/formats.hxx>
+#include <svtools/strings.hrc>
+#include <svtools/svtresid.hxx>
+#include <tools/lineend.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/dispatchcommand.hxx>
+
+SvPasteObjectDialog::SvPasteObjectDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/pastespecial.ui", "PasteSpecialDialog")
+ , m_xFtObjectSource(m_xBuilder->weld_label("source"))
+ , m_xLbInsertList(m_xBuilder->weld_tree_view("list"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+{
+ m_xLbInsertList->set_size_request(m_xLbInsertList->get_approximate_digit_width() * 40,
+ m_xLbInsertList->get_height_rows(6));
+ m_xOKButton->set_sensitive(false);
+
+ ObjectLB().connect_changed(LINK(this, SvPasteObjectDialog, SelectHdl));
+ ObjectLB().connect_row_activated(LINK( this, SvPasteObjectDialog, DoubleClickHdl));
+}
+
+void SvPasteObjectDialog::SelectObject()
+{
+ if (m_xLbInsertList->n_children())
+ {
+ m_xLbInsertList->select(0);
+ SelectHdl(*m_xLbInsertList);
+ }
+}
+
+IMPL_LINK_NOARG(SvPasteObjectDialog, SelectHdl, weld::TreeView&, void)
+{
+ if (!m_xOKButton->get_sensitive())
+ m_xOKButton->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(SvPasteObjectDialog, DoubleClickHdl, weld::TreeView&, bool)
+{
+ m_xDialog->response(RET_OK);
+ return true;
+}
+
+/*************************************************************************
+|* SvPasteObjectDialog::Insert()
+*************************************************************************/
+void SvPasteObjectDialog::Insert( SotClipboardFormatId nFormat, const OUString& rFormatName )
+{
+ aSupplementMap.insert( std::make_pair( nFormat, rFormatName ) );
+}
+
+void SvPasteObjectDialog::InsertUno(const OUString& sCmd, const OUString& sLabel)
+{
+ aExtraCommand.first = sCmd;
+ aExtraCommand.second = sLabel;
+}
+
+
+void SvPasteObjectDialog::PreGetFormat( const TransferableDataHelper &rHelper )
+{
+ //TODO/LATER: why is the Descriptor never used?!
+ TransferableObjectDescriptor aDesc;
+ if (rHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
+ {
+ (void)const_cast<TransferableDataHelper&>(rHelper).GetTransferableObjectDescriptor(
+ SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
+ }
+ const DataFlavorExVector* pFormats = &rHelper.GetDataFlavorExVector();
+
+ // create and fill dialog box
+ OUString aSourceName, aTypeName;
+ SvGlobalName aEmptyNm;
+
+ //ObjectLB().SetUpdateMode( false );
+ ObjectLB().freeze();
+
+ DataFlavorExVector::iterator aIter( const_cast<DataFlavorExVector&>(*pFormats).begin() ),
+ aEnd( const_cast<DataFlavorExVector&>(*pFormats).end() );
+ while( aIter != aEnd )
+ {
+ SotClipboardFormatId nFormat = (*aIter++).mnSotId;
+
+ std::map< SotClipboardFormatId, OUString >::iterator itName =
+ aSupplementMap.find( nFormat );
+
+ // if there is an "Embed Source" or and "Embedded Object" on the
+ // Clipboard we read the Description and the Source of this object
+ // from an accompanied "Object Descriptor" format on the clipboard
+ // Remember: these formats mostly appear together on the clipboard
+ OUString aName;
+ const OUString* pName = nullptr;
+ if ( itName == aSupplementMap.end() )
+ {
+ SvPasteObjectHelper::GetEmbeddedName(rHelper,aName,aSourceName,nFormat);
+ if ( !aName.isEmpty() )
+ pName = &aName;
+ }
+ else
+ {
+ pName = &(itName->second);
+ }
+
+ if( pName )
+ {
+ aName = *pName;
+
+ if( SotClipboardFormatId::EMBED_SOURCE == nFormat )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+
+ if( aDesc.maClassName == aObjClassName )
+ aName = aObjName;
+ else
+ aName = aTypeName = aDesc.maTypeName;
+ }
+ }
+ else if( SotClipboardFormatId::LINK_SOURCE == nFormat )
+ {
+ continue;
+ }
+ else if( aName.isEmpty() )
+ aName = SvPasteObjectHelper::GetSotFormatUIName( nFormat );
+
+ // Show RICHTEXT only in case RTF is not present.
+ if (nFormat == SotClipboardFormatId::RICHTEXT &&
+ std::any_of(pFormats->begin(), pFormats->end(),
+ [](const DataFlavorEx& rFlavor) {
+ return rFlavor.mnSotId == SotClipboardFormatId::RTF;
+ }))
+ {
+ continue;
+ }
+
+ if (ObjectLB().find_text(aName) == -1)
+ {
+ ObjectLB().append(OUString::number(static_cast<sal_uInt32>(nFormat)), aName);
+ }
+ }
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+ aTypeName = aDesc.maTypeName;
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ // global resource from svtools (former so3 resource)
+ aSourceName = SvtResId(STR_UNKNOWN_SOURCE);
+ }
+ }
+
+ ObjectLB().thaw();
+ SelectObject();
+
+ if( !aSourceName.isEmpty() )
+ {
+ if( !aTypeName.isEmpty() )
+ aTypeName += "\n";
+
+ aTypeName += aSourceName;
+ aTypeName = convertLineEnd(aTypeName, GetSystemLineEnd());
+ }
+
+ m_xFtObjectSource->set_label(aTypeName);
+}
+
+SotClipboardFormatId SvPasteObjectDialog::GetFormatOnly()
+{
+ return static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32());
+}
+
+SotClipboardFormatId SvPasteObjectDialog::GetFormat( const TransferableDataHelper& rHelper)
+{
+ //TODO/LATER: why is the Descriptor never used?!
+ TransferableObjectDescriptor aDesc;
+ if (rHelper.HasFormat(SotClipboardFormatId::OBJECTDESCRIPTOR))
+ {
+ (void)const_cast<TransferableDataHelper&>(rHelper).GetTransferableObjectDescriptor(
+ SotClipboardFormatId::OBJECTDESCRIPTOR, aDesc);
+ }
+ const DataFlavorExVector* pFormats = &rHelper.GetDataFlavorExVector();
+
+ // create and fill dialog box
+ OUString aSourceName, aTypeName;
+ SotClipboardFormatId nSelFormat = SotClipboardFormatId::NONE;
+ SvGlobalName aEmptyNm;
+
+ ObjectLB().freeze();
+
+ for (auto const& format : *pFormats)
+ {
+ SotClipboardFormatId nFormat = format.mnSotId;
+
+ std::map< SotClipboardFormatId, OUString >::iterator itName =
+ aSupplementMap.find( nFormat );
+
+ // if there is an "Embed Source" or and "Embedded Object" on the
+ // Clipboard we read the Description and the Source of this object
+ // from an accompanied "Object Descriptor" format on the clipboard
+ // Remember: these formats mostly appear together on the clipboard
+ OUString aName;
+ const OUString* pName = nullptr;
+ if ( itName == aSupplementMap.end() )
+ {
+ SvPasteObjectHelper::GetEmbeddedName(rHelper,aName,aSourceName,nFormat);
+ if ( !aName.isEmpty() )
+ pName = &aName;
+ }
+ else
+ {
+ pName = &(itName->second);
+ }
+
+ if( pName )
+ {
+ aName = *pName;
+
+ if( SotClipboardFormatId::EMBED_SOURCE == nFormat )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+
+ if( aDesc.maClassName == aObjClassName )
+ aName = aObjName;
+ else
+ aName = aTypeName = aDesc.maTypeName;
+ }
+ }
+ else if( SotClipboardFormatId::LINK_SOURCE == nFormat )
+ {
+ continue;
+ }
+ else if( aName.isEmpty() )
+ aName = SvPasteObjectHelper::GetSotFormatUIName( nFormat );
+
+ // Show RICHTEXT only in case RTF is not present.
+ if (nFormat == SotClipboardFormatId::RICHTEXT &&
+ std::any_of(pFormats->begin(), pFormats->end(),
+ [](const DataFlavorEx& rFlavor) {
+ return rFlavor.mnSotId == SotClipboardFormatId::RTF;
+ }))
+ {
+ continue;
+ }
+
+ if (ObjectLB().find_text(aName) == -1)
+ {
+ ObjectLB().append(OUString::number(static_cast<sal_uInt32>(nFormat)), aName);
+ }
+ }
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ if( aDesc.maClassName != aEmptyNm )
+ {
+ aSourceName = aDesc.maDisplayName;
+ aTypeName = aDesc.maTypeName;
+ }
+
+ if( aTypeName.isEmpty() && aSourceName.isEmpty() )
+ {
+ // global resource from svtools (former so3 resource)
+ aSourceName = SvtResId(STR_UNKNOWN_SOURCE);
+ }
+ }
+
+ if (!aExtraCommand.first.isEmpty())
+ {
+ ObjectLB().append(aExtraCommand.first, aExtraCommand.second);
+ }
+
+ ObjectLB().thaw();
+ SelectObject();
+
+ if( !aSourceName.isEmpty() )
+ {
+ if( !aTypeName.isEmpty() )
+ aTypeName += "\n";
+
+ aTypeName += aSourceName;
+ aTypeName = convertLineEnd(aTypeName, GetSystemLineEnd());
+ }
+
+ m_xFtObjectSource->set_label(aTypeName);
+
+ if (run() == RET_OK)
+ {
+ if (ObjectLB().get_selected_id().startsWithIgnoreAsciiCase(".uno"))
+ {
+ comphelper::dispatchCommand(aExtraCommand.first, {});
+ nSelFormat = SotClipboardFormatId::NONE;
+ }
+ else
+ {
+ nSelFormat = static_cast<SotClipboardFormatId>(ObjectLB().get_selected_id().toUInt32());
+ }
+ }
+
+ return nSelFormat;
+}
+
+void SvPasteObjectDialog::SetObjName( const SvGlobalName & rClass, const OUString & rObjName )
+{
+ aObjClassName = rClass;
+ aObjName = rObjName;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/postdlg.cxx b/cui/source/dialogs/postdlg.cxx
new file mode 100644
index 000000000..b96c1dd85
--- /dev/null
+++ b/cui/source/dialogs/postdlg.cxx
@@ -0,0 +1,180 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/date.hxx>
+#include <tools/lineend.hxx>
+#include <tools/time.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <unotools/useroptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svx/svxids.hrc>
+
+#include <svx/postattr.hxx>
+#include <postdlg.hxx>
+
+// class SvxPostItDialog -------------------------------------------------
+
+SvxPostItDialog::SvxPostItDialog(weld::Widget* pParent, const SfxItemSet& rCoreSet,
+ bool bPrevNext)
+ : SfxDialogController(pParent, "cui/ui/comment.ui", "CommentDialog")
+ , m_rSet(rCoreSet)
+ , m_xLastEditFT(m_xBuilder->weld_label("lastedit"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xEditED(m_xBuilder->weld_text_view("edit"))
+ , m_xInsertAuthor(m_xBuilder->weld_widget("insertauthor"))
+ , m_xAuthorBtn(m_xBuilder->weld_button("author"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xPrevBtn(m_xBuilder->weld_button("previous"))
+ , m_xNextBtn(m_xBuilder->weld_button("next"))
+{
+ m_xPrevBtn->connect_clicked( LINK( this, SvxPostItDialog, PrevHdl ) );
+ m_xNextBtn->connect_clicked( LINK( this, SvxPostItDialog, NextHdl ) );
+ m_xAuthorBtn->connect_clicked( LINK( this, SvxPostItDialog, Stamp ) );
+ m_xOKBtn->connect_clicked( LINK( this, SvxPostItDialog, OKHdl ) );
+
+ bool bNew = true;
+ sal_uInt16 nWhich = 0;
+
+ m_xPrevBtn->set_visible(bPrevNext);
+ m_xNextBtn->set_visible(bPrevNext);
+
+ nWhich = m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_AUTHOR );
+ OUString aAuthorStr, aDateStr;
+
+ if (m_rSet.GetItemState( nWhich ) >= SfxItemState::DEFAULT)
+ {
+ bNew = false;
+ const SvxPostItAuthorItem& rAuthor =
+ static_cast<const SvxPostItAuthorItem&>(m_rSet.Get(nWhich));
+ aAuthorStr = rAuthor.GetValue();
+ }
+ else
+ aAuthorStr = SvtUserOptions().GetID();
+
+ nWhich = m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_DATE );
+
+ if (m_rSet.GetItemState( nWhich ) >= SfxItemState::DEFAULT)
+ {
+ const SvxPostItDateItem& rDate =
+ static_cast<const SvxPostItDateItem&>(m_rSet.Get( nWhich ));
+ aDateStr = rDate.GetValue();
+ }
+ else
+ {
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aDateStr = rLocaleWrapper.getDate( Date( Date::SYSTEM ) );
+ }
+
+ nWhich = m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_TEXT );
+
+ OUString aTextStr;
+ if (m_rSet.GetItemState( nWhich ) >= SfxItemState::DEFAULT)
+ {
+ const SvxPostItTextItem& rText =
+ static_cast<const SvxPostItTextItem&>(m_rSet.Get( nWhich ));
+ aTextStr = rText.GetValue();
+ }
+
+ ShowLastAuthor(aAuthorStr, aDateStr);
+
+ //lock to an initial size before replacing contents
+ m_xEditED->set_size_request(m_xEditED->get_approximate_digit_width() * 32,
+ m_xEditED->get_height_rows(10));
+ m_xEditED->set_text(convertLineEnd(aTextStr, GetSystemLineEnd()));
+
+ if (!bNew)
+ m_xDialog->set_title(m_xAltTitle->get_label());
+}
+
+
+SvxPostItDialog::~SvxPostItDialog()
+{
+}
+
+void SvxPostItDialog::ShowLastAuthor(const OUString& rAuthor, const OUString& rDate)
+{
+ OUString sTxt = rAuthor + ", " + rDate;
+ m_xLastEditFT->set_label( sTxt );
+}
+
+const sal_uInt16* SvxPostItDialog::GetRanges()
+{
+ static const sal_uInt16 pRanges[] =
+ {
+ SID_ATTR_POSTIT_AUTHOR,
+ SID_ATTR_POSTIT_TEXT,
+ 0
+ };
+ return pRanges;
+}
+
+void SvxPostItDialog::EnableTravel(bool bNext, bool bPrev)
+{
+ m_xPrevBtn->set_sensitive(bPrev);
+ m_xNextBtn->set_sensitive(bNext);
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, PrevHdl, weld::Button&, void)
+{
+ m_aPrevHdlLink.Call( *this );
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, NextHdl, weld::Button&, void)
+{
+ m_aNextHdlLink.Call( *this );
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, Stamp, weld::Button&, void)
+{
+ Date aDate( Date::SYSTEM );
+ tools::Time aTime( tools::Time::SYSTEM );
+ OUString aTmp( SvtUserOptions().GetID() );
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ OUString aStr( m_xEditED->get_text() + "\n---- " );
+
+ if ( !aTmp.isEmpty() )
+ {
+ aStr += aTmp + ", ";
+ }
+ aStr += rLocaleWrapper.getDate(aDate) + ", " + rLocaleWrapper.getTime(aTime, false) + " ----\n";
+ aStr = convertLineEnd(aStr, GetSystemLineEnd());
+
+ m_xEditED->set_text(aStr);
+ sal_Int32 nLen = aStr.getLength();
+ m_xEditED->grab_focus();
+ m_xEditED->select_region(nLen, nLen);
+}
+
+IMPL_LINK_NOARG(SvxPostItDialog, OKHdl, weld::Button&, void)
+{
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ m_xOutSet.reset(new SfxItemSet(m_rSet));
+ m_xOutSet->Put( SvxPostItAuthorItem(SvtUserOptions().GetID(),
+ m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_AUTHOR ) ) );
+ m_xOutSet->Put( SvxPostItDateItem(rLocaleWrapper.getDate( Date( Date::SYSTEM ) ),
+ m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_DATE ) ) );
+ m_xOutSet->Put( SvxPostItTextItem(m_xEditED->get_text(),
+ m_rSet.GetPool()->GetWhich( SID_ATTR_POSTIT_TEXT ) ) );
+ m_xDialog->response(RET_OK);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/screenshotannotationdlg.cxx b/cui/source/dialogs/screenshotannotationdlg.cxx
new file mode 100644
index 000000000..4054fa573
--- /dev/null
+++ b/cui/source/dialogs/screenshotannotationdlg.cxx
@@ -0,0 +1,583 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <screenshotannotationdlg.hxx>
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <basegfx/range/b2irange.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+
+#include <comphelper/random.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <tools/stream.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/bitmapex.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/pngwrite.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/salgtype.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <set>
+
+using namespace com::sun::star;
+
+namespace
+{
+ OUString lcl_genRandom( const OUString &rId )
+ {
+ //FIXME: plus timestamp
+ unsigned int nRand = comphelper::rng::uniform_uint_distribution(0, 0xFFFF);
+ return OUString( rId + OUString::number( nRand ) );
+ }
+
+
+ OUString lcl_AltDescr()
+ {
+ OUString aTempl("<alt id=\"%1\">"
+ " " //FIXME real dialog title or something
+ "</alt>");
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom("alt_id") );
+
+ return aTempl;
+ }
+
+ OUString lcl_Image( const OUString& rScreenshotId, const Size& rSize )
+ {
+ OUString aTempl("<image id=\"%1\" src=\"media/screenshots/%2.png\""
+ " width=\"%3cm\" height=\"%4cm\">"
+ "%5"
+ "</image>");
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom("img_id") );
+ aTempl = aTempl.replaceFirst( "%2", rScreenshotId );
+ aTempl = aTempl.replaceFirst( "%3", OUString::number( rSize.Width() ) );
+ aTempl = aTempl.replaceFirst( "%4", OUString::number( rSize.Height() ) );
+ aTempl = aTempl.replaceFirst( "%5", lcl_AltDescr() );
+
+ return aTempl;
+ }
+
+ OUString lcl_ParagraphWithImage( const OUString& rScreenshotId, const Size& rSize )
+ {
+ OUString aTempl( "<paragraph id=\"%1\" role=\"paragraph\">%2"
+ "</paragraph>" SAL_NEWLINE_STRING );
+ aTempl = aTempl.replaceFirst( "%1", lcl_genRandom("par_id") );
+ aTempl = aTempl.replaceFirst( "%2", lcl_Image(rScreenshotId, rSize) );
+
+ return aTempl;
+ }
+
+ OUString lcl_Bookmark( const OUString& rWidgetId )
+ {
+ OUString aTempl = "<!-- Bookmark for widget %1 -->" SAL_NEWLINE_STRING
+ "<bookmark branch=\"hid/%2\" id=\"%3\" localize=\"false\"/>" SAL_NEWLINE_STRING;
+ aTempl = aTempl.replaceFirst( "%1", rWidgetId );
+ aTempl = aTempl.replaceFirst( "%2", rWidgetId );
+ aTempl = aTempl.replaceFirst( "%3", lcl_genRandom("bm_id") );
+
+ return aTempl;
+ }
+}
+
+namespace
+{
+ class Picture : public weld::CustomWidgetController
+ {
+ private:
+ ScreenshotAnnotationDlg_Impl *m_pDialog;
+ bool m_bMouseOver;
+ private:
+ virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) override;
+ virtual bool MouseMove(const MouseEvent& rMouseEvent) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMouseEvent) override;
+ public:
+ Picture(ScreenshotAnnotationDlg_Impl* pDialog)
+ : m_pDialog(pDialog)
+ , m_bMouseOver(false)
+ {
+ }
+
+ bool IsMouseOver() const
+ {
+ return m_bMouseOver;
+ }
+ };
+}
+
+class ScreenshotAnnotationDlg_Impl
+{
+public:
+ ScreenshotAnnotationDlg_Impl(
+ weld::Window* pParent,
+ weld::Builder& rParent,
+ weld::Dialog& rParentDialog);
+ ~ScreenshotAnnotationDlg_Impl();
+
+private:
+ // Handler for click on save
+ DECL_LINK(saveButtonHandler, weld::Button&, void);
+
+ // helper methods
+ weld::ScreenShotEntry* CheckHit(const basegfx::B2IPoint& rPosition);
+ void PaintScreenShotEntry(
+ const weld::ScreenShotEntry& rEntry,
+ const Color& rColor,
+ double fLineWidth,
+ double fTransparency);
+ void RepaintToBuffer(
+ bool bUseDimmed = false,
+ bool bPaintHilight = false);
+ void RepaintPictureElement();
+ Point GetOffsetInPicture() const;
+
+ // local variables
+ weld::Window* mpParentWindow;
+ weld::Dialog& mrParentDialog;
+ BitmapEx maParentDialogBitmap;
+ BitmapEx maDimmedDialogBitmap;
+ Size maParentDialogSize;
+
+ // VirtualDevice for buffered interaction paints
+ VclPtr<VirtualDevice> mxVirtualBufferDevice;
+
+ // all detected children
+ weld::ScreenShotCollection maAllChildren;
+
+ // highlighted/selected children
+ weld::ScreenShotEntry* mpHilighted;
+ std::set< weld::ScreenShotEntry* >
+ maSelected;
+
+ // list of detected controls
+ Picture maPicture;
+ std::unique_ptr<weld::CustomWeld> mxPicture;
+ std::unique_ptr<weld::TextView> mxText;
+ std::unique_ptr<weld::Button> mxSave;
+
+ // save as text
+ OUString maSaveAsText;
+ OUString maMainMarkupText;
+
+ // folder URL
+ static OUString maLastFolderURL;
+public:
+ void Paint(vcl::RenderContext& rRenderContext);
+ bool MouseMove(const MouseEvent& rMouseEvent);
+ bool MouseButtonUp();
+};
+
+OUString ScreenshotAnnotationDlg_Impl::maLastFolderURL = OUString();
+
+ScreenshotAnnotationDlg_Impl::ScreenshotAnnotationDlg_Impl(
+ weld::Window* pParent,
+ weld::Builder& rParentBuilder,
+ weld::Dialog& rParentDialog)
+: mpParentWindow(pParent),
+ mrParentDialog(rParentDialog),
+ mxVirtualBufferDevice(nullptr),
+ maAllChildren(),
+ mpHilighted(nullptr),
+ maSelected(),
+ maPicture(this),
+ maSaveAsText(CuiResId(RID_SVXSTR_SAVE_SCREENSHOT_AS))
+{
+ VclPtr<VirtualDevice> xParentDialogSurface(VclPtr<VirtualDevice>::Create(DeviceFormat::DEFAULT));
+ rParentDialog.draw(*xParentDialogSurface);
+ maParentDialogSize = xParentDialogSurface->GetOutputSizePixel();
+ maParentDialogBitmap = xParentDialogSurface->GetBitmapEx(Point(), maParentDialogSize);
+ maDimmedDialogBitmap = maParentDialogBitmap;
+
+ // image ain't empty
+ assert(!maParentDialogBitmap.IsEmpty());
+ assert(0 != maParentDialogBitmap.GetSizePixel().Width());
+ assert(0 != maParentDialogBitmap.GetSizePixel().Height());
+
+ // get needed widgets
+ mxPicture.reset(new weld::CustomWeld(rParentBuilder, "picture", maPicture));
+ assert(mxPicture);
+ mxText = rParentBuilder.weld_text_view("text");
+ assert(mxText);
+ mxSave = rParentBuilder.weld_button("save");
+ assert(mxSave);
+
+ // set screenshot image at DrawingArea, resize, set event listener
+ if (mxPicture)
+ {
+ maAllChildren = mrParentDialog.collect_screenshot_data();
+
+ // to make clear that maParentDialogBitmap is a background image, adjust
+ // luminance a bit for maDimmedDialogBitmap - other methods may be applied
+ maDimmedDialogBitmap.Adjust(-15, 0, 0, 0, 0);
+
+ // init paint buffering VirtualDevice
+ mxVirtualBufferDevice = VclPtr<VirtualDevice>::Create(*Application::GetDefaultDevice(), DeviceFormat::DEFAULT, DeviceFormat::BITMASK);
+ mxVirtualBufferDevice->SetOutputSizePixel(maParentDialogSize);
+ mxVirtualBufferDevice->SetFillColor(COL_TRANSPARENT);
+
+ // initially set image for picture control
+ mxVirtualBufferDevice->DrawBitmapEx(Point(0, 0), maDimmedDialogBitmap);
+
+ // set size for picture control, this will re-layout so that
+ // the picture control shows the whole dialog
+ maPicture.SetOutputSizePixel(maParentDialogSize);
+ mxPicture->set_size_request(maParentDialogSize.Width(), maParentDialogSize.Height());
+
+ mxPicture->queue_draw();
+ }
+
+ // set some test text at VclMultiLineEdit and make read-only - only
+ // copying content to clipboard is allowed
+ if (mxText)
+ {
+ mxText->set_size_request(400, mxText->get_height_rows(10));
+ OUString aHelpId = OStringToOUString( mrParentDialog.get_help_id(), RTL_TEXTENCODING_UTF8 );
+ Size aSizeCm = Application::GetDefaultDevice()->PixelToLogic(maParentDialogSize, MapMode(MapUnit::MapCM));
+ maMainMarkupText = lcl_ParagraphWithImage( aHelpId, aSizeCm );
+ mxText->set_text( maMainMarkupText );
+ mxText->set_editable(false);
+ }
+
+ // set click handler for save button
+ if (mxSave)
+ {
+ mxSave->connect_clicked(LINK(this, ScreenshotAnnotationDlg_Impl, saveButtonHandler));
+ }
+}
+
+ScreenshotAnnotationDlg_Impl::~ScreenshotAnnotationDlg_Impl()
+{
+ mxVirtualBufferDevice.disposeAndClear();
+}
+
+IMPL_LINK_NOARG(ScreenshotAnnotationDlg_Impl, saveButtonHandler, weld::Button&, void)
+{
+ // 'save screenshot...' pressed, offer to save maParentDialogBitmap
+ // as PNG image, use *.id file name as screenshot file name offering
+ // get a suggestion for the filename from buildable name
+ OString aDerivedFileName = mrParentDialog.get_buildable_name();
+
+ auto xFileDlg = std::make_unique<sfx2::FileDialogHelper>(ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION,
+ FileDialogFlags::NONE, mpParentWindow);
+
+ const uno::Reference< ui::dialogs::XFilePicker3 > xFilePicker = xFileDlg->GetFilePicker();
+
+ xFilePicker->setTitle(maSaveAsText);
+
+ if (!maLastFolderURL.isEmpty())
+ {
+ xFilePicker->setDisplayDirectory(maLastFolderURL);
+ }
+
+ xFilePicker->appendFilter("*.png", "*.png");
+ xFilePicker->setCurrentFilter("*.png");
+ xFilePicker->setDefaultName(OStringToOUString(aDerivedFileName, RTL_TEXTENCODING_UTF8));
+ xFilePicker->setMultiSelectionMode(false);
+
+ if (xFilePicker->execute() != ui::dialogs::ExecutableDialogResults::OK)
+ return;
+
+ maLastFolderURL = xFilePicker->getDisplayDirectory();
+ const uno::Sequence< OUString > files(xFilePicker->getSelectedFiles());
+
+ if (!files.hasElements())
+ return;
+
+ OUString aConfirmedName = files[0];
+
+ if (aConfirmedName.isEmpty())
+ return;
+
+ INetURLObject aConfirmedURL(aConfirmedName);
+ OUString aCurrentExtension(aConfirmedURL.getExtension());
+
+ if (!aCurrentExtension.isEmpty() && aCurrentExtension != "png")
+ {
+ aConfirmedURL.removeExtension();
+ aCurrentExtension.clear();
+ }
+
+ if (aCurrentExtension.isEmpty())
+ {
+ aConfirmedURL.setExtension("png");
+ }
+
+ // open stream
+ SvFileStream aNew(aConfirmedURL.PathToFileName(), StreamMode::WRITE | StreamMode::TRUNC);
+
+ if (!aNew.IsOpen())
+ return;
+
+ // prepare bitmap to save - do use the original screenshot here,
+ // not the dimmed one
+ RepaintToBuffer();
+
+ // extract Bitmap
+ const BitmapEx aTargetBitmap(
+ mxVirtualBufferDevice->GetBitmapEx(
+ Point(0, 0),
+ mxVirtualBufferDevice->GetOutputSizePixel()));
+
+ // write as PNG
+ vcl::PNGWriter aPNGWriter(aTargetBitmap);
+ aPNGWriter.Write(aNew);
+}
+
+weld::ScreenShotEntry* ScreenshotAnnotationDlg_Impl::CheckHit(const basegfx::B2IPoint& rPosition)
+{
+ weld::ScreenShotEntry* pRetval = nullptr;
+
+ for (auto&& rCandidate : maAllChildren)
+ {
+ if (rCandidate.getB2IRange().isInside(rPosition))
+ {
+ if (pRetval)
+ {
+ if (pRetval->getB2IRange().isInside(rCandidate.getB2IRange().getMinimum())
+ && pRetval->getB2IRange().isInside(rCandidate.getB2IRange().getMaximum()))
+ {
+ pRetval = &rCandidate;
+ }
+ }
+ else
+ {
+ pRetval = &rCandidate;
+ }
+ }
+ }
+
+ return pRetval;
+}
+
+void ScreenshotAnnotationDlg_Impl::PaintScreenShotEntry(
+ const weld::ScreenShotEntry& rEntry,
+ const Color& rColor,
+ double fLineWidth,
+ double fTransparency)
+{
+ if (!(mxPicture && mxVirtualBufferDevice))
+ return;
+
+ basegfx::B2DRange aB2DRange(rEntry.getB2IRange());
+
+ // grow in pixels to be a little bit 'outside'. This also
+ // ensures that getWidth()/getHeight() ain't 0.0 (see division below)
+ static const double fGrowTopLeft(1.5);
+ static const double fGrowBottomRight(0.5);
+ aB2DRange.expand(aB2DRange.getMinimum() - basegfx::B2DPoint(fGrowTopLeft, fGrowTopLeft));
+ aB2DRange.expand(aB2DRange.getMaximum() + basegfx::B2DPoint(fGrowBottomRight, fGrowBottomRight));
+
+ // edge rounding in pixel. Need to convert, value for
+ // createPolygonFromRect is relative [0.0 .. 1.0]
+ static const double fEdgeRoundPixel(8.0);
+ const basegfx::B2DPolygon aPolygon(
+ basegfx::utils::createPolygonFromRect(
+ aB2DRange,
+ fEdgeRoundPixel / aB2DRange.getWidth(),
+ fEdgeRoundPixel / aB2DRange.getHeight()));
+
+ mxVirtualBufferDevice->SetLineColor(rColor);
+
+ // try to use transparency
+ if (!mxVirtualBufferDevice->DrawPolyLineDirect(
+ basegfx::B2DHomMatrix(),
+ aPolygon,
+ fLineWidth,
+ fTransparency,
+ nullptr, // MM01
+ basegfx::B2DLineJoin::Round))
+ {
+ // no transparency, draw without
+ mxVirtualBufferDevice->DrawPolyLine(
+ aPolygon,
+ fLineWidth);
+ }
+}
+
+Point ScreenshotAnnotationDlg_Impl::GetOffsetInPicture() const
+{
+ const Size aPixelSizeTarget(maPicture.GetOutputSizePixel());
+
+ return Point(
+ aPixelSizeTarget.Width() > maParentDialogSize.Width() ? (aPixelSizeTarget.Width() - maParentDialogSize.Width()) >> 1 : 0,
+ aPixelSizeTarget.Height() > maParentDialogSize.Height() ? (aPixelSizeTarget.Height() - maParentDialogSize.Height()) >> 1 : 0);
+}
+
+void ScreenshotAnnotationDlg_Impl::RepaintToBuffer(
+ bool bUseDimmed,
+ bool bPaintHilight)
+{
+ if (!mxVirtualBufferDevice)
+ return;
+
+ // reset with original screenshot bitmap
+ mxVirtualBufferDevice->DrawBitmapEx(
+ Point(0, 0),
+ bUseDimmed ? maDimmedDialogBitmap : maParentDialogBitmap);
+
+ // get various options
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor());
+ const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01);
+ const bool bIsAntiAliasing(aSvtOptionsDrawinglayer.IsAntiAliasing());
+ const AntialiasingFlags nOldAA(mxVirtualBufferDevice->GetAntialiasing());
+
+ if (bIsAntiAliasing)
+ {
+ mxVirtualBufferDevice->SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+ }
+
+ // paint selected entries
+ for (auto&& rCandidate : maSelected)
+ {
+ static const double fLineWidthEntries(5.0);
+ PaintScreenShotEntry(*rCandidate, COL_LIGHTRED, fLineWidthEntries, fTransparence * 0.2);
+ }
+
+ // paint highlighted entry
+ if (mpHilighted && bPaintHilight)
+ {
+ static const double fLineWidthHilight(7.0);
+ PaintScreenShotEntry(*mpHilighted, aHilightColor, fLineWidthHilight, fTransparence);
+ }
+
+ if (bIsAntiAliasing)
+ {
+ mxVirtualBufferDevice->SetAntialiasing(nOldAA);
+ }
+}
+
+void ScreenshotAnnotationDlg_Impl::RepaintPictureElement()
+{
+ if (mxPicture && mxVirtualBufferDevice)
+ {
+ // reset image in buffer, use dimmed version and allow highlight
+ RepaintToBuffer(true, true);
+ mxPicture->queue_draw();
+ }
+}
+
+void ScreenshotAnnotationDlg_Impl::Paint(vcl::RenderContext& rRenderContext)
+{
+ Point aPos(GetOffsetInPicture());
+ Size aSize(mxVirtualBufferDevice->GetOutputSizePixel());
+ rRenderContext.DrawOutDev(aPos, aSize, Point(), aSize, *mxVirtualBufferDevice);
+}
+
+void Picture::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&)
+{
+ m_pDialog->Paint(rRenderContext);
+}
+
+bool ScreenshotAnnotationDlg_Impl::MouseMove(const MouseEvent& rMouseEvent)
+{
+ bool bRepaint(false);
+
+ if (maPicture.IsMouseOver())
+ {
+ const weld::ScreenShotEntry* pOldHit = mpHilighted;
+ const Point aOffset(GetOffsetInPicture());
+ const basegfx::B2IPoint aMousePos(
+ rMouseEvent.GetPosPixel().X() - aOffset.X(),
+ rMouseEvent.GetPosPixel().Y() - aOffset.Y());
+ const weld::ScreenShotEntry* pHit = CheckHit(aMousePos);
+
+ if (pHit && pOldHit != pHit)
+ {
+ mpHilighted = const_cast<weld::ScreenShotEntry*>(pHit);
+ bRepaint = true;
+ }
+ }
+ else if (mpHilighted)
+ {
+ mpHilighted = nullptr;
+ bRepaint = true;
+ }
+
+ if (bRepaint)
+ {
+ RepaintPictureElement();
+ }
+
+ return true;
+}
+
+bool Picture::MouseMove(const MouseEvent& rMouseEvent)
+{
+ if (rMouseEvent.IsEnterWindow())
+ m_bMouseOver = true;
+ if (rMouseEvent.IsLeaveWindow())
+ m_bMouseOver = false;
+ return m_pDialog->MouseMove(rMouseEvent);
+}
+
+bool ScreenshotAnnotationDlg_Impl::MouseButtonUp()
+{
+ // event in picture frame
+ bool bRepaint(false);
+
+ if (maPicture.IsMouseOver() && mpHilighted)
+ {
+ if (maSelected.erase(mpHilighted) == 0)
+ {
+ maSelected.insert(mpHilighted);
+ }
+
+ OUStringBuffer aBookmarks(maMainMarkupText);
+ for (auto&& rCandidate : maSelected)
+ {
+ OUString aHelpId = OStringToOUString( rCandidate->GetHelpId(), RTL_TEXTENCODING_UTF8 );
+ aBookmarks.append(lcl_Bookmark( aHelpId ));
+ }
+
+ mxText->set_text( aBookmarks.makeStringAndClear() );
+ bRepaint = true;
+ }
+
+ if (bRepaint)
+ {
+ RepaintPictureElement();
+ }
+
+ return true;
+}
+
+bool Picture::MouseButtonUp(const MouseEvent&)
+{
+ return m_pDialog->MouseButtonUp();
+}
+
+ScreenshotAnnotationDlg::ScreenshotAnnotationDlg(weld::Dialog& rParentDialog)
+ : GenericDialogController(&rParentDialog, "cui/ui/screenshotannotationdialog.ui", "ScreenshotAnnotationDialog")
+{
+ m_pImpl.reset(new ScreenshotAnnotationDlg_Impl(m_xDialog.get(), *m_xBuilder, rParentDialog));
+}
+
+ScreenshotAnnotationDlg::~ScreenshotAnnotationDlg()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/scriptdlg.cxx b/cui/source/dialogs/scriptdlg.cxx
new file mode 100644
index 000000000..5319ac680
--- /dev/null
+++ b/cui/source/dialogs/scriptdlg.cxx
@@ -0,0 +1,1351 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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 <utility>
+
+#include <sfx2/objsh.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <scriptdlg.hxx>
+#include <dialmgr.hxx>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorException.hpp>
+#include <com/sun/star/script/provider/XScriptProviderSupplier.hpp>
+#include <com/sun/star/script/provider/XScriptProvider.hpp>
+#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
+#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>
+#include <com/sun/star/script/browse/BrowseNodeFactoryViewTypes.hpp>
+#include <com/sun/star/script/browse/theBrowseNodeFactory.hpp>
+#include <com/sun/star/script/provider/ScriptErrorRaisedException.hpp>
+#include <com/sun/star/script/provider/ScriptExceptionRaisedException.hpp>
+#include <com/sun/star/script/provider/ScriptFrameworkErrorType.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/document/XEmbeddedScripts.hpp>
+
+#include <comphelper/SetFlagContextHelper.hxx>
+#include <comphelper/documentinfo.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <svtools/imagemgr.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::com::sun::star;
+using namespace css::uno;
+using namespace css::script;
+using namespace css::frame;
+using namespace css::document;
+
+static void ShowErrorDialog( const Any& aException )
+{
+ ScopedVclPtrInstance<SvxScriptErrorDialog> pDlg( aException );
+ pDlg->Execute();
+}
+
+void SvxScriptOrgDialog::delUserData(const weld::TreeIter& rIter)
+{
+ SFEntry* pUserData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(rIter).toInt64());
+ if (pUserData)
+ {
+ delete pUserData;
+ // TBD seem to get a Select event on node that is remove ( below )
+ // so need to be able to detect that this node is not to be
+ // processed in order to do this, setting userData to NULL ( must
+ // be a better way to do this )
+ m_xScriptsBox->set_id(rIter, OUString());
+ }
+}
+
+void SvxScriptOrgDialog::deleteTree(weld::TreeIter& rIter)
+{
+ delUserData(rIter);
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator(&rIter);
+ if (!m_xScriptsBox->iter_children(*xIter))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xAltIter = m_xScriptsBox->make_iterator();
+ bool bNextEntry;
+ do
+ {
+ m_xScriptsBox->copy_iterator(*xIter, *xAltIter);
+ bNextEntry = m_xScriptsBox->iter_next_sibling(*xAltIter);
+ deleteTree(*xIter);
+ m_xScriptsBox->remove(*xIter);
+ m_xScriptsBox->copy_iterator(*xAltIter, *xIter);
+ }
+ while (bNextEntry);
+}
+
+void SvxScriptOrgDialog::deleteAllTree()
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_iter_first(*xIter))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xAltIter = m_xScriptsBox->make_iterator();
+ // TBD - below is a candidate for a destroyAllTrees method
+ bool bNextEntry;
+ do
+ {
+ m_xScriptsBox->copy_iterator(*xIter, *xAltIter);
+ bNextEntry = m_xScriptsBox->iter_next_sibling(*xAltIter);
+ deleteTree(*xIter);
+ m_xScriptsBox->remove(*xIter);
+ m_xScriptsBox->copy_iterator(*xAltIter, *xIter);
+ }
+ while (bNextEntry);
+}
+
+void SvxScriptOrgDialog::Init( const OUString& language )
+{
+ m_xScriptsBox->freeze();
+
+ deleteAllTree();
+
+ Reference< browse::XBrowseNode > rootNode;
+ Reference< XComponentContext > xCtx(
+ comphelper::getProcessComponentContext() );
+
+ Sequence< Reference< browse::XBrowseNode > > children;
+
+ OUString userStr("user");
+ OUString const shareStr("share");
+
+ try
+ {
+ Reference< browse::XBrowseNodeFactory > xFac = browse::theBrowseNodeFactory::get(xCtx);
+
+ rootNode.set( xFac->createView(
+ browse::BrowseNodeFactoryViewTypes::MACROORGANIZER ) );
+
+ if ( rootNode.is() && rootNode->hasChildNodes() )
+ {
+ children = rootNode->getChildNodes();
+ }
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Exception getting root browse node from factory");
+ // TODO exception handling
+ }
+
+ Reference<XModel> xDocumentModel;
+ for ( const Reference< browse::XBrowseNode >& childNode : std::as_const(children) )
+ {
+ bool app = false;
+ OUString uiName = childNode->getName();
+ OUString factoryURL;
+ if ( uiName == userStr || uiName == shareStr )
+ {
+ app = true;
+ if ( uiName == userStr )
+ {
+ uiName = m_sMyMacros;
+ }
+ else
+ {
+ uiName = m_sProdMacros;
+ }
+ }
+ else
+ {
+ xDocumentModel.set(getDocumentModel(xCtx, uiName ), UNO_QUERY);
+
+ if ( xDocumentModel.is() )
+ {
+ Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xCtx) );
+
+ // get the long name of the document:
+ Sequence<beans::PropertyValue> moduleDescr;
+ try{
+ OUString appModule = xModuleManager->identify( xDocumentModel );
+ xModuleManager->getByName(appModule) >>= moduleDescr;
+ } catch(const uno::Exception&)
+ {}
+
+ for ( const beans::PropertyValue& prop : std::as_const(moduleDescr))
+ {
+ if ( prop.Name == "ooSetupFactoryEmptyDocumentURL" )
+ {
+ prop.Value >>= factoryURL;
+ break;
+ }
+ }
+ }
+ }
+
+ Reference< browse::XBrowseNode > langEntries =
+ getLangNodeFromRootNode( childNode, language );
+
+ insertEntry( uiName, app ? OUStringLiteral(RID_CUIBMP_HARDDISK) : OUStringLiteral(RID_CUIBMP_DOC),
+ nullptr, true, std::make_unique< SFEntry >( langEntries, xDocumentModel ), factoryURL, false );
+ }
+
+ m_xScriptsBox->thaw();
+}
+
+Reference< XInterface >
+SvxScriptOrgDialog::getDocumentModel( Reference< XComponentContext > const & xCtx, OUString const & docName )
+{
+ Reference< XInterface > xModel;
+ Reference< frame::XDesktop2 > desktop = frame::Desktop::create(xCtx);
+
+ Reference< container::XEnumerationAccess > componentsAccess =
+ desktop->getComponents();
+ Reference< container::XEnumeration > components =
+ componentsAccess->createEnumeration();
+ while (components->hasMoreElements())
+ {
+ Reference< frame::XModel > model(
+ components->nextElement(), UNO_QUERY );
+ if ( model.is() )
+ {
+ OUString sTdocUrl = ::comphelper::DocumentInfo::getDocumentTitle( model );
+ if( sTdocUrl == docName )
+ {
+ xModel = model;
+ break;
+ }
+ }
+ }
+ return xModel;
+}
+
+Reference< browse::XBrowseNode >
+SvxScriptOrgDialog::getLangNodeFromRootNode( Reference< browse::XBrowseNode > const & rootNode, OUString const & language )
+{
+ Reference< browse::XBrowseNode > langNode;
+
+ try
+ {
+ auto tryFind = [&] {
+ const Sequence<Reference<browse::XBrowseNode>> children = rootNode->getChildNodes();
+ const auto it = std::find_if(children.begin(), children.end(),
+ [&](const Reference<browse::XBrowseNode>& child) {
+ return child->getName() == language;
+ });
+ return (it != children.end()) ? *it : nullptr;
+ };
+ {
+ // First try without Java interaction, to avoid warnings for non-JRE-dependent providers
+ css::uno::ContextLayer layer(comphelper::NoEnableJavaInteractionContext());
+ langNode = tryFind();
+ }
+ if (!langNode)
+ {
+ // Now try with Java interaction enabled
+ langNode = tryFind();
+ }
+ }
+ catch ( Exception& )
+ {
+ // if getChildNodes() throws an exception we just return
+ // the empty Reference
+ }
+ return langNode;
+}
+
+void SvxScriptOrgDialog::RequestSubEntries(const weld::TreeIter& rRootEntry, Reference< css::script::browse::XBrowseNode > const & node,
+ Reference< XModel >& model)
+{
+ if (!node.is())
+ {
+ return;
+ }
+
+ Sequence< Reference< browse::XBrowseNode > > children;
+ try
+ {
+ children = node->getChildNodes();
+ }
+ catch ( Exception& )
+ {
+ // if we catch an exception in getChildNodes then no entries are added
+ }
+
+ for ( const Reference< browse::XBrowseNode >& childNode : std::as_const(children) )
+ {
+ OUString name( childNode->getName() );
+ if ( childNode->getType() != browse::BrowseNodeTypes::SCRIPT)
+ {
+ insertEntry(name, RID_CUIBMP_LIB, &rRootEntry, true, std::make_unique<SFEntry>(childNode, model), false);
+ }
+ else
+ {
+ insertEntry(name, RID_CUIBMP_MACRO, &rRootEntry, false, std::make_unique<SFEntry>(childNode, model), false);
+ }
+ }
+}
+
+void SvxScriptOrgDialog::insertEntry(const OUString& rText, const OUString& rBitmap,
+ const weld::TreeIter* pParent, bool bChildrenOnDemand, std::unique_ptr<SFEntry> && aUserData,
+ const OUString& factoryURL, bool bSelect)
+{
+ if (rBitmap == RID_CUIBMP_DOC && !factoryURL.isEmpty())
+ {
+ OUString aImage = SvFileInformationManager::GetFileImageId(INetURLObject(factoryURL));
+ insertEntry(rText, aImage, pParent, bChildrenOnDemand, std::move(aUserData), bSelect);
+ return;
+ }
+ insertEntry(rText, rBitmap, pParent, bChildrenOnDemand, std::move(aUserData), bSelect);
+}
+
+void SvxScriptOrgDialog::insertEntry(
+ const OUString& rText, const OUString& rBitmap, const weld::TreeIter* pParent,
+ bool bChildrenOnDemand, std::unique_ptr<SFEntry> && aUserData, bool bSelect)
+{
+ std::unique_ptr<weld::TreeIter> xRetIter;
+ if (bSelect)
+ xRetIter = m_xScriptsBox->make_iterator();
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(aUserData.release()))); // XXX possible leak
+ m_xScriptsBox->insert(pParent, -1, &rText, &sId, nullptr, nullptr, &rBitmap,
+ bChildrenOnDemand, xRetIter.get());
+ if (bSelect)
+ {
+ m_xScriptsBox->set_cursor(*xRetIter);
+ m_xScriptsBox->select(*xRetIter);
+ }
+}
+
+IMPL_LINK(SvxScriptOrgDialog, ExpandingHdl, const weld::TreeIter&, rIter, bool)
+{
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(rIter).toInt64());
+
+ Reference< browse::XBrowseNode > node;
+ Reference< XModel > model;
+ if ( userData && !userData->isLoaded() )
+ {
+ node = userData->GetNode();
+ model = userData->GetModel();
+ RequestSubEntries(rIter, node, model);
+ userData->setLoaded();
+ }
+
+ return true;
+}
+
+// CuiInputDialog ------------------------------------------------------------
+CuiInputDialog::CuiInputDialog(weld::Window * pParent, InputDialogMode nMode)
+ : GenericDialogController(pParent, "cui/ui/newlibdialog.ui", "NewLibDialog")
+ , m_xEdit(m_xBuilder->weld_entry("entry"))
+{
+ m_xEdit->grab_focus();
+
+ std::unique_ptr<weld::Label> xNewLibFT(m_xBuilder->weld_label("newlibft"));
+
+ if ( nMode == InputDialogMode::NEWMACRO )
+ {
+ xNewLibFT->hide();
+ std::unique_ptr<weld::Label> xNewMacroFT(m_xBuilder->weld_label("newmacroft"));
+ xNewMacroFT->show();
+ std::unique_ptr<weld::Label> xAltTitle(m_xBuilder->weld_label("altmacrotitle"));
+ m_xDialog->set_title(xAltTitle->get_label());
+ }
+ else if ( nMode == InputDialogMode::RENAME )
+ {
+ xNewLibFT->hide();
+ std::unique_ptr<weld::Label> xRenameFT(m_xBuilder->weld_label("renameft"));
+ xRenameFT->show();
+ std::unique_ptr<weld::Label> xAltTitle(m_xBuilder->weld_label("altrenametitle"));
+ m_xDialog->set_title(xAltTitle->get_label());
+ }
+}
+
+// ScriptOrgDialog ------------------------------------------------------------
+
+SvxScriptOrgDialog::SvxScriptOrgDialog(weld::Window* pParent, const OUString& language)
+ : SfxDialogController(pParent, "cui/ui/scriptorganizer.ui", "ScriptOrganizerDialog")
+ , m_sLanguage(language)
+ , m_delErrStr(CuiResId(RID_SVXSTR_DELFAILED))
+ , m_delErrTitleStr(CuiResId(RID_SVXSTR_DELFAILED_TITLE))
+ , m_delQueryStr(CuiResId(RID_SVXSTR_DELQUERY))
+ , m_delQueryTitleStr(CuiResId(RID_SVXSTR_DELQUERY_TITLE))
+ , m_createErrStr(CuiResId(RID_SVXSTR_CREATEFAILED))
+ , m_createDupStr(CuiResId(RID_SVXSTR_CREATEFAILEDDUP))
+ , m_createErrTitleStr(CuiResId(RID_SVXSTR_CREATEFAILED_TITLE))
+ , m_renameErrStr(CuiResId(RID_SVXSTR_RENAMEFAILED))
+ , m_renameErrTitleStr(CuiResId(RID_SVXSTR_RENAMEFAILED_TITLE))
+ , m_sMyMacros(CuiResId(RID_SVXSTR_MYMACROS))
+ , m_sProdMacros(CuiResId(RID_SVXSTR_PRODMACROS))
+ , m_xScriptsBox(m_xBuilder->weld_tree_view("scripts"))
+ , m_xRunButton(m_xBuilder->weld_button("ok"))
+ , m_xCloseButton(m_xBuilder->weld_button("close"))
+ , m_xCreateButton(m_xBuilder->weld_button("create"))
+ , m_xEditButton(m_xBuilder->weld_button("edit"))
+ , m_xRenameButton(m_xBuilder->weld_button("rename"))
+ , m_xDelButton(m_xBuilder->weld_button("delete"))
+{
+ // must be a neater way to deal with the strings than as above
+ // append the language to the dialog title
+ OUString winTitle(m_xDialog->get_title());
+ winTitle = winTitle.replaceFirst( "%MACROLANG", m_sLanguage );
+ m_xDialog->set_title(winTitle);
+
+ m_xScriptsBox->set_size_request(m_xScriptsBox->get_approximate_digit_width() * 45,
+ m_xScriptsBox->get_height_rows(12));
+
+ m_xScriptsBox->connect_changed( LINK( this, SvxScriptOrgDialog, ScriptSelectHdl ) );
+ m_xScriptsBox->connect_expanding(LINK( this, SvxScriptOrgDialog, ExpandingHdl ) );
+ m_xRunButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xCloseButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xRenameButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xEditButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xDelButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+ m_xCreateButton->connect_clicked( LINK( this, SvxScriptOrgDialog, ButtonHdl ) );
+
+ m_xRunButton->set_sensitive(false);
+ m_xRenameButton->set_sensitive(false);
+ m_xEditButton->set_sensitive(false);
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+
+ Init(m_sLanguage);
+ RestorePreviousSelection();
+}
+
+SvxScriptOrgDialog::~SvxScriptOrgDialog()
+{
+ deleteAllTree();
+}
+
+short SvxScriptOrgDialog::run()
+{
+ SfxObjectShell *pDoc = SfxObjectShell::GetFirst();
+
+ // force load of MSPs for all documents
+ while ( pDoc )
+ {
+ Reference< provider::XScriptProviderSupplier > xSPS( pDoc->GetModel(), UNO_QUERY );
+ if ( xSPS.is() )
+ {
+ xSPS->getScriptProvider();
+ }
+
+ pDoc = SfxObjectShell::GetNext(*pDoc);
+ }
+
+ return SfxDialogController::run();
+}
+
+void SvxScriptOrgDialog::CheckButtons( Reference< browse::XBrowseNode > const & node )
+{
+ if ( node.is() )
+ {
+ if ( node->getType() == browse::BrowseNodeTypes::SCRIPT)
+ {
+ m_xRunButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xRunButton->set_sensitive(false);
+ }
+ Reference< beans::XPropertySet > xProps( node, UNO_QUERY );
+
+ if ( !xProps.is() )
+ {
+ m_xEditButton->set_sensitive(false);
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+ m_xRunButton->set_sensitive(false);
+ return;
+ }
+
+ OUString sName("Editable");
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xEditButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xEditButton->set_sensitive(false);
+ }
+
+ sName = "Deletable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xDelButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xDelButton->set_sensitive(false);
+ }
+
+ sName = "Creatable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xCreateButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xCreateButton->set_sensitive(false);
+ }
+
+ sName = "Renamable";
+
+ if ( getBoolProperty( xProps, sName ) )
+ {
+ m_xRenameButton->set_sensitive(true);
+ }
+ else
+ {
+ m_xRenameButton->set_sensitive(false);
+ }
+ }
+ else
+ {
+ // no node info available, disable all configurable actions
+ m_xDelButton->set_sensitive(false);
+ m_xCreateButton->set_sensitive(false);
+ m_xEditButton->set_sensitive(false);
+ m_xRunButton->set_sensitive(false);
+ m_xRenameButton->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxScriptOrgDialog, ScriptSelectHdl, weld::TreeView&, void)
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(*xIter).toInt64());
+
+ Reference< browse::XBrowseNode > node;
+ if (userData)
+ {
+ node = userData->GetNode();
+ CheckButtons(node);
+ }
+}
+
+IMPL_LINK(SvxScriptOrgDialog, ButtonHdl, weld::Button&, rButton, void)
+{
+ if ( &rButton == m_xCloseButton.get() )
+ {
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ }
+ if (!(&rButton == m_xEditButton.get() ||
+ &rButton == m_xCreateButton.get() ||
+ &rButton == m_xDelButton.get() ||
+ &rButton == m_xRunButton.get() ||
+ &rButton == m_xRenameButton.get()))
+
+ return;
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(*xIter).toInt64());
+ if (!userData)
+ return;
+
+ Reference< browse::XBrowseNode > node;
+ Reference< XModel > xModel;
+
+ node = userData->GetNode();
+ xModel = userData->GetModel();
+
+ if ( !node.is() )
+ {
+ return;
+ }
+
+ if (&rButton == m_xRunButton.get())
+ {
+ OUString tmpString;
+ Reference< beans::XPropertySet > xProp( node, UNO_QUERY );
+ Reference< provider::XScriptProvider > mspNode;
+ if( !xProp.is() )
+ {
+ return;
+ }
+
+ if ( xModel.is() )
+ {
+ Reference< XEmbeddedScripts > xEmbeddedScripts( xModel, UNO_QUERY);
+ if( !xEmbeddedScripts.is() )
+ {
+ return;
+ }
+
+ if (!xEmbeddedScripts->getAllowMacroExecution())
+ {
+ // Please FIXME: Show a message box if AllowMacroExecution is false
+ return;
+ }
+ }
+
+ std::unique_ptr<weld::TreeIter> xParentIter = m_xScriptsBox->make_iterator(xIter.get());
+ bool bParent = m_xScriptsBox->iter_parent(*xParentIter);
+ while (bParent && !mspNode.is() )
+ {
+ SFEntry* mspUserData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(*xParentIter).toInt64());
+ mspNode.set( mspUserData->GetNode() , UNO_QUERY );
+ bParent = m_xScriptsBox->iter_parent(*xParentIter);
+ }
+ xProp->getPropertyValue("URI") >>= tmpString;
+ const OUString scriptURL( tmpString );
+
+ if ( mspNode.is() )
+ {
+ try
+ {
+ Reference< provider::XScript > xScript(
+ mspNode->getScript( scriptURL ), UNO_SET_THROW );
+
+ const Sequence< Any > args(0);
+ Sequence< sal_Int16 > outIndex;
+ Sequence< Any > outArgs( 0 );
+ xScript->invoke( args, outIndex, outArgs );
+ }
+ catch ( reflection::InvocationTargetException& ite )
+ {
+ ShowErrorDialog(css::uno::Any(ite));
+ }
+ catch ( provider::ScriptFrameworkErrorException& ite )
+ {
+ ShowErrorDialog(css::uno::Any(ite));
+ }
+ catch ( RuntimeException& re )
+ {
+ ShowErrorDialog(css::uno::Any(re));
+ }
+ catch ( Exception& e )
+ {
+ ShowErrorDialog(css::uno::Any(e));
+ }
+ }
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ }
+ else if ( &rButton == m_xEditButton.get() )
+ {
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ StoreCurrentSelection();
+ m_xDialog->response(RET_CANCEL);
+ Sequence< Any > args(0);
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ // ISSUE need code to run script here
+ xInv->invoke( "Editable", args, outIndex, outArgs );
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to invoke" );
+ }
+ }
+ }
+ else if ( &rButton == m_xCreateButton.get() )
+ {
+ createEntry(*xIter);
+ }
+ else if ( &rButton == m_xDelButton.get() )
+ {
+ deleteEntry(*xIter);
+ }
+ else if ( &rButton == m_xRenameButton.get() )
+ {
+ renameEntry(*xIter);
+ }
+}
+
+Reference< browse::XBrowseNode > SvxScriptOrgDialog::getBrowseNode(const weld::TreeIter& rEntry)
+{
+ Reference< browse::XBrowseNode > node;
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(rEntry).toInt64());
+ if (userData)
+ {
+ node = userData->GetNode();
+ }
+ return node;
+}
+
+Reference< XModel > SvxScriptOrgDialog::getModel(const weld::TreeIter& rEntry)
+{
+ Reference< XModel > model;
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(rEntry).toInt64());
+ if ( userData )
+ {
+ model = userData->GetModel();
+ }
+ return model;
+}
+
+void SvxScriptOrgDialog::createEntry(weld::TreeIter& rEntry)
+{
+
+ Reference< browse::XBrowseNode > aChildNode;
+ Reference< browse::XBrowseNode > node = getBrowseNode( rEntry );
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+
+ if ( xInv.is() )
+ {
+ OUString aNewName;
+ OUString aNewStdName;
+ InputDialogMode nMode = InputDialogMode::NEWLIB;
+ if (m_xScriptsBox->get_iter_depth(rEntry) == 0)
+ {
+ aNewStdName = "Library" ;
+ }
+ else
+ {
+ aNewStdName = "Macro" ;
+ nMode = InputDialogMode::NEWMACRO;
+ }
+ //do we need L10N for this? ie something like:
+ //String aNewStdName( ResId( STR_STDMODULENAME ) );
+ bool bValid = false;
+ sal_Int32 i = 1;
+
+ Sequence< Reference< browse::XBrowseNode > > childNodes;
+ // no children => ok to create Parcel1 or Script1 without checking
+ try
+ {
+ if( !node->hasChildNodes() )
+ {
+ aNewName = aNewStdName + OUString::number(i);
+ bValid = true;
+ }
+ else
+ {
+ childNodes = node->getChildNodes();
+ }
+ }
+ catch ( Exception& )
+ {
+ // ignore, will continue on with empty sequence
+ }
+
+ OUString extn;
+ while ( !bValid )
+ {
+ aNewName = aNewStdName + OUString::number(i);
+ bool bFound = false;
+ if(childNodes.hasElements() )
+ {
+ OUString nodeName = childNodes[0]->getName();
+ sal_Int32 extnPos = nodeName.lastIndexOf( '.' );
+ if(extnPos>0)
+ extn = nodeName.copy(extnPos);
+ }
+ for( const Reference< browse::XBrowseNode >& n : std::as_const(childNodes) )
+ {
+ if (aNewName+extn == n->getName())
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if( bFound )
+ {
+ i++;
+ }
+ else
+ {
+ bValid = true;
+ }
+ }
+
+ CuiInputDialog aNewDlg(m_xDialog.get(), nMode);
+ aNewDlg.SetObjectName(aNewName);
+
+ do
+ {
+ if (aNewDlg.run() && !aNewDlg.GetObjectName().isEmpty())
+ {
+ OUString aUserSuppliedName = aNewDlg.GetObjectName();
+ bValid = true;
+ for( const Reference< browse::XBrowseNode >& n : std::as_const(childNodes) )
+ {
+ if (aUserSuppliedName+extn == n->getName())
+ {
+ bValid = false;
+ OUString aError = m_createErrStr + m_createDupStr;
+
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_createErrTitleStr);
+ xErrorBox->run();
+ aNewDlg.SetObjectName(aNewName);
+ break;
+ }
+ }
+ if( bValid )
+ aNewName = aUserSuppliedName;
+ }
+ else
+ {
+ // user hit cancel or hit OK with nothing in the editbox
+
+ return;
+ }
+ }
+ while ( !bValid );
+
+ // open up parent node (which ensures it's loaded)
+ m_xScriptsBox->expand_row(rEntry);
+
+ Sequence< Any > args( 1 );
+ args[ 0 ] <<= aNewName;
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Creatable", args, outIndex, outArgs );
+ Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
+ aChildNode = newNode;
+
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Create" );
+ }
+ }
+ if ( aChildNode.is() )
+ {
+ OUString aChildName = aChildNode->getName();
+
+ Reference<XModel> xDocumentModel = getModel( rEntry );
+
+ // ISSUE do we need to remove all entries for parent
+ // to achieve sort? Just need to determine position
+ // -- Basic doesn't do this on create.
+ // Suppose we could avoid this too. -> created nodes are
+ // not in alphabetical order
+ if ( aChildNode->getType() == browse::BrowseNodeTypes::SCRIPT )
+ {
+ insertEntry(aChildName, RID_CUIBMP_MACRO, &rEntry, false,
+ std::make_unique<SFEntry>(aChildNode,xDocumentModel), true);
+ }
+ else
+ {
+ insertEntry(aChildName, RID_CUIBMP_LIB, &rEntry, false,
+ std::make_unique<SFEntry>(aChildNode,xDocumentModel), true);
+
+ // If the Parent is not loaded then set to
+ // loaded, this will prevent RequestingChildren ( called
+ // from vcl via RequestingChildren ) from
+ // creating new ( duplicate ) children
+ SFEntry* userData = reinterpret_cast<SFEntry*>(m_xScriptsBox->get_id(rEntry).toInt64());
+ if ( userData && !userData->isLoaded() )
+ {
+ userData->setLoaded();
+ }
+ }
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ OUString aError( m_createErrStr );
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_createErrTitleStr);
+ xErrorBox->run();
+ }
+}
+
+void SvxScriptOrgDialog::renameEntry(const weld::TreeIter& rEntry)
+{
+
+ Reference< browse::XBrowseNode > aChildNode;
+ Reference< browse::XBrowseNode > node = getBrowseNode(rEntry);
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+
+ if ( xInv.is() )
+ {
+ OUString aNewName = node->getName();
+ sal_Int32 extnPos = aNewName.lastIndexOf( '.' );
+ if(extnPos>0)
+ {
+ aNewName = aNewName.copy(0,extnPos);
+ }
+ CuiInputDialog aNewDlg(m_xDialog.get(), InputDialogMode::RENAME);
+ aNewDlg.SetObjectName(aNewName);
+
+ if (!aNewDlg.run() || aNewDlg.GetObjectName().isEmpty())
+ return; // user hit cancel or hit OK with nothing in the editbox
+
+ aNewName = aNewDlg.GetObjectName();
+
+ Sequence< Any > args( 1 );
+ args[ 0 ] <<= aNewName;
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Renamable", args, outIndex, outArgs );
+ Reference< browse::XBrowseNode > newNode( aResult, UNO_QUERY );
+ aChildNode = newNode;
+
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to Rename" );
+ }
+ }
+ if ( aChildNode.is() )
+ {
+ m_xScriptsBox->set_text(rEntry, aChildNode->getName());
+ m_xScriptsBox->set_cursor(rEntry);
+ m_xScriptsBox->select(rEntry);
+
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ OUString aError( m_renameErrStr );
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, aError));
+ xErrorBox->set_title(m_renameErrTitleStr);
+ xErrorBox->run();
+ }
+}
+
+void SvxScriptOrgDialog::deleteEntry(weld::TreeIter& rEntry)
+{
+ bool result = false;
+ Reference< browse::XBrowseNode > node = getBrowseNode(rEntry);
+ // ISSUE L10N string & can we center list?
+ OUString aQuery = m_delQueryStr + getListOfChildren( node, 0 );
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo, aQuery));
+ xQueryBox->set_title(m_delQueryTitleStr);
+ if (xQueryBox->run() == RET_NO)
+ {
+ return;
+ }
+
+ Reference< script::XInvocation > xInv( node, UNO_QUERY );
+ if ( xInv.is() )
+ {
+ Sequence< Any > args( 0 );
+ Sequence< Any > outArgs( 0 );
+ Sequence< sal_Int16 > outIndex;
+ try
+ {
+ Any aResult = xInv->invoke( "Deletable", args, outIndex, outArgs );
+ aResult >>= result; // or do we just assume true if no exception ?
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION("cui.dialogs", "Caught exception trying to delete" );
+ }
+ }
+
+ if ( result )
+ {
+ deleteTree(rEntry);
+ m_xScriptsBox->remove(rEntry);
+ }
+ else
+ {
+ //ISSUE L10N & message from exception?
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, m_delErrStr));
+ xErrorBox->set_title(m_delErrTitleStr);
+ xErrorBox->run();
+ }
+
+}
+
+bool SvxScriptOrgDialog::getBoolProperty( Reference< beans::XPropertySet > const & xProps,
+ OUString const & propName )
+{
+ bool result = false;
+ try
+ {
+ xProps->getPropertyValue( propName ) >>= result;
+ }
+ catch ( Exception& )
+ {
+ return result;
+ }
+ return result;
+}
+
+OUString SvxScriptOrgDialog::getListOfChildren( const Reference< browse::XBrowseNode >& node, int depth )
+{
+ OUStringBuffer result = "\n";
+ for( int i=0;i<=depth;i++ )
+ {
+ result.append("\t");
+ }
+ result.append(node->getName());
+
+ try
+ {
+ if ( node->hasChildNodes() )
+ {
+ const Sequence< Reference< browse::XBrowseNode > > children
+ = node->getChildNodes();
+ for( const Reference< browse::XBrowseNode >& n : children )
+ {
+ result.append( getListOfChildren( n , depth+1 ) );
+ }
+ }
+ }
+ catch ( Exception& )
+ {
+ // ignore, will return an empty string
+ }
+
+ return result.makeStringAndClear();
+}
+
+Selection_hash SvxScriptOrgDialog::m_lastSelection;
+
+void SvxScriptOrgDialog::StoreCurrentSelection()
+{
+ std::unique_ptr<weld::TreeIter> xIter = m_xScriptsBox->make_iterator();
+ if (!m_xScriptsBox->get_selected(xIter.get()))
+ return;
+ OUString aDescription;
+ bool bEntry;
+ do
+ {
+ aDescription = m_xScriptsBox->get_text(*xIter) + aDescription;
+ bEntry = m_xScriptsBox->iter_parent(*xIter);
+ if (bEntry)
+ aDescription = ";" + aDescription;
+ }
+ while (bEntry);
+ OUString sDesc( aDescription );
+ m_lastSelection[ m_sLanguage ] = sDesc;
+}
+
+void SvxScriptOrgDialog::RestorePreviousSelection()
+{
+ OUString aStoredEntry = m_lastSelection[ m_sLanguage ];
+ if( aStoredEntry.isEmpty() )
+ return;
+ std::unique_ptr<weld::TreeIter> xEntry;
+ std::unique_ptr<weld::TreeIter> xTmpEntry(m_xScriptsBox->make_iterator());
+ sal_Int32 nIndex = 0;
+ while (nIndex != -1)
+ {
+ OUString aTmp( aStoredEntry.getToken( 0, ';', nIndex ) );
+
+ bool bTmpEntry;
+ if (!xEntry)
+ {
+ xEntry = m_xScriptsBox->make_iterator();
+ bTmpEntry = m_xScriptsBox->get_iter_first(*xEntry);
+ m_xScriptsBox->copy_iterator(*xEntry, *xTmpEntry);
+ }
+ else
+ {
+ m_xScriptsBox->copy_iterator(*xEntry, *xTmpEntry);
+ bTmpEntry = m_xScriptsBox->iter_children(*xTmpEntry);
+ }
+
+ while (bTmpEntry)
+ {
+ if (m_xScriptsBox->get_text(*xTmpEntry) == aTmp)
+ {
+ m_xScriptsBox->copy_iterator(*xTmpEntry, *xEntry);
+ break;
+ }
+ bTmpEntry = m_xScriptsBox->iter_next_sibling(*xTmpEntry);
+ }
+
+ if (!bTmpEntry)
+ break;
+
+ m_xScriptsBox->expand_row(*xEntry);
+ }
+
+ if (xEntry)
+ m_xScriptsBox->set_cursor(*xEntry);
+}
+
+namespace {
+
+OUString ReplaceString(
+ const OUString& source,
+ const OUString& token,
+ const OUString& value )
+{
+ sal_Int32 pos = source.indexOf( token );
+
+ if ( pos != -1 && !value.isEmpty() )
+ {
+ return source.replaceAt( pos, token.getLength(), value );
+ }
+ else
+ {
+ return source;
+ }
+}
+
+OUString FormatErrorString(
+ const OUString& unformatted,
+ const OUString& language,
+ const OUString& script,
+ const OUString& line,
+ const OUString& type,
+ const OUString& message )
+{
+ OUString result = unformatted.copy( 0 );
+
+ result = ReplaceString(result, "%LANGUAGENAME", language );
+ result = ReplaceString(result, "%SCRIPTNAME", script );
+ result = ReplaceString(result, "%LINENUMBER", line );
+
+ if ( !type.isEmpty() )
+ {
+ result += "\n\n" + CuiResId(RID_SVXSTR_ERROR_TYPE_LABEL) + " " + type;
+ }
+
+ if ( !message.isEmpty() )
+ {
+ result += "\n\n" + CuiResId(RID_SVXSTR_ERROR_MESSAGE_LABEL) + " " + message;
+ }
+
+ return result;
+}
+
+OUString GetErrorMessage(
+ const provider::ScriptErrorRaisedException& eScriptError )
+{
+ OUString unformatted = CuiResId( RID_SVXSTR_ERROR_AT_LINE );
+
+ OUString unknown("UNKNOWN");
+ OUString language = unknown;
+ OUString script = unknown;
+ OUString line = unknown;
+ OUString type = "";
+ OUString message = eScriptError.Message;
+
+ if ( !eScriptError.language.isEmpty() )
+ {
+ language = eScriptError.language;
+ }
+
+ if ( !eScriptError.scriptName.isEmpty() )
+ {
+ script = eScriptError.scriptName;
+ }
+
+ if ( !eScriptError.Message.isEmpty() )
+ {
+ message = eScriptError.Message;
+ }
+ if ( eScriptError.lineNum != -1 )
+ {
+ line = OUString::number( eScriptError.lineNum );
+ unformatted = CuiResId( RID_SVXSTR_ERROR_AT_LINE );
+ }
+ else
+ {
+ unformatted = CuiResId( RID_SVXSTR_ERROR_RUNNING );
+ }
+
+ return FormatErrorString(
+ unformatted, language, script, line, type, message );
+}
+
+OUString GetErrorMessage(
+ const provider::ScriptExceptionRaisedException& eScriptException )
+{
+ OUString unformatted = CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE );
+
+ OUString unknown("UNKNOWN");
+ OUString language = unknown;
+ OUString script = unknown;
+ OUString line = unknown;
+ OUString type = unknown;
+ OUString message = eScriptException.Message;
+
+ if ( !eScriptException.language.isEmpty() )
+ {
+ language = eScriptException.language;
+ }
+ if ( !eScriptException.scriptName.isEmpty() )
+ {
+ script = eScriptException.scriptName;
+ }
+
+ if ( !eScriptException.Message.isEmpty() )
+ {
+ message = eScriptException.Message;
+ }
+
+ if ( eScriptException.lineNum != -1 )
+ {
+ line = OUString::number( eScriptException.lineNum );
+ unformatted = CuiResId( RID_SVXSTR_EXCEPTION_AT_LINE );
+ }
+ else
+ {
+ unformatted = CuiResId( RID_SVXSTR_EXCEPTION_RUNNING );
+ }
+
+ if ( !eScriptException.exceptionType.isEmpty() )
+ {
+ type = eScriptException.exceptionType;
+ }
+
+ return FormatErrorString(
+ unformatted, language, script, line, type, message );
+
+}
+OUString GetErrorMessage(
+ const provider::ScriptFrameworkErrorException& sError )
+{
+ OUString unformatted = CuiResId( RID_SVXSTR_FRAMEWORK_ERROR_RUNNING );
+
+ OUString language("UNKNOWN");
+
+ OUString script("UNKNOWN");
+
+ OUString message;
+
+ if ( !sError.scriptName.isEmpty() )
+ {
+ script = sError.scriptName;
+ }
+ if ( !sError.language.isEmpty() )
+ {
+ language = sError.language;
+ }
+ if ( sError.errorType == provider::ScriptFrameworkErrorType::NOTSUPPORTED )
+ {
+ message =
+ CuiResId( RID_SVXSTR_ERROR_LANG_NOT_SUPPORTED );
+ message = ReplaceString(message, "%LANGUAGENAME", language );
+
+ }
+ else
+ {
+ message = sError.Message;
+ }
+ return FormatErrorString(
+ unformatted, language, script, OUString(), OUString(), message );
+}
+
+OUString GetErrorMessage( const css::uno::Any& aException )
+{
+ if ( aException.getValueType() ==
+ cppu::UnoType<reflection::InvocationTargetException>::get())
+ {
+ reflection::InvocationTargetException ite;
+ aException >>= ite;
+ if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptErrorRaisedException>::get())
+ {
+ // Error raised by script
+ provider::ScriptErrorRaisedException scriptError;
+ ite.TargetException >>= scriptError;
+ return GetErrorMessage( scriptError );
+ }
+ else if ( ite.TargetException.getValueType() == cppu::UnoType<provider::ScriptExceptionRaisedException>::get())
+ {
+ // Exception raised by script
+ provider::ScriptExceptionRaisedException scriptException;
+ ite.TargetException >>= scriptException;
+ return GetErrorMessage( scriptException );
+ }
+ else
+ {
+ // Unknown error, shouldn't happen
+ // OSL_ASSERT(...)
+ }
+
+ }
+ else if ( aException.getValueType() == cppu::UnoType<provider::ScriptFrameworkErrorException>::get())
+ {
+ // A Script Framework error has occurred
+ provider::ScriptFrameworkErrorException sfe;
+ aException >>= sfe;
+ return GetErrorMessage( sfe );
+
+ }
+ // unknown exception
+ auto msg = aException.getValueTypeName();
+ Exception e;
+ if ( (aException >>= e) && !e.Message.isEmpty() )
+ {
+ msg += ": " + e.Message;
+ }
+ return msg;
+}
+
+}
+
+SvxScriptErrorDialog::SvxScriptErrorDialog( css::uno::Any const & aException )
+ : m_sMessage()
+{
+ SolarMutexGuard aGuard;
+ m_sMessage = GetErrorMessage( aException );
+}
+
+SvxScriptErrorDialog::~SvxScriptErrorDialog()
+{
+}
+
+short SvxScriptErrorDialog::Execute()
+{
+ // Show Error dialog asynchronously
+
+ // Pass a copy of the message to the ShowDialog method as the
+ // SvxScriptErrorDialog may be deleted before ShowDialog is called
+ Application::PostUserEvent(
+ LINK( this, SvxScriptErrorDialog, ShowDialog ),
+ new OUString( m_sMessage ) );
+
+ return 0;
+}
+
+IMPL_STATIC_LINK( SvxScriptErrorDialog, ShowDialog, void*, p, void )
+{
+ OUString* pMessage = static_cast<OUString*>(p);
+ OUString message;
+
+ if ( pMessage && !pMessage->isEmpty() )
+ {
+ message = *pMessage;
+ }
+ else
+ {
+ message = CuiResId( RID_SVXSTR_ERROR_TITLE );
+ }
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(nullptr,
+ VclMessageType::Warning, VclButtonsType::Ok, message));
+ xBox->set_title(CuiResId(RID_SVXSTR_ERROR_TITLE));
+ xBox->run();
+
+ delete pMessage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/sdrcelldlg.cxx b/cui/source/dialogs/sdrcelldlg.cxx
new file mode 100644
index 000000000..3c745692f
--- /dev/null
+++ b/cui/source/dialogs/sdrcelldlg.cxx
@@ -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 .
+ */
+
+#include <sdrcelldlg.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svdmodel.hxx>
+#include <border.hxx>
+#include <svx/dialogs.hrc>
+
+SvxFormatCellsDialog::SvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel)
+ : SfxTabDialogController(pParent, "cui/ui/formatcellsdialog.ui", "FormatCellsDialog", pAttr)
+ , mrOutAttrs(*pAttr)
+ , mpColorTab(rModel.GetColorList())
+ , mpGradientList(rModel.GetGradientList())
+ , mpHatchingList(rModel.GetHatchList())
+ , mpBitmapList(rModel.GetBitmapList())
+ , mpPatternList(rModel.GetPatternList())
+{
+ AddTabPage("name", RID_SVXPAGE_CHAR_NAME);
+ AddTabPage("effects", RID_SVXPAGE_CHAR_EFFECTS);
+ AddTabPage("border", RID_SVXPAGE_BORDER );
+ AddTabPage("area", RID_SVXPAGE_AREA);
+}
+
+void SvxFormatCellsDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "area")
+ {
+ SvxAreaTabPage& rAreaPage = static_cast<SvxAreaTabPage&>(rPage);
+ rAreaPage.SetColorList( mpColorTab );
+ rAreaPage.SetGradientList( mpGradientList );
+ rAreaPage.SetHatchingList( mpHatchingList );
+ rAreaPage.SetBitmapList( mpBitmapList );
+ rAreaPage.SetPatternList( mpPatternList );
+ rAreaPage.ActivatePage( mrOutAttrs );
+ }
+ else if (rId == "border")
+ {
+ SvxBorderTabPage& rBorderPage = static_cast<SvxBorderTabPage&>(rPage);
+ rBorderPage.SetTableMode();
+ }
+ else
+ SfxTabDialogController::PageCreated(rId, rPage);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/showcols.cxx b/cui/source/dialogs/showcols.cxx
new file mode 100644
index 000000000..895ed485e
--- /dev/null
+++ b/cui/source/dialogs/showcols.cxx
@@ -0,0 +1,107 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <showcols.hxx>
+
+#include <osl/diagnose.h>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <comphelper/types.hxx>
+#include <tools/debug.hxx>
+
+#define CUIFM_PROP_HIDDEN "Hidden"
+#define CUIFM_PROP_LABEL "Label"
+
+FmShowColsDialog::FmShowColsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/showcoldialog.ui", "ShowColDialog")
+ , m_xList(m_xBuilder->weld_tree_view("treeview"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+{
+ m_xList->set_size_request(m_xList->get_approximate_digit_width() * 40, m_xList->get_height_rows(8));
+ m_xList->set_selection_mode(SelectionMode::Multiple);
+ m_xOK->connect_clicked(LINK(this, FmShowColsDialog, OnClickedOk));
+}
+
+FmShowColsDialog::~FmShowColsDialog()
+{
+}
+
+IMPL_LINK_NOARG(FmShowColsDialog, OnClickedOk, weld::Button&, void)
+{
+ DBG_ASSERT(m_xColumns.is(), "FmShowColsDialog::OnClickedOk : you should call SetColumns before executing the dialog !");
+ if (m_xColumns.is())
+ {
+ css::uno::Reference< css::beans::XPropertySet > xCol;
+ auto nSelectedRows = m_xList->get_selected_rows();
+ for (auto i : nSelectedRows)
+ {
+ m_xColumns->getByIndex(m_xList->get_id(i).toInt32()) >>= xCol;
+ if (xCol.is())
+ {
+ try
+ {
+ xCol->setPropertyValue(CUIFM_PROP_HIDDEN, css::uno::Any(false));
+ }
+ catch(...)
+ {
+ OSL_FAIL("FmShowColsDialog::OnClickedOk Exception occurred!");
+ }
+ }
+ }
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+void FmShowColsDialog::SetColumns(const css::uno::Reference< css::container::XIndexContainer>& xCols)
+{
+ DBG_ASSERT(xCols.is(), "FmShowColsDialog::SetColumns : invalid columns !");
+ if (!xCols.is())
+ return;
+ m_xColumns = xCols.get();
+
+ m_xList->clear();
+
+ css::uno::Reference< css::beans::XPropertySet> xCurCol;
+ OUString sCurName;
+ for (sal_Int32 i=0; i<xCols->getCount(); ++i)
+ {
+ sCurName.clear();
+ xCurCol.set(xCols->getByIndex(i), css::uno::UNO_QUERY);
+ bool bIsHidden = false;
+ try
+ {
+ css::uno::Any aHidden = xCurCol->getPropertyValue(CUIFM_PROP_HIDDEN);
+ bIsHidden = ::comphelper::getBOOL(aHidden);
+
+ OUString sName;
+ xCurCol->getPropertyValue(CUIFM_PROP_LABEL) >>= sName;
+ sCurName = sName;
+ }
+ catch(...)
+ {
+ OSL_FAIL("FmShowColsDialog::SetColumns Exception occurred!");
+ }
+
+ // if the col is hidden, put it into the list
+ if (bIsHidden)
+ m_xList->append(OUString::number(i), sCurName);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/splitcelldlg.cxx b/cui/source/dialogs/splitcelldlg.cxx
new file mode 100644
index 000000000..40b798b7c
--- /dev/null
+++ b/cui/source/dialogs/splitcelldlg.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <splitcelldlg.hxx>
+
+SvxSplitTableDlg::SvxSplitTableDlg(weld::Window *pParent, bool bIsTableVertical, long nMaxVertical, long nMaxHorizontal)
+ : GenericDialogController(pParent, "cui/ui/splitcellsdialog.ui", "SplitCellsDialog")
+ , m_xCountEdit(m_xBuilder->weld_spin_button("countnf"))
+ , m_xHorzBox(!bIsTableVertical ? m_xBuilder->weld_radio_button("hori") : m_xBuilder->weld_radio_button("vert"))
+ , m_xVertBox(!bIsTableVertical ? m_xBuilder->weld_radio_button("vert") : m_xBuilder->weld_radio_button("hori"))
+ , m_xPropCB(m_xBuilder->weld_check_button("prop"))
+ , mnMaxVertical(nMaxVertical)
+ , mnMaxHorizontal(nMaxHorizontal)
+{
+ m_xHorzBox->connect_clicked(LINK(this, SvxSplitTableDlg, ClickHdl));
+ m_xPropCB->connect_clicked(LINK(this, SvxSplitTableDlg, ClickHdl));
+ m_xVertBox->connect_clicked(LINK(this, SvxSplitTableDlg, ClickHdl));
+
+ if (mnMaxVertical < 2)
+ {
+ if (!bIsTableVertical)
+ m_xVertBox->set_sensitive(false);
+ else
+ m_xHorzBox->set_sensitive(false);
+ }
+
+ //exchange the meaning of horizontal and vertical for vertical text
+ if (bIsTableVertical)
+ {
+ int nHorzTopAttach = m_xHorzBox->get_grid_top_attach();
+ int nVertTopAttach = m_xVertBox->get_grid_top_attach();
+ m_xHorzBox->set_grid_top_attach(nVertTopAttach);
+ m_xVertBox->set_grid_top_attach(nHorzTopAttach);
+ m_xHorzBox->set_active(m_xVertBox->get_active());
+ }
+}
+
+IMPL_LINK(SvxSplitTableDlg, ClickHdl, weld::Button&, rButton, void)
+{
+ const bool bIsVert = &rButton == m_xVertBox.get();
+ long nMax = bIsVert ? mnMaxVertical : mnMaxHorizontal;
+ m_xPropCB->set_sensitive(!bIsVert);
+ m_xCountEdit->set_max(nMax);
+}
+
+bool SvxSplitTableDlg::IsHorizontal() const
+{
+ return m_xHorzBox->get_active();
+}
+
+bool SvxSplitTableDlg::IsProportional() const
+{
+ return m_xPropCB->get_active() && m_xHorzBox->get_active();
+}
+
+long SvxSplitTableDlg::GetCount() const
+{
+ return m_xCountEdit->get_value();
+}
+
+short SvxSplitTableDlg::Execute()
+{
+ return run();
+}
+
+void SvxSplitTableDlg::SetSplitVerticalByDefault()
+{
+ if( mnMaxVertical >= 2 )
+ m_xVertBox->set_active(true); // tdf#60242
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/srchxtra.cxx b/cui/source/dialogs/srchxtra.cxx
new file mode 100644
index 000000000..2a68293f0
--- /dev/null
+++ b/cui/source/dialogs/srchxtra.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 <srchxtra.hxx>
+#include <sal/log.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <svl/whiter.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/strarray.hxx>
+#include <editeng/flstitem.hxx>
+#include <chardlg.hxx>
+#include <paragrph.hxx>
+#include <backgrnd.hxx>
+#include <editeng/editids.hrc>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <tools/resary.hxx>
+#include <vcl/svapp.hxx>
+
+SvxSearchFormatDialog::SvxSearchFormatDialog(weld::Window* pParent, const SfxItemSet& rSet)
+ : SfxTabDialogController(pParent, "cui/ui/searchformatdialog.ui", "SearchFormatDialog", &rSet)
+{
+ AddTabPage("font", SvxCharNamePage::Create, nullptr);
+ AddTabPage("fonteffects", SvxCharEffectsPage::Create, nullptr);
+ AddTabPage("position", SvxCharPositionPage::Create, nullptr);
+ AddTabPage("asianlayout", SvxCharTwoLinesPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_STD", SvxStdParagraphTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_ALIGN", SvxParaAlignTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_EXT", SvxExtParagraphTabPage::Create, nullptr);
+ AddTabPage("labelTP_PARA_ASIAN", SvxAsianTabPage::Create, nullptr );
+ AddTabPage("background", SvxBkgTabPage::Create, nullptr);
+
+ // remove asian tabpages if necessary
+ SvtCJKOptions aCJKOptions;
+ if ( !aCJKOptions.IsDoubleLinesEnabled() )
+ RemoveTabPage("asianlayout");
+ if ( !aCJKOptions.IsAsianTypographyEnabled() )
+ RemoveTabPage("labelTP_PARA_ASIAN");
+}
+
+SvxSearchFormatDialog::~SvxSearchFormatDialog()
+{
+}
+
+void SvxSearchFormatDialog::PageCreated(const OString& rId, SfxTabPage& rPage)
+{
+ if (rId == "font")
+ {
+ const FontList* pApm_pFontList = nullptr;
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+
+ if ( pSh )
+ {
+ const SvxFontListItem* pFLItem = static_cast<const SvxFontListItem*>(
+ pSh->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ if ( pFLItem )
+ pApm_pFontList = pFLItem->GetFontList();
+ }
+
+ const FontList* pList = pApm_pFontList;
+
+ if ( !pList )
+ {
+ if ( !m_pFontList )
+ m_pFontList.reset(new FontList(Application::GetDefaultDevice()));
+ pList = m_pFontList.get();
+ }
+
+ static_cast<SvxCharNamePage&>(rPage).
+ SetFontList( SvxFontListItem( pList, SID_ATTR_CHAR_FONTLIST ) );
+ static_cast<SvxCharNamePage&>(rPage).EnableSearchMode();
+ }
+ else if (rId == "labelTP_PARA_STD")
+ {
+ static_cast<SvxStdParagraphTabPage&>(rPage).EnableAutoFirstLine();
+ }
+ else if (rId == "labelTP_PARA_ALIGN")
+ {
+ static_cast<SvxParaAlignTabPage&>(rPage).EnableJustifyExt();
+ }
+ else if (rId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE,static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_HIGHLIGHTING)));
+ rPage.PageCreated(aSet);
+ }
+}
+
+SvxSearchAttributeDialog::SvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst, const sal_uInt16* pWhRanges)
+ : GenericDialogController(pParent, "cui/ui/searchattrdialog.ui", "SearchAttrDialog")
+ , rList(rLst)
+ , m_xAttrLB(m_xBuilder->weld_tree_view("treeview"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ m_xAttrLB->set_size_request(m_xAttrLB->get_approximate_digit_width() * 50,
+ m_xAttrLB->get_height_rows(12));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xAttrLB->get_checkbox_column_width());
+ m_xAttrLB->set_column_fixed_widths(aWidths);
+
+ m_xOKBtn->connect_clicked(LINK( this, SvxSearchAttributeDialog, OKHdl));
+
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+ DBG_ASSERT( pSh, "No DocShell" );
+
+ SfxItemPool& rPool = pSh->GetPool();
+ SfxItemSet aSet( rPool, pWhRanges );
+ SfxWhichIter aIter( aSet );
+ sal_uInt16 nWhich = aIter.FirstWhich();
+
+ while ( nWhich )
+ {
+ sal_uInt16 nSlot = rPool.GetSlotId( nWhich );
+ if ( nSlot >= SID_SVX_START )
+ {
+ bool bChecked = false, bFound = false;
+ for ( sal_uInt16 i = 0; !bFound && i < rList.Count(); ++i )
+ {
+ if ( nSlot == rList[i].nSlot )
+ {
+ bFound = true;
+ if ( IsInvalidItem( rList[i].pItem ) )
+ bChecked = true;
+ }
+ }
+
+ // item resources are in svx
+ sal_uInt32 nId = SvxAttrNameTable::FindIndex(nSlot);
+ if (RESARRAY_INDEX_NOTFOUND != nId)
+ {
+ m_xAttrLB->append();
+ const int nRow = m_xAttrLB->n_children() - 1;
+ m_xAttrLB->set_toggle(nRow, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xAttrLB->set_text(nRow, SvxAttrNameTable::GetString(nId), 1);
+ m_xAttrLB->set_id(nRow, OUString::number(nSlot));
+ }
+ else
+ SAL_WARN( "cui.dialogs", "no resource for slot id " << static_cast<sal_Int32>(nSlot) );
+ }
+ nWhich = aIter.NextWhich();
+ }
+
+ m_xAttrLB->make_sorted();
+ m_xAttrLB->select(0);
+}
+
+SvxSearchAttributeDialog::~SvxSearchAttributeDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxSearchAttributeDialog, OKHdl, weld::Button&, void)
+{
+ SearchAttrItem aInvalidItem;
+ aInvalidItem.pItem = INVALID_POOL_ITEM;
+
+ for (int i = 0, nCount = m_xAttrLB->n_children(); i < nCount; ++i)
+ {
+ sal_uInt16 nSlot = m_xAttrLB->get_id(i).toUInt32();
+ bool bChecked = m_xAttrLB->get_toggle(i, 0) == TRISTATE_TRUE;
+
+ sal_uInt16 j;
+ for ( j = rList.Count(); j; )
+ {
+ SearchAttrItem& rItem = rList[ --j ];
+ if( rItem.nSlot == nSlot )
+ {
+ if( bChecked )
+ {
+ if( !IsInvalidItem( rItem.pItem ) )
+ delete rItem.pItem;
+ rItem.pItem = INVALID_POOL_ITEM;
+ }
+ else if( IsInvalidItem( rItem.pItem ) )
+ rItem.pItem = nullptr;
+ j = 1;
+ break;
+ }
+ }
+
+ if ( !j && bChecked )
+ {
+ aInvalidItem.nSlot = nSlot;
+ rList.Insert( aInvalidItem );
+ }
+ }
+
+ // remove invalid items (pItem == NULL)
+ for ( sal_uInt16 n = rList.Count(); n; )
+ if ( !rList[ --n ].pItem )
+ rList.Remove( n );
+
+ m_xDialog->response(RET_OK);
+}
+
+// class SvxSearchSimilarityDialog ---------------------------------------
+
+SvxSearchSimilarityDialog::SvxSearchSimilarityDialog(weld::Window* pParent, bool bRelax,
+ sal_uInt16 nOther, sal_uInt16 nShorter, sal_uInt16 nLonger)
+ : GenericDialogController(pParent, "cui/ui/similaritysearchdialog.ui", "SimilaritySearchDialog")
+ , m_xOtherFld(m_xBuilder->weld_spin_button("otherfld"))
+ , m_xLongerFld(m_xBuilder->weld_spin_button("longerfld"))
+ , m_xShorterFld(m_xBuilder->weld_spin_button("shorterfld"))
+ , m_xRelaxBox(m_xBuilder->weld_check_button("relaxbox"))
+{
+ m_xOtherFld->set_value(nOther);
+ m_xShorterFld->set_value(nShorter);
+ m_xLongerFld->set_value(nLonger);
+ m_xRelaxBox->set_active(bRelax);
+}
+
+SvxSearchSimilarityDialog::~SvxSearchSimilarityDialog()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/thesdlg.cxx b/cui/source/dialogs/thesdlg.cxx
new file mode 100644
index 000000000..612f5fe01
--- /dev/null
+++ b/cui/source/dialogs/thesdlg.cxx
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <thesdlg.hxx>
+
+#include <tools/debug.hxx>
+#include <svl/lngmisc.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/langtab.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <comphelper/string.hxx>
+
+#include <stack>
+#include <algorithm>
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XMeaning.hpp>
+
+using namespace ::com::sun::star;
+
+IMPL_LINK_NOARG( SvxThesaurusDialog, ModifyTimer_Hdl, Timer *, void )
+{
+ LookUp(m_xWordCB->get_active_text());
+ m_aModifyIdle.Stop();
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceEditHdl_Impl, weld::Entry&, void)
+{
+ m_xReplaceBtn->set_sensitive(!m_xReplaceEdit->get_text().isEmpty());
+}
+
+IMPL_LINK(SvxThesaurusDialog, KeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKey = rKEvt.GetKeyCode();
+
+ if (rKey.GetCode() == KEY_RETURN)
+ {
+ m_xDialog->response(RET_OK);
+ return true;
+ }
+
+ return false;
+}
+
+uno::Sequence< uno::Reference< linguistic2::XMeaning > > SvxThesaurusDialog::queryMeanings_Impl(
+ OUString& rTerm,
+ const lang::Locale& rLocale,
+ const beans::PropertyValues& rProperties )
+{
+ uno::Sequence< uno::Reference< linguistic2::XMeaning > > aMeanings(
+ xThesaurus->queryMeanings( rTerm, rLocale, rProperties ) );
+
+ // text with '.' at the end?
+ if ( !aMeanings.hasElements() && rTerm.endsWith(".") )
+ {
+ // try again without trailing '.' chars. It may be a word at the
+ // end of a sentence and not an abbreviation...
+ OUString aTxt(comphelper::string::stripEnd(rTerm, '.'));
+ aMeanings = xThesaurus->queryMeanings( aTxt, rLocale, rProperties );
+ if (aMeanings.hasElements())
+ {
+ rTerm = aTxt;
+ }
+ }
+
+ return aMeanings;
+}
+
+bool SvxThesaurusDialog::UpdateAlternativesBox_Impl()
+{
+ lang::Locale aLocale( LanguageTag::convertToLocale( nLookUpLanguage ) );
+ uno::Sequence< uno::Reference< linguistic2::XMeaning > > aMeanings = queryMeanings_Impl(
+ aLookUpText, aLocale, uno::Sequence< beans::PropertyValue >() );
+ const sal_Int32 nMeanings = aMeanings.getLength();
+ const uno::Reference< linguistic2::XMeaning > *pMeanings = aMeanings.getConstArray();
+
+ m_xAlternativesCT->freeze();
+
+ m_xAlternativesCT->clear();
+ int nRow = 0;
+ for (sal_Int32 i = 0; i < nMeanings; ++i)
+ {
+ OUString rMeaningTxt = pMeanings[i]->getMeaning();
+ uno::Sequence< OUString > aSynonyms( pMeanings[i]->querySynonyms() );
+ const sal_Int32 nSynonyms = aSynonyms.getLength();
+ const OUString *pSynonyms = aSynonyms.getConstArray();
+ DBG_ASSERT( !rMeaningTxt.isEmpty(), "meaning with empty text" );
+ DBG_ASSERT( nSynonyms > 0, "meaning without synonym" );
+
+ OUString sHeading = OUString::number(i + 1) + ". " + rMeaningTxt;
+ m_xAlternativesCT->append_text(sHeading);
+ m_xAlternativesCT->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ for (sal_Int32 k = 0; k < nSynonyms; ++k)
+ {
+ // GetThesaurusReplaceText will strip the leading spaces
+ m_xAlternativesCT->append_text(" " + pSynonyms[k]);
+ m_xAlternativesCT->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ m_xAlternativesCT->thaw();
+
+ return nMeanings > 0;
+}
+
+void SvxThesaurusDialog::LookUp( const OUString &rText )
+{
+ if (rText != m_xWordCB->get_active_text()) // avoid moving of the cursor if the text is the same
+ m_xWordCB->set_entry_text(rText);
+ LookUp_Impl();
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, LeftBtnHdl_Impl, weld::Button&, void)
+{
+ if (aLookUpHistory.size() >= 2)
+ {
+ aLookUpHistory.pop(); // remove current look up word from stack
+ m_xWordCB->set_entry_text(aLookUpHistory.top()); // retrieve previous look up word
+ aLookUpHistory.pop();
+ LookUp_Impl();
+ }
+}
+
+IMPL_LINK( SvxThesaurusDialog, LanguageHdl_Impl, weld::ComboBox&, rLB, void )
+{
+ OUString aLangText(rLB.get_active_text());
+ LanguageType nLang = SvtLanguageTable::GetLanguageType( aLangText );
+ DBG_ASSERT( nLang != LANGUAGE_NONE && nLang != LANGUAGE_DONTKNOW, "failed to get language" );
+ if (xThesaurus->hasLocale( LanguageTag::convertToLocale( nLang ) ))
+ nLookUpLanguage = nLang;
+ SetWindowTitle( nLang );
+ LookUp_Impl();
+}
+
+void SvxThesaurusDialog::LookUp_Impl()
+{
+ OUString aText(m_xWordCB->get_active_text());
+
+ aLookUpText = aText;
+ if (!aLookUpText.isEmpty() &&
+ (aLookUpHistory.empty() || aLookUpText != aLookUpHistory.top()))
+ aLookUpHistory.push( aLookUpText );
+
+ m_bWordFound = UpdateAlternativesBox_Impl();
+ m_xAlternativesCT->set_visible(m_bWordFound);
+ m_xNotFound->set_visible(!m_bWordFound);
+
+ if (m_bWordFound)
+ Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));
+
+ if (m_xWordCB->find_text(aText) == -1)
+ m_xWordCB->append_text(aText);
+
+ m_xReplaceEdit->set_text( OUString() );
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ m_xLeftBtn->set_sensitive( aLookUpHistory.size() > 1 );
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, WordSelectHdl_Impl, weld::ComboBox&, void)
+{
+ m_aModifyIdle.Start();
+}
+
+IMPL_LINK( SvxThesaurusDialog, AlternativesSelectHdl_Impl, weld::TreeView&, rBox, void )
+{
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
+ if (bIsHeader)
+ {
+ ++nEntry;
+ rBox.select(nEntry);
+ }
+ OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
+ m_xReplaceEdit->set_text(aStr);
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ }
+}
+
+IMPL_LINK( SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl, weld::TreeView&, rBox, bool )
+{
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ bool bIsHeader = rBox.get_text_emphasis(nEntry, 0);
+ if (bIsHeader)
+ {
+ ++nEntry;
+ rBox.select(nEntry);
+ }
+ OUString aStr = linguistic::GetThesaurusReplaceText(rBox.get_text(nEntry));
+ m_xWordCB->set_entry_text(aStr);
+ if (!aStr.isEmpty())
+ LookUp_Impl();
+ }
+
+ //! workaround to set the selection since calling SelectEntryPos within
+ //! the double click handler does not work
+ Application::PostUserEvent(LINK(this, SvxThesaurusDialog, SelectFirstHdl_Impl));
+
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, SelectFirstHdl_Impl, void *, void)
+{
+ if (m_xAlternativesCT->n_children() >= 2)
+ {
+ m_xAlternativesCT->select(1); // pos 0 is a 'header' that is not selectable
+ AlternativesSelectHdl_Impl(*m_xAlternativesCT);
+ }
+}
+
+// class SvxThesaurusDialog ----------------------------------------------
+
+SvxThesaurusDialog::SvxThesaurusDialog(
+ weld::Window* pParent,
+ uno::Reference< linguistic2::XThesaurus > const & xThes,
+ const OUString &rWord,
+ LanguageType nLanguage)
+ : SfxDialogController(pParent, "cui/ui/thesaurus.ui", "ThesaurusDialog")
+ , m_aModifyIdle("cui SvxThesaurusDialog LookUp Modify")
+ , aLookUpText()
+ , nLookUpLanguage(LANGUAGE_NONE)
+ , m_bWordFound(false)
+ , m_xLeftBtn(m_xBuilder->weld_button("left"))
+ , m_xWordCB(m_xBuilder->weld_combo_box("wordcb"))
+ , m_xAlternativesCT(m_xBuilder->weld_tree_view("alternatives"))
+ , m_xNotFound(m_xBuilder->weld_label("notfound"))
+ , m_xReplaceEdit(m_xBuilder->weld_entry("replaceed"))
+ , m_xLangLB(m_xBuilder->weld_combo_box("langcb"))
+ , m_xReplaceBtn(m_xBuilder->weld_button("ok"))
+{
+ m_aModifyIdle.SetInvokeHandler( LINK( this, SvxThesaurusDialog, ModifyTimer_Hdl ) );
+ m_aModifyIdle.SetPriority( TaskPriority::LOWEST );
+
+ m_xReplaceEdit->connect_changed( LINK( this, SvxThesaurusDialog, ReplaceEditHdl_Impl ) );
+ m_xReplaceBtn->connect_clicked( LINK( this, SvxThesaurusDialog, ReplaceBtnHdl_Impl ) );
+ m_xLeftBtn->connect_clicked( LINK( this, SvxThesaurusDialog, LeftBtnHdl_Impl ) );
+ m_xWordCB->set_entry_completion(false);
+ m_xWordCB->connect_changed( LINK( this, SvxThesaurusDialog, WordSelectHdl_Impl ) );
+ m_xLangLB->connect_changed( LINK( this, SvxThesaurusDialog, LanguageHdl_Impl ) );
+ m_xAlternativesCT->connect_changed( LINK( this, SvxThesaurusDialog, AlternativesSelectHdl_Impl ));
+ m_xAlternativesCT->connect_row_activated( LINK( this, SvxThesaurusDialog, AlternativesDoubleClickHdl_Impl ));
+ m_xAlternativesCT->connect_key_press(LINK(this, SvxThesaurusDialog, KeyInputHdl));
+
+ xThesaurus = xThes;
+ aLookUpText = rWord;
+ nLookUpLanguage = nLanguage;
+ if (!rWord.isEmpty())
+ aLookUpHistory.push( rWord );
+
+ OUString aTmp( rWord );
+ (void)linguistic::RemoveHyphens( aTmp );
+ (void)linguistic::ReplaceControlChars( aTmp );
+ m_xReplaceEdit->set_text( aTmp );
+ ReplaceEditHdl_Impl(*m_xReplaceEdit);
+ m_xWordCB->append_text( aTmp );
+
+ LookUp( aTmp );
+ m_xAlternativesCT->grab_focus();
+ m_xLeftBtn->set_sensitive(false);
+
+ // fill language menu button list
+ uno::Sequence< lang::Locale > aLocales;
+ if (xThesaurus.is())
+ aLocales = xThesaurus->getLocales();
+ const sal_Int32 nLocales = aLocales.getLength();
+ const lang::Locale *pLocales = aLocales.getConstArray();
+ m_xLangLB->clear();
+ std::vector< OUString > aLangVec;
+ for (sal_Int32 i = 0; i < nLocales; ++i)
+ {
+ const LanguageType nLang = LanguageTag::convertToLanguageType( pLocales[i] );
+ DBG_ASSERT( nLang != LANGUAGE_NONE && nLang != LANGUAGE_DONTKNOW, "failed to get language" );
+ aLangVec.push_back( SvtLanguageTable::GetLanguageString( nLang ) );
+ }
+ std::sort( aLangVec.begin(), aLangVec.end() );
+ m_xLangLB->freeze();
+ for (const OUString & i : aLangVec)
+ m_xLangLB->append_text(i);
+ m_xLangLB->thaw();
+
+ std::vector< OUString >::iterator aI = std::find(aLangVec.begin(), aLangVec.end(),
+ SvtLanguageTable::GetLanguageString(nLanguage));
+ if (aI != aLangVec.end())
+ {
+ m_xLangLB->set_active_text(*aI);
+ }
+
+ SetWindowTitle(nLanguage);
+
+ // disable controls if service is missing
+ if (!xThesaurus.is())
+ m_xDialog->set_sensitive(false);
+}
+
+SvxThesaurusDialog::~SvxThesaurusDialog()
+{
+}
+
+IMPL_LINK_NOARG(SvxThesaurusDialog, ReplaceBtnHdl_Impl, weld::Button&, void)
+{
+ m_xDialog->response(RET_OK);
+}
+
+void SvxThesaurusDialog::SetWindowTitle( LanguageType nLanguage )
+{
+ // adjust language
+ OUString aStr(m_xDialog->get_title());
+ sal_Int32 nIndex = aStr.indexOf( '(' );
+ if( nIndex != -1 )
+ aStr = aStr.copy( 0, nIndex - 1 );
+ aStr += " (" + SvtLanguageTable::GetLanguageString( nLanguage ) + ")";
+ m_xDialog->set_title(aStr); // set window title
+}
+
+OUString SvxThesaurusDialog::GetWord() const
+{
+ return m_xReplaceEdit->get_text();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/tipofthedaydlg.cxx b/cui/source/dialogs/tipofthedaydlg.cxx
new file mode 100644
index 000000000..4775ed057
--- /dev/null
+++ b/cui/source/dialogs/tipofthedaydlg.cxx
@@ -0,0 +1,168 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tipofthedaydlg.hxx>
+
+#include <dialmgr.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tipoftheday.hrc>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/help.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <unotools/resmgr.hxx>
+#include <unotools/configmgr.hxx>
+
+TipOfTheDayDialog::TipOfTheDayDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/tipofthedaydialog.ui", "TipOfTheDayDialog")
+ , m_pImage(m_xBuilder->weld_image("imImage"))
+ , m_pText(m_xBuilder->weld_label("lbText"))
+ , m_pShowTip(m_xBuilder->weld_check_button("cbShowTip"))
+ , m_pNext(m_xBuilder->weld_button("btnNext"))
+ , m_pLink(m_xBuilder->weld_link_button("btnLink"))
+{
+ m_pShowTip->set_active(officecfg::Office::Common::Misc::ShowTipOfTheDay::get());
+ m_pNext->connect_clicked(LINK(this, TipOfTheDayDialog, OnNextClick));
+
+ nNumberOfTips = SAL_N_ELEMENTS(TIPOFTHEDAY_STRINGARRAY);
+ nCurrentTip = officecfg::Office::Common::Misc::LastTipOfTheDayID::get();
+
+ const auto t0 = std::chrono::system_clock::now().time_since_epoch();
+ nDay = std::chrono::duration_cast<std::chrono::hours>(t0).count() / 24; //days since 1970-01-01
+ if (nDay > officecfg::Office::Common::Misc::LastTipOfTheDayShown::get())
+ nCurrentTip++;
+
+ UpdateTip();
+}
+
+TipOfTheDayDialog::~TipOfTheDayDialog()
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::LastTipOfTheDayShown::set(nDay, xChanges);
+ officecfg::Office::Common::Misc::LastTipOfTheDayID::set(nCurrentTip, xChanges);
+ officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_pShowTip->get_active(), xChanges);
+ xChanges->commit();
+}
+
+static bool file_exists(const OUString& fileName)
+{
+ ::osl::File aFile(fileName);
+ return aFile.open(osl_File_OpenFlag_Read) == osl::FileBase::E_None;
+}
+
+void TipOfTheDayDialog::UpdateTip()
+{
+ if ((nCurrentTip + 1 > nNumberOfTips) || (nCurrentTip < 0))
+ nCurrentTip = 0;
+ m_xDialog->set_title(CuiResId(STR_TITLE) + ": " + OUString::number(nCurrentTip + 1) + "/"
+ + OUString::number(nNumberOfTips));
+
+ // text
+ OUString aText = CuiResId(std::get<0>(TIPOFTHEDAY_STRINGARRAY[nCurrentTip]));
+//replace MOD1 & MOD2 shortcuts depending on platform
+#ifdef MACOSX
+ const OUString aMOD1 = CuiResId(STR_CMD);
+ const OUString aMOD2 = CuiResId(STR_Option);
+#else
+ const OUString aMOD1 = CuiResId(STR_CTRL);
+ const OUString aMOD2 = CuiResId(STR_Alt);
+#endif
+ sal_Int32 aPos;
+ aPos = aText.indexOf("%MOD1");
+ while (aPos != -1)
+ {
+ aText = aText.replaceAt(aPos, 5, aMOD1);
+ aPos = aText.indexOf("%MOD1");
+ }
+ aPos = aText.indexOf("%MOD2");
+ while (aPos != -1)
+ {
+ aText = aText.replaceAt(aPos, 5, aMOD2);
+ aPos = aText.indexOf("%MOD2");
+ }
+ m_pText->set_label(aText);
+
+ // hyperlink
+ aLink = std::get<1>(TIPOFTHEDAY_STRINGARRAY[nCurrentTip]);
+ if (aLink.isEmpty())
+ {
+ m_pLink->set_visible(false);
+ }
+ else if (aLink.startsWith("http"))
+ {
+ // Links may have some %PRODUCTVERSION which need to be expanded
+ aText = Translate::ExpandVariables(aLink);
+ aPos = aText.indexOf("%LANGUAGENAME");
+ if (aPos != -1)
+ {
+ OUString aLang = LanguageTag(utl::ConfigManager::getUILocale()).getLanguage();
+ if (aLang == "en" || aLang == "pt" || aLang == "zh") //en-US/GB, pt-BR, zh-CH/TW
+ aLang = LanguageTag(utl::ConfigManager::getUILocale()).getBcp47();
+ aText = aText.replaceAt(aPos, 13, aLang);
+ }
+ m_pLink->set_uri(aText);
+
+ m_pLink->set_label(CuiResId(STR_MORE_LINK));
+ m_pLink->set_visible(true);
+ m_pLink->connect_activate_link(Link<weld::LinkButton&, bool>());
+ }
+ else
+ {
+ m_pLink->set_uri("");
+ m_pLink->set_label(CuiResId(STR_HELP_LINK));
+ m_pLink->set_visible(true);
+ //converts aLink into the proper offline/online hyperlink
+ m_pLink->connect_activate_link(LINK(this, TipOfTheDayDialog, OnLinkClick));
+ }
+ // image
+ OUString aURL("$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/tipoftheday/");
+ rtl::Bootstrap::expandMacros(aURL);
+ OUString aImage = std::get<2>(TIPOFTHEDAY_STRINGARRAY[nCurrentTip]);
+ // use default image if none is available with the number
+ if (aImage.isEmpty() || !file_exists(aURL + aImage))
+ aImage = "tipoftheday.png";
+ // draw image
+ Graphic aGraphic;
+ if (GraphicFilter::LoadGraphic(aURL + aImage, OUString(), aGraphic) == ERRCODE_NONE)
+ {
+ ScopedVclPtr<VirtualDevice> m_pVirDev = m_pImage->create_virtual_device();
+ m_pVirDev->SetOutputSizePixel(aGraphic.GetSizePixel());
+ m_pVirDev->DrawBitmapEx(Point(0, 0), aGraphic.GetBitmapEx());
+ m_pImage->set_image(m_pVirDev.get());
+ m_pVirDev.disposeAndClear();
+ }
+}
+
+IMPL_LINK_NOARG(TipOfTheDayDialog, OnLinkClick, weld::LinkButton&, bool)
+{
+ Application::GetHelp()->Start(aLink, static_cast<weld::Widget*>(nullptr));
+ return true;
+}
+
+IMPL_LINK_NOARG(TipOfTheDayDialog, OnNextClick, weld::Button&, void)
+{
+ nCurrentTip++; //zeroed at updatetip when out of range
+ UpdateTip();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/dialogs/zoom.cxx b/cui/source/dialogs/zoom.cxx
new file mode 100644
index 000000000..b80080dfa
--- /dev/null
+++ b/cui/source/dialogs/zoom.cxx
@@ -0,0 +1,406 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+#include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
+#include <sfx2/objsh.hxx>
+#include <zoom.hxx>
+#include <sfx2/zoomitem.hxx>
+#include <svx/viewlayoutitem.hxx>
+#include <svx/zoom_def.hxx>
+
+namespace
+{
+const sal_uInt16 SPECIAL_FACTOR = 0xFFFF;
+
+} // anonymous namespace
+
+sal_uInt16 SvxZoomDialog::GetFactor() const
+{
+ if (m_x100Btn->get_active())
+ return 100;
+
+ if (m_xUserBtn->get_active())
+ return static_cast<sal_uInt16>(m_xUserEdit->get_value(FieldUnit::PERCENT));
+ else
+ return SPECIAL_FACTOR;
+}
+
+void SvxZoomDialog::SetFactor(sal_uInt16 nNewFactor, ZoomButtonId nButtonId)
+{
+ m_xUserEdit->set_sensitive(false);
+
+ if (nButtonId == ZoomButtonId::NONE)
+ {
+ if (nNewFactor == 100)
+ {
+ m_x100Btn->set_active(true);
+ m_x100Btn->grab_focus();
+ }
+ else
+ {
+ m_xUserBtn->set_active(true);
+ m_xUserEdit->set_sensitive(true);
+ m_xUserEdit->set_value(nNewFactor, FieldUnit::PERCENT);
+ m_xUserEdit->grab_focus();
+ }
+ }
+ else
+ {
+ m_xUserEdit->set_value(nNewFactor, FieldUnit::PERCENT);
+ switch (nButtonId)
+ {
+ case ZoomButtonId::OPTIMAL:
+ {
+ m_xOptimalBtn->set_active(true);
+ m_xOptimalBtn->grab_focus();
+ break;
+ }
+ case ZoomButtonId::PAGEWIDTH:
+ {
+ m_xPageWidthBtn->set_active(true);
+ m_xPageWidthBtn->grab_focus();
+ break;
+ }
+ case ZoomButtonId::WHOLEPAGE:
+ {
+ m_xWholePageBtn->set_active(true);
+ m_xWholePageBtn->grab_focus();
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+void SvxZoomDialog::HideButton(ZoomButtonId nButtonId)
+{
+ switch (nButtonId)
+ {
+ case ZoomButtonId::OPTIMAL:
+ m_xOptimalBtn->hide();
+ break;
+
+ case ZoomButtonId::PAGEWIDTH:
+ m_xPageWidthBtn->hide();
+ break;
+
+ case ZoomButtonId::WHOLEPAGE:
+ m_xWholePageBtn->hide();
+ break;
+
+ default:
+ OSL_FAIL("Wrong button number!");
+ }
+}
+
+void SvxZoomDialog::SetLimits(sal_uInt16 nMin, sal_uInt16 nMax)
+{
+ DBG_ASSERT(nMin < nMax, "invalid limits");
+ m_xUserEdit->set_range(nMin, nMax, FieldUnit::PERCENT);
+}
+
+const SfxItemSet* SvxZoomDialog::GetOutputItemSet() const { return m_pOutSet.get(); }
+
+SvxZoomDialog::SvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet)
+ : SfxDialogController(pParent, "cui/ui/zoomdialog.ui", "ZoomDialog")
+ , m_rSet(rCoreSet)
+ , m_bModified(false)
+ , m_xOptimalBtn(m_xBuilder->weld_radio_button("optimal"))
+ , m_xWholePageBtn(m_xBuilder->weld_radio_button("fitwandh"))
+ , m_xPageWidthBtn(m_xBuilder->weld_radio_button("fitw"))
+ , m_x100Btn(m_xBuilder->weld_radio_button("100pc"))
+ , m_xUserBtn(m_xBuilder->weld_radio_button("variable"))
+ , m_xUserEdit(m_xBuilder->weld_metric_spin_button("zoomsb", FieldUnit::PERCENT))
+ , m_xViewFrame(m_xBuilder->weld_widget("viewframe"))
+ , m_xAutomaticBtn(m_xBuilder->weld_radio_button("automatic"))
+ , m_xSingleBtn(m_xBuilder->weld_radio_button("singlepage"))
+ , m_xColumnsBtn(m_xBuilder->weld_radio_button("columns"))
+ , m_xColumnsEdit(m_xBuilder->weld_spin_button("columnssb"))
+ , m_xBookModeChk(m_xBuilder->weld_check_button("bookmode"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ Link<weld::ToggleButton&, void> aLink = LINK(this, SvxZoomDialog, UserHdl);
+ m_x100Btn->connect_toggled(aLink);
+ m_xOptimalBtn->connect_toggled(aLink);
+ m_xPageWidthBtn->connect_toggled(aLink);
+ m_xWholePageBtn->connect_toggled(aLink);
+ m_xUserBtn->connect_toggled(aLink);
+
+ Link<weld::ToggleButton&, void> aViewLayoutLink = LINK(this, SvxZoomDialog, ViewLayoutUserHdl);
+ m_xAutomaticBtn->connect_toggled(aViewLayoutLink);
+ m_xSingleBtn->connect_toggled(aViewLayoutLink);
+ m_xColumnsBtn->connect_toggled(aViewLayoutLink);
+
+ Link<weld::SpinButton&, void> aViewLayoutSpinLink
+ = LINK(this, SvxZoomDialog, ViewLayoutSpinHdl);
+ m_xColumnsEdit->connect_value_changed(aViewLayoutSpinLink);
+
+ Link<weld::ToggleButton&, void> aViewLayoutCheckLink
+ = LINK(this, SvxZoomDialog, ViewLayoutCheckHdl);
+ m_xBookModeChk->connect_toggled(aViewLayoutCheckLink);
+
+ m_xOKBtn->connect_clicked(LINK(this, SvxZoomDialog, OKHdl));
+ m_xUserEdit->connect_value_changed(LINK(this, SvxZoomDialog, SpinHdl));
+
+ // default values
+ sal_uInt16 nValue = 100;
+ sal_uInt16 nMin = 10;
+ sal_uInt16 nMax = 1000;
+
+ // maybe get the old value first
+ const SfxUInt16Item* pOldUserItem = nullptr;
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+
+ if (pShell)
+ pOldUserItem = pShell->GetItem(SID_ATTR_ZOOM_USER);
+
+ if (pOldUserItem)
+ nValue = pOldUserItem->GetValue();
+
+ // initialize UserEdit
+ if (nMin > nValue)
+ nMin = nValue;
+ if (nMax < nValue)
+ nMax = nValue;
+
+ SetLimits(nMin, nMax);
+ m_xUserEdit->set_value(nValue, FieldUnit::PERCENT);
+
+ const SfxPoolItem& rItem = m_rSet.Get(m_rSet.GetPool()->GetWhich(SID_ATTR_ZOOM));
+
+ if (nullptr != dynamic_cast<const SvxZoomItem*>(&rItem))
+ {
+ const SvxZoomItem& rZoomItem = static_cast<const SvxZoomItem&>(rItem);
+ const sal_uInt16 nZoom = rZoomItem.GetValue();
+ const SvxZoomType eType = rZoomItem.GetType();
+ const SvxZoomEnableFlags nValSet = rZoomItem.GetValueSet();
+ ZoomButtonId nButtonId = ZoomButtonId::NONE;
+
+ switch (eType)
+ {
+ case SvxZoomType::OPTIMAL:
+ nButtonId = ZoomButtonId::OPTIMAL;
+ break;
+ case SvxZoomType::PAGEWIDTH:
+ nButtonId = ZoomButtonId::PAGEWIDTH;
+ break;
+ case SvxZoomType::WHOLEPAGE:
+ nButtonId = ZoomButtonId::WHOLEPAGE;
+ break;
+ case SvxZoomType::PERCENT:
+ break;
+ case SvxZoomType::PAGEWIDTH_NOBORDER:
+ break;
+ }
+
+ if (!(SvxZoomEnableFlags::N100 & nValSet))
+ m_x100Btn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::OPTIMAL & nValSet))
+ m_xOptimalBtn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::PAGEWIDTH & nValSet))
+ m_xPageWidthBtn->set_sensitive(false);
+ if (!(SvxZoomEnableFlags::WHOLEPAGE & nValSet))
+ m_xWholePageBtn->set_sensitive(false);
+
+ SetFactor(nZoom, nButtonId);
+ }
+ else
+ {
+ const sal_uInt16 nZoom = static_cast<const SfxUInt16Item&>(rItem).GetValue();
+ SetFactor(nZoom);
+ }
+
+ const SfxPoolItem* pPoolViewLayoutItem = nullptr;
+ if (SfxItemState::SET == m_rSet.GetItemState(SID_ATTR_VIEWLAYOUT, false, &pPoolViewLayoutItem))
+ {
+ const SvxViewLayoutItem* pViewLayoutItem
+ = static_cast<const SvxViewLayoutItem*>(pPoolViewLayoutItem);
+ const sal_uInt16 nColumns = pViewLayoutItem->GetValue();
+ const bool bBookMode = pViewLayoutItem->IsBookMode();
+
+ if (0 == nColumns)
+ {
+ m_xAutomaticBtn->set_active(true);
+ m_xColumnsEdit->set_value(2);
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else if (1 == nColumns)
+ {
+ m_xSingleBtn->set_active(true);
+ m_xColumnsEdit->set_value(2);
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else
+ {
+ m_xColumnsBtn->set_active(true);
+ if (!bBookMode)
+ {
+ m_xColumnsEdit->set_value(nColumns);
+ if (nColumns % 2 != 0)
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else
+ {
+ m_xColumnsEdit->set_value(nColumns);
+ m_xBookModeChk->set_active(true);
+ }
+ }
+ }
+ else
+ {
+ // hide view layout related controls:
+ m_xViewFrame->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, UserHdl, weld::ToggleButton&, void)
+{
+ m_bModified = true;
+
+ if (m_xUserBtn->get_active())
+ {
+ m_xUserEdit->set_sensitive(true);
+ m_xUserEdit->grab_focus();
+ }
+ else
+ {
+ m_xUserEdit->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, SpinHdl, weld::MetricSpinButton&, void)
+{
+ if (!m_xUserBtn->get_active())
+ return;
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutUserHdl, weld::ToggleButton&, void)
+{
+ m_bModified = true;
+
+ if (m_xAutomaticBtn->get_active() || m_xSingleBtn->get_active())
+ {
+ m_xColumnsEdit->set_sensitive(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+ else if (m_xColumnsBtn->get_active())
+ {
+ m_xColumnsEdit->set_sensitive(true);
+ m_xColumnsEdit->grab_focus();
+ if (m_xColumnsEdit->get_value() % 2 == 0)
+ m_xBookModeChk->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutSpinHdl, weld::SpinButton&, void)
+{
+ if (!m_xColumnsBtn->get_active())
+ return;
+
+ if (m_xColumnsEdit->get_value() % 2 == 0)
+ {
+ m_xBookModeChk->set_sensitive(true);
+ }
+ else
+ {
+ m_xBookModeChk->set_active(false);
+ m_xBookModeChk->set_sensitive(false);
+ }
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, ViewLayoutCheckHdl, weld::ToggleButton&, void)
+{
+ if (!m_xColumnsBtn->get_active())
+ return;
+
+ m_bModified = true;
+}
+
+IMPL_LINK_NOARG(SvxZoomDialog, OKHdl, weld::Button&, void)
+{
+ if (m_bModified)
+ {
+ SvxZoomItem aZoomItem(SvxZoomType::PERCENT, 0, m_rSet.GetPool()->GetWhich(SID_ATTR_ZOOM));
+ SvxViewLayoutItem aViewLayoutItem(0, false,
+ m_rSet.GetPool()->GetWhich(SID_ATTR_VIEWLAYOUT));
+
+ sal_uInt16 nFactor = GetFactor();
+
+ if (SPECIAL_FACTOR == nFactor)
+ {
+ if (m_xOptimalBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::OPTIMAL);
+ else if (m_xPageWidthBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::PAGEWIDTH);
+ else if (m_xWholePageBtn->get_active())
+ aZoomItem.SetType(SvxZoomType::WHOLEPAGE);
+ }
+ else
+ {
+ aZoomItem.SetValue(nFactor);
+ }
+
+ if (m_xAutomaticBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(0);
+ aViewLayoutItem.SetBookMode(false);
+ }
+ if (m_xSingleBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(1);
+ aViewLayoutItem.SetBookMode(false);
+ }
+ else if (m_xColumnsBtn->get_active())
+ {
+ aViewLayoutItem.SetValue(static_cast<sal_uInt16>(m_xColumnsEdit->get_value()));
+ aViewLayoutItem.SetBookMode(m_xBookModeChk->get_active());
+ }
+
+ m_pOutSet.reset(new SfxItemSet(m_rSet));
+ m_pOutSet->Put(aZoomItem);
+
+ // don't set attribute in case the whole viewlayout stuff is disabled:
+ if (m_xViewFrame->get_sensitive())
+ m_pOutSet->Put(aViewLayoutItem);
+
+ // memorize value from the UserEdit beyond the dialog
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+
+ if (pShell)
+ {
+ sal_uInt16 nZoomValue
+ = static_cast<sal_uInt16>(m_xUserEdit->get_value(FieldUnit::PERCENT));
+ pShell->PutItem(SfxUInt16Item(SID_ATTR_ZOOM_USER, nZoomValue));
+ }
+ m_xDialog->response(RET_OK);
+ }
+ else
+ m_xDialog->response(RET_CANCEL);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/cuiexp.cxx b/cui/source/factory/cuiexp.cxx
new file mode 100644
index 000000000..bbe1d7431
--- /dev/null
+++ b/cui/source/factory/cuiexp.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 "dlgfact.hxx"
+#include <sal/types.h>
+
+namespace cui
+{
+ static AbstractDialogFactory_Impl* GetFactory()
+ {
+ static AbstractDialogFactory_Impl* pFactory = new AbstractDialogFactory_Impl;
+ return pFactory;
+ }
+}
+
+extern "C"
+{
+ SAL_DLLPUBLIC_EXPORT VclAbstractDialogFactory* CreateDialogFactory()
+ {
+ return ::cui::GetFactory();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/cuiresmgr.cxx b/cui/source/factory/cuiresmgr.cxx
new file mode 100644
index 000000000..b59f73cf8
--- /dev/null
+++ b/cui/source/factory/cuiresmgr.cxx
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dialmgr.hxx>
+#include <unotools/resmgr.hxx>
+
+OUString CuiResId(const char *pKey)
+{
+ return Translate::get(pKey, Translate::Create("cui"));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/dlgfact.cxx b/cui/source/factory/dlgfact.cxx
new file mode 100644
index 000000000..40102bae7
--- /dev/null
+++ b/cui/source/factory/dlgfact.cxx
@@ -0,0 +1,1699 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <align.hxx>
+#include "dlgfact.hxx"
+
+#include <about.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/pageids.hxx>
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+#include <numfmt.hxx>
+#include <splitcelldlg.hxx>
+#include <dstribut.hxx>
+#include <cuiimapwnd.hxx>
+#include <cui/cuicharmap.hxx>
+#include <srchxtra.hxx>
+#include <textanim.hxx>
+#include <autocdlg.hxx>
+#include <treeopt.hxx>
+#include <labdlg.hxx>
+#include <hangulhanjadlg.hxx>
+#include <showcols.hxx>
+#include <zoom.hxx>
+#include <cuigaldlg.hxx>
+#include <transfrm.hxx>
+#include <bbdlg.hxx>
+#include <cuisrchdlg.hxx>
+#include <cuitbxform.hxx>
+#include <optdict.hxx>
+#include <dlgname.hxx>
+#include <multipat.hxx>
+#include <cuihyperdlg.hxx>
+#include <cuifmsearch.hxx>
+#include <cuigrfflt.hxx>
+#include <cuitabarea.hxx>
+#include <cuitabline.hxx>
+#include <measure.hxx>
+#include <connect.hxx>
+#include <dbregister.hxx>
+#include <cuioptgenrl.hxx>
+#include <optasian.hxx>
+#include <insdlg.hxx>
+#include <pastedlg.hxx>
+#include <linkdlg.hxx>
+#include <SignatureLineDialog.hxx>
+#include <SignSignatureLineDialog.hxx>
+#include <QrCodeGenDialog.hxx>
+#include <SpellDialog.hxx>
+#include <cfg.hxx>
+#include <numpages.hxx>
+#include <paragrph.hxx>
+#include <tabstpge.hxx>
+#include <textattr.hxx>
+#include <backgrnd.hxx>
+#include <border.hxx>
+#include <chardlg.hxx>
+#include <page.hxx>
+#include <postdlg.hxx>
+#include <grfpage.hxx>
+#include <scriptdlg.hxx>
+#include <cfgutil.hxx>
+#include <macropg.hxx>
+#include <sdrcelldlg.hxx>
+#include <newtabledlg.hxx>
+#include <macroass.hxx>
+#include <insrc.hxx>
+#include <passwdomdlg.hxx>
+#include <screenshotannotationdlg.hxx>
+#include <hyphen.hxx>
+#include <thesdlg.hxx>
+#include <tipofthedaydlg.hxx>
+#include <DiagramDialog.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::container;
+
+using ::com::sun::star::uno::Reference;
+
+using namespace svx;
+// AbstractTabDialog implementations just forwards everything to the dialog
+
+short CuiAbstractController_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short CuiAbstractSingleTabController_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxDistributeDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractHangulHanjaConversionDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractFmShowColsDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractHyphenWordDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractThesaurusDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractThesaurusDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSvxZoomDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractTitleDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractScriptSelectorDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractGalleryIdDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractURLDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxSearchSimilarityDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxTransformTabDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSvxTransformTabDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSvxCaptionDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSvxCaptionDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSvxJSearchOptionsDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractFmInputRecordNoDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxNewDictionaryDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxNameDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+// #i68101#
+short AbstractSvxObjectNameDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxObjectTitleDescDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxMultiPathDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxPathSelectDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxHpLinkDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractFmSearchDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractGraphicFilterDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxAreaTabDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSvxAreaTabDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractPasteDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractPasteDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractInsertObjectDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractLinksDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSpellDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool AbstractSpellDialog_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+short AbstractSvxPostItDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractPasswordToOpenModifyDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSvxCharacterMapDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+const SfxItemSet* AbstractSvxCharacterMapDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSvxCharacterMapDialog_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+short AbstractSignatureLineDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractSignSignatureLineDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractQrCodeGenDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractScreenshotAnnotationDlg_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short CuiAbstractTabController_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+bool CuiAbstractTabController_Impl::StartExecuteAsync(AsyncContext &rCtx)
+{
+ return SfxTabDialogController::runAsync(m_xDlg, rCtx.maEndDialogFn);
+}
+
+void CuiAbstractTabController_Impl::SetCurPageId( const OString &rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* CuiAbstractTabController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const sal_uInt16* CuiAbstractTabController_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void CuiAbstractTabController_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+//From class Window.
+void CuiAbstractTabController_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+std::vector<OString> CuiAbstractTabController_Impl::getAllPageUIXMLDescriptions() const
+{
+ return m_xDlg->getAllPageUIXMLDescriptions();
+}
+
+bool CuiAbstractTabController_Impl::selectPageByUIXMLDescription(const OString& rUIXMLDescription)
+{
+ return m_xDlg->selectPageByUIXMLDescription(rUIXMLDescription);
+}
+
+BitmapEx CuiAbstractTabController_Impl::createScreenshot() const
+{
+ return m_xDlg->createScreenshot();
+}
+
+OString CuiAbstractTabController_Impl::GetScreenshotId() const
+{
+ return m_xDlg->GetScreenshotId();
+}
+
+const SfxItemSet* CuiAbstractSingleTabController_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void CuiAbstractSingleTabController_Impl::SetText(const OUString& rStr)
+{
+ m_xDlg->set_title(rStr);
+}
+
+SvxDistributeHorizontal AbstractSvxDistributeDialog_Impl::GetDistributeHor()const
+{
+ return m_xDlg->GetDistributeHor();
+}
+SvxDistributeVertical AbstractSvxDistributeDialog_Impl::GetDistributeVer()const
+{
+ return m_xDlg->GetDistributeVer();
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::EndDialog(sal_Int32 nResult)
+{
+ m_xDlg->response(nResult);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::EnableRubySupport( bool _bVal )
+{
+ m_xDlg->EnableRubySupport(_bVal);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetByCharacter( bool _bByCharacter )
+{
+ m_xDlg->SetByCharacter(_bByCharacter);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection )
+{
+ m_xDlg->SetConversionDirectionState(_bTryBothDirections, _ePrimaryConversionDirection);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType )
+{
+ m_xDlg->SetConversionFormat(_eType);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl )
+{
+ m_xDlg->SetOptionsChangedHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl )
+{
+ m_xDlg->SetIgnoreHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetIgnoreAllHdl(const Link<weld::Button&,void>& rHdl)
+{
+ m_xDlg->SetIgnoreAllHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetChangeHdl(const Link<weld::Button&,void>& rHdl)
+{
+ m_xDlg->SetChangeHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetChangeAllHdl( const Link<weld::Button&,void>& rHdl )
+{
+ m_xDlg->SetChangeAllHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetClickByCharacterHdl( const Link<weld::ToggleButton&,void>& _rHdl )
+{
+ m_xDlg->SetClickByCharacterHdl(_rHdl );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetConversionFormatChangedHdl(const Link<weld::Button&,void>& rHdl)
+{
+ m_xDlg->SetConversionFormatChangedHdl(rHdl);
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetFindHdl( const Link<weld::Button&,void>& rHdl )
+{
+ m_xDlg->SetFindHdl(rHdl);
+}
+
+bool AbstractHangulHanjaConversionDialog_Impl::GetUseBothDirections( ) const
+{
+ return m_xDlg->GetUseBothDirections();
+}
+
+editeng::HangulHanjaConversion::ConversionDirection AbstractHangulHanjaConversionDialog_Impl::GetDirection( editeng::HangulHanjaConversion::ConversionDirection _eDefaultDirection ) const
+{
+ return m_xDlg->GetDirection( _eDefaultDirection );
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument
+ )
+{
+ m_xDlg->SetCurrentString(_rNewString,_rSuggestions,_bOriginatesFromDocument);
+}
+
+OUString AbstractHangulHanjaConversionDialog_Impl::GetCurrentString( ) const
+{
+ return m_xDlg->GetCurrentString();
+}
+
+editeng::HangulHanjaConversion::ConversionFormat AbstractHangulHanjaConversionDialog_Impl::GetConversionFormat( ) const
+{
+ return m_xDlg->GetConversionFormat();
+}
+
+void AbstractHangulHanjaConversionDialog_Impl::FocusSuggestion( )
+{
+ m_xDlg->FocusSuggestion();
+}
+
+OUString AbstractHangulHanjaConversionDialog_Impl::GetCurrentSuggestion( ) const
+{
+ return m_xDlg->GetCurrentSuggestion();
+}
+
+OUString AbstractThesaurusDialog_Impl::GetWord()
+{
+ return m_xDlg->GetWord();
+};
+
+Reference < css::embed::XEmbeddedObject > AbstractInsertObjectDialog_Impl::GetObject()
+{
+ return m_xDlg->GetObject();
+}
+
+bool AbstractInsertObjectDialog_Impl::IsCreateNew()
+{
+ return m_xDlg->IsCreateNew();
+}
+
+::Reference< css::io::XInputStream > AbstractInsertObjectDialog_Impl::GetIconIfIconified( OUString* pGraphicMediaType )
+{
+ return m_xDlg->GetIconIfIconified( pGraphicMediaType );
+}
+
+void AbstractPasteDialog_Impl::Insert(SotClipboardFormatId nFormat, const OUString& rFormatName)
+{
+ m_xDlg->Insert(nFormat, rFormatName);
+}
+
+void AbstractPasteDialog_Impl::InsertUno(const OUString& sCmd, const OUString& sLabel)
+{
+ m_xDlg->InsertUno(sCmd, sLabel);
+}
+
+void AbstractPasteDialog_Impl::SetObjName(const SvGlobalName & rClass, const OUString& rObjName)
+{
+ m_xDlg->SetObjName(rClass, rObjName);
+}
+
+void AbstractPasteDialog_Impl::PreGetFormat( const TransferableDataHelper& aHelper )
+{
+ m_xDlg->PreGetFormat(aHelper);
+}
+
+SotClipboardFormatId AbstractPasteDialog_Impl::GetFormatOnly()
+{
+ return m_xDlg->GetFormatOnly();
+}
+
+SotClipboardFormatId AbstractPasteDialog_Impl::GetFormat( const TransferableDataHelper& aHelper )
+{
+ return m_xDlg->GetFormat(aHelper);
+}
+
+void AbstractFmShowColsDialog_Impl::SetColumns(const ::Reference< css::container::XIndexContainer>& xCols)
+{
+ m_xDlg->SetColumns(xCols);
+}
+
+void AbstractSvxZoomDialog_Impl::SetLimits( sal_uInt16 nMin, sal_uInt16 nMax )
+{
+ m_xDlg->SetLimits( nMin, nMax );
+}
+
+void AbstractSvxZoomDialog_Impl::HideButton( ZoomButtonId nBtnId )
+{
+ m_xDlg->HideButton( nBtnId );
+}
+
+const SfxItemSet* AbstractSvxZoomDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSpellDialog_Impl::InvalidateDialog()
+{
+ m_xDlg->InvalidateDialog();
+}
+
+std::shared_ptr<SfxDialogController> AbstractSpellDialog_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+SfxBindings& AbstractSpellDialog_Impl::GetBindings()
+{
+ return m_xDlg->GetBindings();
+}
+
+OUString AbstractTitleDialog_Impl::GetTitle() const
+{
+ return m_xDlg->GetTitle();
+}
+
+sal_uInt32 AbstractGalleryIdDialog_Impl::GetId() const
+{
+ return m_xDlg->GetId();
+}
+
+OUString AbstractURLDlg_Impl::GetURL() const
+{
+ return m_xDlg->GetURL();
+}
+
+OUString AbstractURLDlg_Impl::GetAltText() const
+{
+ return m_xDlg->GetAltText();
+}
+
+OUString AbstractURLDlg_Impl::GetDesc() const
+{
+ return m_xDlg->GetDesc();
+}
+
+OUString AbstractURLDlg_Impl::GetTarget() const
+{
+ return m_xDlg->GetTarget();
+}
+
+OUString AbstractURLDlg_Impl::GetName() const
+{
+ return m_xDlg->GetName();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetOther()
+{
+ return m_xDlg->GetOther();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetShorter()
+{
+ return m_xDlg->GetShorter();
+}
+
+sal_uInt16 AbstractSvxSearchSimilarityDialog_Impl::GetLonger()
+{
+ return m_xDlg->GetLonger();
+}
+
+bool AbstractSvxSearchSimilarityDialog_Impl::IsRelaxed()
+{
+ return m_xDlg->IsRelaxed();
+}
+
+// AbstractSvxTransformTabDialog implementations just forwards everything to the dialog
+void AbstractSvxTransformTabDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSvxTransformTabDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const sal_uInt16* AbstractSvxTransformTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxTransformTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+//From class Window.
+void AbstractSvxTransformTabDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxTransformTabDialog_Impl::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ m_xDlg->SetValidateFramePosLink( rLink );
+}
+
+// AbstractSvxCaptionDialog implementations just forwards everything to the dialog
+void AbstractSvxCaptionDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId(rName);
+}
+
+const SfxItemSet* AbstractSvxCaptionDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const sal_uInt16* AbstractSvxCaptionDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxCaptionDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSvxCaptionDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxCaptionDialog_Impl::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ m_xDlg->SetValidateFramePosLink( rLink );
+}
+
+TransliterationFlags AbstractSvxJSearchOptionsDialog_Impl::GetTransliterationFlags() const
+{
+ return m_xDlg->GetTransliterationFlags();
+}
+
+void AbstractFmInputRecordNoDialog_Impl::SetValue(long nNew)
+{
+ m_xDlg->SetValue(nNew);
+}
+
+long AbstractFmInputRecordNoDialog_Impl::GetValue() const
+{
+ return m_xDlg->GetValue();
+}
+
+::Reference< css::linguistic2::XDictionary > AbstractSvxNewDictionaryDialog_Impl::GetNewDictionary()
+{
+ return m_xDlg->GetNewDictionary();
+}
+
+void AbstractSvxNameDialog_Impl::GetName(OUString& rName)
+{
+ rName = m_xDlg->GetName();
+}
+
+void AbstractSvxNameDialog_Impl::SetCheckNameHdl( const Link<AbstractSvxNameDialog&,bool>& rLink, bool bCheckImmediately )
+{
+ aCheckNameHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetCheckNameHdl( LINK(this, AbstractSvxNameDialog_Impl, CheckNameHdl), bCheckImmediately );
+ else
+ m_xDlg->SetCheckNameHdl( Link<SvxNameDialog&,bool>(), bCheckImmediately );
+}
+
+void AbstractSvxNameDialog_Impl::SetCheckNameTooltipHdl( const Link<AbstractSvxNameDialog&,OUString>& rLink)
+{
+ aCheckNameTooltipHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetCheckNameTooltipHdl( LINK(this, AbstractSvxNameDialog_Impl, CheckNameTooltipHdl));
+ else
+ m_xDlg->SetCheckNameTooltipHdl( Link<SvxNameDialog&,OUString>());
+}
+
+void AbstractSvxNameDialog_Impl::SetEditHelpId(const OString& rHelpId)
+{
+ m_xDlg->SetEditHelpId(rHelpId);
+}
+
+void AbstractSvxNameDialog_Impl::SetHelpId(const OString& rHelpId)
+{
+ m_xDlg->set_help_id(rHelpId);
+}
+
+void AbstractSvxNameDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+IMPL_LINK_NOARG(AbstractSvxNameDialog_Impl, CheckNameHdl, SvxNameDialog&, bool)
+{
+ return aCheckNameHdl.Call(*this);
+}
+
+IMPL_LINK_NOARG(AbstractSvxNameDialog_Impl, CheckNameTooltipHdl, SvxNameDialog&, OUString)
+{
+ return aCheckNameTooltipHdl.Call(*this);
+}
+
+void AbstractSvxObjectNameDialog_Impl::GetName(OUString& rName)
+{
+ rName = m_xDlg->GetName();
+}
+
+void AbstractSvxObjectNameDialog_Impl::SetCheckNameHdl(const Link<AbstractSvxObjectNameDialog&,bool>& rLink)
+{
+ aCheckNameHdl = rLink;
+
+ if(rLink.IsSet())
+ {
+ m_xDlg->SetCheckNameHdl(LINK(this, AbstractSvxObjectNameDialog_Impl, CheckNameHdl));
+ }
+ else
+ {
+ m_xDlg->SetCheckNameHdl(Link<SvxObjectNameDialog&,bool>());
+ }
+}
+
+IMPL_LINK_NOARG(AbstractSvxObjectNameDialog_Impl, CheckNameHdl, SvxObjectNameDialog&, bool)
+{
+ return aCheckNameHdl.Call(*this);
+}
+
+void AbstractSvxObjectTitleDescDialog_Impl::GetTitle(OUString& rTitle)
+{
+ rTitle = m_xDlg->GetTitle();
+}
+
+void AbstractSvxObjectTitleDescDialog_Impl::GetDescription(OUString& rDescription)
+{
+ rDescription = m_xDlg->GetDescription();
+}
+
+OUString AbstractSvxMultiPathDialog_Impl::GetPath() const
+{
+ return m_xDlg->GetPath();
+}
+
+void AbstractSvxMultiPathDialog_Impl::SetPath( const OUString& rPath )
+{
+ m_xDlg->SetPath( rPath );
+}
+
+void AbstractSvxMultiPathDialog_Impl::SetTitle( const OUString& rNewTitle )
+{
+ m_xDlg->SetTitle(rNewTitle);
+}
+
+OUString AbstractSvxPathSelectDialog_Impl::GetPath() const
+{
+ return m_xDlg->GetPath();
+}
+
+void AbstractSvxPathSelectDialog_Impl::SetPath( const OUString& rPath )
+{
+ m_xDlg->SetPath( rPath );
+}
+
+void AbstractSvxPathSelectDialog_Impl::SetTitle( const OUString& rNewTitle )
+{
+ m_xDlg->SetTitle(rNewTitle);
+}
+
+std::shared_ptr<SfxDialogController> AbstractSvxHpLinkDlg_Impl::GetController()
+{
+ return m_xDlg;
+}
+
+bool AbstractSvxHpLinkDlg_Impl::QueryClose()
+{
+ return m_xDlg->QueryClose();
+}
+
+void AbstractFmSearchDialog_Impl::SetFoundHandler(const Link<FmFoundRecordInformation&,void>& lnk)
+{
+ m_xDlg->SetFoundHandler(lnk);
+}
+
+void AbstractFmSearchDialog_Impl::SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&,void>& lnk)
+{
+ m_xDlg->SetCanceledNotFoundHdl(lnk);
+}
+
+void AbstractFmSearchDialog_Impl::SetActiveField(const OUString& strField)
+{
+ m_xDlg->SetActiveField(strField);
+}
+
+Graphic AbstractGraphicFilterDialog_Impl::GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY)
+{
+ return m_xDlg->GetFilteredGraphic(rGraphic, fScaleX, fScaleY);
+}
+
+// AbstractSvxAreaTabDialog implementations just forwards everything to the dialog
+void AbstractSvxAreaTabDialog_Impl::SetCurPageId( const OString& rName )
+{
+ m_xDlg->SetCurPageId( rName );
+}
+
+const SfxItemSet* AbstractSvxAreaTabDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+const sal_uInt16* AbstractSvxAreaTabDialog_Impl::GetInputRanges(const SfxItemPool& pItem )
+{
+ return m_xDlg->GetInputRanges( pItem );
+}
+
+void AbstractSvxAreaTabDialog_Impl::SetInputSet( const SfxItemSet* pInSet )
+{
+ m_xDlg->SetInputSet( pInSet );
+}
+
+void AbstractSvxAreaTabDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+void AbstractSvxPostItDialog_Impl::SetText( const OUString& rStr )
+{
+ m_xDlg->set_title(rStr);
+}
+
+const SfxItemSet* AbstractSvxPostItDialog_Impl::GetOutputItemSet() const
+{
+ return m_xDlg->GetOutputItemSet();
+}
+
+void AbstractSvxPostItDialog_Impl::EnableTravel(bool bNext, bool bPrev)
+{
+ m_xDlg->EnableTravel( bNext, bPrev );
+}
+
+OUString AbstractSvxPostItDialog_Impl::GetNote()
+{
+ return m_xDlg->GetNote();
+}
+
+void AbstractSvxPostItDialog_Impl::SetNote(const OUString& rTxt)
+{
+ m_xDlg->SetNote( rTxt );
+}
+
+void AbstractSvxPostItDialog_Impl::ShowLastAuthor(const OUString& rAuthor, const OUString& rDate)
+{
+ m_xDlg->ShowLastAuthor( rAuthor, rDate );
+}
+
+void AbstractSvxPostItDialog_Impl::DontChangeAuthor()
+{
+ m_xDlg->DontChangeAuthor();
+}
+
+void AbstractSvxPostItDialog_Impl::HideAuthor()
+{
+ m_xDlg->HideAuthor();
+}
+
+void AbstractSvxPostItDialog_Impl::SetNextHdl( const Link<AbstractSvxPostItDialog&,void>& rLink )
+{
+ aNextHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetNextHdl( LINK(this, AbstractSvxPostItDialog_Impl, NextHdl ) );
+ else
+ m_xDlg->SetNextHdl( Link<SvxPostItDialog&,void>() );
+}
+
+void AbstractSvxPostItDialog_Impl::SetPrevHdl( const Link<AbstractSvxPostItDialog&,void>& rLink )
+{
+ aPrevHdl = rLink;
+ if( rLink.IsSet() )
+ m_xDlg->SetPrevHdl( LINK(this, AbstractSvxPostItDialog_Impl, PrevHdl ) );
+ else
+ m_xDlg->SetPrevHdl( Link<SvxPostItDialog&,void>() );
+}
+
+IMPL_LINK_NOARG(AbstractSvxPostItDialog_Impl, NextHdl, SvxPostItDialog&, void)
+{
+ aNextHdl.Call(*this);
+}
+
+IMPL_LINK_NOARG(AbstractSvxPostItDialog_Impl, PrevHdl, SvxPostItDialog&, void)
+{
+ aPrevHdl.Call(*this);
+}
+
+std::shared_ptr<weld::Dialog> AbstractSvxPostItDialog_Impl::GetDialog()
+{
+ return m_xDlg->GetDialog();
+}
+
+OUString AbstractPasswordToOpenModifyDialog_Impl::GetPasswordToOpen() const
+{
+ return m_xDlg->GetPasswordToOpen();
+}
+
+OUString AbstractPasswordToOpenModifyDialog_Impl::GetPasswordToModify() const
+{
+ return m_xDlg->GetPasswordToModify();
+}
+
+bool AbstractPasswordToOpenModifyDialog_Impl::IsRecommendToOpenReadonly() const
+{
+ return m_xDlg->IsRecommendToOpenReadonly();
+}
+
+// Create dialogs with simplest interface
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateVclDialog(weld::Window* pParent, sal_uInt32 nResId)
+{
+ std::unique_ptr<OfaTreeOptionsDialog> xDlg;
+ switch ( nResId )
+ {
+ case SID_OPTIONS_TREEDIALOG :
+ case SID_OPTIONS_DATABASES :
+ case SID_LANGUAGE_OPTIONS :
+ {
+ bool bActivateLastSelection = false;
+ if (nResId == SID_OPTIONS_TREEDIALOG)
+ bActivateLastSelection = true;
+ Reference< frame::XFrame > xFrame;
+ xDlg = std::make_unique<OfaTreeOptionsDialog>(pParent, xFrame, bActivateLastSelection);
+ if (nResId == SID_OPTIONS_DATABASES)
+ {
+ xDlg->ActivatePage(SID_SB_DBREGISTEROPTIONS);
+ }
+ else if (nResId == SID_LANGUAGE_OPTIONS)
+ {
+ //open the tab page "tools/options/languages"
+ xDlg->ActivatePage(OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (xDlg)
+ return VclPtr<CuiAbstractController_Impl>::Create(std::move(xDlg));
+ return nullptr;
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateFrameDialog(weld::Window* pParent, const Reference< frame::XFrame >& rxFrame,
+ sal_uInt32 nResId, const OUString& rParameter )
+{
+ std::unique_ptr<OfaTreeOptionsDialog> xDlg;
+ if (SID_OPTIONS_TREEDIALOG == nResId || SID_OPTIONS_DATABASES == nResId)
+ {
+ // only activate last page if we don't want to activate a special page
+ bool bActivateLastSelection = ( nResId != SID_OPTIONS_DATABASES && rParameter.isEmpty() );
+ xDlg = std::make_unique<OfaTreeOptionsDialog>(pParent, rxFrame, bActivateLastSelection);
+ if ( nResId == SID_OPTIONS_DATABASES )
+ xDlg->ActivatePage(SID_SB_DBREGISTEROPTIONS);
+ else if ( !rParameter.isEmpty() )
+ xDlg->ActivatePage( rParameter );
+ }
+
+ if (xDlg)
+ return VclPtr<CuiAbstractController_Impl>::Create(std::move(xDlg));
+ return nullptr;
+}
+
+// TabDialog outside the drawing layer
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateAutoCorrTabDialog(weld::Window* pParent, const SfxItemSet* pAttrSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<OfaAutoCorrDlg>(pParent, pAttrSet));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateCustomizeTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ const Reference< frame::XFrame >& xViewFrame )
+{
+ auto xDlg1 = std::make_shared<SvxConfigDialog>(pParent, pAttrSet);
+ xDlg1->SetFrame(xViewFrame);
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::move(xDlg1));
+}
+
+// TabDialog that use functionality of the drawing layer
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateTextTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ SdrView* pView)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxTextTabDialog>(pParent, pAttrSet, pView));
+}
+
+// TabDialog that use functionality of the drawing layer and add AnchorTypes -- for SvxCaptionTabDialog
+VclPtr<AbstractSvxCaptionDialog> AbstractDialogFactory_Impl::CreateCaptionDialog(weld::Window* pParent,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes)
+{
+ return VclPtr<AbstractSvxCaptionDialog_Impl>::Create(std::make_shared<SvxCaptionTabDialog>(pParent, pView, nAnchorTypes));
+}
+
+VclPtr<AbstractSvxDistributeDialog> AbstractDialogFactory_Impl::CreateSvxDistributeDialog(weld::Window* pParent,
+ const SfxItemSet& rAttr)
+{
+ return VclPtr<AbstractSvxDistributeDialog_Impl>::Create(std::make_unique<SvxDistributeDialog>(pParent, rAttr, SvxDistributeHorizontal::NONE, SvxDistributeVertical::NONE));
+}
+
+VclPtr<AbstractHangulHanjaConversionDialog> AbstractDialogFactory_Impl::CreateHangulHanjaConversionDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractHangulHanjaConversionDialog_Impl>::Create(std::make_unique<HangulHanjaConversionDialog>(pParent));
+}
+
+VclPtr<AbstractThesaurusDialog> AbstractDialogFactory_Impl::CreateThesaurusDialog(weld::Window* pParent,
+ css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
+ const OUString &rWord, LanguageType nLanguage)
+{
+ return VclPtr<AbstractThesaurusDialog_Impl>::Create(std::make_shared<SvxThesaurusDialog>(pParent, xThesaurus, rWord, nLanguage));
+}
+
+VclPtr<AbstractHyphenWordDialog> AbstractDialogFactory_Impl::CreateHyphenWordDialog(weld::Window* pParent,
+ const OUString &rWord, LanguageType nLang,
+ css::uno::Reference< css::linguistic2::XHyphenator > &xHyphen,
+ SvxSpellWrapper* pWrapper)
+{
+ return VclPtr<AbstractHyphenWordDialog_Impl>::Create(std::make_unique<SvxHyphenWordDialog>(rWord, nLang, pParent, xHyphen, pWrapper));
+}
+
+VclPtr<AbstractFmShowColsDialog> AbstractDialogFactory_Impl::CreateFmShowColsDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractFmShowColsDialog_Impl>::Create(std::make_unique<FmShowColsDialog>(pParent));
+}
+
+VclPtr<AbstractSvxZoomDialog> AbstractDialogFactory_Impl::CreateSvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet)
+{
+ return VclPtr<AbstractSvxZoomDialog_Impl>::Create(std::make_unique<SvxZoomDialog>(pParent, rCoreSet));
+}
+
+VclPtr<AbstractSpellDialog> AbstractDialogFactory_Impl::CreateSvxSpellDialog(
+ weld::Window* pParent,
+ SfxBindings* pBindings,
+ svx::SpellDialogChildWindow* pSpellChildWindow)
+{
+ return VclPtr<AbstractSpellDialog_Impl>::Create(std::make_shared<svx::SpellDialog>(pSpellChildWindow, pParent, pBindings));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateActualizeProgressDialog(weld::Widget* pParent,
+ GalleryTheme* pThm)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<ActualizeProgress>(pParent, pThm));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateScriptErrorDialog(const css::uno::Any& rException)
+{
+ return VclPtr<SvxScriptErrorDialog>::Create(rException);
+}
+
+VclPtr<AbstractScriptSelectorDialog> AbstractDialogFactory_Impl::CreateScriptSelectorDialog(weld::Window* pParent,
+ const Reference<frame::XFrame>& rxFrame)
+{
+ return VclPtr<AbstractScriptSelectorDialog_Impl>::Create(std::make_unique<SvxScriptSelectorDialog>(pParent, rxFrame));
+}
+
+OUString AbstractScriptSelectorDialog_Impl::GetScriptURL() const
+{
+ return m_xDlg->GetScriptURL();
+}
+
+void AbstractScriptSelectorDialog_Impl::SetRunLabel()
+{
+ m_xDlg->SetRunLabel();
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxScriptOrgDialog(weld::Window* pParent,
+ const OUString& rLanguage)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxScriptOrgDialog>(pParent, rLanguage));
+}
+
+VclPtr<AbstractTitleDialog> AbstractDialogFactory_Impl::CreateTitleDialog(weld::Widget* pParent,
+ const OUString& rOldText)
+{
+ return VclPtr<AbstractTitleDialog_Impl>::Create(std::make_unique<TitleDialog>(pParent, rOldText));
+}
+
+VclPtr<AbstractGalleryIdDialog> AbstractDialogFactory_Impl::CreateGalleryIdDialog(weld::Widget* pParent,
+ GalleryTheme* pThm)
+{
+ return VclPtr<AbstractGalleryIdDialog_Impl>::Create(std::make_unique<GalleryIdDialog>(pParent, pThm));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateGalleryThemePropertiesDialog(weld::Widget* pParent,
+ ExchangeData* pData,
+ SfxItemSet* pItemSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<GalleryThemeProperties>(
+ pParent, pData, pItemSet));
+}
+
+VclPtr<AbstractURLDlg> AbstractDialogFactory_Impl::CreateURLDialog(weld::Widget* pParent,
+ const OUString& rURL, const OUString& rAltText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList )
+{
+ return VclPtr<AbstractURLDlg_Impl>::Create(std::make_unique<URLDlg>(pParent, rURL, rAltText, rDescription,
+ rTarget, rName, rTargetList));
+
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateTabItemDialog(weld::Window* pParent,
+ const SfxItemSet& rSet)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxSearchFormatDialog>(
+ pParent, rSet));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst,
+ const sal_uInt16* pWhRanges )
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxSearchAttributeDialog>(pParent, rLst, pWhRanges));
+}
+
+VclPtr<AbstractSvxSearchSimilarityDialog> AbstractDialogFactory_Impl::CreateSvxSearchSimilarityDialog(weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger)
+{
+ return VclPtr<AbstractSvxSearchSimilarityDialog_Impl>::Create(std::make_unique<SvxSearchSimilarityDialog>(pParent, bRelax, nOther, nShorter, nLonger));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxBorderBackgroundDlg(
+ weld::Window* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableDrawingLayerFillStyles)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxBorderBackgroundDlg>(
+ pParent,
+ rCoreSet,
+ /*bEnableSelector*/true,
+ bEnableDrawingLayerFillStyles));
+}
+
+VclPtr<AbstractSvxTransformTabDialog> AbstractDialogFactory_Impl::CreateSvxTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes)
+{
+ return VclPtr<AbstractSvxTransformTabDialog_Impl>::Create(std::make_shared<SvxTransformTabDialog>(pParent, pAttr,pView, nAnchorTypes));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSchTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pSdrView,
+ bool bSizeTabPage)
+{
+ auto pDlg = std::make_shared<SvxTransformTabDialog>(pParent, pAttr, pSdrView,
+ bSizeTabPage ? SvxAnchorIds::NoProtect : SvxAnchorIds::NoProtect|SvxAnchorIds::NoResize);
+ pDlg->RemoveTabPage( "RID_SVXPAGE_ANGLE" );
+ pDlg->RemoveTabPage( "RID_SVXPAGE_SLANT" );
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::move(pDlg));
+}
+
+VclPtr<AbstractSvxJSearchOptionsDialog> AbstractDialogFactory_Impl::CreateSvxJSearchOptionsDialog(weld::Window* pParent,
+ const SfxItemSet& rOptionsSet,
+ TransliterationFlags nInitialFlags)
+{
+ return VclPtr<AbstractSvxJSearchOptionsDialog_Impl>::Create(std::make_unique<SvxJSearchOptionsDialog>(pParent, rOptionsSet, nInitialFlags));
+}
+
+VclPtr<AbstractFmInputRecordNoDialog> AbstractDialogFactory_Impl::CreateFmInputRecordNoDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractFmInputRecordNoDialog_Impl>::Create(std::make_unique<FmInputRecordNoDialog>(pParent));
+}
+
+VclPtr<AbstractSvxNewDictionaryDialog> AbstractDialogFactory_Impl::CreateSvxNewDictionaryDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxNewDictionaryDialog_Impl>::Create(std::make_unique<SvxNewDictionaryDialog>(pParent));
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<SvxEditDictionaryDialog>(pParent, rName));
+}
+
+VclPtr<AbstractSvxNameDialog> AbstractDialogFactory_Impl::CreateSvxNameDialog(weld::Window* pParent,
+ const OUString& rName, const OUString& rDesc)
+{
+ return VclPtr<AbstractSvxNameDialog_Impl>::Create(std::make_unique<SvxNameDialog>(pParent, rName, rDesc));
+}
+
+VclPtr<AbstractSvxObjectNameDialog> AbstractDialogFactory_Impl::CreateSvxObjectNameDialog(weld::Window* pParent, const OUString& rName)
+{
+ return VclPtr<AbstractSvxObjectNameDialog_Impl>::Create(std::make_unique<SvxObjectNameDialog>(pParent, rName));
+}
+
+VclPtr<AbstractSvxObjectTitleDescDialog> AbstractDialogFactory_Impl::CreateSvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle, const OUString& rDescription)
+{
+ return VclPtr<AbstractSvxObjectTitleDescDialog_Impl>::Create(std::make_unique<SvxObjectTitleDescDialog>(pParent, rTitle, rDescription));
+}
+
+VclPtr<AbstractSvxMultiPathDialog> AbstractDialogFactory_Impl::CreateSvxMultiPathDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxMultiPathDialog_Impl>::Create(std::make_unique<SvxMultiPathDialog>(pParent));
+}
+
+VclPtr<AbstractSvxMultiPathDialog> AbstractDialogFactory_Impl::CreateSvxPathSelectDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxPathSelectDialog_Impl>::Create(std::make_unique<SvxPathSelectDialog>(pParent));
+}
+
+VclPtr<AbstractSvxHpLinkDlg> AbstractDialogFactory_Impl::CreateSvxHpLinkDlg(SfxChildWindow* pChild, SfxBindings* pBindings, weld::Window* pParent)
+{
+ return VclPtr<AbstractSvxHpLinkDlg_Impl>::Create(std::make_shared<SvxHpLinkDlg>(pBindings, pChild, pParent));
+}
+
+VclPtr<AbstractFmSearchDialog> AbstractDialogFactory_Impl::CreateFmSearchDialog(weld::Window* pParent,
+ const OUString& strInitialText,
+ const std::vector< OUString >& _rContexts,
+ sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier)
+{
+ return VclPtr<AbstractFmSearchDialog_Impl>::Create(std::make_unique<FmSearchDialog>(pParent,
+ strInitialText, _rContexts, nInitialContext, lnkContextSupplier));
+
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterEmboss>(pParent, rGraphic, RectPoint::MM));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterPoster(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterPoster>(pParent, rGraphic, 16));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSepia(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSepia>(pParent, rGraphic, 10));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSmooth(weld::Window* pParent,
+ const Graphic& rGraphic, double nRadius)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSmooth>(pParent, rGraphic, nRadius));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterSolarize(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterSolarize>(pParent, rGraphic, 128, false /*bInvert*/));
+}
+
+VclPtr<AbstractGraphicFilterDialog> AbstractDialogFactory_Impl::CreateGraphicFilterMosaic(weld::Window* pParent,
+ const Graphic& rGraphic)
+{
+ return VclPtr<AbstractGraphicFilterDialog_Impl>::Create(std::make_unique<GraphicFilterMosaic>(pParent, rGraphic, 4, 4, false /*bEnhanceEdges*/));
+}
+
+VclPtr<AbstractSvxAreaTabDialog> AbstractDialogFactory_Impl::CreateSvxAreaTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow)
+{
+ return VclPtr<AbstractSvxAreaTabDialog_Impl>::Create(std::make_shared<SvxAreaTabDialog>(pParent, pAttr, pModel, bShadow));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, //add forSvxLineTabDialog
+ SdrModel* pModel,
+ const SdrObject* pObj ,
+ bool bHasObj)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxLineTabDialog>(pParent, pAttr, pModel, pObj,bHasObj));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateCharMapDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const Reference< XFrame >& rDocumentFrame)
+{
+ return VclPtr<AbstractSvxCharacterMapDialog_Impl>::Create(std::make_unique<SvxCharacterMap>(pParent, &rAttr, rDocumentFrame));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateEventConfigDialog(weld::Widget* pParent,
+ const SfxItemSet& rAttr,
+ const Reference< XFrame >& rDocumentFrame)
+{
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SfxMacroAssignDlg>(pParent, rDocumentFrame, rAttr));
+}
+
+VclPtr<SfxAbstractDialog> AbstractDialogFactory_Impl::CreateSfxDialog(weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const SdrView* pView,
+ sal_uInt32 nResId)
+{
+ switch ( nResId )
+ {
+ case RID_SVXPAGE_MEASURE:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SvxMeasureDialog>(pParent, rAttr, pView));
+ case RID_SVXPAGE_CONNECTION:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<SvxConnectionDialog>(pParent, rAttr, pView));
+ case RID_SFXPAGE_DBREGISTER:
+ return VclPtr<CuiAbstractSingleTabController_Impl>::Create(std::make_unique<DatabaseRegistrationDialog>(pParent, rAttr));
+ }
+
+ return nullptr;
+}
+
+VclPtr<AbstractSvxPostItDialog> AbstractDialogFactory_Impl::CreateSvxPostItDialog(weld::Widget* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bPrevNext)
+{
+ return VclPtr<AbstractSvxPostItDialog_Impl>::Create(std::make_unique<SvxPostItDialog>(pParent, rCoreSet, bPrevNext));
+}
+
+namespace {
+
+class SvxMacroAssignDialog : public VclAbstractDialog
+{
+public:
+ SvxMacroAssignDialog( weld::Window* _pParent, const Reference< XFrame >& _rxDocumentFrame, const bool _bUnoDialogMode,
+ const Reference< XNameReplace >& _rxEvents, const sal_uInt16 _nInitiallySelectedEvent )
+ :m_aItems( SfxGetpApp()->GetPool(), svl::Items<SID_ATTR_MACROITEM, SID_ATTR_MACROITEM>{} )
+ {
+ m_aItems.Put( SfxBoolItem( SID_ATTR_MACROITEM, _bUnoDialogMode ) );
+ m_xDialog.reset(new SvxMacroAssignDlg(_pParent, _rxDocumentFrame, m_aItems, _rxEvents, _nInitiallySelectedEvent));
+ }
+
+ virtual short Execute() override;
+
+private:
+ SfxItemSet m_aItems;
+ std::unique_ptr<SvxMacroAssignDlg> m_xDialog;
+};
+
+}
+
+short SvxMacroAssignDialog::Execute()
+{
+ return m_xDialog->run();
+}
+
+short AbstractAboutDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractTipOfTheDayDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+short AbstractDiagramDialog_Impl::Execute()
+{
+ return m_xDlg->run();
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateSvxMacroAssignDlg(
+ weld::Window* _pParent, const Reference< XFrame >& _rxDocumentFrame, const bool _bUnoDialogMode,
+ const Reference< XNameReplace >& _rxEvents, const sal_uInt16 _nInitiallySelectedEvent )
+{
+ return VclPtr<SvxMacroAssignDialog>::Create( _pParent, _rxDocumentFrame, _bUnoDialogMode, _rxEvents, _nInitiallySelectedEvent );
+}
+
+// Factories for TabPages
+CreateTabPage AbstractDialogFactory_Impl::GetTabPageCreatorFunc( sal_uInt16 nId )
+{
+ switch ( nId )
+ {
+ case RID_SW_TP_BACKGROUND :
+ case RID_SVXPAGE_BKG :
+ return SvxBkgTabPage::Create;
+ case RID_SVXPAGE_TEXTANIMATION :
+ return SvxTextAnimationPage::Create;
+ case RID_SVXPAGE_TRANSPARENCE :
+ return SvxTransparenceTabPage::Create;
+ case RID_SVXPAGE_AREA :
+ return SvxAreaTabPage::Create;
+ case RID_SVXPAGE_SHADOW :
+ return SvxShadowTabPage::Create;
+ case RID_SVXPAGE_LINE :
+ return SvxLineTabPage::Create;
+ case RID_SVXPAGE_CONNECTION :
+ return SvxConnectionPage::Create;
+ case RID_SVXPAGE_MEASURE :
+ return SvxMeasurePage::Create;
+ case RID_SFXPAGE_GENERAL :
+ return SvxGeneralTabPage::Create;
+ case RID_SVXPAGE_PICK_SINGLE_NUM :
+ return SvxSingleNumPickTabPage::Create;
+ case RID_SVXPAGE_PICK_BMP :
+ return SvxBitmapPickTabPage::Create;
+ case RID_SVXPAGE_PICK_BULLET :
+ return SvxBulletPickTabPage::Create;
+ case RID_SVXPAGE_NUM_OPTIONS :
+ return SvxNumOptionsTabPage::Create;
+ case RID_SVXPAGE_PICK_NUM :
+ return SvxNumPickTabPage::Create;
+ case RID_SVXPAGE_NUM_POSITION :
+ return SvxNumPositionTabPage::Create;
+ case RID_SVXPAGE_PARA_ASIAN :
+ return SvxAsianTabPage::Create;
+ case RID_SVXPAGE_EXT_PARAGRAPH :
+ return SvxExtParagraphTabPage::Create;
+ case RID_SVXPAGE_ALIGN_PARAGRAPH :
+ return SvxParaAlignTabPage::Create;
+ case RID_SVXPAGE_STD_PARAGRAPH :
+ return SvxStdParagraphTabPage::Create;
+ case RID_SVXPAGE_TABULATOR :
+ return SvxTabulatorTabPage::Create;
+ case RID_SVXPAGE_TEXTATTR :
+ return SvxTextAttrPage::Create;
+ case RID_SVXPAGE_ALIGNMENT :
+ return svx::AlignmentTabPage::Create;
+ case RID_SVXPAGE_BORDER :
+ return SvxBorderTabPage::Create;
+ case RID_SVXPAGE_CHAR_NAME :
+ return SvxCharNamePage::Create;
+ case RID_SVXPAGE_CHAR_EFFECTS :
+ return SvxCharEffectsPage::Create;
+ case RID_SVXPAGE_CHAR_POSITION :
+ return SvxCharPositionPage::Create;
+ case RID_SVXPAGE_CHAR_TWOLINES :
+ return SvxCharTwoLinesPage::Create;
+ case RID_SVXPAGE_NUMBERFORMAT :
+ return SvxNumberFormatTabPage::Create;
+ case RID_SVXPAGE_PAGE :
+ return SvxPageDescPage::Create;
+ case RID_SVXPAGE_GRFCROP :
+ return SvxGrfCropPage::Create;
+ case RID_SVXPAGE_MACROASSIGN :
+ return SfxMacroTabPage::Create;
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+DialogGetRanges AbstractDialogFactory_Impl::GetDialogGetRangesFunc()
+{
+ return SvxPostItDialog::GetRanges;
+}
+
+GetTabPageRanges AbstractDialogFactory_Impl::GetTabPageRangesFunc( sal_uInt16 nId )
+{
+ switch ( nId )
+ {
+ case RID_SVXPAGE_TEXTANIMATION :
+ return SvxTextAnimationPage::GetRanges;
+ case RID_SVXPAGE_TRANSPARENCE :
+ return SvxTransparenceTabPage::GetRanges;
+ case RID_SVXPAGE_AREA :
+ return SvxAreaTabPage::GetRanges;
+ case RID_SVXPAGE_SHADOW :
+ return SvxShadowTabPage::GetRanges;
+ case RID_SVXPAGE_LINE :
+ return SvxLineTabPage::GetRanges;
+ case RID_SVXPAGE_CONNECTION :
+ return SvxConnectionPage::GetRanges;
+ case RID_SVXPAGE_MEASURE :
+ return SvxMeasurePage::GetRanges;
+ case RID_SVXPAGE_PARA_ASIAN :
+ return SvxAsianTabPage::GetRanges;
+ case RID_SVXPAGE_EXT_PARAGRAPH :
+ return SvxExtParagraphTabPage::GetRanges;
+ case RID_SVXPAGE_ALIGN_PARAGRAPH :
+ return SvxParaAlignTabPage::GetRanges;
+ case RID_SVXPAGE_STD_PARAGRAPH :
+ return SvxStdParagraphTabPage::GetRanges;
+ case RID_SVXPAGE_TABULATOR :
+ return SvxTabulatorTabPage::GetRanges;
+ case RID_SVXPAGE_TEXTATTR :
+ return SvxTextAttrPage::GetRanges;
+ case RID_SVXPAGE_ALIGNMENT :
+ return svx::AlignmentTabPage::GetRanges;
+ case RID_SW_TP_BACKGROUND :
+ case RID_SVXPAGE_BKG:
+ return SvxBkgTabPage::GetRanges;
+ case RID_SVXPAGE_BORDER :
+ return SvxBorderTabPage::GetRanges;
+ case RID_SVXPAGE_CHAR_NAME :
+ return SvxCharNamePage::GetRanges;
+ case RID_SVXPAGE_CHAR_EFFECTS :
+ return SvxCharEffectsPage::GetRanges;
+ case RID_SVXPAGE_CHAR_POSITION :
+ return SvxCharPositionPage::GetRanges;
+ case RID_SVXPAGE_CHAR_TWOLINES :
+ return SvxCharTwoLinesPage::GetRanges;
+ case RID_SVXPAGE_NUMBERFORMAT :
+ return SvxNumberFormatTabPage::GetRanges;
+ case RID_SVXPAGE_PAGE :
+ return SvxPageDescPage::GetRanges;
+ case RID_SVXPAGE_ASIAN_LAYOUT:
+ return SvxAsianLayoutPage::GetRanges;
+ default:
+ break;
+ }
+
+ return nullptr;
+}
+
+VclPtr<SfxAbstractInsertObjectDialog> AbstractDialogFactory_Impl::CreateInsertObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const Reference <css::embed::XStorage>& xStor, const SvObjectServerList* pList)
+{
+ std::unique_ptr<InsertObjectDialog_Impl> pDlg;
+ if ( rCommand == ".uno:InsertObject" )
+ pDlg.reset(new SvInsertOleDlg(pParent, xStor, pList));
+ else if ( rCommand == ".uno:InsertObjectFloatingFrame" )
+ pDlg.reset(new SfxInsertFloatingFrameDialog(pParent, xStor));
+
+ if ( pDlg )
+ {
+ pDlg->SetHelpId( OUStringToOString( rCommand, RTL_TEXTENCODING_UTF8 ) );
+ return VclPtr<AbstractInsertObjectDialog_Impl>::Create( std::move(pDlg) );
+ }
+ return nullptr;
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommand,
+ const Reference<css::embed::XEmbeddedObject>& xObj)
+{
+ if ( rCommand == ".uno:InsertObjectFloatingFrame" )
+ {
+ auto pDlg = std::make_unique<SfxInsertFloatingFrameDialog>(pParent, xObj);
+ pDlg->SetHelpId( OUStringToOString( rCommand, RTL_TEXTENCODING_UTF8 ) );
+ return VclPtr<AbstractInsertObjectDialog_Impl>::Create( std::move(pDlg) );
+ }
+ return nullptr;
+}
+
+VclPtr<SfxAbstractPasteDialog> AbstractDialogFactory_Impl::CreatePasteDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractPasteDialog_Impl>::Create(std::make_shared<SvPasteObjectDialog>(pParent));
+}
+
+VclPtr<SfxAbstractLinksDialog> AbstractDialogFactory_Impl::CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML, sfx2::SvBaseLink* p)
+{
+ auto xLinkDlg(std::make_unique<SvBaseLinksDlg>(pParent, pMgr, bHTML));
+ if (p)
+ xLinkDlg->SetActLink(p);
+ return VclPtr<AbstractLinksDialog_Impl>::Create(std::move(xLinkDlg));
+}
+
+VclPtr<SfxAbstractTabDialog> AbstractDialogFactory_Impl::CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel)
+{
+ return VclPtr<CuiAbstractTabController_Impl>::Create(std::make_shared<SvxFormatCellsDialog>(pParent, pAttr, rModel));
+}
+
+VclPtr<SvxAbstractSplitTableDialog> AbstractDialogFactory_Impl::CreateSvxSplitTableDialog(weld::Window* pParent, bool bIsTableVertical, long nMaxVertical)
+{
+ return VclPtr<SvxSplitTableDlg>::Create( pParent, bIsTableVertical, nMaxVertical, 99 );
+}
+
+std::shared_ptr<SvxAbstractNewTableDialog> AbstractDialogFactory_Impl::CreateSvxNewTableDialog(weld::Window* pParent)
+{
+ return std::make_shared<SvxNewTableDialogWrapper>(pParent);
+}
+
+VclPtr<VclAbstractDialog> AbstractDialogFactory_Impl::CreateOptionsDialog(weld::Window* pParent, const OUString& rExtensionId)
+{
+ return VclPtr<CuiAbstractController_Impl>::Create(std::make_unique<OfaTreeOptionsDialog>(pParent, rExtensionId));
+}
+
+VclPtr<SvxAbstractInsRowColDlg> AbstractDialogFactory_Impl::CreateSvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId)
+{
+ return VclPtr<SvxInsRowColDlg>::Create(pParent, bCol, rHelpId);
+}
+
+VclPtr<AbstractPasswordToOpenModifyDialog> AbstractDialogFactory_Impl::CreatePasswordToOpenModifyDialog(
+ weld::Window * pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify)
+{
+ return VclPtr<AbstractPasswordToOpenModifyDialog_Impl>::Create(std::make_unique<PasswordToOpenModifyDialog>(pParent, nMaxPasswdLen, bIsPasswordToModify));
+}
+
+VclPtr<AbstractScreenshotAnnotationDlg> AbstractDialogFactory_Impl::CreateScreenshotAnnotationDlg(weld::Dialog& rParentDialog)
+{
+ return VclPtr<AbstractScreenshotAnnotationDlg_Impl>::Create(std::make_unique<ScreenshotAnnotationDlg>(rParentDialog));
+}
+
+VclPtr<AbstractSignatureLineDialog> AbstractDialogFactory_Impl::CreateSignatureLineDialog(
+ weld::Window* pParent, const Reference<XModel> xModel, bool bEditExisting)
+{
+ return VclPtr<AbstractSignatureLineDialog_Impl>::Create(
+ std::make_unique<SignatureLineDialog>(pParent, xModel, bEditExisting));
+}
+
+VclPtr<AbstractSignSignatureLineDialog>
+AbstractDialogFactory_Impl::CreateSignSignatureLineDialog(weld::Window* pParent,
+ const Reference<XModel> xModel)
+{
+ return VclPtr<AbstractSignSignatureLineDialog_Impl>::Create(
+ std::make_unique<SignSignatureLineDialog>(pParent, xModel));
+}
+
+VclPtr<AbstractQrCodeGenDialog> AbstractDialogFactory_Impl::CreateQrCodeGenDialog(
+ weld::Window* pParent, const Reference<XModel> xModel, bool bEditExisting)
+{
+ return VclPtr<AbstractQrCodeGenDialog_Impl>::Create(
+ std::make_unique<QrCodeGenDialog>(pParent, xModel, bEditExisting));
+}
+
+VclPtr<AbstractAboutDialog>
+AbstractDialogFactory_Impl::CreateAboutDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractAboutDialog_Impl>::Create(
+ std::make_unique<AboutDialog>(pParent));
+}
+
+VclPtr<AbstractTipOfTheDayDialog>
+AbstractDialogFactory_Impl::CreateTipOfTheDayDialog(weld::Window* pParent)
+{
+ return VclPtr<AbstractTipOfTheDayDialog_Impl>::Create(std::make_unique<TipOfTheDayDialog>(pParent));
+}
+
+VclPtr<AbstractDiagramDialog>
+AbstractDialogFactory_Impl::CreateDiagramDialog(weld::Window* pParent, std::shared_ptr<DiagramDataInterface> pDiagramData)
+{
+ return VclPtr<AbstractDiagramDialog_Impl>::Create(
+ std::make_unique<DiagramDialog>(pParent, pDiagramData));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/dlgfact.hxx b/cui/source/factory/dlgfact.hxx
new file mode 100644
index 000000000..4f54b03f9
--- /dev/null
+++ b/cui/source/factory/dlgfact.hxx
@@ -0,0 +1,981 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_FACTORY_DLGFACT_HXX
+#define INCLUDED_CUI_SOURCE_FACTORY_DLGFACT_HXX
+
+#include <svx/svxdlg.hxx>
+#include <svx/zoom_def.hxx>
+#include <com/sun/star/container/XNameReplace.hpp>
+
+#include <tools/link.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <about.hxx>
+#include <cfgutil.hxx>
+#include <cui/cuicharmap.hxx>
+#include <cuifmsearch.hxx>
+#include <cuigaldlg.hxx>
+#include <cuigrfflt.hxx>
+#include <cuihyperdlg.hxx>
+#include <cuiimapwnd.hxx>
+#include <cuisrchdlg.hxx>
+#include <cuitabarea.hxx>
+#include <cuitbxform.hxx>
+#include <dlgname.hxx>
+#include <DiagramDialog.hxx>
+#include <dstribut.hxx>
+#include <hangulhanjadlg.hxx>
+#include <hyphen.hxx>
+#include <insdlg.hxx>
+#include <labdlg.hxx>
+#include <linkdlg.hxx>
+#include <multipat.hxx>
+#include <optdict.hxx>
+#include <passwdomdlg.hxx>
+#include <pastedlg.hxx>
+#include <postdlg.hxx>
+#include <QrCodeGenDialog.hxx>
+#include <screenshotannotationdlg.hxx>
+#include <showcols.hxx>
+#include <SignatureLineDialog.hxx>
+#include <SignSignatureLineDialog.hxx>
+#include <SpellDialog.hxx>
+#include <srchxtra.hxx>
+#include <thesdlg.hxx>
+#include <tipofthedaydlg.hxx>
+#include <transfrm.hxx>
+#include <zoom.hxx>
+
+class SfxSingleTabDialogController;
+class SfxItemPool;
+class FmShowColsDialog;
+class SvxZoomDialog;
+class FmInputRecordNoDialog;
+class SvxJSearchOptionsDialog;
+class SvxNewDictionaryDialog;
+class SvxNameDialog;
+
+// #i68101#
+class SvxObjectNameDialog;
+class SvxObjectTitleDescDialog;
+
+class SvxMultiPathDialog;
+class SvxHpLinkDlg;
+class FmSearchDialog;
+class Graphic;
+class GraphicFilterDialog;
+class SvxAreaTabDialog;
+class InsertObjectDialog_Impl;
+class SvPasteObjectDialog;
+class SvBaseLinksDlg;
+class SvxTransformTabDialog;
+class SvxCaptionTabDialog;
+class SvxThesaurusDialog;
+class SvxHyphenWordDialog;
+
+namespace svx{
+class HangulHanjaConversionDialog;
+}
+using namespace svx;
+
+#define DECL_ABSTDLG_BASE(Class,DialogClass) \
+ ScopedVclPtr<DialogClass> pDlg; \
+public: \
+ explicit Class( DialogClass* p) \
+ : pDlg(p) \
+ {} \
+ virtual short Execute() override; \
+ virtual bool StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) override;
+
+#define IMPL_ABSTDLG_BASE(Class) \
+short Class::Execute() \
+{ \
+ return pDlg->Execute(); \
+} \
+bool Class::StartExecuteAsync(VclAbstractDialog::AsyncContext &rCtx) \
+{ \
+ return pDlg->StartExecuteAsync(rCtx); \
+}
+
+class CuiAbstractController_Impl : public VclAbstractDialog
+{
+ std::unique_ptr<weld::DialogController> m_xDlg;
+public:
+ explicit CuiAbstractController_Impl(std::unique_ptr<weld::DialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class CuiAbstractSingleTabController_Impl : public SfxAbstractDialog
+{
+ std::unique_ptr<SfxSingleTabDialogController> m_xDlg;
+public:
+ explicit CuiAbstractSingleTabController_Impl(std::unique_ptr<SfxSingleTabDialogController> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+
+ //From class Window.
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class CuiAbstractTabController_Impl : public SfxAbstractTabDialog
+{
+ std::shared_ptr<SfxTabDialogController> m_xDlg;
+public:
+ explicit CuiAbstractTabController_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 OString &rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual const sal_uInt16* GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+
+ // screenshotting
+ virtual std::vector<OString> getAllPageUIXMLDescriptions() const override;
+ virtual bool selectPageByUIXMLDescription(const OString& rUIXMLDescription) override;
+ virtual BitmapEx createScreenshot() const override;
+ virtual OString GetScreenshotId() const override;
+};
+
+class SvxDistributeDialog;
+class AbstractSvxDistributeDialog_Impl: public AbstractSvxDistributeDialog
+{
+ std::unique_ptr<SvxDistributeDialog> m_xDlg;
+public:
+ explicit AbstractSvxDistributeDialog_Impl(std::unique_ptr<SvxDistributeDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+public:
+ virtual SvxDistributeHorizontal GetDistributeHor() const override;
+ virtual SvxDistributeVertical GetDistributeVer() const override;
+};
+
+class AbstractHangulHanjaConversionDialog_Impl: public AbstractHangulHanjaConversionDialog
+{
+private:
+ std::unique_ptr<HangulHanjaConversionDialog> m_xDlg;
+public:
+ explicit AbstractHangulHanjaConversionDialog_Impl(std::unique_ptr<HangulHanjaConversionDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void EndDialog(sal_Int32 nResult) override;
+ virtual void EnableRubySupport( bool _bVal ) override;
+ virtual void SetByCharacter( bool _bByCharacter ) override ;
+ virtual void SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection ) override;
+ virtual void SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType ) override;
+ virtual void SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl ) override;
+ virtual void SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl ) override;
+ virtual void SetIgnoreAllHdl( const Link<weld::Button&,void>& _rHdl ) override ;
+ virtual void SetChangeHdl( const Link<weld::Button&,void>& _rHdl ) override ;
+ virtual void SetChangeAllHdl( const Link<weld::Button&,void>& rHdl ) override ;
+ virtual void SetClickByCharacterHdl( const Link<weld::ToggleButton&,void>& rHdl ) override ;
+ virtual void SetConversionFormatChangedHdl( const Link<weld::Button&,void>& _rHdl ) override ;
+ virtual void SetFindHdl( const Link<weld::Button&,void>& _rHdl ) override;
+ virtual bool GetUseBothDirections( ) const override;
+ virtual editeng::HangulHanjaConversion::ConversionDirection
+ GetDirection( editeng::HangulHanjaConversion::ConversionDirection _eDefaultDirection ) const override;
+ virtual void SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument = true
+ ) override;
+ virtual OUString GetCurrentString( ) const override ;
+ virtual editeng::HangulHanjaConversion::ConversionFormat
+ GetConversionFormat( ) const override ;
+ virtual void FocusSuggestion( ) override;
+ virtual OUString GetCurrentSuggestion( ) const override;
+};
+
+class AbstractThesaurusDialog_Impl : public AbstractThesaurusDialog
+{
+ std::shared_ptr<SvxThesaurusDialog> m_xDlg;
+public:
+ explicit AbstractThesaurusDialog_Impl(std::shared_ptr<SvxThesaurusDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual OUString GetWord() override;
+};
+
+class AbstractHyphenWordDialog_Impl: public AbstractHyphenWordDialog
+{
+ std::unique_ptr<SvxHyphenWordDialog> m_xDlg;
+public:
+ explicit AbstractHyphenWordDialog_Impl(std::unique_ptr<SvxHyphenWordDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class FmShowColsDialog;
+class AbstractFmShowColsDialog_Impl : public AbstractFmShowColsDialog
+{
+ std::unique_ptr<FmShowColsDialog> m_xDlg;
+public:
+ explicit AbstractFmShowColsDialog_Impl(std::unique_ptr<FmShowColsDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetColumns(const css::uno::Reference< css::container::XIndexContainer>& xCols) override;
+};
+
+class SvxZoomDialog;
+class AbstractSvxZoomDialog_Impl : public AbstractSvxZoomDialog
+{
+ std::unique_ptr<SvxZoomDialog> m_xDlg;
+public:
+ explicit AbstractSvxZoomDialog_Impl(std::unique_ptr<SvxZoomDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetLimits( sal_uInt16 nMin, sal_uInt16 nMax ) override;
+ virtual void HideButton( ZoomButtonId nBtnId ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override ;
+};
+
+namespace svx{ class SpellDialog;}
+class AbstractSpellDialog_Impl : public AbstractSpellDialog
+{
+ std::shared_ptr<svx::SpellDialog> m_xDlg;
+public:
+ explicit AbstractSpellDialog_Impl(std::shared_ptr<svx::SpellDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void InvalidateDialog() override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+ virtual SfxBindings& GetBindings() override;
+};
+
+class TitleDialog;
+class AbstractTitleDialog_Impl : public AbstractTitleDialog
+{
+protected:
+ std::unique_ptr<TitleDialog> m_xDlg;
+public:
+ explicit AbstractTitleDialog_Impl(std::unique_ptr<TitleDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetTitle() const override ;
+
+};
+
+class SvxScriptSelectorDialog;
+class AbstractScriptSelectorDialog_Impl : public AbstractScriptSelectorDialog
+{
+ std::unique_ptr<SvxScriptSelectorDialog> m_xDlg;
+public:
+ explicit AbstractScriptSelectorDialog_Impl(std::unique_ptr<SvxScriptSelectorDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetScriptURL() const override;
+ virtual void SetRunLabel() override;
+};
+
+class GalleryIdDialog;
+class AbstractGalleryIdDialog_Impl : public AbstractGalleryIdDialog
+{
+protected:
+ std::unique_ptr<GalleryIdDialog> m_xDlg;
+public:
+ explicit AbstractGalleryIdDialog_Impl(std::unique_ptr<GalleryIdDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual sal_uInt32 GetId() const override;
+};
+
+class URLDlg;
+class AbstractURLDlg_Impl :public AbstractURLDlg
+{
+protected:
+ std::unique_ptr<URLDlg> m_xDlg;
+public:
+ explicit AbstractURLDlg_Impl(std::unique_ptr<URLDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetURL() const override;
+ virtual OUString GetAltText() const override;
+ virtual OUString GetDesc() const override;
+ virtual OUString GetTarget() const override;
+ virtual OUString GetName() const override;
+};
+
+class SvxSearchSimilarityDialog;
+class AbstractSvxSearchSimilarityDialog_Impl :public AbstractSvxSearchSimilarityDialog
+{
+ std::unique_ptr<SvxSearchSimilarityDialog> m_xDlg;
+public:
+ explicit AbstractSvxSearchSimilarityDialog_Impl(std::unique_ptr<SvxSearchSimilarityDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual sal_uInt16 GetOther() override;
+ virtual sal_uInt16 GetShorter() override;
+ virtual sal_uInt16 GetLonger() override;
+ virtual bool IsRelaxed() override;
+};
+
+class SvxJSearchOptionsDialog;
+class AbstractSvxJSearchOptionsDialog_Impl : public AbstractSvxJSearchOptionsDialog
+{
+ std::unique_ptr<SvxJSearchOptionsDialog> m_xDlg;
+public:
+ explicit AbstractSvxJSearchOptionsDialog_Impl(std::unique_ptr<SvxJSearchOptionsDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual TransliterationFlags GetTransliterationFlags() const override;
+};
+
+class AbstractSvxTransformTabDialog_Impl : public AbstractSvxTransformTabDialog
+{
+ std::shared_ptr<SvxTransformTabDialog> m_xDlg;
+public:
+ explicit AbstractSvxTransformTabDialog_Impl(std::shared_ptr<SvxTransformTabDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink ) override;
+ virtual void SetCurPageId( const OString& rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual const sal_uInt16* GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class AbstractSvxCaptionDialog_Impl : public AbstractSvxCaptionDialog
+{
+ std::shared_ptr<SvxCaptionTabDialog> m_xDlg;
+public:
+ explicit AbstractSvxCaptionDialog_Impl(std::shared_ptr<SvxCaptionTabDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink ) override;
+ virtual void SetCurPageId( const OString& rName ) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual const sal_uInt16* GetInputRanges( const SfxItemPool& pItem ) override;
+ virtual void SetInputSet( const SfxItemSet* pInSet ) override;
+ virtual void SetText( const OUString& rStr ) override;
+};
+
+class FmInputRecordNoDialog;
+class AbstractFmInputRecordNoDialog_Impl :public AbstractFmInputRecordNoDialog
+{
+ std::unique_ptr<FmInputRecordNoDialog> m_xDlg;
+public:
+ explicit AbstractFmInputRecordNoDialog_Impl(std::unique_ptr<FmInputRecordNoDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetValue(long nNew) override ;
+ virtual long GetValue() const override ;
+};
+
+class SvxNewDictionaryDialog;
+class AbstractSvxNewDictionaryDialog_Impl :public AbstractSvxNewDictionaryDialog
+{
+ std::unique_ptr<SvxNewDictionaryDialog> m_xDlg;
+public:
+ explicit AbstractSvxNewDictionaryDialog_Impl(std::unique_ptr<SvxNewDictionaryDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual css::uno::Reference< css::linguistic2::XDictionary > GetNewDictionary() override;
+};
+
+class SvxNameDialog;
+class AbstractSvxNameDialog_Impl :public AbstractSvxNameDialog
+{
+public:
+ explicit AbstractSvxNameDialog_Impl(std::unique_ptr<SvxNameDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void GetName( OUString& rName ) override ;
+ virtual void SetCheckNameHdl( const Link<AbstractSvxNameDialog&,bool>& rLink, bool bCheckImmediately = false ) override ;
+ virtual void SetCheckNameTooltipHdl( const Link<AbstractSvxNameDialog&, OUString>& rLink ) override ;
+ virtual void SetEditHelpId(const OString&) override ;
+ //from class Window
+ virtual void SetHelpId( const OString& ) override ;
+ virtual void SetText( const OUString& rStr ) override ;
+private:
+ std::unique_ptr<SvxNameDialog> m_xDlg;
+ Link<AbstractSvxNameDialog&,bool> aCheckNameHdl;
+ Link<AbstractSvxNameDialog&,OUString> aCheckNameTooltipHdl;
+ DECL_LINK(CheckNameHdl, SvxNameDialog&, bool);
+ DECL_LINK(CheckNameTooltipHdl, SvxNameDialog&, OUString);
+};
+
+class SvxObjectNameDialog;
+class SvxObjectTitleDescDialog;
+
+class AbstractSvxObjectNameDialog_Impl : public AbstractSvxObjectNameDialog
+{
+public:
+ explicit AbstractSvxObjectNameDialog_Impl(std::unique_ptr<SvxObjectNameDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void GetName(OUString& rName) override ;
+ virtual void SetCheckNameHdl(const Link<AbstractSvxObjectNameDialog&,bool>& rLink) override;
+
+private:
+ std::unique_ptr<SvxObjectNameDialog> m_xDlg;
+ Link<AbstractSvxObjectNameDialog&,bool> aCheckNameHdl;
+ DECL_LINK(CheckNameHdl, SvxObjectNameDialog&, bool);
+};
+
+class AbstractSvxObjectTitleDescDialog_Impl :public AbstractSvxObjectTitleDescDialog
+{
+ std::unique_ptr<SvxObjectTitleDescDialog> m_xDlg;
+public:
+ explicit AbstractSvxObjectTitleDescDialog_Impl(std::unique_ptr<SvxObjectTitleDescDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void GetTitle(OUString& rName) override;
+ virtual void GetDescription(OUString& rName) override;
+};
+
+class AbstractSvxMultiPathDialog_Impl : public AbstractSvxMultiPathDialog
+{
+ std::unique_ptr<SvxMultiPathDialog> m_xDlg;
+public:
+ explicit AbstractSvxMultiPathDialog_Impl(std::unique_ptr<SvxMultiPathDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetPath() const override;
+ virtual void SetPath( const OUString& rPath ) override;
+ virtual void SetTitle( const OUString& rNewTitle ) override;
+};
+
+class SvxPathSelectDialog;
+class AbstractSvxPathSelectDialog_Impl : public AbstractSvxMultiPathDialog
+{
+protected:
+ std::unique_ptr<SvxPathSelectDialog> m_xDlg;
+public:
+ explicit AbstractSvxPathSelectDialog_Impl(std::unique_ptr<SvxPathSelectDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetPath() const override;
+ virtual void SetPath( const OUString& rPath ) override;
+ virtual void SetTitle( const OUString& rNewTitle ) override;
+};
+
+class SvxHpLinkDlg;
+class AbstractSvxHpLinkDlg_Impl : public AbstractSvxHpLinkDlg
+{
+protected:
+ std::shared_ptr<SvxHpLinkDlg> m_xDlg;
+public:
+ explicit AbstractSvxHpLinkDlg_Impl(std::shared_ptr<SvxHpLinkDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual std::shared_ptr<SfxDialogController> GetController() override;
+ virtual bool QueryClose() override;
+};
+
+class FmSearchDialog;
+struct FmFoundRecordInformation;
+class AbstractFmSearchDialog_Impl :public AbstractFmSearchDialog
+{
+ std::unique_ptr<FmSearchDialog> m_xDlg;
+public:
+ explicit AbstractFmSearchDialog_Impl(std::unique_ptr<FmSearchDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetFoundHandler(const Link<FmFoundRecordInformation&,void>& lnk) override ;
+ virtual void SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&,void>& lnk) override;
+ virtual void SetActiveField(const OUString& strField) override;
+};
+
+class AbstractGraphicFilterDialog_Impl : public AbstractGraphicFilterDialog
+{
+ std::unique_ptr<GraphicFilterDialog> m_xDlg;
+public:
+ explicit AbstractGraphicFilterDialog_Impl(std::unique_ptr<GraphicFilterDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class SvxAreaTabDialog;
+class AbstractSvxAreaTabDialog_Impl : public AbstractSvxAreaTabDialog
+{
+ std::shared_ptr<SvxAreaTabDialog> m_xDlg;
+public:
+ explicit AbstractSvxAreaTabDialog_Impl(std::shared_ptr<SvxAreaTabDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+ virtual void SetCurPageId(const OString& rName) override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual const sal_uInt16* GetInputRanges(const SfxItemPool& pItem) override;
+ virtual void SetInputSet(const SfxItemSet* pInSet) override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+class AbstractInsertObjectDialog_Impl : public SfxAbstractInsertObjectDialog
+{
+ std::unique_ptr<InsertObjectDialog_Impl> m_xDlg;
+public:
+ explicit AbstractInsertObjectDialog_Impl(std::unique_ptr<InsertObjectDialog_Impl> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual css::uno::Reference < css::embed::XEmbeddedObject > GetObject() override;
+ virtual css::uno::Reference< css::io::XInputStream > GetIconIfIconified( OUString* pGraphicMediaType ) override;
+ virtual bool IsCreateNew() override;
+};
+
+class AbstractPasteDialog_Impl : public SfxAbstractPasteDialog
+{
+ std::shared_ptr<SvPasteObjectDialog> m_xDlg;
+public:
+ explicit AbstractPasteDialog_Impl(std::shared_ptr<SvPasteObjectDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual bool StartExecuteAsync(AsyncContext &rCtx) override;
+public:
+ virtual void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName ) override;
+ virtual void InsertUno( const OUString & sCmd, const OUString& sLabel ) override;
+ virtual void SetObjName( const SvGlobalName & rClass, const OUString & rObjName ) override;
+ virtual void PreGetFormat( const TransferableDataHelper& aHelper ) override;
+ virtual SotClipboardFormatId GetFormatOnly() override;
+ virtual SotClipboardFormatId GetFormat( const TransferableDataHelper& aHelper ) override;
+};
+
+class AbstractLinksDialog_Impl : public SfxAbstractLinksDialog
+{
+protected:
+ std::unique_ptr<SvBaseLinksDlg> m_xDlg;
+public:
+ explicit AbstractLinksDialog_Impl(std::unique_ptr<SvBaseLinksDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class SvxPostItDialog;
+class AbstractSvxPostItDialog_Impl :public AbstractSvxPostItDialog
+{
+public:
+ AbstractSvxPostItDialog_Impl(std::unique_ptr<SvxPostItDialog> pDlg)
+ : m_xDlg(std::move(pDlg))
+ {
+ }
+ virtual short Execute() override;
+ virtual void SetText( const OUString& rStr ) override; //From class Window
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetPrevHdl( const Link<AbstractSvxPostItDialog&,void>& rLink ) override;
+ virtual void SetNextHdl( const Link<AbstractSvxPostItDialog&,void>& rLink ) override;
+ virtual void EnableTravel(bool bNext, bool bPrev) override;
+ virtual OUString GetNote() override;
+ virtual void SetNote(const OUString& rTxt) override;
+ virtual void ShowLastAuthor(const OUString& rAuthor, const OUString& rDate) override;
+ virtual void DontChangeAuthor() override;
+ virtual void HideAuthor() override;
+ virtual std::shared_ptr<weld::Dialog> GetDialog() override;
+private:
+ std::unique_ptr<SvxPostItDialog> m_xDlg;
+ Link<AbstractSvxPostItDialog&,void> aNextHdl;
+ Link<AbstractSvxPostItDialog&,void> aPrevHdl;
+ DECL_LINK(NextHdl, SvxPostItDialog&, void);
+ DECL_LINK(PrevHdl, SvxPostItDialog&, void);
+};
+
+class PasswordToOpenModifyDialog;
+class AbstractPasswordToOpenModifyDialog_Impl : public AbstractPasswordToOpenModifyDialog
+{
+ std::unique_ptr<PasswordToOpenModifyDialog> m_xDlg;
+public:
+ explicit AbstractPasswordToOpenModifyDialog_Impl(std::unique_ptr<PasswordToOpenModifyDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual OUString GetPasswordToOpen() const override;
+ virtual OUString GetPasswordToModify() const override;
+ virtual bool IsRecommendToOpenReadonly() const override;
+};
+
+class SvxCharacterMap;
+class AbstractSvxCharacterMapDialog_Impl : public SfxAbstractDialog
+{
+ std::unique_ptr<SvxCharacterMap> m_xDlg;
+public:
+ explicit AbstractSvxCharacterMapDialog_Impl(std::unique_ptr<SvxCharacterMap> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+ virtual const SfxItemSet* GetOutputItemSet() const override;
+ virtual void SetText(const OUString& rStr) override;
+};
+
+class ScreenshotAnnotationDlg;
+class AbstractScreenshotAnnotationDlg_Impl : public AbstractScreenshotAnnotationDlg
+{
+ std::unique_ptr<ScreenshotAnnotationDlg> m_xDlg;
+
+public:
+ explicit AbstractScreenshotAnnotationDlg_Impl(std::unique_ptr<ScreenshotAnnotationDlg> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class SignatureLineDialog;
+class AbstractSignatureLineDialog_Impl : public AbstractSignatureLineDialog
+{
+ std::unique_ptr<SignatureLineDialog> m_xDlg;
+
+public:
+ explicit AbstractSignatureLineDialog_Impl(std::unique_ptr<SignatureLineDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class QrCodeGenDialog;
+class AbstractQrCodeGenDialog_Impl : public AbstractQrCodeGenDialog
+{
+ std::unique_ptr<QrCodeGenDialog> m_xDlg;
+
+public:
+ explicit AbstractQrCodeGenDialog_Impl(std::unique_ptr<QrCodeGenDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class SignSignatureLineDialog;
+class AbstractSignSignatureLineDialog_Impl : public AbstractSignSignatureLineDialog
+{
+protected:
+ std::unique_ptr<SignSignatureLineDialog> m_xDlg;
+
+public:
+ explicit AbstractSignSignatureLineDialog_Impl(std::unique_ptr<SignSignatureLineDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class AboutDialog;
+class AbstractAboutDialog_Impl : public AbstractAboutDialog
+{
+protected:
+ std::unique_ptr<AboutDialog> m_xDlg;
+
+public:
+ explicit AbstractAboutDialog_Impl(std::unique_ptr<AboutDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class TipOfTheDayDialog;
+class AbstractTipOfTheDayDialog_Impl : public AbstractTipOfTheDayDialog
+{
+protected:
+ std::unique_ptr<TipOfTheDayDialog> m_xDlg;
+
+public:
+ explicit AbstractTipOfTheDayDialog_Impl(std::unique_ptr<TipOfTheDayDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+class DiagramDialog;
+
+/** Edit Diagram dialog */
+class AbstractDiagramDialog_Impl : public AbstractDiagramDialog
+{
+protected:
+ std::unique_ptr<DiagramDialog> m_xDlg;
+
+public:
+ explicit AbstractDiagramDialog_Impl(std::unique_ptr<DiagramDialog> p)
+ : m_xDlg(std::move(p))
+ {
+ }
+ virtual short Execute() override;
+};
+
+//AbstractDialogFactory_Impl implementations
+class AbstractDialogFactory_Impl : public SvxAbstractDialogFactory
+{
+public:
+ virtual VclPtr<VclAbstractDialog> CreateVclDialog(weld::Window* pParent, sal_uInt32 nResId) override;
+
+ virtual VclPtr<SfxAbstractDialog> CreateSfxDialog( weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const SdrView* pView,
+ sal_uInt32 nResId ) override;
+ virtual VclPtr<SfxAbstractDialog> CreateCharMapDialog(weld::Window* pParent,
+ const SfxItemSet& rAttr,
+ const css::uno::Reference< css::frame::XFrame >& rFrame) override;
+ virtual VclPtr<SfxAbstractDialog> CreateEventConfigDialog(weld::Widget* pParent,
+ const SfxItemSet& rAttr,
+ const css::uno::Reference< css::frame::XFrame >& rFrame) override;
+ virtual VclPtr<VclAbstractDialog> CreateFrameDialog(weld::Window* pParent, const css::uno::Reference< css::frame::XFrame >& rxFrame,
+ sal_uInt32 nResId,
+ const OUString& rParameter ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateAutoCorrTabDialog(weld::Window* pParent, const SfxItemSet* pAttrSet) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateCustomizeTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ const css::uno::Reference< css::frame::XFrame >& xViewFrame ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateTextTabDialog( weld::Window* pParent,
+ const SfxItemSet* pAttrSet,
+ SdrView* pView ) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateTabItemDialog(weld::Window* pParent, const SfxItemSet& rSet) override;
+ virtual VclPtr<AbstractSvxCaptionDialog>
+ CreateCaptionDialog(weld::Window* pParent,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes = SvxAnchorIds::NONE) override;
+ virtual VclPtr<AbstractSvxDistributeDialog>
+ CreateSvxDistributeDialog(weld::Window* pParent, const SfxItemSet& rAttr) override;
+ virtual VclPtr<SfxAbstractInsertObjectDialog>
+ CreateInsertObjectDialog(weld::Window* pParent, const OUString& rCommmand,
+ const css::uno::Reference < css::embed::XStorage >& xStor,
+ const SvObjectServerList* pList ) override;
+ virtual VclPtr<VclAbstractDialog> CreateEditObjectDialog(weld::Window* pParent, const OUString& rCommmand,
+ const css::uno::Reference < css::embed::XEmbeddedObject >& xObj ) override;
+ virtual VclPtr<SfxAbstractPasteDialog> CreatePasteDialog(weld::Window* pParent) override;
+ virtual VclPtr<SfxAbstractLinksDialog> CreateLinksDialog(weld::Window* pParent, sfx2::LinkManager* pMgr, bool bHTML = false, sfx2::SvBaseLink* p=nullptr) override;
+
+ virtual VclPtr<AbstractHangulHanjaConversionDialog> CreateHangulHanjaConversionDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractThesaurusDialog> CreateThesaurusDialog(weld::Window*,
+ css::uno::Reference<css::linguistic2::XThesaurus> xThesaurus,
+ const OUString &rWord, LanguageType nLanguage) override;
+
+ virtual VclPtr<AbstractHyphenWordDialog> CreateHyphenWordDialog(weld::Window*,
+ const OUString &rWord, LanguageType nLang,
+ css::uno::Reference< css::linguistic2::XHyphenator > &xHyphen,
+ SvxSpellWrapper* pWrapper) override;
+
+ virtual VclPtr<AbstractFmShowColsDialog> CreateFmShowColsDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxZoomDialog> CreateSvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet) override;
+ // add for SvxBorderBackgroundDlg
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxBorderBackgroundDlg(
+ weld::Window* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableDrawingLayerFillStyles) override;
+
+ virtual VclPtr<AbstractSvxTransformTabDialog> CreateSvxTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes = SvxAnchorIds::NONE) override ;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSchTransformTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ const SdrView* pSdrView,
+ bool bSizeTabPage) override;
+ virtual VclPtr<AbstractSpellDialog> CreateSvxSpellDialog(
+ weld::Window* pParent,
+ SfxBindings* pBindings,
+ svx::SpellDialogChildWindow* pSpellChildWindow ) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateActualizeProgressDialog(weld::Widget* pParent, GalleryTheme* pThm) override;
+ virtual VclPtr<AbstractTitleDialog> CreateTitleDialog(weld::Widget* pParent, const OUString& rOldText) override;
+ virtual VclPtr<AbstractGalleryIdDialog> CreateGalleryIdDialog(weld::Widget* pParent,
+ GalleryTheme* pThm) override;
+ virtual VclPtr<VclAbstractDialog> CreateGalleryThemePropertiesDialog(weld::Widget* pParent,
+ ExchangeData* pData,
+ SfxItemSet* pItemSet) override;
+
+ virtual VclPtr<AbstractURLDlg> CreateURLDialog(weld::Widget* pParent,
+ const OUString& rURL, const OUString& rAltText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList ) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateSvxSearchAttributeDialog(weld::Window* pParent,
+ SearchAttrItemList& rLst,
+ const sal_uInt16* pWhRanges) override;
+ virtual VclPtr<AbstractSvxSearchSimilarityDialog> CreateSvxSearchSimilarityDialog( weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger) override;
+ virtual VclPtr<AbstractSvxJSearchOptionsDialog> CreateSvxJSearchOptionsDialog(weld::Window* pParent,
+ const SfxItemSet& rOptionsSet,
+ TransliterationFlags nInitialFlags) override;
+ virtual VclPtr<AbstractFmInputRecordNoDialog> CreateFmInputRecordNoDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxNewDictionaryDialog> CreateSvxNewDictionaryDialog(weld::Window* pParent) override;
+ virtual VclPtr<VclAbstractDialog> CreateSvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName) override;
+ virtual VclPtr<AbstractSvxNameDialog> CreateSvxNameDialog(weld::Window* pParent,
+ const OUString& rName, const OUString& rDesc) override;
+ // #i68101#
+ virtual VclPtr<AbstractSvxObjectNameDialog> CreateSvxObjectNameDialog(weld::Window* pParent, const OUString& rName) override;
+ virtual VclPtr<AbstractSvxObjectTitleDescDialog> CreateSvxObjectTitleDescDialog(weld::Window* pParent, const OUString& rTitle, const OUString& rDescription) override;
+ virtual VclPtr<AbstractSvxMultiPathDialog> CreateSvxMultiPathDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxMultiPathDialog> CreateSvxPathSelectDialog(weld::Window* pParent) override;
+ virtual VclPtr<AbstractSvxHpLinkDlg> CreateSvxHpLinkDlg(SfxChildWindow* pChild, SfxBindings* pBindings, weld::Window* pParent) override;
+ virtual VclPtr<AbstractFmSearchDialog> CreateFmSearchDialog(weld::Window* pParent,
+ const OUString& strInitialText,
+ const std::vector< OUString >& _rContexts,
+ sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterEmboss(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterPoster(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSepia(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSmooth(weld::Window* pParent,
+ const Graphic& rGraphic, double nRadius) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterSolarize(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractGraphicFilterDialog> CreateGraphicFilterMosaic(weld::Window* pParent,
+ const Graphic& rGraphic) override;
+ virtual VclPtr<AbstractSvxAreaTabDialog> CreateSvxAreaTabDialog(weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow) override;
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ const SdrObject* pObj,
+ bool bHasObj ) override;
+ virtual VclPtr<AbstractSvxPostItDialog> CreateSvxPostItDialog(weld::Widget* pParent,
+ const SfxItemSet& rCoreSet,
+ bool bPrevNext = false) override;
+
+ // For TabPage
+ virtual CreateTabPage GetTabPageCreatorFunc( sal_uInt16 nId ) override;
+
+ virtual GetTabPageRanges GetTabPageRangesFunc( sal_uInt16 nId ) override;
+ virtual DialogGetRanges GetDialogGetRangesFunc() override;
+ virtual VclPtr<VclAbstractDialog> CreateSvxScriptOrgDialog(weld::Window* pParent, const OUString& rLanguage) override;
+
+ virtual VclPtr<AbstractScriptSelectorDialog> CreateScriptSelectorDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& rxFrame) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateScriptErrorDialog(const css::uno::Any& rException) override;
+
+ virtual VclPtr<VclAbstractDialog> CreateSvxMacroAssignDlg(
+ weld::Window* _pParent,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const bool _bUnoDialogMode,
+ const css::uno::Reference< css::container::XNameReplace >& _rxEvents,
+ const sal_uInt16 _nInitiallySelectedEvent
+ ) override;
+
+ virtual VclPtr<SfxAbstractTabDialog> CreateSvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel) override;
+
+ virtual VclPtr<SvxAbstractSplitTableDialog> CreateSvxSplitTableDialog(weld::Window* pParent, bool bIsTableVertical, long nMaxVertical) override;
+
+ virtual std::shared_ptr<SvxAbstractNewTableDialog> CreateSvxNewTableDialog(weld::Window* pParent) override ;
+
+ virtual VclPtr<VclAbstractDialog> CreateOptionsDialog(
+ weld::Window* pParent, const OUString& rExtensionId ) override;
+
+ virtual VclPtr<SvxAbstractInsRowColDlg> CreateSvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId) override;
+
+ virtual VclPtr<AbstractPasswordToOpenModifyDialog> CreatePasswordToOpenModifyDialog(weld::Window* pParent, sal_uInt16 nMaxPasswdLen, bool bIsPasswordToModify) override;
+
+ virtual VclPtr<AbstractScreenshotAnnotationDlg> CreateScreenshotAnnotationDlg(weld::Dialog& rParentDialog) override;
+
+ virtual VclPtr<AbstractSignatureLineDialog>
+ CreateSignatureLineDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel, bool bEditExisting) override;
+
+ virtual VclPtr<AbstractSignSignatureLineDialog>
+ CreateSignSignatureLineDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel) override;
+
+ virtual VclPtr<AbstractQrCodeGenDialog>
+ CreateQrCodeGenDialog(weld::Window* pParent,
+ const css::uno::Reference<css::frame::XModel> xModel, bool bEditExisting) override;
+
+ virtual VclPtr<AbstractAboutDialog> CreateAboutDialog(weld::Window* pParent) override;
+
+ virtual VclPtr<AbstractTipOfTheDayDialog> CreateTipOfTheDayDialog(weld::Window* pParent) override;
+
+ virtual VclPtr<AbstractDiagramDialog> CreateDiagramDialog(
+ weld::Window* pParent,
+ std::shared_ptr<DiagramDataInterface> pDiagramData) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/factory/init.cxx b/cui/source/factory/init.cxx
new file mode 100644
index 000000000..87f3105a0
--- /dev/null
+++ b/cui/source/factory/init.cxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <cui/cuicharmap.hxx>
+
+// hook to call special character dialog for edits
+// caution: needs C-Linkage since dynamically loaded via symbol name
+extern "C"
+{
+SAL_DLLPUBLIC_EXPORT bool GetSpecialCharsForEdit(weld::Widget* i_pParent, const vcl::Font& i_rFont, OUString& o_rResult)
+{
+ bool bRet = false;
+ SvxCharacterMap aDlg(i_pParent, nullptr, nullptr);
+ aDlg.DisableFontSelection();
+ aDlg.SetCharFont(i_rFont);
+ if (aDlg.run() == RET_OK)
+ {
+ sal_UCS4 cChar = aDlg.GetChar();
+ // using the new UCS4 constructor
+ OUString aOUStr( &cChar, 1 );
+ o_rResult = aOUStr;
+ bRet = true;
+ }
+ return bRet;
+}
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/CommandCategoryListBox.hxx b/cui/source/inc/CommandCategoryListBox.hxx
new file mode 100644
index 000000000..059c1474f
--- /dev/null
+++ b/cui/source/inc/CommandCategoryListBox.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <i18nutil/searchopt.hxx>
+#include "cfgutil.hxx"
+
+class CommandCategoryListBox
+{
+ SfxGroupInfoArr_Impl m_aGroupInfo;
+ OUString m_sModuleLongName;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xModuleCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xUICmdDescription;
+
+ // For search
+ i18nutil::SearchOptions2 m_searchOptions;
+
+ SfxStylesInfo_Impl* pStylesInfo;
+ SfxStylesInfo_Impl m_aStylesInfo;
+
+ std::unique_ptr<weld::ComboBox> m_xControl;
+
+public:
+ CommandCategoryListBox(std::unique_ptr<weld::ComboBox> xControl);
+ ~CommandCategoryListBox();
+ void ClearAll();
+
+ void Init(
+ const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName);
+ void FillFunctionsList(
+ const css::uno::Sequence< css::frame::DispatchInformation >& xCommands,
+ CuiConfigFunctionListBox* pFunctionListBox,
+ const OUString& filterTerm,
+ SaveInData *pCurrentSaveInData );
+ OUString getCommandName(const OUString& sCommand);
+
+ void connect_changed(const Link<weld::ComboBox&, void>& rLink) { m_xControl->connect_changed(rLink); }
+
+ /**
+ Signals that a command category has been selected.
+ And updates the functions list box to include
+ the commands in the selected category.
+ */
+ void categorySelected(CuiConfigFunctionListBox* pFunctionListBox,
+ const OUString& filterTerm, SaveInData* pCurrentSaveInData = nullptr);
+
+ void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
+
+ // Adds children of the given macro group to the functions list
+ void addChildren(
+ const weld::TreeIter* parentEntry, const css::uno::Reference<com::sun::star::script::browse::XBrowseNode> &parentNode,
+ CuiConfigFunctionListBox* pFunctionListBox, const OUString &filterTerm , SaveInData *pCurrentSaveInData,
+ std::vector<std::unique_ptr<weld::TreeIter>> &rNodesToExpand);
+
+ void set_visible(bool bVisible) {m_xControl->set_visible(bVisible);}
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/CustomNotebookbarGenerator.hxx b/cui/source/inc/CustomNotebookbarGenerator.hxx
new file mode 100644
index 000000000..b06848dbb
--- /dev/null
+++ b/cui/source/inc/CustomNotebookbarGenerator.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+
+using namespace css::uno;
+
+class CustomNotebookbarGenerator
+{
+public:
+ CustomNotebookbarGenerator();
+ static OUString getCustomizedUIPath();
+ static OUString getOriginalUIPath();
+ static OString getSystemPath(OUString const& sURL);
+ static Sequence<OUString> getCustomizedUIItem(OUString sNotebookbarConfigType);
+ static void getFileNameAndAppName(OUString& sAppName, OUString& sNotebookbarUIFileName);
+ static void modifyCustomizedUIFile(const Sequence<OUString>& sUIItemProperties);
+ static void createCustomizedUIFile();
+ static void setCustomizedUIItem(Sequence<OUString> sUIItemProperties,
+ OUString sNotebookbarConfigType);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/DiagramDialog.hxx b/cui/source/inc/DiagramDialog.hxx
new file mode 100644
index 000000000..e97144050
--- /dev/null
+++ b/cui/source/inc/DiagramDialog.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+* This file is part of the LibreOffice project.
+*
+* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this
+* file, You can obtain one at http://mozilla.org/MPL/2.0/.
+*/
+
+#ifndef INCLUDED_CUI_SOURCE_INC_DIAGRAMDIALOG_HXX
+#define INCLUDED_CUI_SOURCE_INC_DIAGRAMDIALOG_HXX
+
+#include <tools/link.hxx>
+#include <vcl/weld.hxx>
+
+class DiagramDataInterface;
+
+/** Edit Diagram dialog */
+class DiagramDialog : public weld::GenericDialogController
+{
+public:
+ DiagramDialog(weld::Window* pWindow, std::shared_ptr<DiagramDataInterface> pDiagramData);
+ virtual ~DiagramDialog() override;
+
+private:
+ std::shared_ptr<DiagramDataInterface> mpDiagramData;
+ std::unique_ptr<weld::Button> mpBtnOk;
+ std::unique_ptr<weld::Button> mpBtnCancel;
+ std::unique_ptr<weld::Button> mpBtnAdd;
+ std::unique_ptr<weld::Button> mpBtnRemove;
+ std::unique_ptr<weld::TreeView> mpTreeDiagram;
+ std::unique_ptr<weld::TextView> mpTextAdd;
+
+ DECL_LINK(OnAddClick, weld::Button&, void);
+ DECL_LINK(OnRemoveClick, weld::Button&, void);
+
+ void populateTree(const weld::TreeIter* pParent, const OUString& rParentId);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_DIAGRAMDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/FontFeaturesDialog.hxx b/cui/source/inc/FontFeaturesDialog.hxx
new file mode 100644
index 000000000..93e5f7c4a
--- /dev/null
+++ b/cui/source/inc/FontFeaturesDialog.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/.
+ *
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_FONTFEATURESDIALOG_HXX
+#define INCLUDED_CUI_SOURCE_INC_FONTFEATURESDIALOG_HXX
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/font/Feature.hxx>
+#include <svx/fntctrl.hxx>
+#include <memory>
+
+namespace cui
+{
+struct FontFeatureItem
+{
+ FontFeatureItem(weld::Widget* pParent)
+ : m_aFeatureCode(0)
+ , m_nDefault(0)
+ , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/fontfragment.ui"))
+ , m_xContainer(m_xBuilder->weld_widget("fontentry"))
+ , m_xText(m_xBuilder->weld_label("label"))
+ , m_xCombo(m_xBuilder->weld_combo_box("combo"))
+ , m_xCheck(m_xBuilder->weld_check_button("check"))
+ {
+ }
+
+ sal_uInt32 m_aFeatureCode;
+ sal_uInt32 m_nDefault;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Widget> m_xContainer;
+ std::unique_ptr<weld::Label> m_xText;
+ std::unique_ptr<weld::ComboBox> m_xCombo;
+ std::unique_ptr<weld::CheckButton> m_xCheck;
+};
+
+class FontFeaturesDialog : public weld::GenericDialogController
+{
+private:
+ std::vector<FontFeatureItem> m_aFeatureItems;
+ OUString m_sFontName;
+ OUString m_sResultFontName;
+
+ SvxFontPrevWindow m_aPreviewWindow;
+ std::unique_ptr<weld::ScrolledWindow> m_xContentWindow;
+ std::unique_ptr<weld::Container> m_xContentGrid;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWindow;
+
+ void initialize();
+ OUString createFontNameWithFeatures();
+
+ void fillGrid(std::vector<vcl::font::Feature> const& rFontFeatures);
+
+ DECL_LINK(ComboBoxSelectedHdl, weld::ComboBox&, void);
+ DECL_LINK(CheckBoxToggledHdl, weld::ToggleButton&, void);
+
+public:
+ FontFeaturesDialog(weld::Window* pParent, OUString const& rFontName);
+ ~FontFeaturesDialog() override;
+ virtual short run() override;
+
+ OUString const& getResultFontName() const { return m_sResultFontName; }
+
+ void updateFontPreview();
+};
+
+} // end svx namespaces
+
+#endif // INCLUDED_CUI_SOURCE_INC_FONTFEATURESDIALOG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/QrCodeGenDialog.hxx b/cui/source/inc/QrCodeGenDialog.hxx
new file mode 100644
index 000000000..832662837
--- /dev/null
+++ b/cui/source/inc/QrCodeGenDialog.hxx
@@ -0,0 +1,50 @@
+/* -*- 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_CUI_INC_QRCODEGENDIALOG_HXX
+#define INCLUDED_CUI_INC_QRCODEGENDIALOG_HXX
+
+#include <config_qrcodegen.h>
+
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+
+class QrCodeGenDialog : public weld::GenericDialogController
+{
+public:
+ QrCodeGenDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ bool bEditExisting);
+
+ virtual short run() override;
+
+protected:
+ css::uno::Reference<css::frame::XModel> m_xModel;
+ void Apply();
+
+private:
+ std::unique_ptr<weld::Entry> m_xEdittext;
+ std::unique_ptr<weld::RadioButton> m_xECC[4];
+ std::unique_ptr<weld::SpinButton> m_xSpinBorder;
+#if ENABLE_QRCODEGEN
+ weld::Widget* mpParent;
+#endif
+
+ css::uno::Reference<css::beans::XPropertySet> m_xExistingShapeProperties;
+
+ void GetErrorCorrection(long);
+ //Function contains QR Code Generating Library Calls
+ static OUString GenerateQRCode(OUString aQrText, long aQrECC, int aQrBorder);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignSignatureLineDialog.hxx b/cui/source/inc/SignSignatureLineDialog.hxx
new file mode 100644
index 000000000..6bd08ff4b
--- /dev/null
+++ b/cui/source/inc/SignSignatureLineDialog.hxx
@@ -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/.
+ */
+#ifndef INCLUDED_CUI_INC_SIGNSIGNATURELINEDIALOG_HXX
+#define INCLUDED_CUI_INC_SIGNSIGNATURELINEDIALOG_HXX
+
+#include "SignatureLineDialogBase.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/graphic/XGraphic.hpp>
+#include <com/sun/star/security/XCertificate.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignSignatureLineDialog : public SignatureLineDialogBase
+{
+public:
+ SignSignatureLineDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel);
+
+private:
+ std::unique_ptr<weld::Entry> m_xEditName;
+ std::unique_ptr<weld::TextView> m_xEditComment;
+ std::unique_ptr<weld::Button> m_xBtnLoadImage;
+ std::unique_ptr<weld::Button> m_xBtnClearImage;
+ std::unique_ptr<weld::Button> m_xBtnChooseCertificate;
+ std::unique_ptr<weld::Button> m_xBtnSign;
+ std::unique_ptr<weld::Label> m_xLabelHint;
+ std::unique_ptr<weld::Label> m_xLabelHintText;
+ std::unique_ptr<weld::Label> m_xLabelAddComment;
+
+ css::uno::Reference<css::beans::XPropertySet> m_xShapeProperties;
+ css::uno::Reference<css::security::XCertificate> m_xSelectedCertifate;
+ css::uno::Reference<css::graphic::XGraphic> m_xSignatureImage;
+ OUString m_aSignatureLineId;
+ OUString m_aSuggestedSignerName;
+ OUString m_aSuggestedSignerTitle;
+ bool m_bShowSignDate;
+ OUString m_sOriginalImageBtnLabel;
+
+ void ValidateFields();
+ css::uno::Reference<css::graphic::XGraphic> getSignedGraphic(bool bValid);
+ virtual void Apply() override;
+
+ DECL_LINK(clearImage, weld::Button&, void);
+ DECL_LINK(loadImage, weld::Button&, void);
+ DECL_LINK(chooseCertificate, weld::Button&, void);
+ DECL_LINK(entryChanged, weld::Entry&, void);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignatureLineDialog.hxx b/cui/source/inc/SignatureLineDialog.hxx
new file mode 100644
index 000000000..fd671acd5
--- /dev/null
+++ b/cui/source/inc/SignatureLineDialog.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_CUI_INC_SIGNATURELINEDIALOG_HXX
+#define INCLUDED_CUI_INC_SIGNATURELINEDIALOG_HXX
+
+#include "SignatureLineDialogBase.hxx"
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignatureLineDialog : public SignatureLineDialogBase
+{
+public:
+ SignatureLineDialog(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ bool bEditExisting);
+
+private:
+ std::unique_ptr<weld::Entry> m_xEditName;
+ std::unique_ptr<weld::Entry> m_xEditTitle;
+ std::unique_ptr<weld::Entry> m_xEditEmail;
+ std::unique_ptr<weld::TextView> m_xEditInstructions;
+ std::unique_ptr<weld::CheckButton> m_xCheckboxCanAddComments;
+ std::unique_ptr<weld::CheckButton> m_xCheckboxShowSignDate;
+
+ css::uno::Reference<css::beans::XPropertySet> m_xExistingShapeProperties;
+ OUString m_aSignatureLineId;
+
+ virtual void Apply() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SignatureLineDialogBase.hxx b/cui/source/inc/SignatureLineDialogBase.hxx
new file mode 100644
index 000000000..2e046d945
--- /dev/null
+++ b/cui/source/inc/SignatureLineDialogBase.hxx
@@ -0,0 +1,34 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_CUI_INC_SIGNATURELINEDIALOGBASE_HXX
+#define INCLUDED_CUI_INC_SIGNATURELINEDIALOGBASE_HXX
+
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+
+class SignatureLineDialogBase : public weld::GenericDialogController
+{
+public:
+ SignatureLineDialogBase(weld::Widget* pParent, css::uno::Reference<css::frame::XModel> xModel,
+ const OUString& rUIFile, const OString& rDialogId);
+
+ virtual short run() override;
+
+protected:
+ css::uno::Reference<css::frame::XModel> m_xModel;
+ static OUString getSignatureImage();
+ virtual void Apply() = 0;
+ static OUString getCDataString(const OUString& rString);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/cui/source/inc/SpellDialog.hxx b/cui/source/inc/SpellDialog.hxx
new file mode 100644
index 000000000..cb23f1004
--- /dev/null
+++ b/cui/source/inc/SpellDialog.hxx
@@ -0,0 +1,231 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_SPELLDIALOG_HXX
+#define INCLUDED_CUI_SOURCE_INC_SPELLDIALOG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+
+#include <svx/langbox.hxx>
+#include <memory>
+#include <svl/undo.hxx>
+#include <vcl/customweld.hxx>
+#include <svx/weldeditview.hxx>
+#include <editeng/SpellPortions.hxx>
+
+#include <set>
+
+namespace svx{ class SpellUndoAction_Impl;}
+class UndoChangeGroupGuard;
+
+// forward ---------------------------------------------------------------
+
+struct SpellDialog_Impl;
+namespace com::sun::star::linguistic2 { class XSpellChecker1; }
+
+namespace svx{
+class SpellDialog;
+struct SpellErrorDescription;
+
+class SentenceEditWindow_Impl : public WeldEditView
+{
+private:
+ std::set<sal_Int32> m_aIgnoreErrorsAt;
+ SpellDialog* m_pSpellDialog;
+ weld::Toolbar* m_pToolbar;
+ sal_Int32 m_nErrorStart;
+ sal_Int32 m_nErrorEnd;
+ bool m_bIsUndoEditMode;
+
+ Link<LinkParamNone*,void> m_aModifyLink;
+
+ void CallModifyLink() {m_aModifyLink.Call(nullptr); }
+
+ SpellDialog* GetSpellDialog() const { return m_pSpellDialog; }
+
+ bool GetErrorDescription(SpellErrorDescription& rSpellErrorDescription, sal_Int32 nPosition);
+
+ DECL_LINK(ToolbarHdl, const OString&, void);
+
+protected:
+ virtual bool KeyInput( const KeyEvent& rKEvt ) override;
+
+public:
+ SentenceEditWindow_Impl();
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void SetSpellDialog(SpellDialog* pDialog) { m_pSpellDialog = pDialog; }
+ virtual ~SentenceEditWindow_Impl() override;
+
+ void Init(weld::Toolbar* pToolbar);
+ void SetModifyHdl(const Link<LinkParamNone*,void>& rLink)
+ {
+ m_aModifyLink = rLink;
+ m_xEditEngine->SetModifyHdl(m_aModifyLink);
+ }
+
+ void SetAttrib(const SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd);
+
+ void SetText(const OUString& rStr);
+
+ bool MarkNextError( bool bIgnoreCurrentError, const css::uno::Reference<css::linguistic2::XSpellChecker1>& );
+ int ChangeMarkedWord(const OUString& rNewWord, LanguageType eLanguage);
+ void MoveErrorMarkTo(sal_Int32 nErrorStart, sal_Int32 nErrorEnd, bool bGrammar);
+ OUString GetErrorText() const;
+ void RestoreCurrentError();
+
+ void SetAlternatives(
+ const css::uno::Reference<css::linguistic2::XSpellAlternatives>& );
+
+ bool GetAlternatives(SpellErrorDescription& rDesc);
+
+ void ClearModifyFlag() { m_xEditEngine->ClearModifyFlag(); }
+ void ResetModified() { ClearModifyFlag(); m_bIsUndoEditMode = false;}
+ bool IsModified() const { return m_xEditEngine->IsModified(); }
+
+ bool IsUndoEditMode() const { return m_bIsUndoEditMode;}
+ void SetUndoEditMode(bool bSet);
+
+ svx::SpellPortions CreateSpellPortions() const;
+
+ void ResetUndo();
+ void Undo();
+ void AddUndoAction( std::unique_ptr<SfxUndoAction> pAction );
+ size_t GetUndoActionCount() const;
+ void UndoActionStart( sal_uInt16 nId );
+ void UndoActionEnd();
+
+ void MoveErrorEnd(long nOffset);
+
+ void ResetIgnoreErrorsAt() { m_aIgnoreErrorsAt.clear(); }
+};
+
+// class SvxSpellDialog ---------------------------------------------
+class SpellDialogChildWindow;
+
+class SpellDialog : public SfxModelessDialogController
+{
+ friend class SentenceEditWindow_Impl;
+private:
+ OUString m_sResumeST;
+ OUString m_sIgnoreOnceST;
+ OUString m_sNoSuggestionsST;
+
+ OUString m_sTitleSpelling;
+ OUString m_sTitleSpellingGrammar;
+
+ Link<SpellUndoAction_Impl&,void> aDialogUndoLink;
+
+ bool bFocusLocked;
+
+ svx::SpellDialogChildWindow& rParent;
+ svx::SpellPortions m_aSavedSentence;
+
+ std::unique_ptr<SpellDialog_Impl> pImpl;
+ css::uno::Reference<
+ css::linguistic2::XSpellChecker1 > xSpell;
+
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<weld::Label> m_xResumeFT;
+ std::unique_ptr<weld::Label> m_xNoSuggestionsFT;
+ std::unique_ptr<weld::Label> m_xIgnoreOnceFT;
+ std::unique_ptr<weld::Label> m_xLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::Label> m_xExplainFT;
+ std::unique_ptr<weld::LinkButton> m_xExplainLink;
+ std::unique_ptr<weld::Label> m_xNotInDictFT;
+ std::unique_ptr<SentenceEditWindow_Impl> m_xSentenceED;
+ std::unique_ptr<weld::Label> m_xSuggestionFT;
+ std::unique_ptr<weld::TreeView> m_xSuggestionLB;
+ std::unique_ptr<weld::Button> m_xIgnorePB;
+ std::unique_ptr<weld::Button> m_xIgnoreAllPB;
+ std::unique_ptr<weld::Button> m_xIgnoreRulePB;
+ std::unique_ptr<weld::Button> m_xAddToDictPB;
+ std::unique_ptr<weld::MenuButton> m_xAddToDictMB;
+ std::unique_ptr<weld::Button> m_xChangePB;
+ std::unique_ptr<weld::Button> m_xChangeAllPB;
+ std::unique_ptr<weld::Button> m_xAutoCorrPB;
+ std::unique_ptr<weld::CheckButton> m_xCheckGrammarCB;
+ std::unique_ptr<weld::Button> m_xOptionsPB;
+ std::unique_ptr<weld::Button> m_xUndoPB;
+ std::unique_ptr<weld::Button> m_xClosePB;
+ std::unique_ptr<weld::Toolbar> m_xToolbar;
+ std::unique_ptr<weld::CustomWeld> m_xSentenceEDWeld;
+
+ DECL_LINK(ChangeHdl, weld::Button&, void);
+ DECL_LINK(DoubleClickChangeHdl, weld::TreeView&, bool);
+ DECL_LINK(ChangeAllHdl, weld::Button&, void);
+ DECL_LINK(IgnoreAllHdl, weld::Button&, void);
+ DECL_LINK(IgnoreHdl, weld::Button&, void);
+ DECL_LINK(CheckGrammarHdl, weld::Button&, void);
+ DECL_LINK(ExtClickHdl, weld::Button&, void);
+ DECL_LINK(CancelHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, LinkParamNone*, void);
+ DECL_LINK(UndoHdl, weld::Button&, void);
+ DECL_LINK(AddToDictSelectHdl, const OString&, void);
+ DECL_LINK(AddToDictClickHdl, weld::Button&, void);
+ DECL_LINK(LanguageSelectHdl, weld::ComboBox&, void);
+ DECL_LINK(DialogUndoHdl, SpellUndoAction_Impl&, void);
+
+ DECL_LINK(InitHdl, void*, void);
+
+ void AddToDictionaryExecute(const OString& rItemId);
+ void StartSpellOptDlg_Impl();
+ int InitUserDicts();
+ void UpdateBoxes_Impl(bool bCallFromSelectHdl = false);
+ void Init_Impl();
+ void SpellContinue_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard = nullptr, bool UseSavedSentence = false, bool bIgnoreCurrentError = false );
+ void LockFocusChanges( bool bLock ) {bFocusLocked = bLock;}
+ void ToplevelFocusChanged();
+ void Impl_Restore(bool bUseSavedSentence);
+
+ LanguageType GetSelectedLang_Impl() const;
+
+ /** Retrieves the next sentence.
+ */
+ bool GetNextSentence_Impl(std::unique_ptr<UndoChangeGroupGuard>* pGuard, bool bUseSavedSentence, bool bRecheck /*for rechecking the current sentence*/);
+ /** Corrects all errors that have been selected to be changed always
+ */
+ static bool ApplyChangeAllList_Impl(SpellPortions& rSentence, bool& bHasReplaced);
+ void SetTitle_Impl(LanguageType nLang);
+
+protected:
+
+ OUString getReplacementString() const;
+
+public:
+ SpellDialog(
+ svx::SpellDialogChildWindow* pChildWindow,
+ weld::Window * pParent,
+ SfxBindings* pBindings);
+ virtual ~SpellDialog() override;
+
+ virtual void Activate() override;
+ virtual void Deactivate() override;
+
+ virtual void Close() override;
+
+ void InvalidateDialog();
+};
+
+} //namespace svx
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxConfigPageHelper.hxx b/cui/source/inc/SvxConfigPageHelper.hxx
new file mode 100644
index 000000000..8beed6069
--- /dev/null
+++ b/cui/source/inc/SvxConfigPageHelper.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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/frame/XModuleManager2.hpp>
+
+#include "cfg.hxx"
+
+class SvxConfigPageHelper
+{
+public:
+ static void RemoveEntry( SvxEntries* pEntries, SvxConfigEntry const * pChildEntry );
+
+ static OUString replaceSaveInName( const OUString& rMessage, const OUString& rSaveInName );
+ static OUString stripHotKey( const OUString& str );
+ static OUString replaceSixteen( const OUString& str, sal_Int32 nReplacement );
+
+ static sal_Int16 GetImageType();
+ static void InitImageType();
+ static css::uno::Reference< css::graphic::XGraphic > GetGraphic(
+ const css::uno::Reference< css::ui::XImageManager >& xImageManager,
+ const OUString& rCommandURL );
+
+ static OUString generateCustomName(
+ const OUString& prefix,
+ SvxEntries* entries,
+ sal_Int32 suffix = 1 );
+ static OUString generateCustomMenuURL(
+ SvxEntries* entries,
+ sal_Int32 suffix = 1 );
+ static sal_uInt32 generateRandomValue();
+ /**
+ Generates a custom resource URL for a new toolbar.
+ Typically something like: private:resource/toolbar/custom_toolbar_########
+ The last 8 letters are randomly generated alphanumeric characters.
+ */
+ static OUString generateCustomURL( SvxEntries* entries );
+
+ static OUString GetModuleName( const OUString& aModuleId );
+ static OUString GetUIModuleName(
+ const OUString& aModuleId,
+ const css::uno::Reference< css::frame::XModuleManager2 >& rModuleManager );
+
+ static bool GetMenuItemData(
+ const css::uno::Reference< css::container::XIndexAccess >& rItemContainer,
+ sal_Int32 nIndex,
+ OUString& rCommandURL,
+ OUString& rLabel,
+ sal_uInt16& rType,
+ sal_Int32& rStyle,
+ css::uno::Reference< css::container::XIndexAccess >& rSubMenu );
+ static bool GetToolbarItemData(
+ const css::uno::Reference< css::container::XIndexAccess >& rItemContainer,
+ sal_Int32 nIndex,
+ OUString& rCommandURL,
+ OUString& rLabel,
+ sal_uInt16& rType,
+ bool& rIsVisible,
+ sal_Int32& rStyle );
+
+ static css::uno::Sequence< css::beans::PropertyValue > ConvertSvxConfigEntry(
+ const SvxConfigEntry* pEntry );
+ static css::uno::Sequence< css::beans::PropertyValue > ConvertToolbarEntry(
+ const SvxConfigEntry* pEntry );
+
+ static bool EntrySort( SvxConfigEntry const * a, SvxConfigEntry const * b );
+
+ static bool SvxConfigEntryModified( SvxConfigEntry const * pEntry );
+
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxMenuConfigPage.hxx b/cui/source/inc/SvxMenuConfigPage.hxx
new file mode 100644
index 000000000..50124e46a
--- /dev/null
+++ b/cui/source/inc/SvxMenuConfigPage.hxx
@@ -0,0 +1,72 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxMenuConfigPage : public SvxConfigPage
+{
+private:
+ bool m_bIsMenuBar;
+
+ DECL_LINK( SelectMenuEntry, weld::TreeView&, void );
+ DECL_LINK( ContentContextMenuHdl, const CommandEvent&, bool );
+ DECL_LINK( FunctionContextMenuHdl, const CommandEvent&, bool );
+
+ DECL_LINK( GearHdl, const OString&, void );
+
+ DECL_LINK( SelectCategory, weld::ComboBox&, void );
+
+ DECL_LINK( AddCommandHdl, weld::Button&, void );
+ DECL_LINK( RemoveCommandHdl, weld::Button&, void );
+
+ DECL_LINK( InsertHdl, const OString&, void );
+ DECL_LINK( ModifyItemHdl, const OString&, void );
+ DECL_LINK( ResetMenuHdl, weld::Button&, void );
+
+ DECL_LINK( MenuEntriesSizeAllocHdl, const Size&, void );
+
+ virtual void ListModified() override;
+
+ void Init() override;
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+
+ virtual void SelectElement() override;
+
+public:
+ SvxMenuConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet, bool bIsMenuBar = true);
+ virtual ~SvxMenuConfigPage() override;
+
+ SaveInData* CreateSaveInData(
+ const css::uno::Reference <
+ css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference <
+ css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxNotebookbarConfigPage.hxx b/cui/source/inc/SvxNotebookbarConfigPage.hxx
new file mode 100644
index 000000000..47870949d
--- /dev/null
+++ b/cui/source/inc/SvxNotebookbarConfigPage.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 .
+ */
+
+#pragma once
+
+#include <libxml/parser.h>
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include <memory>
+#include <vector>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxNotebookbarConfigPage : public SvxConfigPage
+{
+private:
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void Init() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+ virtual void SelectElement() override;
+ void SetElement();
+
+public:
+ struct NotebookbarEntries
+ {
+ OUString sUIItemId;
+ OUString sClassId;
+ OUString sActionName;
+ OUString sDisplayName;
+ OUString sVisibleValue;
+ };
+ struct CategoriesEntries
+ {
+ OUString sDisplayName;
+ OUString sUIItemId;
+ OUString sClassType;
+ };
+ SvxNotebookbarConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet);
+ virtual ~SvxNotebookbarConfigPage() override;
+ SaveInData* CreateSaveInData(const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const css::uno::Reference<css::ui::XUIConfigurationManager>&,
+ const OUString& aModuleId, bool docConfig) override;
+ static void FillFunctionsList(xmlNodePtr pRootNodePtr,
+ std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory);
+ static void searchNodeandAttribute(std::vector<NotebookbarEntries>& aEntries,
+ std::vector<CategoriesEntries>& aCategoryList,
+ OUString& sActiveCategory,
+ CategoriesEntries& aCurCategoryEntry, xmlNode* pNodePtr,
+ bool isCategory);
+ static void getNodeValue(xmlNode* pNodePtr, NotebookbarEntries& aNodeEntries);
+};
+
+class SvxNotebookbarEntriesListBox final : public SvxMenuEntriesListBox
+{
+ void ChangedVisibility(int nRow);
+ typedef std::pair<int, int> row_col;
+ DECL_LINK(CheckButtonHdl, const row_col&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ SvxNotebookbarEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPg);
+ virtual ~SvxNotebookbarEntriesListBox() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/SvxToolbarConfigPage.hxx b/cui/source/inc/SvxToolbarConfigPage.hxx
new file mode 100644
index 000000000..5902cdf4b
--- /dev/null
+++ b/cui/source/inc/SvxToolbarConfigPage.hxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+
+#include <memory>
+
+#include "cfg.hxx" //for SvxConfigPage and SaveInData
+
+class SvxToolbarConfigPage : public SvxConfigPage
+{
+private:
+
+ DECL_LINK( SelectToolbarEntry, weld::TreeView&, void );
+ DECL_LINK( MoveHdl, weld::Button&, void );
+
+ DECL_LINK( GearHdl, const OString&, void );
+
+ DECL_LINK( SelectCategory, weld::ComboBox&, void );
+
+ DECL_LINK( ContentContextMenuHdl, const CommandEvent&, bool );
+ DECL_LINK( FunctionContextMenuHdl, const CommandEvent&, bool );
+
+ DECL_LINK( AddCommandHdl, weld::Button&, void );
+ DECL_LINK( RemoveCommandHdl, weld::Button&, void );
+
+ DECL_LINK( InsertHdl, const OString&, void );
+ DECL_LINK( ModifyItemHdl, const OString&, void );
+ DECL_LINK( ResetToolbarHdl, weld::Button&, void );
+
+ virtual void ListModified() override;
+
+ void UpdateButtonStates() override;
+ short QueryReset() override;
+ void Init() override;
+ void DeleteSelectedContent() override;
+ void DeleteSelectedTopLevel() override;
+ virtual void SelectElement() override;
+
+public:
+ SvxToolbarConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rItemSet);
+ virtual ~SvxToolbarConfigPage() override;
+
+ void AddFunction(int nTarget = -1);
+
+ void MoveEntry( bool bMoveUp ) override;
+
+ SaveInData* CreateSaveInData(
+ const css::uno::Reference <
+ css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference <
+ css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig ) override;
+};
+
+class SvxToolbarEntriesListBox final : public SvxMenuEntriesListBox
+{
+ void ChangedVisibility(int nRow);
+
+ typedef std::pair<int, int> row_col;
+ DECL_LINK(CheckButtonHdl, const row_col&, void);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+
+ SvxToolbarEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxToolbarConfigPage* pPg);
+ virtual ~SvxToolbarEntriesListBox() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/about.hxx b/cui/source/inc/about.hxx
new file mode 100644
index 000000000..2262da38d
--- /dev/null
+++ b/cui/source/inc/about.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_CUI_SOURCE_INC_ABOUT_HXX
+#define INCLUDED_CUI_SOURCE_INC_ABOUT_HXX
+
+#include <vcl/bitmapex.hxx>
+#include <vcl/weld.hxx>
+
+class AboutDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::LinkButton> m_pCreditsButton;
+ std::unique_ptr<weld::LinkButton> m_pWebsiteButton;
+ std::unique_ptr<weld::LinkButton> m_pReleaseNotesButton;
+ std::unique_ptr<weld::Button> m_pCloseButton;
+ std::unique_ptr<weld::Button> m_pCopyButton;
+
+ std::unique_ptr<weld::Image> m_pBrandImage;
+ std::unique_ptr<weld::Image> m_pAboutImage;
+ std::unique_ptr<weld::Label> m_pVersionLabel;
+ std::unique_ptr<weld::Label> m_pBuildCaption;
+ std::unique_ptr<weld::LinkButton> m_pBuildLabel;
+ std::unique_ptr<weld::Label> m_pEnvLabel;
+ std::unique_ptr<weld::Label> m_pUILabel;
+ std::unique_ptr<weld::Label> m_pLocaleLabel;
+ std::unique_ptr<weld::Label> m_pMiscLabel;
+ std::unique_ptr<weld::Label> m_pCopyrightLabel;
+
+ static OUString GetVersionString();
+ static OUString GetBuildString();
+ static OUString GetLocaleString();
+ static OUString GetMiscString();
+
+ static OUString GetCopyrightString();
+ static bool IsStringValidGitHash(const OUString& hash);
+
+ DECL_LINK(HandleClick, weld::Button&, void);
+
+public:
+ AboutDialog(weld::Window* pParent);
+ virtual ~AboutDialog() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_ABOUT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/acccfg.hxx b/cui/source/inc/acccfg.hxx
new file mode 100644
index 000000000..aecc923ad
--- /dev/null
+++ b/cui/source/inc/acccfg.hxx
@@ -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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/keycod.hxx>
+#include <i18nutil/searchopt.hxx>
+#include "cfgutil.hxx"
+
+class SfxMacroInfoItem;
+class CuiConfigFunctionListBox;
+class SfxAcceleratorConfigPage;
+class SfxStringItem;
+
+// class SfxAcceleratorConfigPage ----------------------------------------
+
+struct TAccInfo
+{
+public:
+ TAccInfo(sal_Int32 nKeyPos, sal_Int32 nListPos, const vcl::KeyCode& aKey)
+ : m_nKeyPos(nKeyPos)
+ , m_nListPos(nListPos)
+ , m_bIsConfigurable(true) /**< it's important to set true as default -
+ because only fix entries will be disabled later... */
+ , m_sCommand()
+ , m_aKey(aKey)
+ {
+ }
+
+ bool isConfigured() const
+ {
+ return (m_nKeyPos > -1 && m_nListPos > -1 && !m_sCommand.isEmpty());
+ }
+
+ sal_Int32 m_nKeyPos;
+ sal_Int32 m_nListPos;
+ bool m_bIsConfigurable;
+ OUString m_sCommand;
+ vcl::KeyCode m_aKey;
+};
+
+namespace sfx2
+{
+class FileDialogHelper;
+}
+
+enum class StartFileDialogType
+{
+ Open,
+ SaveAs
+};
+
+class SfxAcceleratorConfigPage : public SfxTabPage
+{
+private:
+ const SfxMacroInfoItem* m_pMacroInfoItem;
+ std::unique_ptr<sfx2::FileDialogHelper> m_pFileDlg;
+
+ OUString aLoadAccelConfigStr;
+ OUString aSaveAccelConfigStr;
+ OUString aFilterAllStr;
+ OUString aFilterCfgStr;
+ SfxStylesInfo_Impl m_aStylesInfo;
+ bool m_bStylesInfoInitialized;
+
+ css::uno::Reference<css::uno::XComponentContext> m_xContext;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xGlobal;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xModule;
+ css::uno::Reference<css::ui::XAcceleratorConfiguration> m_xAct;
+ css::uno::Reference<css::container::XNameAccess> m_xUICmdDescription;
+ css::uno::Reference<css::frame::XFrame> m_xFrame;
+
+ OUString m_sModuleLongName;
+ OUString m_sModuleUIName;
+
+ // For search
+ Timer m_aUpdateDataTimer;
+ i18nutil::SearchOptions2 m_options;
+
+ Idle m_aFillGroupIdle;
+
+ std::unique_ptr<weld::TreeView> m_xEntriesBox;
+ std::unique_ptr<weld::RadioButton> m_xOfficeButton;
+ std::unique_ptr<weld::RadioButton> m_xModuleButton;
+ std::unique_ptr<weld::Button> m_xChangeButton;
+ std::unique_ptr<weld::Button> m_xRemoveButton;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLBox;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xFunctionBox;
+ std::unique_ptr<weld::TreeView> m_xKeyBox;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::Button> m_xLoadButton;
+ std::unique_ptr<weld::Button> m_xSaveButton;
+ std::unique_ptr<weld::Button> m_xResetButton;
+
+ DECL_LINK(ChangeHdl, weld::Button&, void);
+ DECL_LINK(RemoveHdl, weld::Button&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+ DECL_LINK(Save, weld::Button&, void);
+ DECL_LINK(Load, weld::Button&, void);
+ DECL_LINK(Default, weld::Button&, void);
+ DECL_LINK(RadioHdl, weld::Button&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(FocusOut_Impl, weld::Widget&, void);
+ DECL_LINK(TimeOut_Impl, Timer*, void);
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+ DECL_LINK(LoadHdl, sfx2::FileDialogHelper*, void);
+ DECL_LINK(SaveHdl, sfx2::FileDialogHelper*, void);
+
+ OUString GetLabel4Command(const OUString& rCommand);
+ int applySearchFilter(OUString const& rSearchTerm);
+ void InitAccCfg();
+ sal_Int32 MapKeyCodeToPos(const vcl::KeyCode& rCode) const;
+ void StartFileDialog(StartFileDialogType nType, const OUString& rTitle);
+
+ void Init(const css::uno::Reference<css::ui::XAcceleratorConfiguration>& pAccMgr);
+ void ResetConfig();
+
+public:
+ SfxAcceleratorConfigPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rItemSet);
+ virtual ~SfxAcceleratorConfigPage() override;
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+
+ void Apply(const css::uno::Reference<css::ui::XAcceleratorConfiguration>& pAccMgr);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/align.hxx b/cui/source/inc/align.hxx
new file mode 100644
index 000000000..43c2fe0ee
--- /dev/null
+++ b/cui/source/inc/align.hxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_ALIGN_HXX
+#define INCLUDED_CUI_SOURCE_INC_ALIGN_HXX
+
+// list box indexes
+#define ALIGNDLG_HORALIGN_STD 0
+#define ALIGNDLG_HORALIGN_LEFT 1
+#define ALIGNDLG_HORALIGN_CENTER 2
+#define ALIGNDLG_HORALIGN_RIGHT 3
+#define ALIGNDLG_HORALIGN_BLOCK 4
+#define ALIGNDLG_HORALIGN_FILL 5
+#define ALIGNDLG_HORALIGN_DISTRIBUTED 6
+
+#define ALIGNDLG_VERALIGN_STD 0
+#define ALIGNDLG_VERALIGN_TOP 1
+#define ALIGNDLG_VERALIGN_MID 2
+#define ALIGNDLG_VERALIGN_BOTTOM 3
+#define ALIGNDLG_VERALIGN_BLOCK 4
+#define ALIGNDLG_VERALIGN_DISTRIBUTED 5
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/dialcontrol.hxx>
+#include <svx/frmdirlbox.hxx>
+#include <vcl/weld.hxx>
+
+namespace svx {
+
+
+class AlignmentTabPage : public SfxTabPage
+{
+ static const sal_uInt16 s_pRanges[];
+
+public:
+ virtual ~AlignmentTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ explicit AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet);
+
+ static const sal_uInt16* GetRanges() { return s_pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ void InitVsRefEgde();
+ void UpdateEnableControls();
+
+ bool HasAlignmentChanged( const SfxItemSet& rNew, sal_uInt16 nWhich ) const;
+
+ DECL_LINK(UpdateEnableHdl, weld::ComboBox&, void);
+ DECL_LINK(StackedClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(AsianModeClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(WrapClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(HyphenClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(ShrinkClickHdl, weld::ToggleButton&, void);
+
+private:
+ weld::TriStateEnabled m_aStackedState;
+ weld::TriStateEnabled m_aAsianModeState;
+ weld::TriStateEnabled m_aWrapState;
+ weld::TriStateEnabled m_aHyphenState;
+ weld::TriStateEnabled m_aShrinkState;
+
+ ValueSet m_aVsRefEdge;
+
+ std::unique_ptr<weld::ComboBox> m_xLbHorAlign;
+ std::unique_ptr<weld::Label> m_xFtIndent;
+ std::unique_ptr<weld::MetricSpinButton> m_xEdIndent;
+ std::unique_ptr<weld::Label> m_xFtVerAlign;
+ std::unique_ptr<weld::ComboBox> m_xLbVerAlign;
+
+ std::unique_ptr<weld::Label> m_xFtRotate;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfRotate;
+ std::unique_ptr<weld::Label> m_xFtRefEdge;
+ std::unique_ptr<weld::CheckButton> m_xCbStacked;
+ std::unique_ptr<weld::CheckButton> m_xCbAsianMode;
+
+ std::unique_ptr<weld::Widget> m_xBoxDirection;
+ std::unique_ptr<weld::CheckButton> m_xBtnWrap;
+ std::unique_ptr<weld::CheckButton> m_xBtnHyphen;
+ std::unique_ptr<weld::CheckButton> m_xBtnShrink;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xLbFrameDir;
+
+ // hidden labels/string
+ std::unique_ptr<weld::Label> m_xFtBotLock;
+ std::unique_ptr<weld::Label> m_xFtTopLock;
+ std::unique_ptr<weld::Label> m_xFtCelLock;
+ std::unique_ptr<weld::Label> m_xFtABCD;
+
+ std::unique_ptr<weld::Widget> m_xAlignmentFrame;
+ std::unique_ptr<weld::Widget> m_xOrientFrame;
+ std::unique_ptr<weld::Widget> m_xPropertiesFrame;
+
+ std::unique_ptr<weld::CustomWeld> m_xVsRefEdge;
+ std::unique_ptr<DialControl> m_xCtrlDial;
+ std::unique_ptr<weld::CustomWeld> m_xCtrlDialWin;
+};
+
+
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/autocdlg.hxx b/cui/source/inc/autocdlg.hxx
new file mode 100644
index 000000000..e0c780fe8
--- /dev/null
+++ b/cui/source/inc/autocdlg.hxx
@@ -0,0 +1,417 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_AUTOCDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_AUTOCDLG_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+#include <vcl/metric.hxx>
+
+#include <map>
+#include <set>
+
+class CharClass;
+class CollatorWrapper;
+class SmartTagMgr;
+
+namespace editeng { class SortedAutoCompleteStrings; }
+
+// class OfaAutoCorrDlg --------------------------------------------------
+
+class OfaAutoCorrDlg : public SfxTabDialogController
+{
+ std::unique_ptr<weld::Widget> m_xLanguageBox;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+
+ DECL_LINK(SelectLanguageHdl, weld::ComboBox&, void);
+public:
+
+ OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet *pSet);
+ virtual ~OfaAutoCorrDlg() override;
+
+ void EnableLanguage(bool bEnable);
+};
+
+// class OfaAutocorrOptionsPage ------------------------------------------
+
+class OfaAutocorrOptionsPage : public SfxTabPage
+{
+private:
+ OUString m_sInput;
+ OUString m_sDoubleCaps;
+ OUString m_sStartCap;
+ OUString m_sBoldUnderline;
+ OUString m_sURL;
+ OUString m_sNoDblSpaces;
+ OUString m_sDash;
+ OUString m_sAccidentalCaps;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+
+ void InsertEntry(const OUString& rTxt);
+
+public:
+ OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+
+};
+
+// class OfaSwAutoFmtOptionsPage ----------------------------------------------------
+
+class OfaSwAutoFmtOptionsPage : public SfxTabPage
+{
+ OUString sDeleteEmptyPara;
+ OUString sUseReplaceTbl;
+ OUString sCapitalStartWord;
+ OUString sCapitalStartSentence;
+ OUString sUserStyle;
+ OUString sBullet;
+ OUString sBoldUnder;
+ OUString sNoDblSpaces;
+ OUString sCorrectCapsLock;
+ OUString sDetectURL;
+ OUString sDash;
+ OUString sRightMargin;
+ OUString sNum;
+ OUString sBorder;
+ OUString sTable;
+ OUString sReplaceTemplates;
+ OUString sDelSpaceAtSttEnd;
+ OUString sDelSpaceBetweenLines;
+
+ OUString sMargin;
+ OUString sBulletChar;
+ OUString sByInputBulletChar;
+
+ vcl::Font aBulletFont;
+ vcl::Font aByInputBulletFont;
+ sal_uInt16 nPercent;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::Button> m_xEditPB;
+
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(EditHdl, weld::Button&, void);
+ DECL_LINK(DoubleClickEditHdl, weld::TreeView&, bool);
+
+ void CreateEntry(const OUString& rTxt, sal_uInt16 nCol);
+
+public:
+ OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaSwAutoFmtOptionsPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+// class OfaAutocorrReplacePage ------------------------------------------
+
+struct DoubleString
+{
+ OUString sShort;
+ OUString sLong;
+ void* pUserData; ///< CheckBox -> form. Text Bool -> selection text
+};
+
+typedef std::vector<DoubleString> DoubleStringArray;
+
+struct StringChangeList
+{
+ DoubleStringArray aNewEntries;
+ DoubleStringArray aDeletedEntries;
+};
+
+typedef std::map<LanguageType, StringChangeList> StringChangeTable;
+
+class OfaAutocorrReplacePage : public SfxTabPage
+{
+private:
+
+ StringChangeTable aChangesTable;
+
+ OUString sModify;
+ OUString sNew;
+
+ std::set<OUString> aFormatText;
+ std::map<LanguageType, DoubleStringArray>
+ aDoubleStringTable;
+ std::unique_ptr<CollatorWrapper> pCompareClass;
+ std::unique_ptr<CharClass> pCharClass;
+ LanguageType eLang;
+
+ bool bHasSelectionText;
+ bool bFirstSelect:1;
+ bool bReplaceEditChanged:1;
+ bool bSWriter:1;
+
+ std::vector<int> m_aReplaceFixedWidths;
+ std::unique_ptr<weld::CheckButton> m_xTextOnlyCB;
+ std::unique_ptr<weld::Entry> m_xShortED;
+ std::unique_ptr<weld::Entry> m_xReplaceED;
+ std::unique_ptr<weld::TreeView> m_xReplaceTLB;
+ std::unique_ptr<weld::Button> m_xNewReplacePB;
+ std::unique_ptr<weld::Button> m_xReplacePB;
+ std::unique_ptr<weld::Button> m_xDeleteReplacePB;
+ std::unique_ptr<weld::Container> m_xButtonBox;
+
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(EntrySizeAllocHdl, const Size&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ bool NewDelHdl(const weld::Widget*);
+
+ void RefillReplaceBox( bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage);
+
+public:
+ OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrReplacePage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetLanguage(LanguageType eSet);
+ void DeleteEntry(const OUString& sShort, const OUString& sLong);
+ void NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting);
+};
+
+// class OfaAutocorrExceptPage ---------------------------------------------
+
+struct StringsArrays
+{
+ std::vector<OUString> aAbbrevStrings;
+ std::vector<OUString> aDoubleCapsStrings;
+
+ StringsArrays() { }
+};
+typedef std::map<LanguageType, StringsArrays> StringsTable;
+
+class OfaAutocorrExceptPage : public SfxTabPage
+{
+private:
+ StringsTable aStringsTable;
+ std::unique_ptr<CollatorWrapper> pCompareClass;
+ LanguageType eLang;
+
+ std::unique_ptr<weld::Entry> m_xAbbrevED;
+ std::unique_ptr<weld::TreeView> m_xAbbrevLB;
+ std::unique_ptr<weld::Button> m_xNewAbbrevPB;
+ std::unique_ptr<weld::Button> m_xDelAbbrevPB;
+ std::unique_ptr<weld::CheckButton> m_xAutoAbbrevCB;
+
+ std::unique_ptr<weld::Entry> m_xDoubleCapsED;
+ std::unique_ptr<weld::TreeView> m_xDoubleCapsLB;
+ std::unique_ptr<weld::Button> m_xNewDoublePB;
+ std::unique_ptr<weld::Button> m_xDelDoublePB;
+ std::unique_ptr<weld::CheckButton> m_xAutoCapsCB;
+
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ void NewDelHdl(const weld::Widget*);
+ /// Box filled with new language
+ void RefillReplaceBoxes(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage);
+public:
+ OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaAutocorrExceptPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ void SetLanguage(LanguageType eSet);
+
+};
+
+// class OfaQuoteTabPage -------------------------------------------------
+
+class OfaQuoteTabPage : public SfxTabPage
+{
+private:
+ OUString sNonBrkSpace;
+ OUString sOrdinal;
+ OUString sTransliterateRTL;
+ OUString sAngleQuotes;
+
+ sal_UCS4 cSglStartQuote;
+ sal_UCS4 cSglEndQuote;
+
+ sal_UCS4 cStartQuote;
+ sal_UCS4 cEndQuote;
+
+ std::unique_ptr<weld::CheckButton> m_xSingleTypoCB;
+ std::unique_ptr<weld::Button> m_xSglStartQuotePB;
+ std::unique_ptr<weld::Label> m_xSglStartExFT;
+ std::unique_ptr<weld::Button> m_xSglEndQuotePB;
+ std::unique_ptr<weld::Label> m_xSglEndExFT;
+ std::unique_ptr<weld::Button> m_xSglStandardPB;
+ std::unique_ptr<weld::CheckButton> m_xDoubleTypoCB;
+ std::unique_ptr<weld::Button> m_xDblStartQuotePB;
+ std::unique_ptr<weld::Label> m_xDblStartExFT;
+ std::unique_ptr<weld::Button> m_xDblEndQuotePB;
+ std::unique_ptr<weld::Label> m_xDblEndExFT;
+ std::unique_ptr<weld::Button> m_xDblStandardPB;
+ OUString m_sStandard;
+ /// For anything but writer
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ /// Just for writer
+ std::unique_ptr<weld::TreeView> m_xSwCheckLB;
+
+
+ DECL_LINK(QuoteHdl, weld::Button&, void);
+ DECL_LINK(StdQuoteHdl, weld::Button&, void);
+
+ OUString ChangeStringExt_Impl( sal_UCS4 );
+
+ static void CreateEntry(weld::TreeView& rLstBox, const OUString& rTxt,
+ sal_uInt16 nCol, sal_uInt16 nTextCol);
+
+public:
+ OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaQuoteTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+// class OfaAutoCompleteTabPage ---------------------------------------------
+
+class OfaAutoCompleteTabPage : public SfxTabPage
+{
+private:
+ editeng::SortedAutoCompleteStrings* m_pAutoCompleteList;
+ sal_uInt16 m_nAutoCmpltListCnt;
+
+ std::unique_ptr<weld::CheckButton> m_xCBActiv; ///<Enable word completion
+ std::unique_ptr<weld::CheckButton> m_xCBAppendSpace;///<Append space
+ std::unique_ptr<weld::CheckButton> m_xCBAsTip; ///<Show as tip
+
+ std::unique_ptr<weld::CheckButton> m_xCBCollect;///<Collect words
+ std::unique_ptr<weld::CheckButton> m_xCBRemoveList;///<...save the list for later use...
+
+ std::unique_ptr<weld::ComboBox> m_xDCBExpandKey;
+ std::unique_ptr<weld::SpinButton> m_xNFMinWordlen;
+ std::unique_ptr<weld::SpinButton> m_xNFMaxEntries;
+ std::unique_ptr<weld::TreeView> m_xLBEntries;
+ std::unique_ptr<weld::Button> m_xPBEntries;
+
+ DECL_LINK(CheckHdl, weld::ToggleButton&, void);
+ DECL_LINK(KeyReleaseHdl, const KeyEvent&, bool);
+
+public:
+ OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ virtual ~OfaAutoCompleteTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+
+ void CopyToClipboard() const;
+ DECL_LINK(DeleteHdl, weld::Button&, void);
+};
+
+// class OfaSmartTagOptionsTabPage ---------------------------------------------
+
+/** Smart tag options tab page
+
+ This tab page is used to enable/disable smart tag types
+*/
+class OfaSmartTagOptionsTabPage : public SfxTabPage
+{
+private:
+
+ // controls
+ std::unique_ptr<weld::CheckButton> m_xMainCB;
+ std::unique_ptr<weld::TreeView> m_xSmartTagTypesLB;
+ std::unique_ptr<weld::Button> m_xPropertiesPB;
+
+ /** Inserts items into m_aSmartTagTypesLB
+
+ Reads out the smart tag types supported by the SmartTagMgr and
+ inserts the associated strings into the list box.
+ */
+ void FillListBox( const SmartTagMgr& rSmartTagMgr );
+
+ /** Clears the m_aSmartTagTypesLB
+ */
+ void ClearListBox();
+
+ /** Handler for the check box
+
+ Enables/disables all controls in the tab page (except from the
+ check box.
+ */
+ DECL_LINK(CheckHdl, weld::ToggleButton&, void);
+
+ /** Handler for the push button
+
+ Calls the displayPropertyPage function of the smart tag recognizer
+ associated with the currently selected smart tag type.
+ */
+ DECL_LINK(ClickHdl, weld::Button&, void);
+
+ /** Handler for the list box
+
+ Enables/disables the properties push button if selection in the
+ smart tag types list box changes.
+ */
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+public:
+ /// construction via Create()
+ OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaSmartTagOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/backgrnd.hxx b/cui/source/inc/backgrnd.hxx
new file mode 100644
index 000000000..14d30703e
--- /dev/null
+++ b/cui/source/inc/backgrnd.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_CUI_SOURCE_INC_BACKGRND_HXX
+#define INCLUDED_CUI_SOURCE_INC_BACKGRND_HXX
+
+#include <memory>
+
+#include "cuitabarea.hxx"
+
+class BackgroundPreviewImpl;
+class SvxOpenGraphicDialog;
+class SvxBrushItem;
+
+/** class SvxBackgroundTabPage --------------------------------------------
+
+ [Description]
+ With this TabPage a Brush (e. g. for a frame's background color)
+ can be set.
+ [Items]
+ <SvxBrushItem>: <SID_ATTR_BRUSH>;
+*/
+
+class SvxBkgTabPage : public SvxAreaTabPage
+{
+ static const sal_uInt16 pPageRanges[];
+
+ std::unique_ptr<weld::ComboBox> m_xTblLBox;
+ bool bHighlighting : 1;
+ bool bCharBackColor : 1;
+ SfxItemSet maSet;
+ std::unique_ptr<SfxItemSet> m_pResetSet;
+
+ sal_Int32 m_nActPos = -1;
+
+ DECL_LINK(TblDestinationHdl_Impl, weld::ComboBox&, void);
+public:
+ SvxBkgTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxBkgTabPage() override;
+
+ // returns the area of the which-values
+ static const sal_uInt16* GetRanges() { return pPageRanges; }
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void PageCreated( const SfxAllItemSet& aSet ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_BACKGRND_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/bbdlg.hxx b/cui/source/inc/bbdlg.hxx
new file mode 100644
index 000000000..b25b7cc09
--- /dev/null
+++ b/cui/source/inc/bbdlg.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_CUI_SOURCE_INC_BBDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_BBDLG_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+/*--------------------------------------------------------------------
+ Description: bunch the border background pages
+ --------------------------------------------------------------------*/
+
+class SvxBorderBackgroundDlg: public SfxTabDialogController
+{
+public:
+ SvxBorderBackgroundDlg(weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableSelector,
+ bool bEnableDrawingLayerFillStyles);
+protected:
+ virtual void PageCreated(const OString& rPageId, SfxTabPage& rTabPage) override;
+
+private:
+ bool mbEnableBackgroundSelector : 1; ///< for Border/Background
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/border.hxx b/cui/source/inc/border.hxx
new file mode 100644
index 000000000..7af464924
--- /dev/null
+++ b/cui/source/inc/border.hxx
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_BORDER_HXX
+#define INCLUDED_CUI_SOURCE_INC_BORDER_HXX
+
+#include <editeng/shaditem.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/valueset.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/algitem.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/frmsel.hxx>
+#include <svx/flagsdef.hxx>
+
+#include <set>
+
+// forward ---------------------------------------------------------------
+
+namespace editeng
+{
+ class SvxBorderLine;
+}
+
+class ShadowControlsWrapper
+{
+public:
+ explicit ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor);
+
+ SvxShadowItem GetControlValue(const SvxShadowItem& rItem) const;
+ void SetControlValue(const SvxShadowItem& rItem);
+ void SetControlDontKnow();
+
+ bool get_value_changed_from_saved() const;
+
+private:
+ ValueSet& mrVsPos;
+ weld::MetricSpinButton& mrMfSize;
+ ColorListBox& mrLbColor;
+};
+
+class MarginControlsWrapper
+{
+public:
+ explicit MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
+ weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom);
+
+ SvxMarginItem GetControlValue(const SvxMarginItem& rItem) const;
+ void SetControlValue(const SvxMarginItem& rItem);
+ void SetControlDontKnow();
+
+ bool get_value_changed_from_saved() const;
+
+private:
+ weld::MetricSpinButton& mrLeftWrp;
+ weld::MetricSpinButton& mrRightWrp;
+ weld::MetricSpinButton& mrTopWrp;
+ weld::MetricSpinButton& mrBottomWrp;
+};
+
+class SvxBorderTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pRanges[];
+
+public:
+ SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ virtual ~SvxBorderTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rCoreAttrs ) override;
+ virtual void Reset( const SfxItemSet* ) override;
+ virtual void ChangesApplied() override;
+
+ void HideShadowControls();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+ void SetTableMode();
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ std::vector<Image> m_aShadowImgVec;
+ std::vector<Image> m_aBorderImgVec;
+
+ long nMinValue; ///< minimum distance
+ SwBorderModes nSWMode; ///< table, textframe, paragraph
+ sal_uInt16 mnBoxSlot;
+ sal_uInt16 mnShadowSlot;
+
+ bool mbHorEnabled; ///< true = Inner horizontal border enabled.
+ bool mbVerEnabled; ///< true = Inner vertical border enabled.
+ bool mbTLBREnabled; ///< true = Top-left to bottom-right border enabled.
+ bool mbBLTREnabled; ///< true = Bottom-left to top-right border enabled.
+ bool mbUseMarginItem;
+ bool mbLeftModified;
+ bool mbRightModified;
+ bool mbTopModified;
+ bool mbBottomModified;
+ bool mbSync;
+ bool mbRemoveAdjacentCellBorders;
+ bool bIsCalcDoc;
+
+ std::set<SvxBorderLineStyle> maUsedBorderStyles;
+
+ // Controls
+ svx::FrameSelector m_aFrameSel;
+ std::unique_ptr<ValueSet> m_xWndPresets;
+ std::unique_ptr<weld::CustomWeld> m_xWndPresetsWin;
+ std::unique_ptr<weld::Label> m_xUserDefFT;
+ std::unique_ptr<weld::CustomWeld> m_xFrameSelWin;
+
+ std::unique_ptr<SvtLineListBox> m_xLbLineStyle;
+ std::unique_ptr<ColorListBox> m_xLbLineColor;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineWidthMF;
+
+ std::unique_ptr<weld::Container> m_xSpacingFrame;
+ std::unique_ptr<weld::Label> m_xLeftFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
+ std::unique_ptr<weld::Label> m_xRightFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMF;
+ std::unique_ptr<weld::Label> m_xTopFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
+ std::unique_ptr<weld::Label> m_xBottomFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMF;
+ std::unique_ptr<weld::CheckButton> m_xSynchronizeCB;
+
+ std::unique_ptr<weld::Container> m_xShadowFrame;
+ std::unique_ptr<ValueSet> m_xWndShadows;
+ std::unique_ptr<weld::CustomWeld> m_xWndShadowsWin;
+ std::unique_ptr<weld::Label> m_xFtShadowSize;
+ std::unique_ptr<weld::MetricSpinButton> m_xEdShadowSize;
+ std::unique_ptr<weld::Label> m_xFtShadowColor;
+ std::unique_ptr<ColorListBox> m_xLbShadowColor;
+
+ std::unique_ptr<weld::Container> m_xPropertiesFrame;///< properties - "Merge with next paragraph" in Writer
+ std::unique_ptr<weld::CheckButton> m_xMergeWithNextCB;
+ // #i29550#
+ std::unique_ptr<weld::CheckButton> m_xMergeAdjacentBordersCB;
+ std::unique_ptr<weld::CheckButton> m_xRemoveAdjcentCellBordersCB;
+ std::unique_ptr<weld::Label> m_xRemoveAdjcentCellBordersFT;
+ std::unique_ptr<ShadowControlsWrapper> m_xShadowControls;
+ std::unique_ptr<MarginControlsWrapper> m_xMarginControls;
+
+ // Handler
+ DECL_LINK(SelStyleHdl_Impl, SvtLineListBox&, void);
+ DECL_LINK(SelColHdl_Impl, ColorListBox&, void);
+ DECL_LINK(SelPreHdl_Impl, ValueSet*, void);
+ DECL_LINK(SelSdwHdl_Impl, ValueSet*, void);
+ DECL_LINK(LinesChanged_Impl, LinkParamNone*, void);
+ DECL_LINK(ModifyDistanceHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifyWidthHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(SyncHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(RemoveAdjacentCellBorderHdl_Impl, weld::ToggleButton&, void);
+
+ sal_uInt16 GetPresetImageId(sal_uInt16 nValueSetIdx) const;
+ const char* GetPresetStringId(sal_uInt16 nValueSetIdx) const;
+
+ void FillPresetVS();
+ void FillShadowVS();
+ void FillValueSets();
+
+ // Filler
+ void FillLineListBox_Impl();
+
+ /// share for individual Frame-/Core-Line
+ void ResetFrameLine_Impl( svx::FrameBorderType eBorder,
+ const editeng::SvxBorderLine* pCurLine,
+ bool bValid );
+
+ bool IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const;
+ void UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset );
+};
+
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cfg.hxx b/cui/source/inc/cfg.hxx
new file mode 100644
index 000000000..f413495a1
--- /dev/null
+++ b/cui/source/inc/cfg.hxx
@@ -0,0 +1,673 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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/transfer.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/weld.hxx>
+#include <svtools/valueset.hxx>
+
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/XUIConfigurationManager.hpp>
+#include <com/sun/star/ui/XImageManager.hpp>
+#include <com/sun/star/graphic/XGraphicProvider.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
+
+#include <sfx2/tabdlg.hxx>
+#include <memory>
+#include <vector>
+
+#include "cfgutil.hxx"
+#include "CommandCategoryListBox.hxx"
+
+#define notebookbarTabScope "notebookbarTabScope"
+
+static const char ITEM_DESCRIPTOR_COMMANDURL[] = "CommandURL";
+static const char ITEM_DESCRIPTOR_CONTAINER[] = "ItemDescriptorContainer";
+static const char ITEM_DESCRIPTOR_LABEL[] = "Label";
+static const char ITEM_DESCRIPTOR_TYPE[] = "Type";
+static const char ITEM_DESCRIPTOR_STYLE[] = "Style";
+static const char ITEM_DESCRIPTOR_ISVISIBLE[] = "IsVisible";
+static const char ITEM_DESCRIPTOR_RESOURCEURL[] = "ResourceURL";
+static const char ITEM_DESCRIPTOR_UINAME[] = "UIName";
+
+static const char ITEM_MENUBAR_URL[] = "private:resource/menubar/menubar";
+static const char ITEM_TOOLBAR_URL[] = "private:resource/toolbar/";
+
+static const char CUSTOM_TOOLBAR_STR[] = "custom_toolbar_";
+
+static const char aMenuSeparatorStr[] = " | ";
+
+class SvxConfigEntry;
+class SvxConfigPage;
+
+typedef std::vector< SvxConfigEntry* > SvxEntries;
+
+class SvxConfigDialog : public SfxTabDialogController
+{
+private:
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+
+public:
+ SvxConfigDialog(weld::Window*, const SfxItemSet*);
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+ void SetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame);
+};
+
+class SaveInData
+{
+private:
+
+ bool bModified;
+
+ bool bDocConfig;
+ bool bReadOnly;
+
+ css::uno::Reference
+ < css::ui::XUIConfigurationManager > m_xCfgMgr;
+
+ css::uno::Reference
+ < css::ui::XUIConfigurationManager > m_xParentCfgMgr;
+
+ css::uno::Reference
+ < css::ui::XImageManager > m_xImgMgr;
+
+ css::uno::Reference
+ < css::ui::XImageManager > m_xParentImgMgr;
+
+ static css::uno::Reference
+ < css::ui::XImageManager >* xDefaultImgMgr;
+
+protected:
+
+ void ApplyMenu(
+ css::uno::Reference< css::container::XIndexContainer > const & rMenuBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry *pMenuData );
+
+ void LoadSubMenus(
+ const css::uno::Reference< css::container::XIndexAccess >& xMenuSettings,
+ const OUString& rBaseTitle, SvxConfigEntry const * pParentData, bool bContextMenu );
+
+public:
+
+ SaveInData(
+ const css::uno::Reference < css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference < css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~SaveInData() {}
+
+ bool PersistChanges(
+ const css::uno::Reference< css::uno::XInterface >& xManager );
+
+ void SetModified( bool bValue = true ) { bModified = bValue; }
+ bool IsModified( ) const { return bModified; }
+
+ bool IsReadOnly( ) const { return bReadOnly; }
+ bool IsDocConfig( ) const { return bDocConfig; }
+
+ const css::uno::Reference
+ < css::ui::XUIConfigurationManager >&
+ GetConfigManager() const { return m_xCfgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XUIConfigurationManager >&
+ GetParentConfigManager() const { return m_xParentCfgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XImageManager >&
+ GetImageManager() const { return m_xImgMgr; };
+
+ const css::uno::Reference
+ < css::ui::XImageManager >&
+ GetParentImageManager() const { return m_xParentImgMgr; };
+
+ css::uno::Reference
+ < css::container::XNameAccess > m_xCommandToLabelMap;
+
+ css::uno::Sequence
+ < css::beans::PropertyValue > m_aSeparatorSeq;
+
+ css::uno::Reference<css::graphic::XGraphic> GetImage(const OUString& rCommandURL);
+
+ virtual bool HasURL( const OUString& aURL ) = 0;
+ virtual bool HasSettings() = 0;
+ virtual SvxEntries* GetEntries() = 0;
+ virtual void SetEntries( std::unique_ptr<SvxEntries> ) = 0;
+ virtual void Reset() = 0;
+ virtual bool Apply() = 0;
+};
+
+class MenuSaveInData : public SaveInData
+{
+private:
+
+ OUString m_aMenuResourceURL;
+ OUString m_aDescriptorContainer;
+
+ css::uno::Reference
+ < css::container::XIndexAccess > m_xMenuSettings;
+
+ std::unique_ptr<SvxConfigEntry> pRootEntry;
+
+
+ static MenuSaveInData* pDefaultData; ///< static holder of the default menu data
+
+ static void SetDefaultData( MenuSaveInData* pData ) {pDefaultData = pData;}
+ static MenuSaveInData* GetDefaultData() { return pDefaultData; }
+
+ void Apply(
+ css::uno::Reference< css::container::XIndexContainer > const & rNewMenuBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory );
+
+public:
+
+ MenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~MenuSaveInData() override;
+
+ /// methods inherited from SaveInData
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> ) override;
+ bool HasURL( const OUString& ) override { return false; }
+ bool HasSettings() override { return m_xMenuSettings.is(); }
+ void Reset() override;
+ bool Apply() override;
+};
+
+class ContextMenuSaveInData : public SaveInData
+{
+private:
+ std::unique_ptr< SvxConfigEntry > m_pRootEntry;
+ css::uno::Reference< css::container::XNameAccess > m_xPersistentWindowState;
+ OUString GetUIName( const OUString& rResourceURL );
+
+public:
+ ContextMenuSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xCfgMgr,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >& xParentCfgMgr,
+ const OUString& aModuleId, bool bIsDocConfig );
+ virtual ~ContextMenuSaveInData() override;
+
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> pNewEntries ) override;
+ bool HasSettings() override;
+ bool HasURL( const OUString& rURL ) override;
+ void Reset() override;
+ bool Apply() override;
+
+ void ResetContextMenu( const SvxConfigEntry* pEntry );
+};
+
+class SvxConfigEntry
+{
+private:
+
+ /// common properties
+ sal_uInt16 nId;
+ OUString aLabel;
+ OUString aCommand;
+
+ bool bPopUp;
+ bool bStrEdited;
+ bool bIsUserDefined;
+ bool bIsMain;
+ bool bIsParentData;
+ bool bIsModified;
+
+ /// toolbar specific properties
+ bool bIsVisible;
+ sal_Int32 nStyle;
+
+ css::uno::Reference<
+ css::graphic::XGraphic > xBackupGraphic;
+
+ std::unique_ptr<SvxEntries> mpEntries;
+
+public:
+
+ SvxConfigEntry( const OUString& rDisplayName,
+ const OUString& rCommandURL,
+ bool bPopup,
+ bool bParentData );
+
+ SvxConfigEntry()
+ :
+ nId( 0 ),
+ bPopUp( false ),
+ bStrEdited( false ),
+ bIsUserDefined( false ),
+ bIsMain( false ),
+ bIsParentData( false ),
+ bIsModified( false ),
+ bIsVisible( true ),
+ nStyle( 0 )
+ {}
+
+ ~SvxConfigEntry();
+
+ const OUString& GetCommand() const { return aCommand; }
+
+ const OUString& GetName() const { return aLabel; }
+ void SetName( const OUString& rStr ) { aLabel = rStr; bStrEdited = true; }
+ bool HasChangedName() const { return bStrEdited; }
+
+ bool IsPopup() const { return bPopUp; }
+
+ void SetUserDefined( bool bOn = true ) { bIsUserDefined = bOn; }
+ bool IsUserDefined() const { return bIsUserDefined; }
+
+ bool IsBinding() const { return !bPopUp; }
+ bool IsSeparator() const { return nId == 0; }
+
+ SvxEntries* GetEntries() const { return mpEntries.get(); }
+ void SetEntries( std::unique_ptr<SvxEntries> entries ) { mpEntries = std::move(entries); }
+
+ void SetMain() { bIsMain = true; }
+ bool IsMain() const { return bIsMain; }
+
+ void SetParentData( bool bValue = true ) { bIsParentData = bValue; }
+ bool IsParentData() const { return bIsParentData; }
+
+ void SetModified( bool bValue = true ) { bIsModified = bValue; }
+ bool IsModified() const { return bIsModified; }
+
+ bool IsMovable() const;
+ bool IsDeletable() const;
+ bool IsRenamable() const;
+
+ void SetVisible( bool b ) { bIsVisible = b; }
+ bool IsVisible() const { return bIsVisible; }
+
+ void SetBackupGraphic( css::uno::Reference< css::graphic::XGraphic > const & graphic )
+ { xBackupGraphic = graphic; }
+
+ const css::uno::Reference< css::graphic::XGraphic >& GetBackupGraphic() const
+ { return xBackupGraphic; }
+
+ sal_Int32 GetStyle() const { return nStyle; }
+ void SetStyle( sal_Int32 style ) { nStyle = style; }
+};
+
+class SvxMenuEntriesListBox
+{
+protected:
+ std::unique_ptr<weld::TreeView> m_xControl;
+ ScopedVclPtr<VirtualDevice> m_xDropDown;
+ SvxConfigPage* m_pPage;
+
+public:
+ SvxMenuEntriesListBox(std::unique_ptr<weld::TreeView> xControl, SvxConfigPage* pPage);
+ virtual ~SvxMenuEntriesListBox();
+
+ VirtualDevice& get_dropdown_image() const { return *m_xDropDown; }
+
+ int get_selected_index() const { return m_xControl->get_selected_index(); }
+ OUString get_id(int nPos) const { return m_xControl->get_id(nPos); }
+ void remove(int nPos) { m_xControl->remove(nPos); }
+ int n_children() const { return m_xControl->n_children(); }
+ void set_text(int row, const OUString& rText, int col) { m_xControl->set_text(row, rText, col); }
+ OUString get_text(int row) { return m_xControl->get_text(row); }
+ void set_image(int row, const css::uno::Reference<css::graphic::XGraphic>& rImage, int col) { m_xControl->set_image(row, rImage, col); }
+ void set_dropdown(int row, int col) { m_xControl->set_image(row, *m_xDropDown, col); }
+ void set_id(int row, const OUString& rId) { m_xControl->set_id(row, rId); }
+ void clear() { m_xControl->clear(); } //need frees ?
+ void set_toggle(int row, TriState eState, int col) { m_xControl->set_toggle(row, eState, col); }
+ void scroll_to_row(int pos) { m_xControl->scroll_to_row(pos); }
+ void select(int pos) { m_xControl->select(pos); }
+
+ weld::TreeView& get_widget() { return *m_xControl; }
+
+ void insert(int pos, const OUString& rId)
+ {
+ m_xControl->insert(nullptr, pos, nullptr, &rId,
+ nullptr, nullptr, nullptr, false, nullptr);
+ }
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+ void CreateDropDown();
+};
+
+class SvxConfigPageFunctionDropTarget : public DropTargetHelper
+{
+private:
+ SvxConfigPage& m_rPage;
+ weld::TreeView& m_rTreeView;
+
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+public:
+ SvxConfigPageFunctionDropTarget(SvxConfigPage&rPage, weld::TreeView& rTreeView);
+};
+
+class SvxConfigPage : public SfxTabPage
+{
+private:
+
+ Timer m_aUpdateDataTimer;
+ bool bInitialised;
+ SaveInData* pCurrentSaveInData;
+
+ DECL_LINK(SearchUpdateHdl, weld::Entry&, void);
+
+protected:
+
+ /// the ResourceURL to select when opening the dialog
+ OUString m_aURLToSelect;
+
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ OUString m_aModuleId;
+
+ // Left side of the dialog where command categories and the available
+ // commands in them are displayed as a searchable list
+ std::unique_ptr<CommandCategoryListBox> m_xCommandCategoryListBox;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xFunctions;
+
+ std::unique_ptr<weld::Label> m_xCategoryLabel;
+ std::unique_ptr<weld::Label> m_xDescriptionFieldLb;
+ std::unique_ptr<weld::TextView> m_xDescriptionField;
+ std::unique_ptr<weld::Label> m_xLeftFunctionLabel;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::Label> m_xSearchLabel;
+
+
+ // Right side of the dialog where the contents of the selected
+ // menu or toolbar are displayed
+ std::unique_ptr<weld::Label> m_xCustomizeLabel;
+ std::unique_ptr<weld::ComboBox> m_xTopLevelListBox;
+ // Used to add and remove toolbars/menus
+ std::unique_ptr<weld::MenuButton> m_xGearBtn;
+ std::unique_ptr<SvxMenuEntriesListBox> m_xContentsListBox;
+ std::unique_ptr<SvxConfigPageFunctionDropTarget> m_xDropTargetHelper;
+
+ std::unique_ptr<weld::Button> m_xMoveUpButton;
+ std::unique_ptr<weld::Button> m_xMoveDownButton;
+
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ std::unique_ptr<weld::MenuButton> m_xInsertBtn;
+ std::unique_ptr<weld::MenuButton> m_xModifyBtn;
+ // Used to reset the selected toolbar/menu/context menu
+ std::unique_ptr<weld::Button> m_xResetBtn;
+
+ // Middle buttons
+ std::unique_ptr<weld::Button> m_xAddCommandButton;
+ std::unique_ptr<weld::Button> m_xRemoveCommandButton;
+
+ OUString m_sAppName;
+ OUString m_sFileName;
+
+ SvxConfigPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet&);
+
+ DECL_LINK(MoveHdl, weld::Button&, void);
+ DECL_LINK(SelectFunctionHdl, weld::TreeView&, void);
+ DECL_LINK(FunctionDoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(SelectSaveInLocation, weld::ComboBox&, void);
+ DECL_LINK(SelectElementHdl, weld::ComboBox&, void);
+ DECL_LINK(ImplUpdateDataHdl, Timer*, void);
+ DECL_LINK(FocusOut_Impl, weld::Widget&, void);
+
+ virtual SaveInData* CreateSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig ) = 0;
+
+ virtual void Init() = 0;
+ virtual void UpdateButtonStates() = 0;
+ virtual short QueryReset() = 0;
+
+ virtual void SelectElement() = 0;
+
+ int AppendEntry(SvxConfigEntry* pNewEntryData,
+ int nTarget);
+
+ void AddSubMenusToUI( const OUString& rBaseTitle,
+ SvxConfigEntry const * pParentData );
+
+ void InsertEntryIntoUI(SvxConfigEntry* pNewEntryData,
+ weld::TreeView& rTreeView, int nPos,
+ int nStartCol);
+ void InsertEntryIntoUI(SvxConfigEntry* pNewEntryData,
+ weld::TreeView& rTreeView, weld::TreeIter& rIter,
+ int nStartCol);
+
+ void InsertEntryIntoNotebookbarTabUI(const OUString& sClassId, const OUString& sUIItemId,
+ const OUString& sUIItemCommand,
+ weld::TreeView& rTreeView, weld::TreeIter& rIter,
+ int nStartCol);
+
+ SvxEntries* FindParentForChild( SvxEntries* pParentEntries,
+ SvxConfigEntry* pChildData );
+
+ void ReloadTopLevelListBox( SvxConfigEntry const * pSelection = nullptr );
+
+public:
+
+ virtual ~SvxConfigPage() override;
+
+ static bool CanConfig( const OUString& rModuleId );
+
+ SaveInData* GetSaveInData() { return pCurrentSaveInData; }
+ const OUString& GetAppName() const { return m_sAppName; }
+ const OUString& GetFileName() const { return m_sFileName; }
+
+ int AddFunction(int nTarget,
+ bool bAllowDuplicates);
+
+ virtual void MoveEntry( bool bMoveUp );
+
+ bool MoveEntryData(int SourceEntry, int nTargetEntry);
+
+ bool FillItemSet( SfxItemSet* ) override;
+ void Reset( const SfxItemSet* ) override;
+
+ virtual void DeleteSelectedContent() = 0;
+ virtual void DeleteSelectedTopLevel() = 0;
+
+ virtual void ListModified() {}
+
+ SvxConfigEntry* GetTopLevelSelection()
+ {
+ return reinterpret_cast<SvxConfigEntry*>(m_xTopLevelListBox->get_active_id().toInt64());
+ }
+
+ /** identifies the module in the given frame. If the frame is <NULL/>, a default
+ frame will be determined beforehand.
+
+ If the given frame is <NULL/>, a default frame will be used: The method the active
+ frame of the desktop, then the current frame. If both are <NULL/>,
+ the SfxViewFrame::Current's XFrame is used. If this is <NULL/>, too, an empty string is returned.
+
+ If the given frame is not <NULL/>, or a default frame could be successfully determined, then
+ the ModuleManager is asked for the module ID of the component in the frame.
+ */
+ static OUString
+ GetFrameWithDefaultAndIdentify( css::uno::Reference< css::frame::XFrame >& _inout_rxFrame );
+
+ OUString GetScriptURL() const;
+ OUString GetSelectedDisplayName() const;
+};
+
+class SvxMainMenuOrganizerDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<SvxEntries> mpEntries;
+ OUString m_sNewMenuEntryId;
+
+ std::unique_ptr<weld::Widget> m_xMenuBox;
+ std::unique_ptr<weld::Entry> m_xMenuNameEdit;
+ std::unique_ptr<weld::TreeView> m_xMenuListBox;
+ std::unique_ptr<weld::Button> m_xMoveUpButton;
+ std::unique_ptr<weld::Button> m_xMoveDownButton;
+
+ void UpdateButtonStates();
+
+ DECL_LINK(MoveHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+public:
+ SvxMainMenuOrganizerDialog(
+ weld::Window*, SvxEntries*,
+ SvxConfigEntry const *, bool bCreateMenu);
+ virtual ~SvxMainMenuOrganizerDialog() override;
+
+ std::unique_ptr<SvxEntries> ReleaseEntries() { return std::move(mpEntries);}
+ SvxConfigEntry* GetSelectedEntry();
+};
+
+class ToolbarSaveInData : public SaveInData
+{
+private:
+
+ std::unique_ptr<SvxConfigEntry> pRootEntry;
+ OUString m_aDescriptorContainer;
+
+ css::uno::Reference
+ < css::container::XNameAccess > m_xPersistentWindowState;
+
+ void LoadToolbar(
+ const css::uno::Reference< css::container::XIndexAccess >& xToolBarSettings,
+ SvxConfigEntry const * pParentData );
+
+ void ApplyToolbar(
+ css::uno::Reference< css::container::XIndexContainer > const & rNewToolbarBar,
+ css::uno::Reference< css::lang::XSingleComponentFactory >& rFactory,
+ SvxConfigEntry const *pToolbar );
+
+public:
+
+ ToolbarSaveInData(
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const css::uno::Reference< css::ui::XUIConfigurationManager >&,
+ const OUString& aModuleId,
+ bool docConfig );
+
+ virtual ~ToolbarSaveInData() override;
+
+ void CreateToolbar( SvxConfigEntry* pToolbar );
+ void RestoreToolbar( SvxConfigEntry* pToolbar );
+ void RemoveToolbar( SvxConfigEntry* pToolbar );
+ void ApplyToolbar( SvxConfigEntry* pToolbar );
+
+ OUString GetSystemUIName( const OUString& rResourceURL );
+
+ sal_Int32 GetSystemStyle( const OUString& rResourceURL );
+
+ void SetSystemStyle( const OUString& rResourceURL, sal_Int32 nStyle );
+
+ void SetSystemStyle(
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& rResourceURL, sal_Int32 nStyle );
+
+ SvxEntries* GetEntries() override;
+ void SetEntries( std::unique_ptr<SvxEntries> ) override;
+ bool HasSettings() override;
+ bool HasURL( const OUString& rURL ) override;
+ void Reset() override;
+ bool Apply() override;
+};
+
+class SvxNewToolbarDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Button> m_xBtnOK;
+public:
+ std::unique_ptr<weld::ComboBox> m_xSaveInListBox;
+
+ SvxNewToolbarDialog(weld::Window* pWindow, const OUString& rName);
+ virtual ~SvxNewToolbarDialog() override;
+
+ OUString GetName() const
+ {
+ return m_xEdtName->get_text();
+ }
+};
+
+class SvxIconSelectorDialog : public weld::GenericDialogController
+{
+private:
+ sal_Int32 m_nExpectedSize;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xImageManager;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xParentImageManager;
+
+ css::uno::Reference<
+ css::ui::XImageManager > m_xImportedImageManager;
+
+ css::uno::Reference<
+ css::graphic::XGraphicProvider > m_xGraphProvider;
+
+ std::vector<css::uno::Reference<css::graphic::XGraphic>> m_aGraphics;
+
+ std::unique_ptr<ValueSet> m_xTbSymbol;
+ std::unique_ptr<weld::CustomWeld> m_xTbSymbolWin;
+ std::unique_ptr<weld::Label> m_xFtNote;
+ std::unique_ptr<weld::Button> m_xBtnImport;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+
+ bool ReplaceGraphicItem( const OUString& aURL );
+
+ bool ImportGraphic( const OUString& aURL );
+
+ void ImportGraphics( const css::uno::Sequence< OUString >& aURLs );
+
+public:
+
+ SvxIconSelectorDialog(
+ weld::Window *pWindow,
+ const css::uno::Reference< css::ui::XImageManager >& rXImageManager,
+ const css::uno::Reference< css::ui::XImageManager >& rXParentImageManager);
+
+ virtual ~SvxIconSelectorDialog() override;
+
+ css::uno::Reference< css::graphic::XGraphic >
+ GetSelectedIcon();
+
+ DECL_LINK(SelectHdl, ValueSet*, void);
+ DECL_LINK(ImportHdl, weld::Button&, void);
+ DECL_LINK(DeleteHdl, weld::Button&, void);
+};
+
+//added for issue83555
+class SvxIconChangeDialog : public weld::MessageDialogController
+{
+private:
+ std::unique_ptr<weld::TextView> m_xLineEditDescription;
+public:
+ SvxIconChangeDialog(weld::Window *pWindow, const OUString& rMessage);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cfgutil.hxx b/cui/source/inc/cfgutil.hxx
new file mode 100644
index 000000000..944ab68e8
--- /dev/null
+++ b/cui/source/inc/cfgutil.hxx
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_CFGUTIL_HXX
+#define INCLUDED_CUI_SOURCE_INC_CFGUTIL_HXX
+
+#include <vector>
+#include <memory>
+#include <rtl/ustring.hxx>
+
+#include <com/sun/star/frame/DispatchInformation.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <vcl/weld.hxx>
+
+class Button;
+class SaveInData;
+class SfxMacroInfoItem;
+
+struct SfxStyleInfo_Impl
+{
+ OUString sFamily;
+ OUString sStyle;
+ OUString sCommand;
+ OUString sLabel;
+
+ SfxStyleInfo_Impl()
+ {}
+
+ SfxStyleInfo_Impl(const SfxStyleInfo_Impl& rCopy)
+ {
+ sFamily = rCopy.sFamily;
+ sStyle = rCopy.sStyle;
+ sCommand = rCopy.sCommand;
+ sLabel = rCopy.sLabel;
+ }
+};
+
+struct SfxStylesInfo_Impl
+{
+private:
+ OUString m_aModuleName;
+ css::uno::Reference< css::frame::XModel > m_xDoc;
+
+public:
+
+ SfxStylesInfo_Impl();
+ void init(const OUString& rModuleName, const css::uno::Reference< css::frame::XModel >& xModel);
+
+ static bool parseStyleCommand(SfxStyleInfo_Impl& aStyle);
+ void getLabel4Style(SfxStyleInfo_Impl& aStyle);
+
+ std::vector< SfxStyleInfo_Impl > getStyleFamilies() const;
+ std::vector< SfxStyleInfo_Impl > getStyles(const OUString& sFamily);
+
+ static OUString generateCommand(const OUString& sFamily, const OUString& sStyle);
+};
+
+enum class SfxCfgKind
+{
+ GROUP_FUNCTION = 1,
+ FUNCTION_SLOT = 2,
+ GROUP_SCRIPTCONTAINER = 3,
+ FUNCTION_SCRIPT = 4,
+ GROUP_STYLES = 5,
+ GROUP_ALLFUNCTIONS = 6
+};
+
+struct SfxGroupInfo_Impl
+{
+ SfxCfgKind nKind;
+ sal_uInt16 nUniqueID;
+ void* pObject;
+ OUString sCommand;
+ OUString sLabel;
+ OUString sHelpText;
+ OUString sTooltip;
+
+ SfxGroupInfo_Impl( SfxCfgKind n, sal_uInt16 nr, void* pObj = nullptr ) :
+ nKind( n ), nUniqueID( nr ), pObject( pObj ) {}
+};
+
+typedef std::vector<std::unique_ptr<SfxGroupInfo_Impl> > SfxGroupInfoArr_Impl;
+
+class CuiConfigFunctionListBox
+{
+ friend class CuiConfigGroupListBox;
+ SfxGroupInfoArr_Impl aArr;
+
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+public:
+ CuiConfigFunctionListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xTreeView->connect_changed(rLink); }
+ void connect_row_activated(const Link<weld::TreeView&, bool>& rLink) { m_xTreeView->connect_row_activated(rLink); }
+ void freeze() { m_xTreeView->freeze(); }
+ void thaw() { m_xTreeView->thaw(); }
+ void append(const OUString& rId, const OUString& rStr, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, nullptr, false, nullptr);
+ }
+ std::unique_ptr<weld::TreeIter> tree_append(const OUString& rId, const OUString& rStr, const weld::TreeIter* pParent = nullptr)
+ {
+ std::unique_ptr<weld::TreeIter> xIter(m_xTreeView->make_iterator());
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, nullptr, false, xIter.get());
+ return xIter;
+ }
+ void append(const OUString& rId, const OUString& rStr, const OUString& rImage, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, &rImage, false, nullptr);
+ }
+ void append(const OUString& rId, const OUString& rStr, const css::uno::Reference<css::graphic::XGraphic>& rImage, const weld::TreeIter* pParent = nullptr)
+ {
+ m_xTreeView->insert(pParent, -1, &rStr, &rId, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xTreeView->set_image(*m_xScratchIter, rImage, -1);
+ }
+ void remove(int nPos) { m_xTreeView->remove(nPos); }
+ void scroll_to_row(int pos) { m_xTreeView->scroll_to_row(pos); }
+ void remove(const weld::TreeIter& rIter) { m_xTreeView->remove(rIter); }
+ void expand_row(const weld::TreeIter& rIter) { m_xTreeView->expand_row(rIter); }
+ int n_children() const { return m_xTreeView->n_children(); }
+ std::unique_ptr<weld::TreeIter> make_iterator(const weld::TreeIter* pOrig = nullptr) const { return m_xTreeView->make_iterator(pOrig); }
+ bool get_iter_first(weld::TreeIter& rIter) const { return m_xTreeView->get_iter_first(rIter); }
+ // set iter to point to next node, depth first, then sibling
+ bool iter_next(weld::TreeIter& rIter) const { return m_xTreeView->iter_next(rIter); }
+ bool iter_next_sibling(weld::TreeIter& rIter) const { return m_xTreeView->iter_next_sibling(rIter); }
+ bool iter_has_child(const weld::TreeIter& rIter) const { return m_xTreeView->iter_has_child(rIter); }
+ OUString get_text(const weld::TreeIter& rIter) const { return m_xTreeView->get_text(rIter); }
+ OUString get_text(int nPos) const { return m_xTreeView->get_text(nPos); }
+ OUString get_id(const weld::TreeIter& rIter) const { return m_xTreeView->get_id(rIter); }
+ OUString get_id(int nPos) const { return m_xTreeView->get_id(nPos); }
+ bool get_selected(weld::TreeIter* pIter) const { return m_xTreeView->get_selected(pIter); }
+ OUString get_selected_text() const
+ {
+ if (!m_xTreeView->get_selected(m_xScratchIter.get()))
+ return OUString();
+ return m_xTreeView->get_text(*m_xScratchIter);
+ }
+ OUString get_selected_id() const
+ {
+ if (!m_xTreeView->get_selected(m_xScratchIter.get()))
+ return OUString();
+ return m_xTreeView->get_id(*m_xScratchIter);
+ }
+ int get_selected_index() const { return m_xTreeView->get_selected_index(); }
+ void select(const weld::TreeIter& rIter) { m_xTreeView->select(rIter); }
+ void select(int pos) { m_xTreeView->select(pos); }
+ void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
+ Size get_size_request() const { return m_xTreeView->get_size_request(); }
+ weld::TreeView& get_widget() { return *m_xTreeView; }
+
+ ~CuiConfigFunctionListBox();
+
+ void ClearAll();
+ OUString GetSelectedScriptURI() const;
+ OUString GetHelpText( bool bConsiderParent = true );
+ OUString GetCurCommand() const;
+ OUString GetCurLabel() const;
+
+ DECL_LINK(QueryTooltip, const weld::TreeIter& rIter, OUString);
+};
+
+struct SvxConfigGroupBoxResource_Impl;
+class CuiConfigGroupListBox
+{
+ std::unique_ptr<SvxConfigGroupBoxResource_Impl> xImp;
+ CuiConfigFunctionListBox* m_pFunctionListBox;
+ SfxGroupInfoArr_Impl aArr;
+ OUString m_sModuleLongName;
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+ css::uno::Reference< css::frame::XFrame > m_xFrame;
+ css::uno::Reference< css::container::XNameAccess > m_xGlobalCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xModuleCategoryInfo;
+ css::uno::Reference< css::container::XNameAccess > m_xUICmdDescription;
+ SfxStylesInfo_Impl* m_pStylesInfo;
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+
+ static OUString GetImage(
+ const css::uno::Reference< css::script::browse::XBrowseNode >& node,
+ css::uno::Reference< css::uno::XComponentContext > const & xCtx,
+ bool bIsRootNode);
+
+ static css::uno::Reference< css::uno::XInterface > getDocumentModel(
+ css::uno::Reference< css::uno::XComponentContext > const & xCtx,
+ OUString const & docName);
+
+ void InitModule();
+ void FillScriptList(const css::uno::Reference< css::script::browse::XBrowseNode >& xRootNode,
+ const weld::TreeIter* pParentEntry, bool bCheapChildrenOnDemand);
+ void FillFunctionsList(const css::uno::Sequence< css::frame::DispatchInformation >& xCommands);
+ OUString MapCommand2UIName(const OUString& sCommand);
+
+ DECL_LINK(ExpandingHdl, const weld::TreeIter&, bool);
+
+public:
+ CuiConfigGroupListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void connect_changed(const Link<weld::TreeView&, void>& rLink) { m_xTreeView->connect_changed(rLink); }
+ void set_size_request(int nWidth, int nHeight) { m_xTreeView->set_size_request(nWidth, nHeight); }
+ weld::TreeView& get_widget() { return *m_xTreeView; }
+ ~CuiConfigGroupListBox();
+ void ClearAll();
+
+ void Init(const css::uno::Reference< css::uno::XComponentContext >& xContext,
+ const css::uno::Reference< css::frame::XFrame >& xFrame,
+ const OUString& sModuleLongName,
+ bool bEventMode);
+ void SetFunctionListBox( CuiConfigFunctionListBox *pBox )
+ { m_pFunctionListBox = pBox; }
+ void GroupSelected();
+ void SelectMacro(const SfxMacroInfoItem*);
+ void SelectMacro(const OUString&, const OUString&);
+ void SetStylesInfo(SfxStylesInfo_Impl* pStyles);
+};
+
+class SvxScriptSelectorDialog : public weld::GenericDialogController
+{
+ OUString m_sDefaultDesc;
+ SfxStylesInfo_Impl m_aStylesInfo;
+
+ std::unique_ptr<weld::Label> m_xDialogDescription;
+ std::unique_ptr<CuiConfigGroupListBox> m_xCategories;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xCommands;
+ std::unique_ptr<weld::Label> m_xLibraryFT;
+ std::unique_ptr<weld::Label> m_xCategoryFT;
+ std::unique_ptr<weld::Label> m_xMacronameFT;
+ std::unique_ptr<weld::Label> m_xCommandsFT;
+ std::unique_ptr<weld::Button> m_xOKButton;
+ std::unique_ptr<weld::Button> m_xCancelButton;
+ std::unique_ptr<weld::TextView> m_xDescriptionText;
+
+ DECL_LINK(ClickHdl, weld::Button&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(FunctionDoubleClickHdl, weld::TreeView&, bool);
+
+ void UpdateUI();
+
+public:
+ SvxScriptSelectorDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& xFrame);
+ virtual ~SvxScriptSelectorDialog() override;
+
+ OUString GetScriptURL() const;
+ void SetRunLabel();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/chardlg.hxx b/cui/source/inc/chardlg.hxx
new file mode 100644
index 000000000..e81284cc6
--- /dev/null
+++ b/cui/source/inc/chardlg.hxx
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_CHARDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_CHARDLG_HXX
+
+#include <svtools/ctrlbox.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/fntctrl.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/langbox.hxx>
+#include <vcl/weld.hxx>
+#include <memory>
+
+// forward ---------------------------------------------------------------
+
+class SvxFontListItem;
+class FontList;
+
+class SvxCharBasePage : public SfxTabPage
+{
+protected:
+ SvxFontPrevWindow m_aPreviewWin;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWin;
+
+ bool m_bPreviewBackgroundToCharacter;
+
+ SvxCharBasePage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rAttrSet);
+
+ void SetPrevFontWidthScale( const SfxItemSet& rSet );
+ void SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc );
+
+ inline SvxFont& GetPreviewFont();
+ inline SvxFont& GetPreviewCJKFont();
+ inline SvxFont& GetPreviewCTLFont();
+
+public:
+ virtual ~SvxCharBasePage() override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+};
+
+// class SvxCharNamePage -------------------------------------------------
+
+struct SvxCharNamePage_Impl;
+
+class SvxCharNamePage : public SvxCharBasePage
+{
+private:
+ static const sal_uInt16 pNameRanges[];
+
+ std::unique_ptr<SvxCharNamePage_Impl> m_pImpl;
+
+ std::unique_ptr<weld::Widget> m_xWestFrame;
+ std::unique_ptr<weld::Label> m_xWestFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xWestFontNameLB;
+ std::unique_ptr<weld::Label> m_xWestFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xWestFontStyleLB;
+ std::unique_ptr<weld::Label> m_xWestFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xWestFontSizeLB;
+ std::unique_ptr<weld::Label> m_xWestFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xWestFontLanguageLB;
+ std::unique_ptr<weld::Label> m_xWestFontTypeFT;
+ std::unique_ptr<weld::Button> m_xWestFontFeaturesButton;
+
+ std::unique_ptr<weld::Widget> m_xEastFrame;
+ std::unique_ptr<weld::Label> m_xEastFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xEastFontNameLB;
+ std::unique_ptr<weld::Label> m_xEastFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xEastFontStyleLB;
+ std::unique_ptr<weld::Label> m_xEastFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xEastFontSizeLB;
+ std::unique_ptr<weld::Label> m_xEastFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xEastFontLanguageLB;
+ std::unique_ptr<weld::Label> m_xEastFontTypeFT;
+ std::unique_ptr<weld::Button> m_xEastFontFeaturesButton;
+
+ std::unique_ptr<weld::Widget> m_xCTLFrame;
+ std::unique_ptr<weld::Label> m_xCTLFontNameFT;
+ std::unique_ptr<weld::ComboBox> m_xCTLFontNameLB;
+ std::unique_ptr<weld::Label> m_xCTLFontStyleFT;
+ std::unique_ptr<FontStyleBox> m_xCTLFontStyleLB;
+ std::unique_ptr<weld::Label> m_xCTLFontSizeFT;
+ std::unique_ptr<FontSizeBox> m_xCTLFontSizeLB;
+ std::unique_ptr<weld::Label> m_xCTLFontLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xCTLFontLanguageLB;
+ std::unique_ptr<weld::Label> m_xCTLFontTypeFT;
+ std::unique_ptr<weld::Button> m_xCTLFontFeaturesButton;
+
+ void Initialize();
+ const FontList* GetFontList() const;
+ void UpdatePreview_Impl();
+ void FillStyleBox_Impl(const weld::Widget& rBox);
+ void FillSizeBox_Impl(const weld::Widget& rBox);
+
+ enum LanguageGroup
+ {
+ /** Language for western text.
+ */
+ Western = 0,
+
+ /** Language for asian text.
+ */
+ Asian,
+
+ /** Language for ctl text.
+ */
+ Ctl
+ };
+
+ void Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp );
+ bool FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp );
+
+ DECL_LINK(UpdateHdl_Impl, Timer *, void );
+ DECL_LINK(FontModifyComboBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(FontFeatureButtonClicked, weld::Button&, void);
+
+ void FontModifyHdl_Impl(const weld::Widget&);
+
+public:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxCharNamePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharNamePage() override;
+
+ static const sal_uInt16* GetRanges() { return pNameRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void SetFontList( const SvxFontListItem& rItem );
+ void EnableRelativeMode();
+ void EnableSearchMode();
+
+ void DisableControls( sal_uInt16 nDisable );
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharEffectsPage ----------------------------------------------
+
+class SvxCharEffectsPage : public SvxCharBasePage
+{
+private:
+ static const sal_uInt16 pEffectsRanges[];
+ bool m_bOrigFontColor;
+ bool m_bNewFontColor;
+ bool m_bEnableNoneFontColor;
+ Color m_aOrigFontColor;
+ sal_uInt16 m_nHtmlMode;
+ bool m_bUnderlineColorDisabled;
+
+ weld::TriStateEnabled m_aOutlineState;
+ weld::TriStateEnabled m_aShadowState;
+ weld::TriStateEnabled m_aHiddenState;
+ weld::TriStateEnabled m_aIndividualWordsState;
+
+ std::unique_ptr<weld::Label> m_xFontColorFT;
+ std::unique_ptr<ColorListBox> m_xFontColorLB;
+ std::unique_ptr<weld::Label> m_xFontTransparencyFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xFontTransparencyMtr;
+ std::unique_ptr<weld::Label> m_xEffectsFT;
+ std::unique_ptr<weld::ComboBox> m_xEffectsLB;
+ std::unique_ptr<weld::Label> m_xReliefFT;
+ std::unique_ptr<weld::ComboBox> m_xReliefLB;
+ std::unique_ptr<weld::CheckButton> m_xOutlineBtn;
+ std::unique_ptr<weld::CheckButton> m_xShadowBtn;
+ std::unique_ptr<weld::CheckButton> m_xHiddenBtn;
+ std::unique_ptr<weld::ComboBox> m_xOverlineLB;
+ std::unique_ptr<weld::Label> m_xOverlineColorFT;
+ std::unique_ptr<ColorListBox> m_xOverlineColorLB;
+ std::unique_ptr<weld::ComboBox> m_xStrikeoutLB;
+ std::unique_ptr<weld::ComboBox> m_xUnderlineLB;
+ std::unique_ptr<weld::Label> m_xUnderlineColorFT;
+ std::unique_ptr<ColorListBox> m_xUnderlineColorLB;
+ std::unique_ptr<weld::CheckButton> m_xIndividualWordsBtn;
+ std::unique_ptr<weld::Label> m_xEmphasisFT;
+ std::unique_ptr<weld::ComboBox> m_xEmphasisLB;
+ std::unique_ptr<weld::Label> m_xPositionFT;
+ std::unique_ptr<weld::ComboBox> m_xPositionLB;
+ std::unique_ptr<weld::Label> m_xA11yWarningFT;
+
+ void Initialize();
+ void UpdatePreview_Impl();
+ void SetCaseMap_Impl( SvxCaseMap eCaseMap );
+ void ResetColor_Impl( const SfxItemSet& rSet );
+ bool FillItemSetColor_Impl( SfxItemSet& rSet );
+ Color GetPreviewFontColor(const Color& rColor) const;
+ void EnableNoneFontColor();
+
+ void SelectHdl_Impl(const weld::ComboBox*);
+ DECL_LINK(SelectListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(OutlineBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(ShadowBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(HiddenBtnClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(CbClickHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ColorBoxSelectHdl_Impl, ColorListBox&, void);
+ DECL_LINK(ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void);
+
+public:
+ SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharEffectsPage() override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ static const sal_uInt16* GetRanges() { return pEffectsRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void DisableControls( sal_uInt16 nDisable );
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharPositionPage ---------------------------------------------
+class SvxCharPositionPage : public SvxCharBasePage
+{
+ static const sal_uInt16 pPositionRanges[];
+
+private:
+ short m_nSuperEsc;
+ short m_nSubEsc;
+
+ sal_uInt16 m_nScaleWidthItemSetVal;
+ sal_uInt16 m_nScaleWidthInitialVal;
+
+ sal_uInt8 m_nSuperProp;
+ sal_uInt8 m_nSubProp;
+
+ std::unique_ptr<weld::RadioButton> m_xHighPosBtn;
+ std::unique_ptr<weld::RadioButton> m_xNormalPosBtn;
+ std::unique_ptr<weld::RadioButton> m_xLowPosBtn;
+ std::unique_ptr<weld::Label> m_xHighLowFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHighLowMF;
+ std::unique_ptr<weld::CheckButton> m_xHighLowRB;
+ std::unique_ptr<weld::Label> m_xFontSizeFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xFontSizeMF;
+
+ std::unique_ptr<weld::Widget> m_xRotationContainer;
+
+ std::unique_ptr<weld::Label> m_xScalingFT;
+ std::unique_ptr<weld::Label> m_xScalingAndRotationFT;
+ std::unique_ptr<weld::RadioButton> m_x0degRB;
+ std::unique_ptr<weld::RadioButton> m_x90degRB;
+ std::unique_ptr<weld::RadioButton> m_x270degRB;
+ std::unique_ptr<weld::CheckButton> m_xFitToLineCB;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xScaleWidthMF;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xKerningMF;
+ std::unique_ptr<weld::CheckButton> m_xPairKerningBtn;
+
+ void Initialize();
+ void UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc );
+ void SetEscapement_Impl( SvxEscapement nEsc );
+
+ DECL_LINK(PositionHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(RotationHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(AutoPositionHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(FitToLineHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(KerningModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ValueChangedHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void);
+ void FontModifyHdl_Impl();
+
+public:
+ SvxCharPositionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharPositionPage() override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ static const sal_uInt16* GetRanges() { return pPositionRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+ virtual void FillUserData() override;
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxCharTwoLinesPage ---------------------------------------------
+
+class SvxCharTwoLinesPage : public SvxCharBasePage
+{
+private:
+ static const sal_uInt16 pTwoLinesRanges[];
+ sal_uInt16 m_nStartBracketPosition;
+ sal_uInt16 m_nEndBracketPosition;
+
+ std::unique_ptr<weld::CheckButton> m_xTwoLinesBtn;
+ std::unique_ptr<weld::Widget> m_xEnclosingFrame;
+ std::unique_ptr<weld::TreeView> m_xStartBracketLB;
+ std::unique_ptr<weld::TreeView> m_xEndBracketLB;
+
+ void UpdatePreview_Impl();
+ void Initialize();
+ void SelectCharacter(weld::TreeView* pBox);
+ void SetBracket(sal_Unicode cBracket, bool bStart);
+
+ DECL_LINK(TwoLinesHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(CharacterMapHdl_Impl, weld::TreeView&, void);
+
+public:
+ SvxCharTwoLinesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxCharTwoLinesPage() override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ static const sal_uInt16* GetRanges() { return pTwoLinesRanges; }
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CHARDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/colorpicker.hxx b/cui/source/inc/colorpicker.hxx
new file mode 100644
index 000000000..7c05ebabc
--- /dev/null
+++ b/cui/source/inc/colorpicker.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_CUI_SOURCE_INC_COLORPICKER_HXX
+#define INCLUDED_CUI_SOURCE_INC_COLORPICKER_HXX
+
+#include <sal/config.h>
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <rtl/ustring.hxx>
+
+namespace com::sun::star::uno {
+ class XComponentContext;
+ class XInterface;
+}
+
+namespace cui {
+
+OUString ColorPicker_getImplementationName();
+
+css::uno::Reference<css::uno::XInterface> ColorPicker_createInstance(
+ css::uno::Reference<css::uno::XComponentContext> const &);
+
+/// @throws css::uno::RuntimeException
+css::uno::Sequence<OUString> ColorPicker_getSupportedServiceNames();
+}
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/connect.hxx b/cui/source/inc/connect.hxx
new file mode 100644
index 000000000..1b4185147
--- /dev/null
+++ b/cui/source/inc/connect.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_CONNECT_HXX
+#define INCLUDED_CUI_SOURCE_INC_CONNECT_HXX
+
+#include <svx/connctrl.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/basedlgs.hxx>
+
+class SdrView;
+
+/// Dialog for changing connectors.
+class SvxConnectionPage : public SfxTabPage
+{
+private:
+ static const sal_uInt16 pRanges[];
+ const SfxItemSet& rOutAttrs;
+ SfxItemSet aAttrSet;
+ const SdrView* pView;
+ MapUnit eUnit;
+
+ SvxXConnectionPreview m_aCtlPreview;
+ std::unique_ptr<weld::ComboBox> m_xLbType;
+ std::unique_ptr<weld::Label> m_xFtLine1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine1;
+ std::unique_ptr<weld::Label> m_xFtLine2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine2;
+ std::unique_ptr<weld::Label> m_xFtLine3;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLine3;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHorz1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldVert1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHorz2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldVert2;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillTypeLB();
+
+ DECL_LINK(ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void);
+
+public:
+
+ SvxConnectionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxConnectionPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/* Derived from SfxSingleTabDialogController, in order to be informed about
+ virtual methods by the control. */
+class SvxConnectionDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxConnectionDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const SdrView* pView);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CONNECT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuifmsearch.hxx b/cui/source/inc/cuifmsearch.hxx
new file mode 100644
index 000000000..42183e627
--- /dev/null
+++ b/cui/source/inc/cuifmsearch.hxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_CUIFMSEARCH_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIFMSEARCH_HXX
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+
+#include <svx/fmsearch.hxx>
+#include <vcl/weld.hxx>
+#include <tools/link.hxx>
+#include <rtl/ustring.hxx>
+
+namespace svxform {
+ class FmSearchConfigItem;
+}
+
+struct FmSearchProgress;
+
+class FmSearchEngine;
+
+/// Dialog for searching in Forms/Tables
+class FmSearchDialog final : public weld::GenericDialogController
+{
+ friend class FmSearchEngine;
+
+ OUString m_sSearch;
+ OUString m_sCancel;
+
+ Link<FmFoundRecordInformation&,void> m_lnkFoundHandler; ///< Handler for "found"
+ Link<FmFoundRecordInformation&,void> m_lnkCanceledNotFoundHdl; ///< Handler for Positioning the Cursors
+
+ Link<FmSearchContext&,sal_uInt32> m_lnkContextSupplier; ///< for search in contexts
+
+ /// memorize the currently selected field for every context
+ std::vector<OUString> m_arrContextFields;
+
+ std::unique_ptr<FmSearchEngine> m_pSearchEngine;
+
+ // see EnableSearchUI
+ std::unique_ptr<::svxform::FmSearchConfigItem> m_pConfig;
+
+ // my all Controls
+ std::unique_ptr<weld::RadioButton> m_prbSearchForText;
+ std::unique_ptr<weld::RadioButton> m_prbSearchForNull;
+ std::unique_ptr<weld::RadioButton> m_prbSearchForNotNull;
+ std::unique_ptr<weld::ComboBox> m_pcmbSearchText;
+ std::unique_ptr<weld::Label> m_pftForm;
+ std::unique_ptr<weld::ComboBox> m_plbForm;
+ std::unique_ptr<weld::RadioButton> m_prbAllFields;
+ std::unique_ptr<weld::RadioButton> m_prbSingleField;
+ std::unique_ptr<weld::ComboBox> m_plbField;
+ std::unique_ptr<weld::Label> m_pftPosition;
+ std::unique_ptr<weld::ComboBox> m_plbPosition;
+ std::unique_ptr<weld::CheckButton> m_pcbUseFormat;
+ std::unique_ptr<weld::CheckButton> m_pcbCase;
+ std::unique_ptr<weld::CheckButton> m_pcbBackwards;
+ std::unique_ptr<weld::CheckButton> m_pcbStartOver;
+ std::unique_ptr<weld::CheckButton> m_pcbWildCard;
+ std::unique_ptr<weld::CheckButton> m_pcbRegular;
+ std::unique_ptr<weld::CheckButton> m_pcbApprox;
+ std::unique_ptr<weld::Button> m_ppbApproxSettings;
+ std::unique_ptr<weld::CheckButton> m_pHalfFullFormsCJK;
+ std::unique_ptr<weld::CheckButton> m_pSoundsLikeCJK;
+ std::unique_ptr<weld::Button> m_pSoundsLikeCJKSettings;
+ std::unique_ptr<weld::Label> m_pftRecord;
+ std::unique_ptr<weld::Label> m_pftHint;
+ std::unique_ptr<weld::Button> m_pbSearchAgain;
+ std::unique_ptr<weld::Button> m_pbClose;
+
+public:
+ /** This can search in different sets of fields. There is a number of contexts; their names are in strContexts (separated
+ by ';'), the user can choose one of them.
+ When the user chooses a context, lnkContextSupplier is called, it gets a pointer on a FmSearchContext-structure,
+ that has to be filled.
+ The following counts for the search :
+ a) in case of formatted search the iterator itself is used (like in the first constructor)
+ b) in case of formatted search NOT the FormatKey at the fields of the iterator is used, but the respective TextComponent
+ is asked (that's why the original iterator is used; by its move the controls behind the TextComponent-interface are
+ updated hopefully)
+ c) in case of not-formatted search a clone of the iterator is used (because the TextComponent-interfaces don't need to
+ be asked)
+ (of course needed : the string number i in strUsedFields of a context must correspond with the interface number i in the
+ arrFields of the context)
+ */
+ FmSearchDialog(weld::Window* pParent, const OUString& strInitialText, const std::vector< OUString >& _rContexts, sal_Int16 nInitialContext,
+ const Link<FmSearchContext&,sal_uInt32>& lnkContextSupplier);
+
+ virtual short run() override;
+
+ virtual ~FmSearchDialog() override;
+
+ /** The found-handler gets in the 'found'-case a pointer on a FmFoundRecordInformation-structure
+ (which is only valid in the handler; so if one needs to memorize the data, don't copy the pointer but
+ the structure).
+ This handler MUST be set.
+ Furthermore, it should be considered, that during the handler the search-dialog is still modal.
+ */
+ void SetFoundHandler(const Link<FmFoundRecordInformation&,void>& lnk) { m_lnkFoundHandler = lnk; }
+ /**
+ If the search has been cancelled or has been finished without success, the current data set is always displayed in the
+ search dialog. This handler exists to make this synchronous with the possible display of the caller (it does not
+ necessarily need to be set).
+ The pointer that is passed to the handler points to a FmFoundRecordInformation-structure, for which aPosition and
+ possibly (in a search with contexts) nContext are valid.
+ */
+ void SetCanceledNotFoundHdl(const Link<FmFoundRecordInformation&,void>& lnk) { m_lnkCanceledNotFoundHdl = lnk; }
+
+ inline void SetActiveField(const OUString& strField);
+
+private:
+ void Init(const OUString& strVisibleFields, const OUString& strInitialText);
+ // only to be used out of the constructors
+
+ void OnFound(const css::uno::Any& aCursorPos, sal_Int16 nFieldPos);
+
+ void EnableSearchUI(bool bEnable);
+
+ void EnableSearchForDependees(bool bEnable);
+
+ void InitContext(sal_Int16 nContext);
+
+ void LoadParams();
+ void SaveParams() const;
+
+ // Handler for the Controls
+ DECL_LINK( OnClickedFieldRadios, weld::Button&, void );
+ DECL_LINK( OnClickedSearchAgain, weld::Button&, void );
+ DECL_LINK( OnClickedSpecialSettings, weld::Button&, void );
+
+ DECL_LINK( OnSearchTextModified, weld::ComboBox&, void );
+
+ DECL_LINK( OnPositionSelected, weld::ComboBox&, void );
+ DECL_LINK( OnFieldSelected, weld::ComboBox&, void );
+
+ DECL_LINK( OnFocusGrabbed, weld::Widget&, void );
+ DECL_LINK( OnCheckBoxToggled, weld::ToggleButton&, void );
+
+ DECL_LINK( OnContextSelection, weld::ComboBox&, void );
+
+ DECL_LINK( OnSearchProgress, const FmSearchProgress*, void );
+
+ void initCommon( const css::uno::Reference< css::sdbc::XResultSet >& _rxCursor );
+};
+
+inline void FmSearchDialog::SetActiveField(const OUString& strField)
+{
+ int nInitialField = m_plbField->find_text(strField);
+ if (nInitialField == -1)
+ nInitialField = 0;
+ m_plbField->set_active(nInitialField);
+ OnFieldSelected(*m_plbField);
+}
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUIFMSEARCH_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuigaldlg.hxx b/cui/source/inc/cuigaldlg.hxx
new file mode 100644
index 000000000..0ad85b654
--- /dev/null
+++ b/cui/source/inc/cuigaldlg.hxx
@@ -0,0 +1,277 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_CUIGALDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIGALDLG_HXX
+
+#include <sal/config.h>
+
+#include <salhelper/thread.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/idle.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/galctrl.hxx>
+#include <svx/galmisc.hxx>
+#include <com/sun/star/media/XPlayer.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+#include <vector>
+
+class GalleryTheme;
+class SearchProgress;
+class TakeProgress;
+class TPGalleryThemeProperties;
+
+typedef std::vector< sal_uLong > TokenList_impl;
+
+struct FilterEntry
+{
+ OUString aFilterName;
+};
+
+class SearchThread: public salhelper::Thread
+{
+private:
+
+ SearchProgress* mpProgress;
+ TPGalleryThemeProperties* mpBrowser;
+ INetURLObject maStartURL;
+
+ void ImplSearch( const INetURLObject& rStartURL,
+ const std::vector< OUString >& rFormats,
+ bool bRecursive );
+
+ virtual ~SearchThread() override;
+ virtual void execute() override;
+
+public:
+
+ SearchThread(SearchProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ const INetURLObject& rStartURL);
+};
+
+class SearchProgress : public weld::GenericDialogController
+{
+private:
+ INetURLObject startUrl_;
+ TPGalleryThemeProperties* m_pTabPage;
+ rtl::Reference< SearchThread > m_aSearchThread;
+ std::unique_ptr<weld::Label> m_xFtSearchDir;
+ std::unique_ptr<weld::Label> m_xFtSearchType;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+
+public:
+ SearchProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage, const INetURLObject& rStartURL);
+ void LaunchThread();
+ virtual ~SearchProgress() override;
+
+ DECL_LINK( CleanUpHdl, void*, void );
+
+ void SetFileType( const OUString& rType ) { m_xFtSearchType->set_label(rType); }
+ void SetDirectory( const INetURLObject& rURL ) { m_xFtSearchDir->set_label(GetReducedString(rURL, 30)); }
+};
+
+class TakeThread: public salhelper::Thread
+{
+private:
+
+ TakeProgress* mpProgress;
+ TPGalleryThemeProperties* mpBrowser;
+ TokenList_impl& mrTakenList;
+
+ virtual ~TakeThread() override;
+ virtual void execute() override;
+
+public:
+
+ TakeThread(
+ TakeProgress* pProgress,
+ TPGalleryThemeProperties* pBrowser,
+ TokenList_impl& rTakenList
+ );
+};
+
+class TakeProgress : public weld::GenericDialogController
+{
+private:
+ weld::Window* m_pParent;
+ TPGalleryThemeProperties* m_pTabPage;
+ rtl::Reference< TakeThread > maTakeThread;
+ TokenList_impl maTakenList;
+ std::unique_ptr<weld::Label> m_xFtTakeFile;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+
+public:
+
+ TakeProgress(weld::Window* pParent, TPGalleryThemeProperties* pTabPage);
+ void LaunchThread();
+ virtual ~TakeProgress() override;
+
+ DECL_LINK( CleanUpHdl, void*, void );
+
+ void SetFile( const INetURLObject& rURL ) { m_xFtTakeFile->set_label(GetReducedString(rURL, 30)); }
+};
+
+class ActualizeProgress : public weld::GenericDialogController
+{
+private:
+ Idle* pIdle;
+ GalleryTheme* pTheme;
+ GalleryProgress aStatusProgress;
+ std::unique_ptr<weld::Label> m_xFtActualizeFile;
+ std::unique_ptr<weld::Button> m_xBtnCancel;
+
+ DECL_LINK(ClickCancelBtn, weld::Button&, void);
+ DECL_LINK(TimeoutHdl, Timer*, void);
+ DECL_LINK(ActualizeHdl, const INetURLObject&, void);
+
+public:
+ ActualizeProgress(weld::Widget* pWindow, GalleryTheme* pThm);
+ virtual ~ActualizeProgress() override;
+
+ virtual short run() override;
+};
+
+class TitleDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdit;
+public:
+ TitleDialog(weld::Widget* pParent, const OUString& rOldText);
+ virtual ~TitleDialog() override;
+ OUString GetTitle() const { return m_xEdit->get_text(); }
+};
+
+class GalleryIdDialog : public weld::GenericDialogController
+{
+private:
+ GalleryTheme* m_pThm;
+ std::unique_ptr<weld::Button> m_xBtnOk;
+ std::unique_ptr<weld::ComboBox> m_xLbResName;
+
+ DECL_LINK(ClickOkHdl, weld::Button&, void);
+public:
+ GalleryIdDialog(weld::Widget* pParent, GalleryTheme* pThm);
+ virtual ~GalleryIdDialog() override;
+ sal_uInt32 GetId() const { return m_xLbResName->get_active(); }
+};
+
+class GalleryThemeProperties : public SfxTabDialogController
+{
+ ExchangeData* pData;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ GalleryThemeProperties(weld::Widget* pParent, ExchangeData* pData, SfxItemSet const * pItemSet);
+};
+
+class TPGalleryThemeGeneral : public SfxTabPage
+{
+private:
+ ExchangeData* pData;
+
+ std::unique_ptr<weld::Image> m_xFiMSImage;
+ std::unique_ptr<weld::Entry> m_xEdtMSName;
+ std::unique_ptr<weld::Label> m_xFtMSShowType;
+ std::unique_ptr<weld::Label> m_xFtMSShowPath;
+ std::unique_ptr<weld::Label> m_xFtMSShowContent;
+ std::unique_ptr<weld::Label> m_xFtMSShowChangeDate;
+
+ virtual void Reset( const SfxItemSet* ) override {}
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+public:
+ TPGalleryThemeGeneral(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ void SetXChgData( ExchangeData* pData );
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+};
+
+class TPGalleryThemeProperties : public SfxTabPage
+{
+ friend class SearchThread;
+ friend class TakeProgress;
+ friend class TakeThread;
+
+ ExchangeData* pData;
+ std::vector<OUString> aFoundList;
+ std::vector< std::unique_ptr<FilterEntry> >
+ aFilterEntryList;
+ Timer aPreviewTimer;
+ OUString aLastFilterName;
+ OUString aPreviewString;
+ INetURLObject aURL;
+ bool bEntriesFound;
+ bool bInputAllowed;
+ bool bTakeAll;
+ bool bSearchRecursive;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::media::XPlayer > xMediaPlayer;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ DialogGalleryPreview m_aWndPreview;
+ std::unique_ptr<weld::ComboBox> m_xCbbFileType;
+ std::unique_ptr<weld::TreeView> m_xLbxFound;
+ std::unique_ptr<weld::Button> m_xBtnSearch;
+ std::unique_ptr<weld::Button> m_xBtnTake;
+ std::unique_ptr<weld::Button> m_xBtnTakeAll;
+ std::unique_ptr<weld::CheckButton> m_xCbxPreview;
+ std::unique_ptr<weld::CustomWeld> m_xWndPreview;
+
+ virtual void Reset( const SfxItemSet* /*rSet*/ ) override {}
+ virtual bool FillItemSet( SfxItemSet* /*rSet*/ ) override { return true; }
+ static OUString addExtension( const OUString&, const OUString& );
+ void FillFilterList();
+
+ void SearchFiles();
+ void TakeFiles();
+ void DoPreview();
+ void EndSearchProgressHdl(sal_Int32 nResult);
+
+ DECL_LINK(ClickPreviewHdl, weld::ToggleButton&, void);
+ DECL_LINK(ClickSearchHdl, weld::Button&, void);
+ DECL_LINK(ClickTakeHdl, weld::Button&, void);
+ DECL_LINK(ClickTakeAllHdl, weld::Button&, void);
+ DECL_LINK(SelectFoundHdl, weld::TreeView&, void);
+ DECL_LINK(SelectFileTypeHdl, weld::ComboBox&, void);
+ DECL_LINK(DClickFoundHdl, weld::TreeView&, bool);
+ DECL_LINK(PreviewTimerHdl, Timer*, void);
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+public:
+ TPGalleryThemeProperties(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~TPGalleryThemeProperties() override;
+
+ void SetXChgData( ExchangeData* pData );
+ const ExchangeData* GetXChgData() const { return pData; }
+
+ void StartSearchFiles( const OUString& _rFolderURL, short _nDlgResult );
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUIGALDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuigrfflt.hxx b/cui/source/inc/cuigrfflt.hxx
new file mode 100644
index 000000000..b52804673
--- /dev/null
+++ b/cui/source/inc/cuigrfflt.hxx
@@ -0,0 +1,183 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_CUIGRFFLT_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIGRFFLT_HXX
+
+#include <vcl/timer.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/rectenum.hxx>
+
+class CuiGraphicPreviewWindow : public weld::CustomWidgetController
+{
+private:
+ const Graphic* mpOrigGraphic;
+ Size maOrigGraphicSizePixel;
+ Size maOutputSizePixel;
+ Link<LinkParamNone*,void> maModifyHdl;
+ Graphic maScaledOrig;
+ Graphic maPreview;
+ double mfScaleX;
+ double mfScaleY;
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+
+ void ScaleImageToFit();
+
+public:
+ CuiGraphicPreviewWindow();
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+ void init(const Graphic* pOrigGraphic, const Link<LinkParamNone*,void>& rLink)
+ {
+ mpOrigGraphic = pOrigGraphic;
+ maModifyHdl = rLink;
+ maOrigGraphicSizePixel = GetDrawingArea()->get_ref_device().LogicToPixel(mpOrigGraphic->GetPrefSize(),
+ mpOrigGraphic->GetPrefMapMode());
+ ScaleImageToFit();
+ }
+
+ void SetPreview(const Graphic& rGraphic);
+ const Graphic& GetScaledOriginal() const { return maScaledOrig; }
+ double GetScaleX() const { return mfScaleX; }
+ double GetScaleY() const { return mfScaleY; }
+ const Size& GetGraphicSizePixel() const { return maOrigGraphicSizePixel; }
+};
+
+class GraphicFilterDialog : public weld::GenericDialogController
+{
+private:
+
+ Timer maTimer;
+ Link<LinkParamNone*,void> maModifyHdl;
+ bool bIsBitmap;
+
+ DECL_LINK( ImplPreviewTimeoutHdl, Timer *, void );
+ DECL_LINK( ImplModifyHdl, LinkParamNone*, void);
+
+ CuiGraphicPreviewWindow maPreview;
+ std::unique_ptr<weld::CustomWeld> mxPreview;
+
+protected:
+ const Link<LinkParamNone*,void>& GetModifyHdl() const { return maModifyHdl; }
+ const Size& GetGraphicSizePixel() const { return maPreview.GetGraphicSizePixel(); }
+
+public:
+
+ GraphicFilterDialog(weld::Window* pParent, const OUString& rUIXMLDescription, const OString& rID, const Graphic& rGraphic);
+ virtual Graphic GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY) = 0;
+};
+
+class GraphicFilterSmooth : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxMtrRadius;
+ DECL_LINK(EditModifyHdl, weld::SpinButton&, void);
+
+public:
+
+ GraphicFilterSmooth(weld::Window* pParent, const Graphic& rGraphic, double nRadius);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class GraphicFilterMosaic : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrWidth;
+ std::unique_ptr<weld::MetricSpinButton> mxMtrHeight;
+ std::unique_ptr<weld::CheckButton> mxCbxEdges;
+ DECL_LINK(CheckBoxModifyHdl, weld::ToggleButton&, void);
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+public:
+
+ GraphicFilterMosaic(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nTileWidth, sal_uInt16 nTileHeight, bool bEnhanceEdges);
+
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+ bool IsEnhanceEdges() const { return mxCbxEdges->get_active(); }
+};
+
+class GraphicFilterSolarize : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrThreshold;
+ std::unique_ptr<weld::CheckButton> mxCbxInvert;
+ DECL_LINK(CheckBoxModifyHdl, weld::ToggleButton&, void);
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+
+public:
+ GraphicFilterSolarize(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt8 nGreyThreshold, bool bInvert);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+ bool IsInvert() const { return mxCbxInvert->get_active(); }
+};
+
+class GraphicFilterSepia : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::MetricSpinButton> mxMtrSepia;
+ DECL_LINK(EditModifyHdl, weld::MetricSpinButton&, void);
+public:
+ GraphicFilterSepia(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nSepiaPercent);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class GraphicFilterPoster : public GraphicFilterDialog
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxNumPoster;
+ DECL_LINK(EditModifyHdl, weld::SpinButton&, void);
+public:
+ GraphicFilterPoster(weld::Window* pParent, const Graphic& rGraphic,
+ sal_uInt16 nPosterColorCount);
+ virtual Graphic GetFilteredGraphic( const Graphic& rGraphic, double fScaleX, double fScaleY ) override;
+};
+
+class EmbossControl : public SvxRectCtl
+{
+private:
+ Link<LinkParamNone*, void> maModifyHdl;
+ virtual bool MouseButtonDown( const MouseEvent& rEvt ) override;
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+public:
+ EmbossControl()
+ : SvxRectCtl(nullptr)
+ {
+ }
+
+ void SetModifyHdl( const Link<LinkParamNone*,void>& rHdl ) { maModifyHdl = rHdl; }
+};
+
+class GraphicFilterEmboss : public GraphicFilterDialog
+{
+private:
+ EmbossControl maCtlLight;
+ std::unique_ptr<weld::CustomWeld> mxCtlLight;
+public:
+ GraphicFilterEmboss(weld::Window* pParent, const Graphic& rGraphic,
+ RectPoint eLightSource);
+ virtual ~GraphicFilterEmboss() override;
+
+ virtual Graphic GetFilteredGraphic(const Graphic& rGraphic, double fScaleX, double fScaleY) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuihyperdlg.hxx b/cui/source/inc/cuihyperdlg.hxx
new file mode 100644
index 000000000..702cf6396
--- /dev/null
+++ b/cui/source/inc/cuihyperdlg.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 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_CUIHYPERDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIHYPERDLG_HXX
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <svx/hlnkitem.hxx>
+#include <sfx2/childwin.hxx>
+#include <sfx2/ctrlitem.hxx>
+#include <sfx2/bindings.hxx>
+
+#include "iconcdlg.hxx"
+
+/*************************************************************************
+|*
+|* Hyperlink-Dialog
+|*
+\************************************************************************/
+
+class SvxHpLinkDlg;
+class SvxHlinkCtrl : public SfxControllerItem
+{
+private:
+ SvxHpLinkDlg* pParent;
+
+ SfxStatusForwarder aRdOnlyForwarder;
+
+public:
+ SvxHlinkCtrl( sal_uInt16 nId, SfxBindings & rBindings, SvxHpLinkDlg* pDlg);
+ virtual void dispose() override;
+
+ virtual void StateChanged( sal_uInt16 nSID, SfxItemState eState,
+ const SfxPoolItem* pState ) override;
+};
+
+
+/*************************************************************************
+|*
+|* Hyperlink-Dialog
+|*
+\************************************************************************/
+
+class SvxHpLinkDlg : public SfxModelessDialogController
+{
+private:
+ friend class IconChoicePage;
+
+ std::vector< std::unique_ptr<IconChoicePageData> > maPageList;
+
+ OString msCurrentPageId;
+
+ const SfxItemSet* pSet;
+ std::unique_ptr<SfxItemSet> pOutSet;
+ SfxItemSet* pExampleSet;
+ std::unique_ptr<sal_uInt16[]> pRanges;
+
+ SvxHlinkCtrl maCtrl; ///< Controller
+ std::unique_ptr<SfxItemSet> mpItemSet;
+
+ bool mbGrabFocus : 1;
+ bool mbIsHTMLDoc : 1;
+
+ std::unique_ptr<weld::Notebook> m_xIconCtrl;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::Button> m_xApplyBtn;
+ std::unique_ptr<weld::Button> m_xCancelBtn;
+ std::unique_ptr<weld::Button> m_xHelpBtn;
+ std::unique_ptr<weld::Button> m_xResetBtn;
+
+ DECL_LINK( ChosePageHdl_Impl, const OString&, void );
+
+ IconChoicePageData* GetPageData ( const OString& rId );
+
+ void SwitchPage( const OString& rId );
+
+ DECL_LINK( ResetHdl, weld::Button&, void) ;
+ DECL_LINK (ClickOkHdl_Impl, weld::Button&, void );
+ DECL_LINK (ClickApplyHdl_Impl, weld::Button&, void );
+
+ IconChoicePage* GetTabPage( const OString& rPageId )
+ { return GetPageData(rPageId)->xPage.get(); }
+
+ void ActivatePageImpl ();
+ void DeActivatePageImpl ();
+ void ResetPageImpl ();
+
+ virtual void Close() override;
+ void Apply();
+
+public:
+ SvxHpLinkDlg(SfxBindings* pBindings, SfxChildWindow* pChild, weld::Window* pParent);
+ virtual ~SvxHpLinkDlg () override;
+
+ // interface
+ void AddTabPage(const OString &rId, CreatePage pCreateFunc /* != NULL */);
+
+ void SetCurPageId( const OString& rId ) { msCurrentPageId = rId; SwitchPage(rId ); }
+ OString GetCurPageId() const { return msCurrentPageId; }
+ void ShowPage( const OString& rId );
+
+ /// gives via map converted local slots if applicable
+ const sal_uInt16* GetInputRanges( const SfxItemPool& );
+ void SetInputSet( const SfxItemSet* pInSet );
+
+ void Start();
+ bool QueryClose();
+
+ void PageCreated(const OString& rId, IconChoicePage& rPage);
+
+ void SetPage( SvxHyperlinkItem const * pItem );
+ void SetReadOnlyMode( bool bReadOnly );
+ bool IsHTMLDoc() const { return mbIsHTMLDoc; }
+
+ SfxDispatcher* GetDispatcher() const { return GetBindings().GetDispatcher(); }
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUIHYPERDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuiimapwnd.hxx b/cui/source/inc/cuiimapwnd.hxx
new file mode 100644
index 000000000..b8fcf1053
--- /dev/null
+++ b/cui/source/inc/cuiimapwnd.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_CUI_SOURCE_INC_CUIIMAPWND_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIIMAPWND_HXX
+
+#include <vcl/weld.hxx>
+#include <sfx2/frame.hxx>
+
+class URLDlg : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Entry> m_xEdtURL;
+ std::unique_ptr<weld::ComboBox> m_xCbbTargets;
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Entry> m_xEdtAlternativeText;
+ std::unique_ptr<weld::TextView> m_xEdtDescription;
+
+public:
+
+ URLDlg(weld::Widget* pWindow,
+ const OUString& rURL, const OUString& rAlternativeText, const OUString& rDescription,
+ const OUString& rTarget, const OUString& rName,
+ TargetList& rTargetList);
+ virtual ~URLDlg() override;
+
+ OUString GetURL() const { return m_xEdtURL->get_text(); }
+ OUString GetAltText() const { return m_xEdtAlternativeText->get_text(); }
+ OUString GetDesc() const { return m_xEdtDescription->get_text(); }
+ OUString GetTarget() const { return m_xCbbTargets->get_active_text(); }
+ OUString GetName() const { return m_xEdtName->get_text(); }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuioptgenrl.hxx b/cui/source/inc/cuioptgenrl.hxx
new file mode 100644
index 000000000..fa2310d17
--- /dev/null
+++ b/cui/source/inc/cuioptgenrl.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_CUI_SOURCE_INC_CUIOPTGENRL_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUIOPTGENRL_HXX
+
+// include ---------------------------------------------------------------
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+
+#include <vector>
+
+// class SvxGeneralTabPage -----------------------------------------------
+
+class SvxGeneralTabPage : public SfxTabPage
+{
+private:
+ // the "Use data for document properties" checkbox
+ std::unique_ptr<weld::CheckButton> m_xUseDataCB;
+ std::unique_ptr<weld::Widget> m_xCryptoFrame;
+ std::unique_ptr<weld::ComboBox> m_xSigningKeyLB;
+ std::unique_ptr<weld::ComboBox> m_xEncryptionKeyLB;
+ std::unique_ptr<weld::CheckButton> m_xEncryptToSelfCB;
+ // rows
+ struct Row;
+ std::vector<std::shared_ptr<Row> > vRows;
+ // fields
+ struct Field;
+ std::vector<std::shared_ptr<Field> > vFields;
+ // "name" fields
+ unsigned nNameRow;
+ unsigned nShortNameField;
+
+ DECL_LINK( ModifyHdl_Impl, weld::Entry&, void );
+
+ bool GetData_Impl();
+ void SetData_Impl();
+
+ void InitControls ();
+ void InitCryptography();
+ void SetLinks ();
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxGeneralTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxGeneralTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUIOPTGENRL_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuisrchdlg.hxx b/cui/source/inc/cuisrchdlg.hxx
new file mode 100644
index 000000000..fc16a4a10
--- /dev/null
+++ b/cui/source/inc/cuisrchdlg.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_CUI_SOURCE_INC_CUISRCHDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUISRCHDLG_HXX
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/basedlgs.hxx>
+
+class SvxJSearchOptionsPage;
+
+class SvxJSearchOptionsDialog : public SfxSingleTabDialogController
+{
+ SvxJSearchOptionsPage* m_pPage;
+
+ SvxJSearchOptionsDialog( const SvxJSearchOptionsDialog & ) = delete;
+ SvxJSearchOptionsDialog & operator == ( const SvxJSearchOptionsDialog & ) = delete;
+
+public:
+ SvxJSearchOptionsDialog(weld::Window *pParent,
+ const SfxItemSet& rOptionsSet, TransliterationFlags nInitialFlags);
+ virtual ~SvxJSearchOptionsDialog() override;
+
+ TransliterationFlags GetTransliterationFlags() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitabarea.hxx b/cui/source/inc/cuitabarea.hxx
new file mode 100644
index 000000000..849b009c3
--- /dev/null
+++ b/cui/source/inc/cuitabarea.hxx
@@ -0,0 +1,739 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_CUITABAREA_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUITABAREA_HXX
+
+#include <svtools/valueset.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/xflasit.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/hexcolorcontrol.hxx>
+#include <svx/SvxColorValueSet.hxx>
+#include <svx/SvxPresetListBox.hxx>
+#include <svx/PaletteManager.hxx>
+#include <svx/svdview.hxx>
+
+#define NO_BUTTON_SELECTED -1
+
+class ColorListBox;
+class SdrModel;
+class SvxBitmapCtl;
+
+/************************************************************************/
+class ButtonBox
+{
+ private:
+ sal_Int32 mnCurrentButton;
+ std::vector<weld::ToggleButton*> maButtonList;
+ std::map<weld::ToggleButton*, sal_Int32 > maButtonToPos;
+ void SelectButtonImpl( sal_Int32 nPos )
+ {
+ if(mnCurrentButton != NO_BUTTON_SELECTED)
+ {
+ maButtonList[mnCurrentButton]->set_active(false);
+ }
+ mnCurrentButton = nPos;
+ maButtonList[mnCurrentButton]->set_active(true);
+ };
+ public:
+ ButtonBox()
+ {
+ mnCurrentButton = NO_BUTTON_SELECTED;
+ };
+ void AddButton(weld::ToggleButton* pButton)
+ {
+ maButtonList.push_back(pButton);
+ maButtonToPos.insert( std::make_pair(pButton, maButtonList.size() - 1) );
+ }
+ sal_Int32 GetCurrentButtonPos() const { return mnCurrentButton; }
+ sal_Int32 GetButtonPos(weld::ToggleButton* pButton)
+ {
+ std::map<weld::ToggleButton*, sal_Int32>::const_iterator aBtnPos = maButtonToPos.find(pButton);
+ if(aBtnPos != maButtonToPos.end())
+ return aBtnPos->second;
+ else
+ return -1;
+ }
+ void SelectButton(weld::ToggleButton* pButton)
+ {
+ sal_Int32 nPos = GetButtonPos(pButton);
+ if(nPos != -1)
+ SelectButtonImpl(nPos);
+ }
+};
+
+enum class PageType
+{
+ Area,
+ Gradient,
+ Hatch,
+ Bitmap,
+ Shadow,
+ Transparence,
+};
+
+class SvxAreaTabDialog final : public SfxTabDialogController
+{
+ SdrModel* mpDrawModel;
+
+ XColorListRef mpColorList;
+ XColorListRef mpNewColorList;
+ XGradientListRef mpGradientList;
+ XGradientListRef mpNewGradientList;
+ XHatchListRef mpHatchingList;
+ XHatchListRef mpNewHatchingList;
+ XBitmapListRef mpBitmapList;
+ XBitmapListRef mpNewBitmapList;
+ XPatternListRef mpPatternList;
+ XPatternListRef mpNewPatternList;
+
+ ChangeType mnColorListState;
+ ChangeType mnBitmapListState;
+ ChangeType mnPatternListState;
+ ChangeType mnGradientListState;
+ ChangeType mnHatchingListState;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+ virtual short Ok() override;
+ DECL_LINK(CancelHdlImpl, weld::Button&, void);
+ void SavePalettes();
+
+public:
+ SvxAreaTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, SdrModel* pModel, bool bShadow);
+
+ void SetNewColorList( XColorListRef const & pColorList )
+ { mpNewColorList = pColorList; }
+ const XColorListRef& GetNewColorList() const { return mpNewColorList; }
+};
+
+/************************************************************************/
+
+class SvxTransparenceTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pTransparenceRanges[];
+
+ const SfxItemSet& rOutAttrs;
+
+ PageType nPageType;
+ sal_uInt16 nDlgType;
+
+ bool bBitmap;
+
+ XFillAttrSetItem aXFillAttr;
+ SfxItemSet& rXFSet;
+
+ SvxXRectPreview m_aCtlBitmapPreview;
+ SvxXRectPreview m_aCtlXRectPreview;
+
+ // main selection
+ std::unique_ptr<weld::RadioButton> m_xRbtTransOff;
+ std::unique_ptr<weld::RadioButton> m_xRbtTransLinear;
+ std::unique_ptr<weld::RadioButton> m_xRbtTransGradient;
+
+ /// linear transparency
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+
+ // gradient transparency
+ std::unique_ptr<weld::Widget> m_xGridGradient;
+ std::unique_ptr<weld::ComboBox> m_xLbTrgrGradientType;
+ std::unique_ptr<weld::Label> m_xFtTrgrCenterX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrCenterX;
+ std::unique_ptr<weld::Label> m_xFtTrgrCenterY;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrCenterY;
+ std::unique_ptr<weld::Label> m_xFtTrgrAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrBorder;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrStartValue;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTrgrEndValue;
+ std::unique_ptr<weld::Widget> m_xCtlBitmapBorder;
+ std::unique_ptr<weld::Widget> m_xCtlXRectBorder;
+
+ // preview
+ std::unique_ptr<weld::CustomWeld> m_xCtlBitmapPreview;
+ std::unique_ptr<weld::CustomWeld> m_xCtlXRectPreview;
+
+ DECL_LINK(ClickTransOffHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ClickTransLinearHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ClickTransGradientHdl_Impl, weld::ToggleButton&, void );
+ DECL_LINK(ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedTrgrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedTrgrListBoxHdl_Impl, weld::ComboBox&, void);
+ void ModifiedTrgrHdl_Impl(const weld::ComboBox*);
+
+ void ActivateLinear(bool bActivate);
+ void ActivateGradient(bool bActivate);
+ void SetControlState_Impl(css::awt::GradientStyle eXGS);
+
+ bool InitPreview ( const SfxItemSet& rSet );
+ void InvalidatePreview (bool bEnable = true );
+
+public:
+ SvxTransparenceTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTransparenceTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet*);
+ static const sal_uInt16* GetRanges() { return pTransparenceRanges; }
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+ virtual void ChangesApplied() override;
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet* pSet) override;
+
+ void SetPageType(PageType nInType) { nPageType = nInType; }
+ void SetDlgType(sal_uInt16 nInType) { nDlgType = nInType; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/************************************************************************/
+
+class SvxAreaTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pAreaRanges[];
+private:
+ std::unique_ptr<SfxTabPage> m_xFillTabPage;
+ ButtonBox maBox;
+
+ XColorListRef m_pColorList;
+ XGradientListRef m_pGradientList;
+ XHatchListRef m_pHatchingList;
+ XBitmapListRef m_pBitmapList;
+ XPatternListRef m_pPatternList;
+
+ // Placeholders for pointer-based entries; these will be inited
+ // to point to these so that the page is usable without that
+ // SvxAreaTabDialog has to call the setter methods (e.g. SetColorChgd).
+ // Without that the pages used in SvxAreaTabDialog are not usable
+ ChangeType maFixed_ChangeType;
+
+ ChangeType* m_pnColorListState;
+ ChangeType* m_pnBitmapListState;
+ ChangeType* m_pnPatternListState;
+ ChangeType* m_pnGradientListState;
+ ChangeType* m_pnHatchingListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ bool m_bBtnClicked = false;
+
+protected:
+ std::unique_ptr<weld::Container> m_xFillTab;
+ std::unique_ptr<weld::ToggleButton> m_xBtnNone;
+ std::unique_ptr<weld::ToggleButton> m_xBtnColor;
+ std::unique_ptr<weld::ToggleButton> m_xBtnGradient;
+ std::unique_ptr<weld::ToggleButton> m_xBtnHatch;
+ std::unique_ptr<weld::ToggleButton> m_xBtnBitmap;
+ std::unique_ptr<weld::ToggleButton> m_xBtnPattern;
+
+ void SetOptimalSize(weld::DialogController* pController);
+
+ void SelectFillType( weld::ToggleButton& rButton, const SfxItemSet* _pSet = nullptr );
+ SfxTabPage* GetFillTabPage() { return m_xFillTabPage.get(); }
+
+ bool IsBtnClicked() const { return m_bBtnClicked; }
+
+private:
+ DECL_LINK(SelectFillTypeHdl_Impl, weld::ToggleButton&, void);
+
+ template< typename TabPage >
+ bool FillItemSet_Impl( SfxItemSet* );
+ template< typename TabPage >
+ void Reset_Impl( const SfxItemSet* );
+ template< typename TabPage >
+ DeactivateRC DeactivatePage_Impl( SfxItemSet* pSet );
+
+public:
+ SvxAreaTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxAreaTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pAreaRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetGradientList( XGradientListRef const & pGrdLst)
+ { m_pGradientList = pGrdLst; }
+ void SetHatchingList( XHatchListRef const & pHtchLst)
+ { m_pHatchingList = pHtchLst; }
+ void SetBitmapList( XBitmapListRef const & pBmpLst) { m_pBitmapList = pBmpLst; }
+ void SetPatternList( XPatternListRef const &pPtrnLst ) { m_pPatternList = pPtrnLst; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+ void CreatePage(sal_Int32 nId, SfxTabPage* pTab);
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ void SetGrdChgd( ChangeType* pIn ) { m_pnGradientListState = pIn; }
+ void SetHtchChgd( ChangeType* pIn ) { m_pnHatchingListState = pIn; }
+ void SetBmpChgd( ChangeType* pIn ) { m_pnBitmapListState = pIn; }
+ void SetPtrnChgd( ChangeType* pIn ) { m_pnPatternListState = pIn; }
+};
+
+
+class SvxShadowTabPage : public SvxTabPage
+{
+ static const sal_uInt16 pShadowRanges[];
+
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ ChangeType* m_pnColorListState;
+ PageType m_nPageType;
+ sal_uInt16 m_nDlgType;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+ MapUnit m_ePoolUnit;
+
+ SvxRectCtl m_aCtlPosition;
+ SvxXShadowPreview m_aCtlXRectPreview;
+ std::unique_ptr<weld::CheckButton> m_xTsbShowShadow;
+ std::unique_ptr<weld::Widget> m_xGridShadow;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<ColorListBox> m_xLbShadowColor;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlXRectPreview;
+
+ DECL_LINK(ClickShadowHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ModifyShadowHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(SelectShadowHdl_Impl, ColorListBox&, void);
+
+public:
+ SvxShadowTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxShadowTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pShadowRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetPageType( PageType nInType ) { m_nPageType = nInType; }
+ void SetDlgType( sal_uInt16 nInType ) { m_nDlgType = nInType; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/************************************************************************/
+
+class SvxGradientTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XGradientListRef m_pGradientList;
+
+ ChangeType* m_pnGradientListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<weld::ComboBox> m_xLbGradientType;
+ std::unique_ptr<weld::Label> m_xFtCenter;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrCenterX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrCenterY;
+ std::unique_ptr<weld::Label> m_xFtAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Scale> m_xSliderAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrBorder;
+ std::unique_ptr<weld::Scale> m_xSliderBorder;
+ std::unique_ptr<ColorListBox> m_xLbColorFrom;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrColorFrom;
+ std::unique_ptr<ColorListBox> m_xLbColorTo;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrColorTo;
+ std::unique_ptr<SvxPresetListBox> m_xGradientLB;
+ std::unique_ptr<weld::SpinButton> m_xMtrIncrement;
+ std::unique_ptr<weld::CheckButton> m_xCbIncrement;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+ std::unique_ptr<weld::CustomWeld> m_xGradientLBWin;
+
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ChangeGradientHdl, ValueSet*, void );
+ void ChangeGradientHdl_Impl();
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ModifiedEditHdl_Impl, weld::SpinButton&, void );
+ DECL_LINK( ModifiedMetricHdl_Impl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifiedColorListBoxHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ModifiedListBoxHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ChangeAutoStepHdl_Impl, weld::ToggleButton&, void );
+ DECL_LINK( ModifiedSliderHdl_Impl, weld::Scale&, void );
+ void ModifiedHdl_Impl(void const *);
+
+ void SetControlState_Impl( css::awt::GradientStyle eXGS );
+ sal_Int32 SearchGradientList(const OUString& rGradientName);
+
+public:
+ SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxGradientTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetGradientList( XGradientListRef const & pGrdLst)
+ { m_pGradientList = pGrdLst; }
+ void SetGrdChgd( ChangeType* pIn ) { m_pnGradientListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxHatchTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XHatchListRef m_pHatchingList;
+
+ ChangeType* m_pnHatchingListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ MapUnit m_ePoolUnit;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Scale> m_xSliderAngle;
+ std::unique_ptr<weld::ComboBox> m_xLbLineType;
+ std::unique_ptr<ColorListBox> m_xLbLineColor;
+ std::unique_ptr<weld::CheckButton> m_xCbBackgroundColor;
+ std::unique_ptr<ColorListBox> m_xLbBackgroundColor;
+ std::unique_ptr<SvxPresetListBox> m_xHatchLB;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xHatchLBWin;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ DECL_LINK(ChangeHatchHdl, ValueSet*, void);
+ void ChangeHatchHdl_Impl();
+ DECL_LINK( ModifiedEditHdl_Impl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifiedListBoxHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ModifiedColorListBoxHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ToggleHatchBackgroundColor_Impl, weld::ToggleButton&, void );
+ DECL_LINK( ModifiedBackgroundHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ModifiedSliderHdl_Impl, weld::Scale&, void );
+ void ModifiedHdl_Impl(void const *);
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+
+ sal_Int32 SearchHatchList(const OUString& rHatchName);
+
+public:
+ SvxHatchTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxHatchTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetHatchingList( XHatchListRef const & pHtchLst)
+ { m_pHatchingList = pHtchLst; }
+
+ void SetHtchChgd( ChangeType* pIn ) { m_pnHatchingListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxBitmapTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pBitmapRanges[];
+private:
+
+ const SfxItemSet& m_rOutAttrs;
+
+ XBitmapListRef m_pBitmapList;
+ ChangeType* m_pnBitmapListState;
+
+ double m_fObjectWidth;
+ double m_fObjectHeight;
+ bool m_bLogicalSize;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+ const SdrView* mpView;
+ MapUnit mePoolUnit;
+ FieldUnit meFieldUnit;
+ Size rBitmapSize;
+ Size rFilledSize;
+ Size rZoomedSize;
+
+ SvxXRectPreview m_aCtlBitmapPreview;
+ std::unique_ptr<SvxPresetListBox> m_xBitmapLB;
+ std::unique_ptr<weld::ComboBox> m_xBitmapStyleLB;
+ std::unique_ptr<weld::Container> m_xSizeBox;
+ std::unique_ptr<weld::CheckButton> m_xTsbScale;
+ std::unique_ptr<weld::MetricSpinButton> m_xBitmapWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xBitmapHeight;
+ std::unique_ptr<weld::Container> m_xPositionBox;
+ std::unique_ptr<weld::ComboBox> m_xPositionLB;
+ std::unique_ptr<weld::Container> m_xPositionOffBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xPositionOffX;
+ std::unique_ptr<weld::MetricSpinButton> m_xPositionOffY;
+ std::unique_ptr<weld::Container> m_xTileOffBox;
+ std::unique_ptr<weld::ComboBox> m_xTileOffLB;
+ std::unique_ptr<weld::MetricSpinButton> m_xTileOffset;
+ std::unique_ptr<weld::Button> m_xBtnImport;
+ std::unique_ptr<weld::CustomWeld> m_xCtlBitmapPreview;
+ std::unique_ptr<weld::CustomWeld> m_xBitmapLBWin;
+
+ DECL_LINK( ModifyBitmapHdl, ValueSet*, void );
+ DECL_LINK( ClickScaleHdl, weld::Button&, void );
+ DECL_LINK( ModifyBitmapStyleHdl, weld::ComboBox&, void );
+ DECL_LINK( ModifyBitmapSizeHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifyBitmapPositionHdl, weld::ComboBox&, void );
+ DECL_LINK( ModifyPositionOffsetHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ModifyTileOffsetHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ClickRenameHdl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl, SvxPresetListBox*, void );
+ DECL_LINK( ClickImportHdl, weld::Button&, void );
+ void ClickBitmapHdl_Impl();
+ void CalculateBitmapPresetSize();
+ sal_Int32 SearchBitmapList(const OUString& rBitmapName);
+ sal_Int32 SearchBitmapList(const GraphicObject& rGraphicObject);
+
+public:
+ SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxBitmapTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetBitmapList( const XBitmapListRef& pBmpLst) { m_pBitmapList = pBmpLst; }
+ void SetBmpChgd( ChangeType* pIn ) { m_pnBitmapListState = pIn; }
+};
+
+/************************************************************************/
+
+class SvxPatternTabPage : public SvxTabPage
+{
+private:
+ const SfxItemSet& m_rOutAttrs;
+
+ XColorListRef m_pColorList;
+ XPatternListRef m_pPatternList;
+
+ ChangeType* m_pnPatternListState;
+ ChangeType* m_pnColorListState;
+
+ XFillAttrSetItem m_aXFillAttr;
+ SfxItemSet& m_rXFSet;
+
+ SvxXRectPreview m_aCtlPreview;
+ std::unique_ptr<SvxPixelCtl> m_xCtlPixel;
+ std::unique_ptr<ColorListBox> m_xLbColor;
+ std::unique_ptr<ColorListBox> m_xLbBackgroundColor;
+ std::unique_ptr<SvxPresetListBox> m_xPatternLB;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPixelWin;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+ std::unique_ptr<weld::CustomWeld> m_xPatternLBWin;
+ std::unique_ptr<SvxBitmapCtl> m_xBitmapCtl;
+
+ DECL_LINK( ClickAddHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickModifyHdl_Impl, weld::Button&, void );
+ DECL_LINK( ChangePatternHdl_Impl, ValueSet*, void );
+ DECL_LINK( ChangeColorHdl_Impl, ColorListBox&, void );
+ DECL_LINK( ClickRenameHdl_Impl, SvxPresetListBox*, void );
+ DECL_LINK( ClickDeleteHdl_Impl, SvxPresetListBox*, void );
+
+ sal_Int32 SearchPatternList(const OUString& rPatternName);
+
+public:
+ SvxPatternTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxPatternTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged( weld::DrawingArea*, RectPoint eRP ) override;
+
+ void SetColorList( XColorListRef const & pColorList ) { m_pColorList = pColorList; }
+ void SetPatternList( XPatternListRef const & pPatternList) { m_pPatternList = pPatternList; }
+ void SetPtrnChgd( ChangeType* pIn ) { m_pnPatternListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+ void ChangeColor_Impl();
+};
+
+/************************************************************************/
+
+enum class ColorModel
+{
+ RGB,
+ CMYK
+};
+
+class SvxColorTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+
+ XColorListRef pColorList;
+
+ ChangeType* pnColorListState;
+
+ XFillAttrSetItem aXFillAttr;
+ SfxItemSet& rXFSet;
+
+ ColorModel eCM;
+
+ Color aPreviousColor;
+ Color aCurrentColor;
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+
+ PaletteManager maPaletteManager;
+ SvxXRectPreview m_aCtlPreviewOld;
+ SvxXRectPreview m_aCtlPreviewNew;
+ std::unique_ptr<SvxColorValueSet> m_xValSetColorList;
+ std::unique_ptr<SvxColorValueSet> m_xValSetRecentList;
+ std::unique_ptr<weld::ComboBox> m_xSelectPalette;
+ std::unique_ptr<weld::RadioButton> m_xRbRGB;
+ std::unique_ptr<weld::RadioButton> m_xRbCMYK;
+ std::unique_ptr<weld::Widget> m_xRGBcustom;
+ std::unique_ptr<weld::Widget> m_xRGBpreset;
+ std::unique_ptr<weld::Entry> m_xRpreset;
+ std::unique_ptr<weld::Entry> m_xGpreset;
+ std::unique_ptr<weld::Entry> m_xBpreset;
+ std::unique_ptr<weld::SpinButton> m_xRcustom;
+ std::unique_ptr<weld::SpinButton> m_xGcustom;
+ std::unique_ptr<weld::SpinButton> m_xBcustom;
+ std::unique_ptr<weld::HexColorControl> m_xHexpreset;
+ std::unique_ptr<weld::HexColorControl> m_xHexcustom;
+ std::unique_ptr<weld::Widget> m_xCMYKcustom;
+ std::unique_ptr<weld::Widget> m_xCMYKpreset;
+ std::unique_ptr<weld::Entry> m_xCpreset;
+ std::unique_ptr<weld::Entry> m_xYpreset;
+ std::unique_ptr<weld::Entry> m_xMpreset;
+ std::unique_ptr<weld::Entry> m_xKpreset;
+ std::unique_ptr<weld::MetricSpinButton> m_xCcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xYcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xMcustom;
+ std::unique_ptr<weld::MetricSpinButton> m_xKcustom;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnWorkOn;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreviewOld;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreviewNew;
+ std::unique_ptr<weld::CustomWeld> m_xValSetColorListWin;
+ std::unique_ptr<weld::CustomWeld> m_xValSetRecentListWin;
+
+ static void ConvertColorValues (Color& rColor, ColorModel eModell);
+ static void RgbToCmyk_Impl( Color& rColor, sal_uInt16& rK );
+ static void CmykToRgb_Impl( Color& rColor, const sal_uInt16 nKey );
+ sal_uInt16 ColorToPercent_Impl( sal_uInt16 nColor );
+ sal_uInt16 PercentToColor_Impl( sal_uInt16 nPercent );
+
+ void ImpColorCountChanged();
+ void FillPaletteLB();
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickWorkOnHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(SelectPaletteLBHdl, weld::ComboBox&, void);
+ DECL_LINK( SelectValSetHdl_Impl, ValueSet*, void );
+ DECL_LINK( SelectColorModeHdl_Impl, weld::ToggleButton&, void );
+ void ChangeColor(const Color &rNewColor, bool bUpdatePreset = true);
+ void SetColorModel(ColorModel eModel);
+ void ChangeColorModel();
+ void UpdateColorValues( bool bUpdatePreset = true );
+ DECL_LINK(SpinValueHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(MetricSpinValueHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ModifiedHdl_Impl, weld::Entry&, void);
+
+ void UpdateModified();
+
+ static sal_Int32 FindInCustomColors( OUString const & aColorName );
+ sal_Int32 FindInPalette( const Color& rColor );
+
+public:
+ SvxColorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxColorTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetPropertyList( XPropertyListType t, const XPropertyListRef &xRef );
+ void SetColorList( const XColorListRef& pColList );
+
+
+ void SetColorChgd( ChangeType* pIn ) { pnColorListState = pIn; }
+
+ void SetCtlPreviewOld( const SfxItemSet& rAttrs ) { m_aCtlPreviewOld.SetAttributes( rAttrs ); }
+
+ virtual void FillUserData() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUITABAREA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitabline.hxx b/cui/source/inc/cuitabline.hxx
new file mode 100644
index 000000000..87ae008da
--- /dev/null
+++ b/cui/source/inc/cuitabline.hxx
@@ -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 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_CUITABLINE_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUITABLINE_HXX
+
+#include <vector>
+#include <editeng/brushitem.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/tabarea.hxx>
+#include <svx/xlnasit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/dlgctrl.hxx>
+#include <vcl/customweld.hxx>
+
+enum class PageType;
+class ColorListBox;
+
+class SvxLineTabDialog final : public SfxTabDialogController
+{
+ SdrModel* pDrawModel;
+ const SdrObject* pObj;
+
+ XColorListRef pColorList;
+ XColorListRef mpNewColorList;
+ XDashListRef pDashList;
+ XDashListRef pNewDashList;
+ XLineEndListRef pLineEndList;
+ XLineEndListRef pNewLineEndList;
+ bool bObjSelected;
+
+ ChangeType nLineEndListState;
+ ChangeType nDashListState;
+ ChangeType mnColorListState;
+
+ PageType nPageType;
+ sal_Int32 nPosDashLb;
+ sal_Int32 nPosLineEndLb;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+ virtual short Ok() override;
+ DECL_LINK(CancelHdlImpl, weld::Button&, void);
+ void SavePalettes();
+
+public:
+ SvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel, const SdrObject* pObj,
+ bool bHasObj);
+
+ void SetNewDashList( XDashListRef const & pInLst)
+ { pNewDashList = pInLst; }
+ const XDashListRef& GetNewDashList() const { return pNewDashList; }
+
+ void SetNewLineEndList( XLineEndListRef const & pInLst)
+ { pNewLineEndList = pInLst; }
+ const XLineEndListRef& GetNewLineEndList() const { return pNewLineEndList; }
+
+ void SetNewColorList( XColorListRef const & pColTab ) { mpNewColorList = pColTab; }
+ const XColorListRef& GetNewColorList() const { return mpNewColorList; }
+};
+
+/*************************************************************************/
+
+struct SvxBmpItemInfo
+{
+ std::unique_ptr<SvxBrushItem> pBrushItem;
+ OUString sItemId;
+};
+
+class SvxLineTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pLineRanges[];
+private:
+ //#58425# symbols on a line (e. g. StarChart) ->
+ /** a list of symbols to be shown in menu. Symbol at position SID_ATTR_SYMBOLTYPE is to be shown in preview.
+ The list position is to be used cyclic. */
+ SdrObjList* m_pSymbolList;
+ bool m_bNewSize;
+ /// a graphic to be displayed in the preview in case that an automatic symbol is chosen
+ Graphic m_aAutoSymbolGraphic;
+ long m_nSymbolType;
+ /// attributes for the shown symbols; only necessary if not equal to line properties
+ SfxItemSet* m_pSymbolAttr;
+
+ std::vector<OUString> m_aGrfNames;
+ std::vector< std::unique_ptr<SvxBmpItemInfo> >
+ m_aGalleryBrushItems;
+ std::vector< std::unique_ptr<SvxBmpItemInfo> >
+ m_aSymbolBrushItems;
+ bool m_bLastWidthModified;
+ Size m_aSymbolLastSize;
+ Graphic m_aSymbolGraphic;
+ Size m_aSymbolSize;
+ bool m_bSymbols;
+
+ const SfxItemSet& m_rOutAttrs;
+ bool m_bObjSelected;
+
+ XLineAttrSetItem m_aXLineAttr;
+ SfxItemSet& m_rXLSet;
+
+ XDashListRef m_pDashList;
+ XLineEndListRef m_pLineEndList;
+
+ ChangeType* m_pnLineEndListState;
+ ChangeType* m_pnDashListState;
+ ChangeType* m_pnColorListState;
+ PageType m_nPageType;
+ sal_uInt16 m_nDlgType;
+ sal_Int32* m_pPosDashLb;
+ sal_Int32* m_pPosLineEndLb;
+
+ MapUnit m_ePoolUnit;
+
+ sal_Int32 m_nActLineWidth;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<weld::Widget> m_xBoxColor;
+ std::unique_ptr<SvxLineLB> m_xLbLineStyle;
+ std::unique_ptr<ColorListBox> m_xLbColor;
+ std::unique_ptr<weld::Widget> m_xBoxWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLineWidth;
+ std::unique_ptr<weld::Widget> m_xBoxTransparency;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrTransparent;
+ std::unique_ptr<weld::Widget> m_xFlLineEnds;
+ std::unique_ptr<weld::Widget> m_xBoxArrowStyles;
+ std::unique_ptr<SvxLineEndLB> m_xLbStartStyle;
+ std::unique_ptr<weld::Widget> m_xBoxStart;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrStartWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbCenterStart;
+ std::unique_ptr<weld::Widget> m_xBoxEnd;
+ std::unique_ptr<SvxLineEndLB> m_xLbEndStyle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrEndWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbCenterEnd;
+ std::unique_ptr<weld::CheckButton> m_xCbxSynchronize;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ std::unique_ptr<weld::Widget> m_xFLEdgeStyle;
+ std::unique_ptr<weld::Widget> m_xGridEdgeCaps;
+ std::unique_ptr<weld::ComboBox> m_xLBEdgeStyle;
+
+ // LineCaps
+ std::unique_ptr<weld::ComboBox> m_xLBCapStyle;
+
+ std::unique_ptr<weld::Widget> m_xFlSymbol;
+ std::unique_ptr<weld::Widget> m_xGridIconSize;
+ std::unique_ptr<weld::MenuButton> m_xSymbolMB;
+ std::unique_ptr<weld::Menu> m_xSymbolsMenu;
+ std::unique_ptr<weld::Menu> m_xGalleryMenu;
+ std::unique_ptr<weld::MetricSpinButton> m_xSymbolWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xSymbolHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xSymbolRatioCB;
+
+ // handler for gallery popup menu button + size
+ DECL_LINK(GraphicHdl_Impl, const OString&, void);
+ DECL_LINK(SizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(MenuCreateHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(RatioHdl_Impl, weld::ToggleButton&, void);
+
+ DECL_LINK(ClickInvisibleHdl_Impl, weld::ComboBox&, void);
+ void ClickInvisibleHdl_Impl();
+ DECL_LINK(ChangeStartClickHdl_Impl, weld::Button&, void);
+ DECL_LINK(ChangeStartListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeEndListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeEndClickHdl_Impl, weld::Button&, void);
+ DECL_LINK(ChangePreviewListBoxHdl_Impl, ColorListBox&, void);
+ DECL_LINK(ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, void);
+ void ChangePreviewHdl_Impl(const weld::MetricSpinButton*);
+ DECL_LINK(ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void);
+
+ DECL_LINK(ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void);
+
+ // LineCaps
+ DECL_LINK(ChangeCapStyleHdl_Impl, weld::ComboBox&, void);
+
+ void FillXLSet_Impl();
+
+ void FillListboxes();
+public:
+
+ void ShowSymbolControls(bool bOn);
+
+ SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pLineRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet* ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void FillUserData() override;
+
+ void SetDashList( XDashListRef const & pDshLst ) { m_pDashList = pDshLst; }
+ void SetLineEndList( XLineEndListRef const & pLneEndLst) { m_pLineEndList = pLneEndLst; }
+ void SetObjSelected( bool bHasObj ) { m_bObjSelected = bHasObj; }
+
+ void SetPageType( PageType nInType ) { m_nPageType = nInType; }
+ void SetDlgType( sal_uInt16 nInType ) { m_nDlgType = nInType; }
+ void SetPosDashLb( sal_Int32* pInPos ) { m_pPosDashLb = pInPos; }
+ void SetPosLineEndLb( sal_Int32* pInPos ) { m_pPosLineEndLb = pInPos; }
+
+ void SetLineEndChgd( ChangeType* pIn ) { m_pnLineEndListState = pIn; }
+ void SetDashChgd( ChangeType* pIn ) { m_pnDashListState = pIn; }
+ void SetColorChgd( ChangeType* pIn ) { m_pnColorListState = pIn; }
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+/*************************************************************************/
+
+class SvxLineDefTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+ XDash aDash;
+
+ XLineAttrSetItem aXLineAttr;
+ SfxItemSet& rXLSet;
+
+ XDashListRef pDashList;
+
+ ChangeType* pnDashListState;
+ PageType* pPageType;
+ sal_uInt16 nDlgType;
+ sal_Int32* pPosDashLb;
+
+ MapUnit ePoolUnit;
+ FieldUnit eFUnit;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<SvxLineLB> m_xLbLineStyles;
+ std::unique_ptr<weld::ComboBox> m_xLbType1;
+ std::unique_ptr<weld::ComboBox> m_xLbType2;
+ std::unique_ptr<weld::SpinButton> m_xNumFldNumber1;
+ std::unique_ptr<weld::SpinButton> m_xNumFldNumber2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLength1;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrLength2;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrDistance;
+ std::unique_ptr<weld::CheckButton> m_xCbxSynchronize;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnLoad;
+ std::unique_ptr<weld::Button> m_xBtnSave;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillDash_Impl();
+ void FillDialog_Impl();
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickModifyHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, void);
+ void SelectLinestyleHdl_Impl(const weld::ComboBox*);
+ DECL_LINK(ChangePreviewHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeNumber1Hdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ChangeNumber2Hdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ClickLoadHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickSaveHdl_Impl, weld::Button&, void);
+ DECL_LINK(ChangeMetricHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(SelectTypeListBoxHdl_Impl, weld::ComboBox&, void);
+ void SelectTypeHdl_Impl(const weld::ComboBox*);
+ void ChangeMetricHdl_Impl(const weld::ToggleButton*);
+
+ void CheckChanges_Impl();
+
+public:
+ SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineDefTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetDashList( XDashListRef const & pDshLst ) { pDashList = pDshLst; }
+
+ void SetPageType( PageType* pInType ) { pPageType = pInType; }
+ void SetDlgType( sal_uInt16 nInType ) { nDlgType = nInType; }
+ void SetPosDashLb( sal_Int32* pInPos ) { pPosDashLb = pInPos; }
+
+ void SetDashChgd( ChangeType* pIn ) { pnDashListState = pIn; }
+};
+
+/*************************************************************************/
+
+class SvxLineEndDefTabPage : public SfxTabPage
+{
+private:
+ const SfxItemSet& rOutAttrs;
+ const SdrObject* pPolyObj;
+
+ XLineAttrSetItem aXLineAttr;
+ SfxItemSet& rXLSet;
+
+ XLineEndListRef pLineEndList;
+
+ ChangeType* pnLineEndListState;
+ PageType* pPageType;
+ sal_uInt16 nDlgType;
+ sal_Int32* pPosLineEndLb;
+
+ SvxXLinePreview m_aCtlPreview;
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<SvxLineEndLB> m_xLbLineEnds;
+ std::unique_ptr<weld::Button> m_xBtnAdd;
+ std::unique_ptr<weld::Button> m_xBtnModify;
+ std::unique_ptr<weld::Button> m_xBtnDelete;
+ std::unique_ptr<weld::Button> m_xBtnLoad;
+ std::unique_ptr<weld::Button> m_xBtnSave;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ DECL_LINK(ClickAddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickModifyHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickLoadHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickSaveHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectLineEndHdl_Impl, weld::ComboBox&, void);
+
+ void SelectLineEndHdl_Impl();
+ void CheckChanges_Impl();
+
+public:
+ SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxLineEndDefTabPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void SetLineEndList( XLineEndListRef const & pInList ) { pLineEndList = pInList; }
+ void SetPolyObj( const SdrObject* pObj ) { pPolyObj = pObj; }
+
+ void SetPageType( PageType* pInType ) { pPageType = pInType; }
+ void SetDlgType( sal_uInt16 nInType ) { nDlgType = nInType; }
+ void SetPosLineEndLb( sal_Int32* pInPos ) { pPosLineEndLb = pInPos; }
+
+ void SetLineEndChgd( ChangeType* pIn ) { pnLineEndListState = pIn; }
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_CUITABLINE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/cuitbxform.hxx b/cui/source/inc/cuitbxform.hxx
new file mode 100644
index 000000000..f6e52b094
--- /dev/null
+++ b/cui/source/inc/cuitbxform.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_CUITBXFORM_HXX
+#define INCLUDED_CUI_SOURCE_INC_CUITBXFORM_HXX
+
+#include <vcl/weld.hxx>
+
+class FmInputRecordNoDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::SpinButton> m_xRecordNo;
+
+public:
+ FmInputRecordNoDialog(weld::Window* pParent);
+ virtual ~FmInputRecordNoDialog() override;
+
+ void SetValue(int dNew) { m_xRecordNo->set_value(dNew); }
+ int GetValue() const { return m_xRecordNo->get_value(); }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dbregister.hxx b/cui/source/inc/dbregister.hxx
new file mode 100644
index 000000000..e1bc2f6b1
--- /dev/null
+++ b/cui/source/inc/dbregister.hxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_DBREGISTER_HXX
+#define INCLUDED_CUI_SOURCE_INC_DBREGISTER_HXX
+
+#include <rtl/ustring.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+
+namespace svx
+{
+
+ class DbRegistrationOptionsPage : public SfxTabPage
+ {
+ private:
+ sal_uLong m_nOldCount;
+ bool m_bModified;
+
+ std::unique_ptr<weld::Button> m_xNew;
+ std::unique_ptr<weld::Button> m_xEdit;
+ std::unique_ptr<weld::Button> m_xDelete;
+ std::unique_ptr<weld::TreeView> m_xPathBox;
+ std::unique_ptr<weld::TreeIter> m_xIter;
+
+ DECL_LINK( NewHdl, weld::Button&, void );
+ DECL_LINK( EditHdl, weld::Button&, void );
+ DECL_LINK( DeleteHdl, weld::Button&, void );
+ DECL_LINK( PathBoxDoubleClickHdl, weld::TreeView&, bool);
+
+ DECL_LINK( PathSelect_Impl, weld::TreeView&, void);
+
+ DECL_LINK( HeaderSelect_Impl, int, void );
+ DECL_LINK( NameValidator, const OUString&, bool);
+
+ /** inserts a new entry in the tablistbox
+ @param _sName
+ The name of the entry.
+ @param _sLocation
+ The location of the file.
+ */
+ void insertNewEntry( const OUString& _sName,const OUString& _sLocation, const bool bReadOnly );
+
+ /** opens the LinkDialog to create a register pair
+ @param sOldName
+ The old name of the entry may be empty.
+ @param sOldLocation
+ The old location of the entry may be empty.
+ @param nEntry
+ The entry to remove if the entry will be changed
+ */
+ void openLinkDialog(const OUString& sOldName, const OUString& sOldLocation, int nEntry = -1);
+
+ public:
+ DbRegistrationOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~DbRegistrationOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+ };
+
+ /** helper for DatabaseRegistrationDialog
+
+ Necessary so that DatabaseRegistrationDialog is self-contained, i.e. always reflects
+ the current registration state.
+ */
+ class RegistrationItemSetHolder
+ {
+ private:
+ SfxItemSet m_aRegistrationItems;
+
+ protected:
+ RegistrationItemSetHolder( const SfxItemSet& _rMasterSet );
+ ~RegistrationItemSetHolder();
+
+ protected:
+ const SfxItemSet& getRegistrationItems() const { return m_aRegistrationItems; }
+ };
+
+ class DatabaseRegistrationDialog :public RegistrationItemSetHolder
+ ,public SfxSingleTabDialogController
+ {
+ public:
+ DatabaseRegistrationDialog(weld::Window* pParent, const SfxItemSet& rAttr);
+
+ virtual short run() override;
+ };
+}
+
+#endif // INCLUDED_CUI_SOURCE_INC_DBREGISTER_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/defdlgname.hxx b/cui/source/inc/defdlgname.hxx
new file mode 100644
index 000000000..08aa42497
--- /dev/null
+++ b/cui/source/inc/defdlgname.hxx
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_DEFDLGNAME_HXX
+#define INCLUDED_CUI_SOURCE_INC_DEFDLGNAME_HXX
+
+
+// const -----------------------------------------------------------------
+
+const short RET_BTN_1 = 100;
+const short RET_BTN_2 = 101;
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dialmgr.hxx b/cui/source/inc/dialmgr.hxx
new file mode 100644
index 000000000..c31fde3a2
--- /dev/null
+++ b/cui/source/inc/dialmgr.hxx
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+OUString CuiResId(const char* pKey);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dlgname.hxx b/cui/source/inc/dlgname.hxx
new file mode 100644
index 000000000..8fd754990
--- /dev/null
+++ b/cui/source/inc/dlgname.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_CUI_SOURCE_INC_DLGNAME_HXX
+#define INCLUDED_CUI_SOURCE_INC_DLGNAME_HXX
+
+#include <vcl/weld.hxx>
+
+/// Dialog for editing a name
+class SvxNameDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdtName;
+ std::unique_ptr<weld::Label> m_xFtDescription;
+ std::unique_ptr<weld::Button> m_xBtnOK;
+
+ Link<SvxNameDialog&,bool> m_aCheckNameHdl;
+ Link<SvxNameDialog&,OUString> m_aCheckNameTooltipHdl;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ SvxNameDialog(weld::Window* pWindow, const OUString& rName, const OUString& rDesc);
+
+ OUString GetName() const { return m_xEdtName->get_text(); }
+
+ /** add a callback Link that is called whenever the content of the edit
+ field is changed. The Link result determines whether the OK
+ Button is enabled (> 0) or disabled (== 0).
+
+ @param rLink a Callback declared with DECL_LINK and implemented with
+ IMPL_LINK, that is executed on modification.
+
+ @param bCheckImmediately If true, the Link is called directly after
+ setting it. It is recommended to set this flag to true to avoid
+ an inconsistent state if the initial String (given in the CTOR)
+ does not satisfy the check condition.
+
+ @todo Remove the parameter bCheckImmediately and incorporate the 'true'
+ behaviour as default.
+ */
+ void SetCheckNameHdl(const Link<SvxNameDialog&,bool>& rLink, bool bCheckImmediately)
+ {
+ m_aCheckNameHdl = rLink;
+ if (bCheckImmediately)
+ m_xBtnOK->set_sensitive(rLink.Call(*this));
+ }
+
+ void SetCheckNameTooltipHdl(const Link<SvxNameDialog&,OUString>& rLink)
+ {
+ m_aCheckNameTooltipHdl = rLink;
+ m_xBtnOK->set_tooltip_text(rLink.Call(*this));
+ }
+
+ void SetEditHelpId(const OString& aHelpId) { m_xEdtName->set_help_id(aHelpId);}
+};
+
+/** #i68101#
+ Dialog for editing Object name
+ plus uniqueness-callback-linkHandler */
+class SvxObjectNameDialog : public weld::GenericDialogController
+{
+private:
+ // name
+ std::unique_ptr<weld::Entry> m_xEdtName;
+
+ // buttons
+ std::unique_ptr<weld::Button> m_xBtnOK;
+
+ // callback link for name uniqueness
+ Link<SvxObjectNameDialog&,bool> aCheckNameHdl;
+
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ // constructor
+ SvxObjectNameDialog(weld::Window* pWindow, const OUString& rName);
+
+ // data access
+ OUString GetName() const { return m_xEdtName->get_text(); }
+
+ // set handler
+ void SetCheckNameHdl(const Link<SvxObjectNameDialog&,bool>& rLink)
+ {
+ aCheckNameHdl = rLink;
+ }
+};
+
+/** #i68101#
+ Dialog for editing Object Title and Description */
+class SvxObjectTitleDescDialog : public weld::GenericDialogController
+{
+private:
+ // title
+ std::unique_ptr<weld::Entry> m_xEdtTitle;
+
+ // description
+ std::unique_ptr<weld::TextView> m_xEdtDescription;
+
+public:
+ // constructor
+ SvxObjectTitleDescDialog(weld::Window* pWindow, const OUString& rTitle, const OUString& rDesc);
+ // data access
+ OUString GetTitle() const { return m_xEdtTitle->get_text(); }
+ OUString GetDescription() const { return m_xEdtDescription->get_text(); }
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_DLGNAME_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/dstribut.hxx b/cui/source/inc/dstribut.hxx
new file mode 100644
index 000000000..3d3c99de1
--- /dev/null
+++ b/cui/source/inc/dstribut.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_CUI_SOURCE_INC_DSTRIBUT_HXX
+#define INCLUDED_CUI_SOURCE_INC_DSTRIBUT_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/dstribut_enum.hxx>
+#include <vcl/weld.hxx>
+
+class SvxDistributePage : public SfxTabPage
+{
+ SvxDistributeHorizontal m_eDistributeHor;
+ SvxDistributeVertical m_eDistributeVer;
+
+ std::unique_ptr<weld::RadioButton> m_xBtnHorNone;
+ std::unique_ptr<weld::RadioButton> m_xBtnHorLeft;
+ std::unique_ptr<weld::RadioButton> m_xBtnHorCenter;
+ std::unique_ptr<weld::RadioButton> m_xBtnHorDistance;
+ std::unique_ptr<weld::RadioButton> m_xBtnHorRight;
+ std::unique_ptr<weld::RadioButton> m_xBtnVerNone;
+ std::unique_ptr<weld::RadioButton> m_xBtnVerTop;
+ std::unique_ptr<weld::RadioButton> m_xBtnVerCenter;
+ std::unique_ptr<weld::RadioButton> m_xBtnVerDistance;
+ std::unique_ptr<weld::RadioButton> m_xBtnVerBottom;
+
+public:
+ SvxDistributePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs,
+ SvxDistributeHorizontal eHor,
+ SvxDistributeVertical eVer);
+ virtual ~SvxDistributePage() override;
+
+ virtual bool FillItemSet(SfxItemSet*) override;
+ virtual void Reset(const SfxItemSet*) override;
+
+ SvxDistributeHorizontal GetDistributeHor() const { return m_eDistributeHor; }
+ SvxDistributeVertical GetDistributeVer() const { return m_eDistributeVer; }
+};
+
+class SvxDistributeDialog : public SfxSingleTabDialogController
+{
+ SvxDistributePage* mpPage;
+
+public:
+ SvxDistributeDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ SvxDistributeHorizontal eHor,
+ SvxDistributeVertical eVer);
+ virtual ~SvxDistributeDialog() override;
+
+ SvxDistributeHorizontal GetDistributeHor() const { return mpPage->GetDistributeHor(); }
+ SvxDistributeVertical GetDistributeVer() const { return mpPage->GetDistributeVer(); }
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_DSTRIBUT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/grfpage.hxx b/cui/source/inc/grfpage.hxx
new file mode 100644
index 000000000..afdc7cb6b
--- /dev/null
+++ b/cui/source/inc/grfpage.hxx
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_GRFPAGE_HXX
+#define INCLUDED_CUI_SOURCE_INC_GRFPAGE_HXX
+
+#include <vcl/customweld.hxx>
+#include <vcl/graph.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SvxCropExample : public weld::CustomWidgetController
+{
+ MapMode m_aMapMode;
+ Size m_aFrameSize;
+ Point m_aTopLeft, m_aBottomRight;
+ Graphic m_aGrf;
+
+public:
+ SvxCropExample();
+
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+ virtual void Resize() override;
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override;
+
+ void SetTop( long nVal ) { m_aTopLeft.setX(nVal); }
+ void SetBottom( long nVal ) { m_aBottomRight.setX(nVal); }
+ void SetLeft( long nVal ) { m_aTopLeft.setY(nVal); }
+ void SetRight( long nVal) { m_aBottomRight.setY(nVal); }
+ void SetFrameSize( const Size& rSz );
+ void SetGraphic( const Graphic& rGrf ) { m_aGrf = rGrf; }
+};
+
+class SvxGrfCropPage : public SfxTabPage
+{
+ friend class VclPtr<SvxGrfCropPage>;
+
+ OUString aGraphicName;
+ Size aOrigSize;
+ Size aOrigPixelSize;
+ Size aPageSize;
+ long nOldWidth;
+ long nOldHeight;
+ bool bSetOrigSize;
+
+ SvxCropExample m_aExampleWN;
+
+ std::unique_ptr<weld::Widget> m_xCropFrame;
+ std::unique_ptr<weld::RadioButton> m_xZoomConstRB;
+ std::unique_ptr<weld::RadioButton> m_xSizeConstRB;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMF;
+
+ std::unique_ptr<weld::Widget> m_xScaleFrame;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthZoomMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightZoomMF;
+
+ std::unique_ptr<weld::Widget> m_xSizeFrame;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+
+ std::unique_ptr<weld::Widget> m_xOrigSizeGrid;
+ std::unique_ptr<weld::Label> m_xOrigSizeFT;
+ std::unique_ptr<weld::Button> m_xOrigSizePB;
+
+ // Example
+ std::unique_ptr<weld::CustomWeld> m_xExampleWN;
+
+ DECL_LINK(ZoomHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(SizeHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(CropModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(OrigSizeHdl, weld::Button&, void);
+
+ void CalcZoom();
+ void CalcMinMaxBorder();
+ void GraphicHasChanged(bool bFound);
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+
+ static Size GetGrfOrigSize(const Graphic&);
+public:
+ SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet );
+ virtual ~SvxGrfCropPage() override;
+
+ virtual bool FillItemSet( SfxItemSet *rSet ) override;
+ virtual void Reset( const SfxItemSet *rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet *pSet ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hangulhanjadlg.hxx b/cui/source/inc/hangulhanjadlg.hxx
new file mode 100644
index 000000000..056aee159
--- /dev/null
+++ b/cui/source/inc/hangulhanjadlg.hxx
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_HANGULHANJADLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_HANGULHANJADLG_HXX
+
+#include <vcl/customweld.hxx>
+#include <vcl/event.hxx>
+#include <vcl/weld.hxx>
+#include <editeng/hangulhanja.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/linguistic2/XConversionDictionaryList.hpp>
+#include <svtools/valueset.hxx>
+
+#include <vector>
+#include <memory>
+
+namespace svx
+{
+
+ class SuggestionSet : public ValueSet
+ {
+ public:
+ SuggestionSet(std::unique_ptr<weld::ScrolledWindow> xScrolledWindow);
+
+ virtual void UserDraw( const UserDrawEvent& rUDEvt ) override;
+ };
+
+ class SuggestionDisplay
+ {
+ public:
+ SuggestionDisplay(weld::Builder& rBuilder);
+
+ void DisplayListBox( bool bDisplayListBox );
+
+ void SetSelectHdl( const Link<SuggestionDisplay&,void>& rLink );
+
+ void Clear();
+ void InsertEntry( const OUString& rStr );
+ void SelectEntryPos( sal_uInt16 nPos );
+
+ sal_uInt16 GetEntryCount() const;
+
+ OUString GetEntry( sal_uInt16 nPos ) const;
+ OUString GetSelectedEntry() const;
+
+ DECL_LINK( SelectSuggestionListBoxHdl, weld::TreeView&, void );
+ DECL_LINK( SelectSuggestionValueSetHdl, ValueSet*, void );
+ void SelectSuggestionHdl(bool bListBox);
+
+ void SetHelpIds();
+
+ void set_size_request(int nWidth, int nHeight)
+ {
+ m_xValueSetWin->set_size_request(nWidth, nHeight);
+ m_xListBox->set_size_request(nWidth, nHeight);
+ }
+
+ private:
+ void implUpdateDisplay();
+ weld::Widget& implGetCurrentControl();
+
+ private:
+ bool m_bDisplayListBox; //otherwise ValueSet
+ bool m_bInSelectionUpdate;
+ Link<SuggestionDisplay&,void> m_aSelectLink;
+
+ std::unique_ptr<SuggestionSet> m_xValueSet;
+ std::unique_ptr<weld::CustomWeld> m_xValueSetWin;
+ std::unique_ptr<weld::TreeView> m_xListBox;
+ };
+
+ class RubyRadioButton;
+
+ class HangulHanjaConversionDialog : public weld::GenericDialogController
+ {
+ private:
+ /** are we working for a document? This is normally true, but in case
+ the user uses the "find" functionality, we switch to working
+ with what the user entered, which then does not have any relation to
+ the document anymore. Some functionality must be disabled then */
+ bool m_bDocumentMode;
+
+ Link<LinkParamNone*,void> m_aOptionsChangedLink;
+ Link<weld::ToggleButton&,void> m_aClickByCharacterLink;
+
+ std::unique_ptr<weld::Button> m_xFind;
+ std::unique_ptr<weld::Button> m_xIgnore;
+ std::unique_ptr<weld::Button> m_xIgnoreAll;
+ std::unique_ptr<weld::Button> m_xReplace;
+ std::unique_ptr<weld::Button> m_xReplaceAll;
+ std::unique_ptr<weld::Button> m_xOptions;
+ std::unique_ptr<SuggestionDisplay> m_xSuggestions;
+ std::unique_ptr<weld::RadioButton> m_xSimpleConversion;
+ std::unique_ptr<weld::RadioButton> m_xHangulBracketed;
+ std::unique_ptr<weld::RadioButton> m_xHanjaBracketed;
+ std::unique_ptr<weld::Entry> m_xWordInput;
+ std::unique_ptr<weld::Label> m_xOriginalWord;
+ std::unique_ptr<RubyRadioButton> m_xHanjaAbove;
+ std::unique_ptr<RubyRadioButton> m_xHanjaBelow;
+ std::unique_ptr<RubyRadioButton> m_xHangulAbove;
+ std::unique_ptr<RubyRadioButton> m_xHangulBelow;
+ std::unique_ptr<weld::CheckButton> m_xHangulOnly;
+ std::unique_ptr<weld::CheckButton> m_xHanjaOnly;
+ std::unique_ptr<weld::CheckButton> m_xReplaceByChar;
+ public:
+ HangulHanjaConversionDialog(weld::Window* pParent);
+ virtual ~HangulHanjaConversionDialog() override;
+
+ public:
+ void SetOptionsChangedHdl( const Link<LinkParamNone*,void>& _rHdl );
+ void SetIgnoreHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetIgnoreAllHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetChangeHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetChangeAllHdl( const Link<weld::Button&,void>& _rHdl );
+
+ void SetClickByCharacterHdl( const Link<weld::ToggleButton&,void>& _rHdl );
+ void SetConversionFormatChangedHdl( const Link<weld::Button&,void>& _rHdl );
+ void SetFindHdl( const Link<weld::Button&,void>& _rHdl );
+
+ OUString GetCurrentString( ) const;
+ void SetCurrentString(
+ const OUString& _rNewString,
+ const css::uno::Sequence< OUString >& _rSuggestions,
+ bool _bOriginatesFromDocument
+ );
+
+ void FocusSuggestion( );
+
+ /// retrieves the current suggestion
+ OUString GetCurrentSuggestion( ) const;
+
+ void SetConversionFormat( editeng::HangulHanjaConversion::ConversionFormat _eType );
+ editeng::HangulHanjaConversion::ConversionFormat GetConversionFormat( ) const;
+
+ void SetByCharacter( bool _bByCharacter );
+ void SetConversionDirectionState( bool _bTryBothDirections, editeng::HangulHanjaConversion::ConversionDirection _ePrimaryConversionDirection );
+
+ /// should text which does not match the primary conversion direction be ignored?
+ bool GetUseBothDirections( ) const;
+
+ /** get current conversion direction to use
+ (return argument if GetUseBothDirections is true) */
+ editeng::HangulHanjaConversion::ConversionDirection GetDirection( editeng::HangulHanjaConversion::ConversionDirection eDefaultDirection ) const;
+
+ /// enables or disables the checkboxes for ruby formatted replacements
+ void EnableRubySupport( bool bVal );
+
+ private:
+ DECL_LINK( OnOption, weld::Button&, void );
+ DECL_LINK( OnSuggestionModified, weld::Entry&, void );
+ DECL_LINK( OnSuggestionSelected, SuggestionDisplay&, void );
+ DECL_LINK( OnConversionDirectionClicked, weld::ToggleButton&, void );
+ DECL_LINK( ClickByCharacterHdl, weld::ToggleButton&, void );
+
+ /// fill the suggestion list box with suggestions for the actual input
+ void FillSuggestions( const css::uno::Sequence< OUString >& _rSuggestions );
+ };
+
+
+ typedef std::vector< css::uno::Reference< css::linguistic2::XConversionDictionary > > HHDictList;
+
+ class HangulHanjaOptionsDialog : public weld::GenericDialogController
+ {
+ private:
+ HHDictList m_aDictList;
+ css::uno::Reference< css::linguistic2::XConversionDictionaryList > m_xConversionDictionaryList;
+
+ std::unique_ptr<weld::TreeView> m_xDictsLB;
+ std::unique_ptr<weld::CheckButton> m_xIgnorepostCB;
+ std::unique_ptr<weld::CheckButton> m_xShowrecentlyfirstCB;
+ std::unique_ptr<weld::CheckButton> m_xAutoreplaceuniqueCB;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xEditPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<weld::Button> m_xOkPB;
+
+ DECL_LINK( OkHdl, weld::Button&, void );
+ DECL_LINK( DictsLB_SelectHdl, weld::TreeView&, void );
+ DECL_LINK( NewDictHdl, weld::Button&, void );
+ DECL_LINK( EditDictHdl, weld::Button&, void );
+ DECL_LINK( DeleteDictHdl, weld::Button&, void );
+
+ void Init(); ///< reads settings from core and init controls
+ public:
+ HangulHanjaOptionsDialog(weld::Window* pParent);
+ virtual ~HangulHanjaOptionsDialog() override;
+
+ void AddDict( const OUString& _rName, bool _bChecked );
+ };
+
+ class HangulHanjaNewDictDialog : public weld::GenericDialogController
+ {
+ private:
+ bool m_bEntered;
+
+ std::unique_ptr<weld::Button> m_xOkBtn;
+ std::unique_ptr<weld::Entry> m_xDictNameED;
+
+ DECL_LINK(OKHdl, weld::Button&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ public:
+ HangulHanjaNewDictDialog(weld::Window* pParent);
+ virtual ~HangulHanjaNewDictDialog() override;
+
+ bool GetName( OUString& _rRetName ) const;
+ };
+
+ class SuggestionList;
+ class HangulHanjaEditDictDialog;
+
+ class SuggestionEdit
+ {
+ private:
+ HangulHanjaEditDictDialog* m_pParent;
+ SuggestionEdit* m_pPrev;
+ SuggestionEdit* m_pNext;
+ weld::ScrolledWindow* m_pScrollBar;
+ std::unique_ptr<weld::Entry> m_xEntry;
+
+ bool ShouldScroll( bool _bUp ) const;
+ void DoJump( bool _bUp );
+ public:
+ SuggestionEdit(std::unique_ptr<weld::Entry> xEntry, HangulHanjaEditDictDialog* pParent);
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+ void init(weld::ScrolledWindow* pScrollBar, SuggestionEdit* pPrev, SuggestionEdit* pNext);
+
+ void grab_focus() { m_xEntry->grab_focus(); }
+ OUString get_text() const { return m_xEntry->get_text(); }
+ void set_text(const OUString& rText) { m_xEntry->set_text(rText); }
+ void connect_changed(const Link<weld::Entry&, void>& rLink) { m_xEntry->connect_changed(rLink); }
+ };
+
+ class HangulHanjaEditDictDialog : public weld::GenericDialogController
+ {
+ private:
+ const OUString m_aEditHintText;
+ HHDictList& m_rDictList;
+ sal_uInt32 m_nCurrentDict;
+
+ OUString m_aOriginal;
+ std::unique_ptr<SuggestionList> m_xSuggestions;
+
+ sal_uInt16 m_nTopPos;
+ bool m_bModifiedSuggestions;
+ bool m_bModifiedOriginal;
+
+ std::unique_ptr<weld::ComboBox> m_xBookLB;
+ std::unique_ptr<weld::ComboBox> m_xOriginalLB;
+ std::unique_ptr<SuggestionEdit> m_xEdit1;
+ std::unique_ptr<SuggestionEdit> m_xEdit2;
+ std::unique_ptr<SuggestionEdit> m_xEdit3;
+ std::unique_ptr<SuggestionEdit> m_xEdit4;
+ std::unique_ptr<weld::Widget> m_xContents;
+ std::unique_ptr<weld::ScrolledWindow> m_xScrollSB;
+ std::unique_ptr<weld::Button> m_xNewPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+
+ DECL_LINK( OriginalModifyHdl, weld::ComboBox&, void );
+ DECL_LINK( ScrollHdl, weld::ScrolledWindow&, void );
+ DECL_LINK( EditModifyHdl1, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl2, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl3, weld::Entry&, void );
+ DECL_LINK( EditModifyHdl4, weld::Entry&, void );
+
+ DECL_LINK( BookLBSelectHdl, weld::ComboBox&, void );
+ DECL_LINK( NewPBPushHdl, weld::Button&, void );
+ DECL_LINK( DeletePBPushHdl, weld::Button&, void );
+
+ void InitEditDictDialog(sal_uInt32 nSelDict);
+ void UpdateOriginalLB();
+ void UpdateSuggestions();
+ void UpdateButtonStates();
+
+ void SetEditText( SuggestionEdit& rEdit, sal_uInt16 nEntryNum );
+ void EditModify( const weld::Entry* pEdit, sal_uInt8 nEntryOffset );
+
+ bool DeleteEntryFromDictionary( const css::uno::Reference< css::linguistic2::XConversionDictionary >& xDict );
+
+ public:
+ HangulHanjaEditDictDialog(weld::Window* pParent, HHDictList& rDictList, sal_uInt32 nSelDict);
+ virtual ~HangulHanjaEditDictDialog() override;
+
+ void UpdateScrollbar();
+ };
+}
+
+#endif // SVX_HANGUL_HANJA_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/headertablistbox.hxx b/cui/source/inc/headertablistbox.hxx
new file mode 100644
index 000000000..c4c65feac
--- /dev/null
+++ b/cui/source/inc/headertablistbox.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_CUI_SOURCE_INC_HEADERTABLISTBOX_HXX
+#define INCLUDED_CUI_SOURCE_INC_HEADERTABLISTBOX_HXX
+
+#include <vcl/weld.hxx>
+
+class MacroEventListBox final
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xTreeView;
+public:
+ MacroEventListBox(std::unique_ptr<weld::TreeView> xTreeView);
+ void set_sensitive(bool bSensitive) { m_xTreeView->set_sensitive(bSensitive); }
+ void show() { m_xTreeView->show(); }
+
+ weld::TreeView& GetListBox()
+ {
+ return *m_xTreeView;
+ }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/helpids.h b/cui/source/inc/helpids.h
new file mode 100644
index 000000000..3ae4404c1
--- /dev/null
+++ b/cui/source/inc/helpids.h
@@ -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_CUI_SOURCE_INC_HELPID_HRC
+#define INCLUDED_CUI_SOURCE_INC_HELPID_HRC
+
+#define HID_OPTIONS_COLORCONFIG_SAVE_SCHEME "CUI_HID_OPTIONS_COLORCONFIG_SAVE_SCHEME"
+#define HID_OFA_FONT_SUBST_CLB "CUI_HID_OFA_FONT_SUBST_CLB"
+#define HID_DBPATH_CTL_PATH "CUI_HID_DBPATH_CTL_PATH"
+#define HID_DBPATH_HEADERBAR "CUI_HID_DBPATH_HEADERBAR"
+#define HID_OFADLG_TREELISTBOX "CUI_HID_OFADLG_TREELISTBOX"
+#define HID_SVX_CONFIG_TOOLBAR "CUI_HID_SVX_CONFIG_TOOLBAR"
+#define HID_SVX_CONFIG_TOOLBAR_CONTENTS "CUI_HID_SVX_CONFIG_TOOLBAR_CONTENTS"
+#define HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS "CUI_HID_SVX_CONFIG_NOTEBOOKBAR_CONTENTS"
+#define HID_HANGULDLG_SUGGESTIONS_GRID "CUI_HID_HANGULDLG_SUGGESTIONS_GRID"
+#define HID_HANGULDLG_SUGGESTIONS_LIST "CUI_HID_HANGULDLG_SUGGESTIONS_LIST"
+#define HID_SVX_CONFIG_NAME_SUBMENU "CUI_HID_SVX_CONFIG_NAME_SUBMENU"
+#define HID_SVX_CONFIG_RENAME_MENU "CUI_HID_SVX_CONFIG_RENAME_MENU"
+#define HID_SVX_CONFIG_RENAME_MENU_ITEM "CUI_HID_SVX_CONFIG_RENAME_MENU_ITEM"
+#define HID_SVX_CONFIG_RENAME_TOOLBAR "CUI_HID_SVX_CONFIG_RENAME_TOOLBAR"
+#define HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM "CUI_HID_SVX_CONFIG_RENAME_TOOLBAR_ITEM"
+#define HID_SVX_UP_TOOLBAR_ITEM "CUI_HID_SVX_UP_TOOLBAR_ITEM"
+#define HID_SVX_DOWN_TOOLBAR_ITEM "CUI_HID_SVX_DOWN_TOOLBAR_ITEM"
+#define HID_SVX_SAVE_IN "CUI_HID_SVX_SAVE_IN"
+#define HID_SVX_TOPLEVELLISTBOX "CUI_HID_SVX_TOPLEVELLISTBOX"
+#define HID_SVX_DESCFIELD "CUI_HID_SVX_DESCFIELD"
+#define HID_MACRO_HEADERTABLISTBOX "CUI_HID_MACRO_HEADERTABLISTBOX"
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hldocntp.hxx b/cui/source/inc/hldocntp.hxx
new file mode 100644
index 000000000..719968853
--- /dev/null
+++ b/cui/source/inc/hldocntp.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_CUI_SOURCE_INC_HLDOCNTP_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLDOCNTP_HXX
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - New Document
+|*
+\************************************************************************/
+class SvxHyperlinkNewDocTp : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<weld::RadioButton> m_xRbtEditNow;
+ std::unique_ptr<weld::RadioButton> m_xRbtEditLater;
+ std::unique_ptr<SvxHyperURLBox> m_xCbbPath;
+ std::unique_ptr<weld::Button> m_xBtCreate;
+ std::unique_ptr<weld::TreeView> m_xLbDocTypes;
+
+ bool ImplGetURLObject( const OUString& rPath, const OUString& rBase, INetURLObject& aURLObject ) const;
+ void FillDocumentList ();
+
+ DECL_LINK (ClickNewHdl_Impl, weld::Button&, void );
+ DECL_STATIC_LINK(SvxHyperlinkNewDocTp, DispatchDocument, void*, void);
+
+protected:
+ void FillDlgFields(const OUString& rStrURL) override;
+ void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+
+public:
+ SvxHyperlinkNewDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkNewDocTp () override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual bool AskApply () override;
+ virtual void DoApply () override;
+
+ virtual void SetInitFocus() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLDOCNTP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hldoctp.hxx b/cui/source/inc/hldoctp.hxx
new file mode 100644
index 000000000..9f5f8395f
--- /dev/null
+++ b/cui/source/inc/hldoctp.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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_HLDOCTP_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLDOCTP_HXX
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Document
+|*
+\************************************************************************/
+class SvxHyperlinkDocTp final : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<SvxHyperURLBox> m_xCbbPath;
+ std::unique_ptr<weld::Button> m_xBtFileopen;
+ std::unique_ptr<weld::Entry> m_xEdTarget;
+ std::unique_ptr<weld::Label> m_xFtFullURL;
+ std::unique_ptr<weld::Button> m_xBtBrowse;
+
+ OUString maStrURL;
+
+ bool m_bMarkWndOpen;
+
+ DECL_LINK (ClickFileopenHdl_Impl, weld::Button&, void );
+ DECL_LINK (ClickTargetHdl_Impl, weld::Button&, void );
+
+ DECL_LINK (ModifiedPathHdl_Impl, weld::ComboBox&, void ); ///< Contents of combobox "Path" modified
+ DECL_LINK (ModifiedTargetHdl_Impl, weld::Entry&, void ); ///< Contents of editfield "Target" modified
+
+ DECL_LINK( LostFocusPathHdl_Impl, weld::Widget&, void ); ///< Combobox "path" lost its focus
+
+ DECL_LINK( TimeoutHdl_Impl, Timer *, void ); ///< Handler for timer -timeout
+
+ enum class EPathType { Invalid, ExistsFile };
+ static EPathType GetPathType ( const OUString& rStrPath );
+
+ void FillDlgFields(const OUString& rStrURL) override;
+ void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+ virtual bool ShouldOpenMarkWnd () override {return m_bMarkWndOpen;}
+ virtual void SetMarkWndShouldOpen (bool bOpen) override {m_bMarkWndOpen=bOpen;}
+ OUString GetCurrentURL() const;
+
+public:
+ SvxHyperlinkDocTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkDocTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetMarkStr ( const OUString& aStrMark ) override;
+
+ virtual void SetInitFocus() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLDOCTP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlinettp.hxx b/cui/source/inc/hlinettp.hxx
new file mode 100644
index 000000000..115e1e428
--- /dev/null
+++ b/cui/source/inc/hlinettp.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_CUI_SOURCE_INC_HLINETTP_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLINETTP_HXX
+
+#include "cuihyperdlg.hxx"
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Internet
+|*
+\************************************************************************/
+
+class SvxHyperlinkInternetTp : public SvxHyperlinkTabPageBase
+{
+private:
+ OUString maStrOldUser;
+ OUString maStrOldPassword;
+
+ bool m_bMarkWndOpen;
+
+ std::unique_ptr<weld::RadioButton> m_xRbtLinktypInternet;
+ std::unique_ptr<weld::RadioButton> m_xRbtLinktypFTP;
+ std::unique_ptr<SvxHyperURLBox> m_xCbbTarget;
+ std::unique_ptr<weld::Label> m_xFtTarget;
+ std::unique_ptr<weld::Label> m_xFtLogin;
+ std::unique_ptr<weld::Entry> m_xEdLogin;
+ std::unique_ptr<weld::Label> m_xFtPassword;
+ std::unique_ptr<weld::Entry> m_xEdPassword;
+ std::unique_ptr<weld::CheckButton> m_xCbAnonymous;
+
+ DECL_LINK( Click_SmartProtocol_Impl, weld::Button&, void ); ///< Radiobutton clicked: Type HTTP or FTP
+ DECL_LINK( ClickAnonymousHdl_Impl, weld::Button&, void ); ///< Checkbox : Anonymous User
+ DECL_LINK( ModifiedLoginHdl_Impl, weld::Entry&, void ); ///< Contents of editfield "Login" modified
+ DECL_LINK( LostFocusTargetHdl_Impl, weld::Widget&, void ); ///< Combobox "Target" lost its focus
+ DECL_LINK( ModifiedTargetHdl_Impl, weld::ComboBox&, void ); ///< Contents of editfield "Target" modified
+
+ DECL_LINK( TimeoutHdl_Impl, Timer *, void); ///< Handler for timer -timeout
+
+
+ void SetScheme(const OUString& rScheme);
+ void RemoveImproperProtocol(const OUString& rProperScheme);
+ OUString GetSchemeFromButtons() const;
+ INetProtocol GetSmartProtocolFromButtons() const;
+
+ OUString CreateAbsoluteURL() const;
+
+ void setAnonymousFTPUser();
+ void setFTPUser(const OUString& rUser, const OUString& rPassword);
+ void RefreshMarkWindow();
+
+protected:
+ virtual void FillDlgFields(const OUString& rStrURL) override;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+ virtual bool ShouldOpenMarkWnd () override {return ( m_bMarkWndOpen && m_xRbtLinktypInternet->get_active() );}
+ virtual void SetMarkWndShouldOpen (bool bOpen) override {m_bMarkWndOpen=bOpen;}
+
+public:
+ SvxHyperlinkInternetTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkInternetTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetMarkStr ( const OUString& aStrMark ) override;
+
+ virtual void SetInitFocus() override;
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLINETTP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmailtp.hxx b/cui/source/inc/hlmailtp.hxx
new file mode 100644
index 000000000..c137a3cf1
--- /dev/null
+++ b/cui/source/inc/hlmailtp.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_HLMAILTP_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLMAILTP_HXX
+
+#include "hltpbase.hxx"
+
+/*************************************************************************
+|*
+|* Tabpage : Hyperlink - Mail
+|*
+\************************************************************************/
+
+class SvxHyperlinkMailTp : public SvxHyperlinkTabPageBase
+{
+private:
+ std::unique_ptr<SvxHyperURLBox> m_xCbbReceiver;
+ std::unique_ptr<weld::Button> m_xBtAdrBook;
+ std::unique_ptr<weld::Label> m_xFtSubject;
+ std::unique_ptr<weld::Entry> m_xEdSubject;
+
+ DECL_STATIC_LINK(SvxHyperlinkMailTp, ClickAdrBookHdl_Impl, weld::Button&, void);
+ ///< Button : Address book
+ DECL_LINK (ModifiedReceiverHdl_Impl, weld::ComboBox&, void ); ///< Combobox "receiver" modified
+
+ void SetScheme(const OUString& rScheme);
+ void RemoveImproperProtocol(const OUString& aProperScheme);
+
+ OUString CreateAbsoluteURL() const;
+
+protected:
+ virtual void FillDlgFields(const OUString& rStrURL) override;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) override;
+
+public:
+ SvxHyperlinkMailTp(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+ virtual ~SvxHyperlinkMailTp() override;
+
+ static std::unique_ptr<IconChoicePage> Create(weld::Container* pWindow, SvxHpLinkDlg* pDlg, const SfxItemSet* pItemSet);
+
+ virtual void SetInitFocus() override;
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLMAILTP_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmarkwn.hxx b/cui/source/inc/hlmarkwn.hxx
new file mode 100644
index 000000000..9dd566a74
--- /dev/null
+++ b/cui/source/inc/hlmarkwn.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_CUI_SOURCE_INC_HLMARKWN_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLMARKWN_HXX
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <vcl/weld.hxx>
+
+class SvxHyperlinkTabPageBase;
+
+//# #
+//# Window-Class #
+//# #
+class SvxHlinkDlgMarkWnd : public weld::GenericDialogController
+{
+private:
+ friend class SvxHlmarkTreeLBox;
+
+ SvxHyperlinkTabPageBase* mpParent;
+
+ sal_uInt16 mnError;
+
+ std::unique_ptr<weld::Button> mxBtApply;
+ std::unique_ptr<weld::Button> mxBtClose;
+ std::unique_ptr<weld::TreeView> mxLbTree;
+ std::unique_ptr<weld::Label> mxError;
+
+ void ErrorChanged();
+
+protected:
+ bool RefreshFromDoc( const OUString& aURL );
+ void RestoreLastSelection();
+
+ std::unique_ptr<weld::TreeIter> FindEntry(const OUString& aStrName);
+ void ClearTree();
+ int FillTree( const css::uno::Reference< css::container::XNameAccess >& xLinks, const weld::TreeIter* pParentEntry =nullptr );
+
+ DECL_LINK( ClickApplyHdl_Impl, weld::Button&, void );
+ DECL_LINK( DoubleClickApplyHdl_Impl, weld::TreeView&, bool );
+ DECL_LINK( ClickCloseHdl_Impl, weld::Button&, void );
+
+public:
+ SvxHlinkDlgMarkWnd(weld::Window* pParentDialog, SvxHyperlinkTabPageBase *pParentPage);
+ virtual ~SvxHlinkDlgMarkWnd() override;
+
+ void MoveTo(const Point& rNewPos);
+ void RefreshTree(const OUString& aStrURL);
+ bool SelectEntry(const OUString& aStrMark);
+
+ sal_uInt16 SetError( sal_uInt16 nError);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLMARKWN_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hlmarkwn_def.hxx b/cui/source/inc/hlmarkwn_def.hxx
new file mode 100644
index 000000000..6caa0c510
--- /dev/null
+++ b/cui/source/inc/hlmarkwn_def.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 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_HLMARKWN_DEF_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLMARKWN_DEF_HXX
+
+#define LERR_NOERROR 0
+#define LERR_NOENTRIES 1
+#define LERR_DOCNOTOPEN 2
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hltpbase.hxx b/cui/source/inc/hltpbase.hxx
new file mode 100644
index 000000000..0860fff0e
--- /dev/null
+++ b/cui/source/inc/hltpbase.hxx
@@ -0,0 +1,138 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_HLTPBASE_HXX
+#define INCLUDED_CUI_SOURCE_INC_HLTPBASE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/dispatch.hxx>
+#include <svtools/inettbc.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/waitobj.hxx>
+
+#include <com/sun/star/frame/XFrame.hpp>
+#include <svx/hlnkitem.hxx>
+
+#include "hlmarkwn.hxx"
+#include "iconcdlg.hxx"
+
+/// ComboBox-Control for URL's with History and Autocompletion
+class SvxHyperURLBox : public SvtURLBox, public DropTargetHelper
+{
+protected:
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ) override;
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ) override;
+
+public:
+ SvxHyperURLBox(std::unique_ptr<weld::ComboBox> xWidget);
+};
+
+/// Tabpage : Basisclass
+class SvxHyperlinkTabPageBase : public IconChoicePage
+{
+private:
+ std::unique_ptr<weld::ComboBox> mxCbbFrame;
+ std::unique_ptr<weld::ComboBox> mxLbForm;
+ std::unique_ptr<weld::Entry> mxEdIndication;
+ std::unique_ptr<weld::Entry> mxEdText;
+ std::unique_ptr<weld::Button> mxBtScript;
+ std::unique_ptr<weld::Label> mxFormLabel;
+ std::unique_ptr<weld::Label> mxFrameLabel;
+
+ bool mbIsCloseDisabled;
+
+ css::uno::Reference< css::frame::XFrame >
+ mxDocumentFrame;
+
+protected:
+ SvxHpLinkDlg* mpDialog;
+
+ bool mbStdControlsInit;
+
+ OUString maStrInitURL;
+
+ Timer maTimer;
+
+ TopLevelWindowLocker maBusy;
+
+ std::shared_ptr<SvxHlinkDlgMarkWnd> mxMarkWnd;
+
+ void InitStdControls ();
+ void FillStandardDlgFields ( const SvxHyperlinkItem* pHyperlinkItem );
+ virtual void FillDlgFields(const OUString& rStrURL) = 0;
+ virtual void GetCurentItemData ( OUString& rStrURL, OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode ) = 0;
+
+ void GetDataFromCommonFields( OUString& aStrName,
+ OUString& aStrIntName, OUString& aStrFrame,
+ SvxLinkInsertMode& eMode );
+
+ DECL_LINK (ClickScriptHdl_Impl, weld::Button&, void ); ///< Button : Script
+
+ static OUString GetSchemeFromURL( const OUString& rStrURL );
+
+ void DisableClose( bool _bDisable );
+
+public:
+ SvxHyperlinkTabPageBase (
+ weld::Container* pParent,
+ SvxHpLinkDlg* pDlg,
+ const OUString& rUIXMLDescription,
+ const OString& rID,
+ const SfxItemSet* pItemSet
+ );
+ virtual ~SvxHyperlinkTabPageBase () override;
+
+ void SetDocumentFrame(
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame )
+ {
+ mxDocumentFrame = rxDocumentFrame;
+ }
+
+ virtual bool AskApply ();
+ virtual void DoApply ();
+ virtual void SetInitFocus();
+ virtual void SetMarkStr ( const OUString& aStrMark );
+ virtual void Reset( const SfxItemSet& ) override;
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void ActivatePage( const SfxItemSet& rItemSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ bool IsMarkWndVisible() const { return static_cast<bool>(mxMarkWnd); }
+ void MoveToExtraWnd ( Point aNewPos );
+
+ virtual bool QueryClose() override;
+
+protected:
+ virtual bool ShouldOpenMarkWnd();
+ virtual void SetMarkWndShouldOpen(bool bOpen);
+
+ void ShowMarkWnd();
+ void HideMarkWnd();
+
+ SfxDispatcher* GetDispatcher() const;
+
+ HyperDialogEvent GetMacroEvents() const;
+ SvxMacroTableDtor* GetMacroTable();
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_HLTPBASE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/hyphen.hxx b/cui/source/inc/hyphen.hxx
new file mode 100644
index 000000000..fdf65cd4b
--- /dev/null
+++ b/cui/source/inc/hyphen.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_CUI_SOURCE_INC_HYPHEN_HXX
+#define INCLUDED_CUI_SOURCE_INC_HYPHEN_HXX
+
+#include <memory>
+
+#include <vcl/weld.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/linguistic2/XPossibleHyphens.hpp>
+
+class SvxSpellWrapper;
+
+class SvxHyphenWordDialog : public SfxDialogController
+{
+ OUString m_aLabel;
+ SvxSpellWrapper *const m_pHyphWrapper;
+ css::uno::Reference< css::linguistic2::XHyphenator > m_xHyphenator;
+ css::uno::Reference< css::linguistic2::XPossibleHyphens > m_xPossHyph;
+ OUString m_aEditWord; // aEditWord and aWordEdit.GetText() differ only by the character for the current selected hyphenation position
+ OUString m_aActWord; // actual word to be hyphenated
+ LanguageType m_nActLanguage; // and its language
+ sal_Int16 m_nMaxHyphenationPos; // right most valid hyphenation pos
+ sal_Int32 m_nOldPos;
+ sal_Int32 m_nHyphenationPositionsOffset;
+ int m_nWordEditWidth;
+ bool m_bBusy;
+
+ std::unique_ptr<weld::Entry> m_xWordEdit;
+ std::unique_ptr<weld::Button> m_xLeftBtn;
+ std::unique_ptr<weld::Button> m_xRightBtn;
+ std::unique_ptr<weld::Button> m_xOkBtn;
+ std::unique_ptr<weld::Button> m_xContBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+ std::unique_ptr<weld::Button> m_xHyphAll;
+ std::unique_ptr<weld::Button> m_xCloseBtn;
+
+ void EnableLRBtn_Impl();
+ OUString EraseUnusableHyphens_Impl();
+
+ void InitControls_Impl();
+ void ContinueHyph_Impl( sal_Int32 nInsPos = -1 ); // continue by default
+
+ void select_region(int nStart, int nEnd);
+
+ DECL_LINK(Left_Impl, weld::Button&, void);
+ DECL_LINK(Right_Impl, weld::Button&, void);
+ DECL_LINK(CutHdl_Impl, weld::Button&, void);
+ DECL_LINK(ContinueHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(HyphenateAllHdl_Impl, weld::Button&, void);
+ DECL_LINK(CancelHdl_Impl, weld::Button&, void);
+ DECL_LINK(GetFocusHdl_Impl, weld::Widget&, void);
+ DECL_LINK(CursorChangeHdl_Impl, weld::Entry&, void);
+
+public:
+ SvxHyphenWordDialog(const OUString &rWord, LanguageType nLang,
+ weld::Window* pParent,
+ css::uno::Reference<css::linguistic2::XHyphenator> const &xHyphen,
+ SvxSpellWrapper* pWrapper);
+ virtual ~SvxHyphenWordDialog() override;
+
+ void SetWindowTitle( LanguageType nLang );
+ bool SelLeft();
+ bool SelRight();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/iconcdlg.hxx b/cui/source/inc/iconcdlg.hxx
new file mode 100644
index 000000000..230c22be7
--- /dev/null
+++ b/cui/source/inc/iconcdlg.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_CUI_SOURCE_INC_ICONCDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_ICONCDLG_HXX
+
+#include <rtl/ustring.hxx>
+#include <sfx2/tabdlg.hxx>
+
+// forward-declarations
+struct IconChoicePageData;
+class SvxHpLinkDlg;
+class IconChoicePage;
+class SfxItemPool;
+class SfxItemSet;
+
+// Create-Function
+typedef std::unique_ptr<IconChoicePage> (*CreatePage)(weld::Container* pParent, SvxHpLinkDlg* pDlg, const SfxItemSet* pAttrSet);
+
+/// Data-structure for pages in dialog
+struct IconChoicePageData
+{
+ OString sId;
+ std::unique_ptr<IconChoicePage> xPage; ///< the TabPage itself
+ bool bRefresh; ///< Flag: page has to be newly initialized
+
+ // constructor
+ IconChoicePageData(const OString& rId, std::unique_ptr<IconChoicePage> xInPage)
+ : sId(rId)
+ , xPage(std::move(xInPage))
+ , bRefresh(false)
+ {}
+};
+
+class IconChoicePage
+{
+protected:
+ std::unique_ptr<weld::Builder> xBuilder;
+ std::unique_ptr<weld::Container> xContainer;
+
+private:
+ const SfxItemSet* pSet;
+ bool bHasExchangeSupport;
+
+protected:
+
+ IconChoicePage(weld::Container* pParent, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet* pItemSet);
+
+public:
+ virtual ~IconChoicePage();
+
+ OString GetHelpId() const { return xContainer->get_help_id(); }
+
+ const SfxItemSet& GetItemSet() const { return *pSet; }
+
+ virtual bool FillItemSet( SfxItemSet* ) = 0;
+ virtual void Reset( const SfxItemSet& ) = 0;
+
+ bool HasExchangeSupport() const { return bHasExchangeSupport; }
+ void SetExchangeSupport() { bHasExchangeSupport = true; }
+
+ virtual void ActivatePage( const SfxItemSet& );
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet );
+ virtual bool QueryClose();
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_ICONCDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/insdlg.hxx b/cui/source/inc/insdlg.hxx
new file mode 100644
index 000000000..7c17022ed
--- /dev/null
+++ b/cui/source/inc/insdlg.hxx
@@ -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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_INSDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_INSDLG_HXX
+
+#include <com/sun/star/uno/Reference.h>
+#include <com/sun/star/embed/XEmbeddedObject.hpp>
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <svtools/insdlg.hxx>
+#include <vcl/weld.hxx>
+#include <comphelper/embeddedobjectcontainer.hxx>
+
+class INetURLObject;
+
+class InsertObjectDialog_Impl : public weld::GenericDialogController
+{
+protected:
+ css::uno::Reference < css::embed::XEmbeddedObject > m_xObj;
+ const css::uno::Reference < css::embed::XStorage > m_xStorage;
+ comphelper::EmbeddedObjectContainer aCnt;
+
+ InsertObjectDialog_Impl(weld::Window * pParent,
+ const OUString& rUIXMLDescription, const OString& rID,
+ const css::uno::Reference < css::embed::XStorage >& xStorage);
+public:
+ const css::uno::Reference<css::embed::XEmbeddedObject>& GetObject() const { return m_xObj; }
+ virtual css::uno::Reference<css::io::XInputStream> GetIconIfIconified(OUString* pGraphicMediaType);
+ void SetHelpId(const OString& rHelpId) { m_xDialog->set_help_id(rHelpId); }
+ virtual bool IsCreateNew() const;
+};
+
+class SvInsertOleDlg : public InsertObjectDialog_Impl
+{
+ const SvObjectServerList* m_pServers;
+
+ css::uno::Sequence< sal_Int8 > m_aIconMetaFile;
+ OUString m_aIconMediaType;
+
+ std::unique_ptr<weld::RadioButton> m_xRbNewObject;
+ std::unique_ptr<weld::RadioButton> m_xRbObjectFromfile;
+ std::unique_ptr<weld::Frame> m_xObjectTypeFrame;
+ std::unique_ptr<weld::TreeView> m_xLbObjecttype;
+ std::unique_ptr<weld::Frame> m_xFileFrame;
+ std::unique_ptr<weld::Entry> m_xEdFilepath;
+ std::unique_ptr<weld::Button> m_xBtnFilepath;
+ std::unique_ptr<weld::CheckButton> m_xCbFilelink;
+ std::unique_ptr<weld::CheckButton> m_xCbAsIcon;
+
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+ DECL_LINK(BrowseHdl, weld::Button&, void);
+ DECL_LINK(RadioHdl, weld::Button&, void);
+ bool IsCreateNew() const override { return m_xRbNewObject->get_active(); }
+
+public:
+ SvInsertOleDlg(weld::Window* pParent,
+ const css::uno::Reference < css::embed::XStorage >& xStorage,
+ const SvObjectServerList* pServers );
+ virtual short run() override;
+
+ /// get replacement for the iconified embedded object and the mediatype of the replacement
+ css::uno::Reference< css::io::XInputStream > GetIconIfIconified( OUString* pGraphicMediaType ) override;
+};
+
+class SfxInsertFloatingFrameDialog : public InsertObjectDialog_Impl
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEDName;
+ std::unique_ptr<weld::Entry> m_xEDURL;
+ std::unique_ptr<weld::Button> m_xBTOpen;
+
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingOn;
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingOff;
+ std::unique_ptr<weld::RadioButton> m_xRBScrollingAuto;
+
+ std::unique_ptr<weld::RadioButton> m_xRBFrameBorderOn;
+ std::unique_ptr<weld::RadioButton> m_xRBFrameBorderOff;
+
+ std::unique_ptr<weld::Label> m_xFTMarginWidth;
+ std::unique_ptr<weld::SpinButton> m_xNMMarginWidth;
+ std::unique_ptr<weld::CheckButton> m_xCBMarginWidthDefault;
+ std::unique_ptr<weld::Label> m_xFTMarginHeight;
+ std::unique_ptr<weld::SpinButton> m_xNMMarginHeight;
+ std::unique_ptr<weld::CheckButton> m_xCBMarginHeightDefault;
+
+ DECL_LINK(OpenHdl, weld::Button&, void);
+ DECL_LINK(CheckHdl, weld::Button&, void);
+
+ void Init();
+
+public:
+ SfxInsertFloatingFrameDialog(weld::Window *pParent,
+ const css::uno::Reference<css::embed::XStorage>& xStorage);
+ SfxInsertFloatingFrameDialog(weld::Window* pParent,
+ const css::uno::Reference<css::embed::XEmbeddedObject>& xObj);
+ virtual short run() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_INSDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/insrc.hxx b/cui/source/inc/insrc.hxx
new file mode 100644
index 000000000..ea6428eb3
--- /dev/null
+++ b/cui/source/inc/insrc.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_CUI_SOURCE_INC_INSRC_HXX
+#define INCLUDED_CUI_SOURCE_INC_INSRC_HXX
+
+#include <rtl/string.hxx>
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxInsRowColDlg : public SvxAbstractInsRowColDlg, public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xCountEdit;
+ std::unique_ptr<weld::RadioButton> m_xBeforeBtn;
+ std::unique_ptr<weld::RadioButton> m_xAfterBtn;
+
+public:
+ SvxInsRowColDlg(weld::Window* pParent, bool bCol, const OString& rHelpId);
+
+ virtual short Execute() override;
+
+ virtual bool isInsertBefore() const override;
+ virtual sal_uInt16 getInsertCount() const override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/labdlg.hxx b/cui/source/inc/labdlg.hxx
new file mode 100644
index 000000000..d759df2e6
--- /dev/null
+++ b/cui/source/inc/labdlg.hxx
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_LABDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_LABDLG_HXX
+
+#include <svtools/valueset.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/sxctitm.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/anchorid.hxx>
+#include <vcl/image.hxx>
+
+class SdrView;
+
+// class SvxCaptionTabPage -----------------------------------------------
+
+const sal_uInt16 CAPTYPE_BITMAPS_COUNT = 3;
+
+class SvxCaptionTabPage : public SfxTabPage
+{
+private:
+ static const sal_uInt16 pCaptionRanges[];
+
+ Image m_aBmpCapTypes[CAPTYPE_BITMAPS_COUNT];
+
+ std::vector<OUString> m_aStrHorzList;
+ std::vector<OUString> m_aStrVertList;
+
+ SdrCaptionType nCaptionType;
+ sal_Int32 nGap;
+ SdrCaptionEscDir nEscDir;
+ bool bEscRel;
+ sal_Int32 nEscAbs;
+ sal_Int32 nEscRel;
+ sal_Int32 nLineLen;
+ bool bFitLineLen;
+
+ sal_uInt16 nPosition;
+ sal_uInt16 nExtension;
+
+ const SfxItemSet& rOutAttrs;
+ const SdrView* pView;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_SPACING;
+ std::unique_ptr<weld::ComboBox> m_xLB_EXTENSION;
+ std::unique_ptr<weld::Label> m_xFT_BYFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_BY;
+ std::unique_ptr<weld::Label> m_xFT_POSITIONFT;
+ std::unique_ptr<weld::ComboBox> m_xLB_POSITION;
+ std::unique_ptr<weld::ComboBox> m_xLineTypes;
+ std::unique_ptr<weld::Label> m_xFT_LENGTHFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xMF_LENGTH;
+ std::unique_ptr<weld::CheckButton> m_xCB_OPTIMAL;
+ std::unique_ptr<ValueSet> m_xCT_CAPTTYPE;
+ std::unique_ptr<weld::CustomWeld> m_xCT_CAPTTYPEWin;
+
+ void SetupExtension_Impl( sal_uInt16 nType );
+ void SetupType_Impl( SdrCaptionType nType );
+ DECL_LINK(ExtensionSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PositionSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LineOptHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(SelectCaptTypeHdl_Impl, ValueSet*, void);
+
+public:
+ SvxCaptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxCaptionTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pCaptionRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+ void Construct();
+ void SetView( const SdrView* pSdrView )
+ { pView = pSdrView; }
+
+ void FillValueSet();
+};
+
+// class SvxCaptionTabDialog ---------------------------------------------
+struct SvxSwFrameValidation;
+class SvxCaptionTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+ SvxAnchorIds nAnchorCtrls;
+
+ Link<SvxSwFrameValidation&,void> aValidateLink;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxCaptionTabDialog(weld::Window* pParent, const SdrView* pView,
+ SvxAnchorIds nAnchorTypes);
+
+ /// link for the Writer to validate positions
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink );
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_LABDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/linkdlg.hxx b/cui/source/inc/linkdlg.hxx
new file mode 100644
index 000000000..90d51aba8
--- /dev/null
+++ b/cui/source/inc/linkdlg.hxx
@@ -0,0 +1,85 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_LINKDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_LINKDLG_HXX
+
+#include <vcl/idle.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+
+/********************** SvUpdateLinksDialog ******************************
+*************************************************************************/
+namespace sfx2
+{
+ class LinkManager;
+ class SvBaseLink;
+}
+
+enum class SfxLinkUpdateMode;
+
+class SvBaseLinksDlg : public weld::GenericDialogController
+{
+ OUString aStrAutolink;
+ OUString aStrManuallink;
+ OUString aStrBrokenlink;
+ OUString aStrCloselinkmsg;
+ OUString aStrCloselinkmsgMulti;
+ OUString aStrWaitinglink;
+ sfx2::LinkManager* pLinkMgr;
+ Idle aUpdateIdle;
+
+ std::unique_ptr<weld::TreeView> m_xTbLinks;
+ std::unique_ptr<weld::LinkButton> m_xFtFullFileName;
+ std::unique_ptr<weld::Label> m_xFtFullSourceName;
+ std::unique_ptr<weld::Label> m_xFtFullTypeName;
+ std::unique_ptr<weld::RadioButton> m_xRbAutomatic;
+ std::unique_ptr<weld::RadioButton> m_xRbManual;
+ std::unique_ptr<weld::Button> m_xPbUpdateNow;
+ std::unique_ptr<weld::Button> m_xPbChangeSource;
+ std::unique_ptr<weld::Button> m_xPbBreakLink;
+
+ ScopedVclPtr<VirtualDevice> m_xVirDev;
+
+ DECL_LINK( LinksSelectHdl, weld::TreeView&, void );
+ DECL_LINK( LinksDoubleClickHdl, weld::TreeView&, bool );
+ DECL_LINK( AutomaticClickHdl, weld::Button&, void );
+ DECL_LINK( ManualClickHdl, weld::Button&, void );
+ DECL_LINK( UpdateNowClickHdl, weld::Button&, void);
+ DECL_LINK( ChangeSourceClickHdl, weld::Button&, void );
+ DECL_LINK( BreakLinkClickHdl, weld::Button&, void );
+ DECL_LINK( UpdateWaitingHdl, Timer *, void );
+ DECL_LINK( EndEditHdl, sfx2::SvBaseLink&, void );
+ void LinksSelectHdl(weld::TreeView* pTreeView);
+ sfx2::SvBaseLink* GetSelEntry(int* pPos);
+ OUString ImplGetStateStr( const sfx2::SvBaseLink& );
+ void SetType(sfx2::SvBaseLink& rLink, int nPos, SfxLinkUpdateMode nType);
+ void InsertEntry(const sfx2::SvBaseLink& rLink, int nPos = -1, bool bSelect = false);
+
+ void SetManager( sfx2::LinkManager* );
+
+public:
+ SvBaseLinksDlg(weld::Window * pParent, sfx2::LinkManager*, bool bHtml);
+ virtual ~SvBaseLinksDlg() override;
+ void SetActLink( sfx2::SvBaseLink const * pLink );
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_LINKDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/macroass.hxx b/cui/source/inc/macroass.hxx
new file mode 100644
index 000000000..d4403686c
--- /dev/null
+++ b/cui/source/inc/macroass.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_CUI_SOURCE_INC_MACROASS_HXX
+#define INCLUDED_CUI_SOURCE_INC_MACROASS_HXX
+
+#include <sal/config.h>
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svl/macitem.hxx>
+#include <vcl/weld.hxx>
+#include <com/sun/star/frame/XFrame.hpp>
+#include <memory>
+
+class SfxMacroTabPage_;
+class SfxMacroTabPage_Impl;
+
+class SfxMacroTabPage final : public SfxTabPage
+{
+ SvxMacroTableDtor aTbl;
+ DECL_LINK(SelectEvent_Impl, weld::TreeView&, void);
+ DECL_LINK(SelectGroup_Impl, weld::TreeView&, void);
+ DECL_LINK(SelectMacro_Impl, weld::TreeView&, void);
+
+ DECL_LINK(AssignDeleteHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(AssignDeleteClickHdl_Impl, weld::Button&, void);
+ void AssignDeleteHdl(const weld::Widget*);
+ DECL_LINK( TimeOut_Impl, Timer*, void );
+
+ std::unique_ptr<SfxMacroTabPage_Impl> mpImpl;
+
+ void InitAndSetHandler();
+ void FillEvents();
+ void EnableButtons();
+
+public:
+ SfxMacroTabPage(
+ weld::Container* pPage, weld::DialogController* pController,
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame,
+ const SfxItemSet& rSet
+ );
+
+ virtual ~SfxMacroTabPage() override;
+
+ void AddEvent( const OUString & rEventName, SvMacroItemId nEventId );
+
+ void ScriptChanged();
+ virtual void PageCreated (const SfxAllItemSet& aSet) override;
+ virtual void ActivatePage( const SfxItemSet& ) override;
+ void LaunchFillGroup();
+
+ // --------- inherit from the base -------------
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ bool IsReadOnly() const override;
+
+ // --------- inherit from the base -------------
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+};
+
+class SfxMacroAssignDlg : public SfxSingleTabDialogController
+{
+public:
+ SfxMacroAssignDlg(weld::Widget* pParent,
+ const css::uno::Reference< css::frame::XFrame >& rxDocumentFrame,
+ const SfxItemSet& rSet);
+ SfxMacroTabPage* GetTabPage()
+ {
+ return static_cast<SfxMacroTabPage*>(m_xSfxPage.get());
+ }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/macropg.hxx b/cui/source/inc/macropg.hxx
new file mode 100644
index 000000000..5017aeeab
--- /dev/null
+++ b/cui/source/inc/macropg.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_MACROPG_HXX
+#define INCLUDED_CUI_SOURCE_INC_MACROPG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <sfx2/tabdlg.hxx>
+
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/util/XModifiable.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <rtl/ustring.hxx>
+
+#include <unordered_map>
+#include <vector>
+
+typedef std::unordered_map< OUString, std::pair< OUString, OUString > > EventsHash;
+
+struct EventDisplayName
+{
+ const char* pAsciiEventName;
+ const char* pEventResourceID;
+ EventDisplayName(const char* pAsciiName, const char* pResId)
+ : pAsciiEventName(pAsciiName)
+ , pEventResourceID(pResId)
+ {
+ }
+};
+typedef std::vector< EventDisplayName > EventDisplayNames;
+
+class SvxMacroTabPage_;
+class SvTabListBox;
+
+class SvxMacroTabPage_Impl;
+
+
+class SvxMacroTabPage_ : public SfxTabPage
+{
+ DECL_LINK( SelectEvent_Impl, weld::TreeView&, void );
+ DECL_LINK( AssignDeleteHdl_Impl, weld::Button&, void );
+ DECL_LINK( DoubleClickHdl_Impl, weld::TreeView&, bool );
+
+ static void GenericHandler_Impl( SvxMacroTabPage_* pThis, const weld::Button* pBtn );
+
+ css::uno::Reference< css::container::XNameReplace > m_xAppEvents;
+protected:
+ std::unique_ptr<SvxMacroTabPage_Impl> mpImpl;
+ css::uno::Reference< css::container::XNameReplace > m_xDocEvents;
+ css::uno::Reference< css::util::XModifiable > m_xModifiable;
+ EventsHash m_appEventsHash;
+ EventsHash m_docEventsHash;
+ bool bDocModified, bAppEvents, bInitialized;
+ EventDisplayNames aDisplayNames;
+
+ SvxMacroTabPage_(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rItemSet);
+
+ void EnableButtons();
+ static css::uno::Any GetPropsByName( const OUString& eventName, EventsHash& eventsHash );
+ static std::pair< OUString, OUString > GetPairFromAny( const css::uno::Any& aAny );
+
+public:
+
+ virtual ~SvxMacroTabPage_() override;
+ void InitResources();
+
+ void InitAndSetHandler( const css::uno::Reference< css::container::XNameReplace >& xAppEvents, const css::uno::Reference< css::container::XNameReplace >& xDocEvents, const css::uno::Reference< css::util::XModifiable >& xModifiable );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+ virtual void Reset( const SfxItemSet* ) override;
+
+ void DisplayAppEvents( bool appEvents);
+ void SetReadOnly( bool bSet );
+ bool IsReadOnly() const override;
+};
+
+class SvxMacroTabPage : public SvxMacroTabPage_
+{
+public:
+ SvxMacroTabPage(
+ weld::Container* pPage, weld::DialogController* pController,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ css::uno::Reference< css::container::XNameReplace > const & xNameReplace,
+ sal_uInt16 nSelectedIndex
+ );
+};
+
+// class SvxMacroAssignDlg --------------------------------------------------
+
+typedef const sal_uInt16* (*GetTabPageRanges)(); // gives international Which-values
+
+class SvxMacroAssignSingleTabDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxMacroAssignSingleTabDialog(weld::Window* pParent, const SfxItemSet& rOptionsSet);
+
+private:
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+};
+
+class SvxMacroAssignDlg : public SvxMacroAssignSingleTabDialog
+{
+public:
+ SvxMacroAssignDlg(
+ weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& _rxDocumentFrame,
+ const SfxItemSet& rSet,
+ const css::uno::Reference< css::container::XNameReplace >& xNameReplace,
+ sal_uInt16 nSelectedIndex
+ );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/measure.hxx b/cui/source/inc/measure.hxx
new file mode 100644
index 000000000..7915fcc38
--- /dev/null
+++ b/cui/source/inc/measure.hxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_MEASURE_HXX
+#define INCLUDED_CUI_SOURCE_INC_MEASURE_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/measctrl.hxx>
+
+class SdrView;
+
+/// Dialog for changing TextAttributes
+class SvxMeasurePage : public SvxTabPage
+{
+private:
+ static const sal_uInt16 pRanges[];
+
+ const SfxItemSet& rOutAttrs;
+ SfxItemSet aAttrSet;
+ const SdrView* pView;
+ MapUnit eUnit;
+
+ bool bPositionModified;
+
+ SvxRectCtl m_aCtlPosition;
+ SvxXMeasurePreview m_aCtlPreview;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelplineOverhang;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelplineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelpline1Len;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldHelpline2Len;
+ std::unique_ptr<weld::CheckButton> m_xTsbBelowRefEdge;
+ std::unique_ptr<weld::SpinButton> m_xMtrFldDecimalPlaces;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoPosV;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoPosH;
+ std::unique_ptr<weld::CheckButton> m_xTsbShowUnit;
+ std::unique_ptr<weld::ComboBox> m_xLbUnit;
+ std::unique_ptr<weld::CheckButton> m_xTsbParallel;
+ std::unique_ptr<weld::Label> m_xFtAutomatic;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPreview;
+
+ void FillUnitLB();
+
+ DECL_LINK(ClickAutoPosHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(ChangeAttrSpinHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ChangeAttrClickHdl_Impl, weld::ToggleButton&, void);
+ void ChangeAttrHdl_Impl(void const *);
+
+public:
+
+ SvxMeasurePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxMeasurePage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+
+};
+
+/* Derived from SfxSingleTabDialogController, in order to be able to be
+ informed about virtual methods by the control. */
+class SvxMeasureDialog : public SfxSingleTabDialogController
+{
+public:
+ SvxMeasureDialog(weld::Window* pParent, const SfxItemSet& rAttr,
+ const SdrView* pView);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_MEASURE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/multipat.hxx b/cui/source/inc/multipat.hxx
new file mode 100644
index 000000000..67832c1e8
--- /dev/null
+++ b/cui/source/inc/multipat.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_CUI_SOURCE_INC_MULTIPAT_HXX
+#define INCLUDED_CUI_SOURCE_INC_MULTIPAT_HXX
+
+#include <vcl/weld.hxx>
+
+// define ----------------------------------------------------------------
+
+// different delimiter for Unix (:) and Windows (;)
+
+#ifdef UNX
+#define CLASSPATH_DELIMITER ':'
+#else
+#define CLASSPATH_DELIMITER ';'
+#endif
+
+class SvxMultiPathDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xRadioLB;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ void AppendEntry(const OUString& rText, const OUString& rId);
+ void HandleEntryChecked(int nRow);
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ typedef std::pair<int, int> row_col;
+ DECL_LINK(CheckHdl_Impl, const row_col&, void);
+
+public:
+ SvxMultiPathDialog(weld::Window* pParent);
+ virtual ~SvxMultiPathDialog() override;
+
+ OUString GetPath() const;
+ void SetPath(const OUString& rPath);
+ void SetTitle(const OUString& rTitle) { m_xDialog->set_title(rTitle); }
+};
+
+class SvxPathSelectDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xPathLB;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+
+public:
+ SvxPathSelectDialog(weld::Window* pParent);
+
+ OUString GetPath() const;
+ void SetPath( const OUString& rPath );
+ void SetTitle(const OUString& rTitle) { m_xDialog->set_title(rTitle); }
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_MULTIPAT_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/newtabledlg.hxx b/cui/source/inc/newtabledlg.hxx
new file mode 100644
index 000000000..9ec717c70
--- /dev/null
+++ b/cui/source/inc/newtabledlg.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_CUI_SOURCE_INC_NEWTABLEDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_NEWTABLEDLG_HXX
+
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxNewTableDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> mxNumColumns;
+ std::unique_ptr<weld::SpinButton> mxNumRows;
+
+public:
+ SvxNewTableDialog(weld::Window* pParent);
+
+ virtual sal_Int32 getRows() const;
+ virtual sal_Int32 getColumns() const;
+};
+
+class SvxNewTableDialogWrapper : public SvxAbstractNewTableDialog
+{
+private:
+ std::shared_ptr<weld::DialogController> m_xDlg;
+
+public:
+ SvxNewTableDialogWrapper(weld::Window* pParent)
+ : m_xDlg(std::make_shared<SvxNewTableDialog>(pParent))
+ {
+ }
+
+ virtual std::shared_ptr<weld::DialogController> getDialogController() override
+ {
+ return m_xDlg;
+ }
+
+ virtual sal_Int32 getRows() const override
+ {
+ SvxNewTableDialog* pDlg = dynamic_cast<SvxNewTableDialog*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->getRows();
+
+ return 0;
+ }
+
+ virtual sal_Int32 getColumns() const override
+ {
+ SvxNewTableDialog* pDlg = dynamic_cast<SvxNewTableDialog*>(m_xDlg.get());
+ if (pDlg)
+ return pDlg->getColumns();
+
+ return 0;
+ }
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_NEWTABLEDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/numfmt.hxx b/cui/source/inc/numfmt.hxx
new file mode 100644
index 000000000..1be328d94
--- /dev/null
+++ b/cui/source/inc/numfmt.hxx
@@ -0,0 +1,157 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_NUMFMT_HXX
+#define INCLUDED_CUI_SOURCE_INC_NUMFMT_HXX
+
+
+#include <rtl/ustring.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+#include <tools/color.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+
+class SvxNumberFormatShell;
+class SvxNumberInfoItem;
+class vector;
+
+
+class SvxNumberPreview : public weld::CustomWidgetController
+{
+private:
+ OUString aPrevStr;
+ Color aPrevCol;
+ sal_Int32 mnPos;
+ sal_Unicode mnChar;
+
+protected:
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+
+public:
+ SvxNumberPreview();
+
+ void NotifyChange( const OUString& rPrevStr, const Color* pColor = nullptr );
+
+ virtual void SetDrawingArea(weld::DrawingArea* pDrawingArea) override
+ {
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ pDrawingArea->set_size_request(-1, pDrawingArea->get_text_height() * 3);
+ }
+};
+
+class SvxNumberFormatTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pRanges[];
+
+public:
+ SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+ virtual ~SvxNumberFormatTabPage() override;
+ // Returns area information.
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual DeactivateRC DeactivatePage ( SfxItemSet* pSet ) override;
+
+ void HideLanguage(bool bFlag=true);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+
+private:
+ std::unique_ptr<SvxNumberInfoItem> pNumItem;
+ std::unique_ptr<SvxNumberFormatShell> pNumFmtShell;
+ sal_uLong nInitFormat;
+ short m_nLbFormatSelPosEdComment;
+
+ bool bNumItemFlag; ///< for handling with DocShell
+ bool bOneAreaFlag;
+ bool bLegacyAutomaticCurrency;
+ short nFixedCategory;
+
+ OUString sAutomaticLangEntry;
+ OUString sAutomaticCurrencyEntry;
+
+ SvxNumberPreview m_aWndPreview;
+ std::unique_ptr<weld::Label> m_xFtCategory;
+ std::unique_ptr<weld::TreeView> m_xLbCategory;
+ std::unique_ptr<weld::Label> m_xFtFormat;
+ std::unique_ptr<weld::ComboBox> m_xLbCurrency;
+ std::unique_ptr<weld::TreeView> m_xLbFormat;
+ std::unique_ptr<weld::Label> m_xFtLanguage;
+ std::unique_ptr<weld::CheckButton> m_xCbSourceFormat;
+ std::unique_ptr<weld::Label> m_xFtOptions;
+ std::unique_ptr<weld::Label> m_xFtDecimals;
+ std::unique_ptr<weld::SpinButton> m_xEdDecimals;
+ std::unique_ptr<weld::Label> m_xFtDenominator;
+ std::unique_ptr<weld::SpinButton> m_xEdDenominator;
+ std::unique_ptr<weld::CheckButton> m_xBtnNegRed;
+ std::unique_ptr<weld::Label> m_xFtLeadZeroes;
+ std::unique_ptr<weld::SpinButton> m_xEdLeadZeroes;
+ std::unique_ptr<weld::CheckButton> m_xBtnThousand;
+ std::unique_ptr<weld::CheckButton> m_xBtnEngineering;
+ std::unique_ptr<weld::Widget> m_xFormatCodeFrame;
+ std::unique_ptr<weld::Entry> m_xEdFormat;
+ std::unique_ptr<weld::Button> m_xIbAdd;
+ std::unique_ptr<weld::Button> m_xIbInfo;
+ std::unique_ptr<weld::Button> m_xIbRemove;
+ std::unique_ptr<weld::Label> m_xFtComment;
+ std::unique_ptr<weld::Entry> m_xEdComment;
+ std::unique_ptr<SvxLanguageBox> m_xLbLanguage;
+ std::unique_ptr<weld::CustomWeld> m_xWndPreview;
+
+ void Init_Impl();
+ void FillCurrencyBox();
+ void FillFormatListBox_Impl( std::vector<OUString>& rEntries );
+ void UpdateOptions_Impl( bool bCheckCatChange );
+ void UpdateFormatListBox_Impl( bool bCat, bool bUpdateEdit );
+ void UpdateThousandEngineeringCheckBox();
+ void UpdateDecimalsDenominatorEditBox();
+ void Obstructing();
+ void EnableBySourceFormat_Impl();
+ void SetCategory( sal_uInt16 nPos );
+ OUString GetExpColorString( Color*& rpPreviewColor, const OUString& aFormatStr, short nTmpCatPos );
+ void MakePreviewText( const OUString& rFormat );
+ void ChangePreviewText( sal_uInt16 nPos );
+ void AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect);
+ bool Click_Impl(weld::Button& rIB);
+ // Handler
+ DECL_LINK(LostFocusHdl_Impl, weld::Widget&, void);
+ DECL_LINK(DoubleClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(SelFormatListBoxHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelFormatTreeListBoxHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(SelFormatClickHdl_Impl, weld::Button&, void);
+ void SelFormatHdl_Impl(weld::Widget*);
+ DECL_LINK(ClickHdl_Impl, weld::Button&, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(OptEditHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(OptClickHdl_Impl, weld::Button&, void);
+ void EditHdl_Impl(const weld::Entry*);
+ void OptHdl_Impl(const weld::Widget*);
+
+ // set and get currency, taking into account if the legacy
+ // automatic currency entry exists
+ void set_active_currency(sal_Int32 nCurCurrencyEntryPos);
+ sal_uInt32 get_active_currency() const;
+
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/numpages.hxx b/cui/source/inc/numpages.hxx
new file mode 100644
index 000000000..ebbe46625
--- /dev/null
+++ b/cui/source/inc/numpages.hxx
@@ -0,0 +1,388 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_NUMPAGES_HXX
+#define INCLUDED_CUI_SOURCE_INC_NUMPAGES_HXX
+
+#include <vector>
+#include <memory>
+
+#include <sfx2/tabdlg.hxx>
+#include <editeng/numdef.hxx>
+#include <editeng/svxenum.hxx>
+#include <svtools/ctrlbox.hxx>
+#include <vcl/customweld.hxx>
+#include <vcl/timer.hxx>
+#include <cui/numberingpreview.hxx>
+
+#define MN_GALLERY_ENTRY 100
+
+class ColorListBox;
+class SvxNumValueSet;
+class SvxNumRule;
+class SvxBmpNumValueSet;
+class SvxBrushItem;
+struct ImplSVEvent;
+
+struct SvxNumSettings_Impl
+{
+ SvxNumType nNumberType;
+ short nParentNumbering;
+ OUString sPrefix;
+ OUString sSuffix;
+ OUString sBulletChar;
+ OUString sBulletFont;
+ SvxNumSettings_Impl() :
+ nNumberType(SVX_NUM_CHARS_UPPER_LETTER),
+ nParentNumbering(0)
+ {}
+};
+
+typedef std::vector<std::unique_ptr<SvxNumSettings_Impl> > SvxNumSettingsArr_Impl;
+
+
+class SvxSingleNumPickTabPage final : public SfxTabPage
+{
+ SvxNumSettingsArr_Impl aNumSettingsArr;
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ bool bModified : 1;
+ bool bPreset : 1;
+
+ sal_uInt16 nNumItemId;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+
+public:
+ SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxSingleNumPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvxBulletPickTabPage final : public SfxTabPage
+{
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ bool bModified : 1;
+ bool bPreset : 1;
+ sal_uInt16 nNumItemId;
+
+ OUString sBulletCharFormatName;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+public:
+ SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBulletPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#define NUM_VALUSET_COUNT 16
+
+/// TabPage for complete numeration
+class SvxNumPickTabPage final : public SfxTabPage
+{
+ OUString sNumCharFmtName;
+ OUString sBulletCharFormatName;
+
+ SvxNumSettingsArr_Impl aNumSettingsArrays[NUM_VALUSET_COUNT]; // is initialized with the five formats
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ sal_uInt16 nNumItemId;
+ bool bModified : 1;
+ bool bPreset : 1;
+
+ std::unique_ptr<SvxNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+
+public:
+ SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void SetCharFormatNames(const OUString& rCharName, const OUString& rBulName)
+ { sNumCharFmtName = rCharName;
+ sBulletCharFormatName = rBulName;}
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+class SvxBitmapPickTabPage final : public SfxTabPage
+{
+ std::vector<OUString> aGrfNames;
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+ sal_uInt16 nActNumLvl;
+ sal_uInt16 nNumItemId;
+ MapUnit eCoreUnit;
+ bool bModified : 1;
+ bool bPreset : 1;
+
+ std::unique_ptr<weld::Label> m_xErrorText;
+ std::unique_ptr<weld::Button> m_xBtBrowseFile;
+ std::unique_ptr<SvxBmpNumValueSet> m_xExamplesVS;
+ std::unique_ptr<weld::CustomWeld> m_xExamplesVSWin;
+
+ DECL_LINK(NumSelectHdl_Impl, ValueSet*, void);
+ DECL_LINK(DoubleClickHdl_Impl, ValueSet*, void);
+ DECL_LINK(ClickAddBrowseHdl_Impl, weld::Button&, void);
+
+public:
+ SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBitmapPickTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvxNumOptionsTabPage : public SfxTabPage
+{
+ OUString m_sNumCharFmtName;
+ OUString m_sBulletCharFormatName;
+
+ Timer aInvalidateTimer;
+
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+
+ Size aInitSize[SVX_MAX_NUM];
+
+ ImplSVEvent* m_pLevelHdlEvent;
+
+ bool bLastWidthModified : 1;
+ bool bModified : 1;
+ bool bPreset : 1;
+ bool bAutomaticCharStyles: 1;
+ bool bHTMLMode : 1;
+
+ std::vector<OUString> aGrfNames;
+ vcl::Font aActBulletFont;
+
+ sal_uInt8 nBullet;
+ sal_uInt16 nActNumLvl;
+ sal_uInt16 nNumItemId;
+ MapUnit eCoreUnit;
+
+ SvxNumberingPreview m_aPreviewWIN;
+ std::unique_ptr<weld::Widget> m_xGrid;
+ std::unique_ptr<weld::TreeView> m_xLevelLB;
+ std::unique_ptr<weld::ComboBox> m_xFmtLB;
+ std::unique_ptr<weld::Label> m_xSeparatorFT;
+ std::unique_ptr<weld::Label> m_xPrefixFT;
+ std::unique_ptr<weld::Entry> m_xPrefixED;
+ std::unique_ptr<weld::Label> m_xSuffixFT;
+ std::unique_ptr<weld::Entry> m_xSuffixED;
+ std::unique_ptr<weld::Label> m_xCharFmtFT;
+ std::unique_ptr<weld::ComboBox> m_xCharFmtLB;
+ std::unique_ptr<weld::Label> m_xBulColorFT;
+ std::unique_ptr<ColorListBox> m_xBulColLB;
+ std::unique_ptr<weld::Label> m_xBulRelSizeFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xBulRelSizeMF;
+ std::unique_ptr<weld::Label> m_xAllLevelFT;
+ std::unique_ptr<weld::SpinButton> m_xAllLevelNF;
+ std::unique_ptr<weld::Label> m_xStartFT;
+ std::unique_ptr<weld::SpinButton> m_xStartED;
+ std::unique_ptr<weld::Label> m_xBulletFT;
+ std::unique_ptr<weld::Button> m_xBulletPB;
+ std::unique_ptr<weld::Label> m_xBitmapFT;
+ std::unique_ptr<weld::MenuButton> m_xBitmapMB;
+ std::unique_ptr<weld::Label> m_xWidthFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::Label> m_xHeightFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xRatioCB;
+ std::unique_ptr<weld::Label> m_xOrientFT;
+ std::unique_ptr<weld::ComboBox> m_xOrientLB;
+ std::unique_ptr<weld::Widget> m_xAllLevelsFrame;
+ std::unique_ptr<weld::Menu> m_xGalleryMenu;
+ std::unique_ptr<weld::CheckButton> m_xSameLevelCB;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ void InitControls();
+ /** To switch between the numbering type
+ 0 - Number;
+ 1 - Bullet;
+ 2 - Bitmap; */
+ void SwitchNumberType( sal_uInt8 nType );
+ void CheckForStartValue_Impl(sal_uInt16 nNumberingType);
+
+ DECL_LINK(NumberTypeSelectHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LevelHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(LevelHdl, void *, void);
+ DECL_LINK(PopupActivateHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(GraphicHdl_Impl, const OString&, void);
+ DECL_LINK(BulletHdl_Impl, weld::Button&, void);
+ DECL_LINK(SizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(RatioHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(CharFmtHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(SpinModifyHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(AllLevelHdl_Impl, weld::SpinButton&, void);
+ DECL_LINK(OrientHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SameLevelHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(BulColorHdl_Impl, ColorListBox&, void);
+ DECL_LINK(BulRelSizeHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(PreviewInvalidateHdl_Impl, Timer*, void);
+ void EditModifyHdl_Impl(const weld::Entry*);
+
+public:
+ SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void SetCharFmts(const OUString& rNumName, const OUString& rBulletName)
+ {
+ m_sNumCharFmtName = rNumName;
+ m_sBulletCharFormatName = rBulletName;
+ }
+ void SetMetric(FieldUnit eSet);
+
+ void SetModified(bool bRepaint = true);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+
+class SvxNumPositionTabPage : public SfxTabPage
+{
+ std::unique_ptr<SvxNumRule> pActNum;
+ std::unique_ptr<SvxNumRule> pSaveNum;
+
+ ImplSVEvent* m_pLevelHdlEvent;
+ sal_uInt16 nActNumLvl;
+ sal_uInt16 nNumItemId;
+ MapUnit eCoreUnit;
+
+ bool bModified : 1;
+ bool bPreset : 1;
+ bool bInInintControl : 1; // workaround for Modify-error, is said to be corrected from 391 on
+ bool bLabelAlignmentPosAndSpaceModeActive;
+
+ SvxNumberingPreview m_aPreviewWIN;
+ std::unique_ptr<weld::TreeView> m_xLevelLB;
+ // former set of controls shown for numbering rules containing list level
+ // attributes in SvxNumberFormat::SvxNumPositionAndSpaceMode == LABEL_WIDTH_AND_POSITION
+ std::unique_ptr<weld::Label> m_xDistBorderFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xDistBorderMF;
+ std::unique_ptr<weld::CheckButton> m_xRelativeCB;
+ std::unique_ptr<weld::Label> m_xIndentFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xIndentMF;
+ std::unique_ptr<weld::Label> m_xDistNumFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xDistNumMF;
+ std::unique_ptr<weld::Label> m_xAlignFT;
+ std::unique_ptr<weld::ComboBox> m_xAlignLB;
+ // new set of controls shown for numbering rules containing list level
+ // attributes in SvxNumberFormat::SvxNumPositionAndSpaceMode == LABEL_ALIGNMENT
+ std::unique_ptr<weld::Label> m_xLabelFollowedByFT;
+ std::unique_ptr<weld::ComboBox> m_xLabelFollowedByLB;
+ std::unique_ptr<weld::Label> m_xListtabFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xListtabMF;
+ std::unique_ptr<weld::Label>m_xAlign2FT;
+ std::unique_ptr<weld::ComboBox> m_xAlign2LB;
+ std::unique_ptr<weld::Label> m_xAlignedAtFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xAlignedAtMF;
+ std::unique_ptr<weld::Label> m_xIndentAtFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xIndentAtMF;
+ std::unique_ptr<weld::Button> m_xStandardPB;
+ std::unique_ptr<weld::CustomWeld> m_xPreviewWIN;
+
+ void InitControls();
+
+ DECL_LINK(LevelHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(LevelHdl, void *, void);
+ DECL_LINK(EditModifyHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(DistanceHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(RelativeHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+
+ void InitPosAndSpaceMode();
+ void ShowControlsDependingOnPosAndSpaceMode();
+
+ DECL_LINK(LabelFollowedByHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ListtabPosHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(AlignAtHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(IndentAtHdl_Impl, weld::MetricSpinButton&, void);
+
+public:
+ SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxNumPositionTabPage() override;
+
+ virtual void ActivatePage(const SfxItemSet& rSet) override;
+ virtual DeactivateRC DeactivatePage(SfxItemSet *pSet) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet);
+
+ void SetMetric(FieldUnit eSet);
+ void SetModified();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optasian.hxx b/cui/source/inc/optasian.hxx
new file mode 100644
index 000000000..d8febfb7b
--- /dev/null
+++ b/cui/source/inc/optasian.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_CUI_SOURCE_INC_OPTASIAN_HXX
+#define INCLUDED_CUI_SOURCE_INC_OPTASIAN_HXX
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+struct SvxAsianLayoutPage_Impl;
+class SvxAsianLayoutPage : public SfxTabPage
+{
+ std::unique_ptr<SvxAsianLayoutPage_Impl> pImpl;
+
+ std::unique_ptr<weld::RadioButton> m_xCharKerningRB;
+ std::unique_ptr<weld::RadioButton> m_xCharPunctKerningRB;
+ std::unique_ptr<weld::RadioButton> m_xNoCompressionRB;
+ std::unique_ptr<weld::RadioButton> m_xPunctCompressionRB;
+ std::unique_ptr<weld::RadioButton> m_xPunctKanaCompressionRB;
+ std::unique_ptr<weld::Label> m_xLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xStandardCB;
+ std::unique_ptr<weld::Label> m_xStartFT;
+ std::unique_ptr<weld::Entry> m_xStartED;
+ std::unique_ptr<weld::Label> m_xEndFT;
+ std::unique_ptr<weld::Entry> m_xEndED;
+ std::unique_ptr<weld::Label> m_xHintFT;
+
+ DECL_LINK(LanguageHdl, weld::ComboBox&, void);
+ DECL_LINK(ChangeStandardHdl, weld::ToggleButton&, void);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+
+public:
+ SvxAsianLayoutPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~SvxAsianLayoutPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ static const sal_uInt16* GetRanges();
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optdict.hxx b/cui/source/inc/optdict.hxx
new file mode 100644
index 000000000..7d8ffd522
--- /dev/null
+++ b/cui/source/inc/optdict.hxx
@@ -0,0 +1,112 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_OPTDICT_HXX
+#define INCLUDED_CUI_SOURCE_INC_OPTDICT_HXX
+
+#include <vcl/weld.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <svx/langbox.hxx>
+
+namespace com::sun::star{
+ namespace linguistic2{
+ class XDictionary;
+ class XSpellChecker1;
+ }
+}
+
+// forward ---------------------------------------------------------------
+
+
+// class SvxNewDictionaryDialog ------------------------------------------
+
+class SvxNewDictionaryDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xNameEdit;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xExceptBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ css::uno::Reference<css::linguistic2::XDictionary> m_xNewDic;
+
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+
+public:
+ SvxNewDictionaryDialog(weld::Window* pParent);
+
+ const css::uno::Reference<css::linguistic2::XDictionary>& GetNewDictionary() const { return m_xNewDic; }
+};
+
+// class SvxEditDictionaryDialog -----------------------------------------
+
+class SvxEditDictionaryDialog : public weld::GenericDialogController
+{
+private:
+ OUString sModify;
+ OUString sNew;
+ OUString sReplaceFT_Text;
+
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::linguistic2::XDictionary > > aDics; //! snapshot copy to work on
+
+ bool bFirstSelect;
+ bool bDoNothing;
+ bool bDicIsReadonly;
+
+ weld::TreeView* m_pWordsLB;
+ std::unique_ptr<weld::ComboBox> m_xAllDictsLB;
+ std::unique_ptr<weld::Label> m_xLangFT;
+ std::unique_ptr<SvxLanguageBox> m_xLangLB;
+ std::unique_ptr<weld::Entry> m_xWordED;
+ std::unique_ptr<weld::Label> m_xReplaceFT;
+ std::unique_ptr<weld::Entry> m_xReplaceED;
+ std::unique_ptr<weld::TreeView> m_xSingleColumnLB;
+ std::unique_ptr<weld::TreeView> m_xDoubleColumnLB;
+ std::unique_ptr<weld::Button> m_xNewReplacePB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+
+ DECL_LINK(SelectBookHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelectLangHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(NewDelButtonHdl, weld::Button&, void);
+ DECL_LINK(NewDelActionHdl, weld::Entry&, bool);
+ DECL_LINK(ModifyHdl, weld::Entry&, void);
+ DECL_LINK(EntrySizeAllocHdl, const Size&, void);
+ DECL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, bool);
+ bool NewDelHdl(const weld::Widget*);
+
+ void ShowWords_Impl( sal_uInt16 nId );
+ void SetLanguage_Impl( LanguageType nLanguage );
+ bool IsDicReadonly_Impl() const { return bDicIsReadonly; }
+ void SetDicReadonly_Impl( css::uno::Reference<
+ css::linguistic2::XDictionary > const &xDic );
+
+ void RemoveDictEntry(int nEntry);
+ int GetLBInsertPos(const OUString &rDicWord);
+
+public:
+ SvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName);
+ virtual ~SvxEditDictionaryDialog() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optlingu.hxx b/cui/source/inc/optlingu.hxx
new file mode 100644
index 000000000..cbaaaefdf
--- /dev/null
+++ b/cui/source/inc/optlingu.hxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_OPTLINGU_HXX
+#define INCLUDED_CUI_SOURCE_INC_OPTLINGU_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace com::sun::star{
+ namespace beans{
+ class XPropertySet;
+ }
+ namespace linguistic2{
+ class XDictionary;
+ class XDictionaryList;
+ class XLinguProperties;
+ }
+}
+
+class SvTreeListEntry;
+class SvxLinguData_Impl;
+
+// define ----------------------------------------------------------------
+
+#define GROUP_MODULES (sal_uInt16(0x0008))
+
+// forward ---------------------------------------------------------------
+
+class SvxEditModulesDlg : public weld::GenericDialogController
+{
+ OUString sSpell;
+ OUString sHyph;
+ OUString sThes;
+ OUString sGrammar;
+
+ std::unique_ptr<SvxLinguData_Impl> pDefaultLinguData;
+ SvxLinguData_Impl& rLinguData;
+
+ std::unique_ptr<weld::TreeView> m_xModulesCLB;
+ std::unique_ptr<weld::Button> m_xPrioUpPB;
+ std::unique_ptr<weld::Button> m_xPrioDownPB;
+ std::unique_ptr<weld::Button> m_xBackPB;
+ std::unique_ptr<weld::LinkButton> m_xMoreDictsLink;
+ std::unique_ptr<weld::Button> m_xClosePB;
+ std::unique_ptr<SvxLanguageBox> m_xLanguageLB;
+
+ DECL_LINK( SelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( UpDownHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickHdl_Impl, weld::Button&, void );
+ DECL_LINK( BackHdl_Impl, weld::Button&, void );
+ DECL_LINK( LangSelectListBoxHdl_Impl, weld::ComboBox&, void );
+ typedef std::pair<int, int> row_col;
+ DECL_LINK( BoxCheckButtonHdl_Impl, const row_col&, void );
+ void LangSelectHdl_Impl(const SvxLanguageBox* pBox);
+
+public:
+ SvxEditModulesDlg(weld::Window* pParent, SvxLinguData_Impl& rData);
+ virtual ~SvxEditModulesDlg() override;
+};
+
+struct ImplSVEvent;
+
+// class SvxLinguTabPage -------------------------------------------------
+class SvxLinguTabPage : public SfxTabPage
+{
+private:
+ OUString sCapitalWords;
+ OUString sWordsWithDigits;
+ OUString sSpellSpecial;
+ OUString sSpellAuto;
+ OUString sGrammarAuto;
+ OUString sNumMinWordlen;
+ OUString sNumPreBreak;
+ OUString sNumPostBreak;
+ OUString sHyphAuto;
+ OUString sHyphSpecial;
+
+ int nUPN_HYPH_MIN_WORD_LENGTH;
+ int nUPN_HYPH_MIN_LEADING;
+ int nUPN_HYPH_MIN_TRAILING;
+
+ ImplSVEvent* m_nDlbClickEventId;
+
+ css::uno::Reference<
+ css::linguistic2::XLinguProperties > xProp;
+
+ css::uno::Reference<
+ css::linguistic2::XDictionaryList > xDicList;
+ css::uno::Sequence<
+ css::uno::Reference<
+ css::linguistic2::XDictionary > > aDics;
+
+ std::unique_ptr<SvxLinguData_Impl> pLinguData;
+
+ std::unique_ptr<weld::Label> m_xLinguModulesFT;
+ std::unique_ptr<weld::TreeView> m_xLinguModulesCLB;
+ std::unique_ptr<weld::Button> m_xLinguModulesEditPB;
+ std::unique_ptr<weld::Label> m_xLinguDicsFT;
+ std::unique_ptr<weld::TreeView> m_xLinguDicsCLB;
+ std::unique_ptr<weld::Button> m_xLinguDicsNewPB;
+ std::unique_ptr<weld::Button> m_xLinguDicsEditPB;
+ std::unique_ptr<weld::Button> m_xLinguDicsDelPB;
+ std::unique_ptr<weld::TreeView> m_xLinguOptionsCLB;
+ std::unique_ptr<weld::Button> m_xLinguOptionsEditPB;
+ std::unique_ptr<weld::LinkButton> m_xMoreDictsLink;
+
+ void AddDicBoxEntry( const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx );
+ static sal_uInt32 GetDicUserData( const css::uno::Reference< css::linguistic2::XDictionary > &rxDic, sal_uInt16 nIdx );
+
+ DECL_LINK( SelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( ClickHdl_Impl, weld::Button&, void );
+ DECL_LINK( BoxDoubleClickHdl_Impl, weld::TreeView&, bool );
+ typedef std::pair<int, int> row_col;
+ DECL_LINK( ModulesBoxCheckButtonHdl_Impl, const row_col&, void );
+ DECL_LINK( DicsBoxCheckButtonHdl_Impl, const row_col&, void );
+ DECL_LINK( PostDblClickHdl_Impl, void *, void);
+
+ void UpdateModulesBox_Impl();
+ void UpdateDicBox_Impl();
+
+public:
+ SvxLinguTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxLinguTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void HideGroups( sal_uInt16 nGrp );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/optpath.hxx b/cui/source/inc/optpath.hxx
new file mode 100644
index 000000000..cc3d67b42
--- /dev/null
+++ b/cui/source/inc/optpath.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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_OPTPATH_HXX
+#define INCLUDED_CUI_SOURCE_INC_OPTPATH_HXX
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+
+// forward ---------------------------------------------------------------
+struct OptPath_Impl;
+class SvxPathTabPage;
+
+// class SvxPathTabPage --------------------------------------------------
+class SvxPathTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<OptPath_Impl> pImpl;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ std::unique_ptr<weld::Button> m_xStandardBtn;
+ std::unique_ptr<weld::Button> m_xPathBtn;
+ std::unique_ptr<weld::TreeView> m_xPathBox;
+
+ void ChangeCurrentEntry( const OUString& _rFolder );
+
+ DECL_LINK(PathHdl_Impl, weld::Button&, void);
+ DECL_LINK(DoubleClickPathHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(PathSelect_Impl, weld::TreeView&, void);
+
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+ void GetPathList( sal_uInt16 _nPathHandle, OUString& _rInternalPath,
+ OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly );
+ void SetPathList( sal_uInt16 _nPathHandle,
+ const OUString& _rUserPath, const OUString& _rWritablePath );
+
+public:
+ SvxPathTabPage( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxPathTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/page.hxx b/cui/source/inc/page.hxx
new file mode 100644
index 000000000..1019a9fbc
--- /dev/null
+++ b/cui/source/inc/page.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_PAGE_HXX
+#define INCLUDED_CUI_SOURCE_INC_PAGE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/pagectrl.hxx>
+#include <svx/pagenumberlistbox.hxx>
+#include <svx/papersizelistbox.hxx>
+#include <svx/frmdirlbox.hxx>
+#include <i18nutil/paper.hxx>
+#include <svx/flagsdef.hxx>
+
+// class SvxPageDescPage -------------------------------------------------
+/*
+ [Description]
+ TabPage for page settings (size, margins, ...)
+
+ [Items]
+ <SvxPageItem>: <SID_ATTR_PAGE>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxSizeItem>: <SID_ATTR_MAXSIZE>
+ <SvxULSpaceItem>: <SID_ATTR_LRSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_ULSPACE>
+ <SfxAllEnumItem>: <SID_ATTR_PAPERTRAY>
+ <SvxPaperBinItem>: <SID_ATTR_PAPERBIN>
+ <SvxBoolItem>: <SID_ATTR_EXT1>
+ <SvxBoolItem>: <SID_ATTR_EXT2>
+
+ <SfxSetItem>: <SID_ATTR_HEADERSET>
+ <SfxBoolItem>: <SID_ATTR_ON>
+ <SfxBoolItem>: <SID_ATTR_DYNAMIC>
+ <SfxBoolItem>: <SID_ATTR_SHARED>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxULSpaceItem>: <SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_LRSPACE>
+
+ <SfxSetItem>: <SID_ATTR_FOOTERSET>
+ <SfxBoolItem>: <SID_ATTR_ON>
+ <SfxBoolItem>: <SID_ATTR_DYNAMIC>
+ <SfxBoolItem>: <SID_ATTR_SHARED>
+ <SvxSizeItem>: <SID_ATTR_SIZE>
+ <SvxULSpaceItem>: <SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem>: <SID_ATTR_LRSPACE>
+*/
+
+typedef sal_uInt16 MarginPosition;
+
+class SvxPageDescPage : public SfxTabPage
+{
+ static const sal_uInt16 pRanges[];
+private:
+ OUString sStandardRegister;
+ long nFirstLeftMargin;
+ long nFirstRightMargin;
+ long nFirstTopMargin;
+ long nFirstBottomMargin;
+ long nLastLeftMargin;
+ long nLastRightMargin;
+ long nLastTopMargin;
+ long nLastBottomMargin;
+
+ bool bLandscape;
+ bool bBorderModified;
+ SvxModeType eMode;
+ Paper ePaperStart;
+
+ MarginPosition m_nPos;
+ VclPtr<Printer> mpDefPrinter;
+
+ bool mbDelPrinter : 1;
+ bool mbEnableDrawingLayerFillStyles : 1;
+
+ SvxPageWindow m_aBspWin;
+
+ // paper format
+ std::unique_ptr<SvxPaperSizeListBox> m_xPaperSizeBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xPaperWidthEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xPaperHeightEdit;
+ std::unique_ptr<weld::Label> m_xOrientationFT;
+ std::unique_ptr<weld::RadioButton> m_xPortraitBtn;
+ std::unique_ptr<weld::RadioButton> m_xLandscapeBtn;
+ std::unique_ptr<weld::Label> m_xTextFlowLbl;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xTextFlowBox;
+ std::unique_ptr<weld::ComboBox> m_xPaperTrayBox;
+ // Margins
+ std::unique_ptr<weld::Label> m_xLeftMarginLbl;
+ std::unique_ptr<weld::MetricSpinButton> m_xLeftMarginEdit;
+ std::unique_ptr<weld::Label> m_xRightMarginLbl;
+ std::unique_ptr<weld::MetricSpinButton> m_xRightMarginEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xTopMarginEdit;
+ std::unique_ptr<weld::MetricSpinButton> m_xBottomMarginEdit;
+ // layout settings
+ std::unique_ptr<weld::Label> m_xPageText;
+ std::unique_ptr<weld::ComboBox> m_xLayoutBox;
+ std::unique_ptr<weld::Label> m_xNumberFormatText;
+ std::unique_ptr<SvxPageNumberListBox> m_xNumberFormatBox;
+ //Extras Calc
+ std::unique_ptr<weld::Label> m_xTblAlignFT;
+ std::unique_ptr<weld::CheckButton> m_xHorzBox;
+ std::unique_ptr<weld::CheckButton> m_xVertBox;
+ // Impress and Draw
+ std::unique_ptr<weld::CheckButton> m_xAdaptBox;
+ //Register Writer
+ std::unique_ptr<weld::CheckButton> m_xRegisterCB;
+ std::unique_ptr<weld::Label> m_xRegisterFT;
+ std::unique_ptr<weld::ComboBox> m_xRegisterLB;
+ std::unique_ptr<weld::Label> m_xInsideLbl;
+ std::unique_ptr<weld::Label> m_xOutsideLbl;
+ std::unique_ptr<weld::Label> m_xPrintRangeQueryText;
+ std::unique_ptr<weld::CustomWeld> m_xBspWin;
+
+ void Init_Impl();
+ DECL_LINK(LayoutHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PaperBinHdl_Impl, weld::Widget&, void);
+ DECL_LINK(SwapOrientation_Impl, weld::Button&, void);
+ void SwapFirstValues_Impl( bool bSet );
+ DECL_LINK(BorderModify_Impl, weld::MetricSpinButton&, void);
+ void InitHeadFoot_Impl( const SfxItemSet& rSet );
+ DECL_LINK(CenterHdl_Impl, weld::ToggleButton&, void);
+ void UpdateExample_Impl( bool bResetbackground = false );
+
+ DECL_LINK(PaperSizeSelect_Impl, weld::ComboBox&, void );
+ DECL_LINK(PaperSizeModify_Impl, weld::MetricSpinButton&, void);
+
+ DECL_LINK(FrameDirectionModify_Impl, weld::ComboBox&, void );
+
+ void ResetBackground_Impl( const SfxItemSet& rSet );
+
+ void RangeHdl_Impl();
+ void CalcMargin_Impl();
+
+ DECL_LINK(RegisterModify, weld::ToggleButton&, void);
+
+ // page direction
+ /** Disables vertical page direction entries in the text flow listbox. */
+ void DisableVerticalPageDir();
+
+ bool IsPrinterRangeOverflow(weld::MetricSpinButton& rField, long nFirstMargin,
+ long nLastMargin, MarginPosition nPos);
+ void CheckMarginEdits( bool _bClear );
+ bool IsMarginOutOfRange() const;
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxPageDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxPageDescPage() override;
+
+ // returns the range of the Which values
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rOutSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+
+ void SetPaperFormatRanges( Paper eStart )
+ { ePaperStart = eStart; }
+
+ void SetCollectionList(const std::vector<OUString> &aList);
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_PAGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/paragrph.hxx b/cui/source/inc/paragrph.hxx
new file mode 100644
index 000000000..b57199d91
--- /dev/null
+++ b/cui/source/inc/paragrph.hxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_PARAGRPH_HXX
+#define INCLUDED_CUI_SOURCE_INC_PARAGRPH_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/relfld.hxx>
+#include <svx/paraprev.hxx>
+#include <svx/frmdirlbox.hxx>
+
+class SvxLineSpacingItem;
+
+// class SvxStdParagraphTabPage ------------------------------------------
+/*
+ [Description]
+ With this TabPage standard attributes of a paragraph can be set
+ (indention, distance, alignment, line spacing).
+
+ [Items]
+ <SvxAdjustItem><SID_ATTR_PARA_ADJUST>
+ <SvxLineSpacingItem><SID_ATTR_PARA_LINESPACE>
+ <SvxULSpaceItem><SID_ATTR_ULSPACE>
+ <SvxLRSpaceItem><SID_ATTR_LRSPACE>
+*/
+
+class SvxStdParagraphTabPage: public SfxTabPage
+{
+ static const sal_uInt16 pStdRanges[];
+
+private:
+ long nWidth;
+ long nMinFixDist;
+ bool bRelativeMode;
+ OUString sAbsDist;
+
+ SvxParaPrevWindow m_aExampleWin;
+
+ // indention
+ std::unique_ptr<SvxRelativeField> m_xLeftIndent;
+
+ std::unique_ptr<weld::Label> m_xRightLabel;
+ std::unique_ptr<SvxRelativeField> m_xRightIndent;
+
+ std::unique_ptr<weld::Label> m_xFLineLabel;
+ std::unique_ptr<SvxRelativeField> m_xFLineIndent;
+ std::unique_ptr<weld::CheckButton> m_xAutoCB;
+
+ // distance
+ std::unique_ptr<SvxRelativeField> m_xTopDist;
+ std::unique_ptr<SvxRelativeField> m_xBottomDist;
+ std::unique_ptr<weld::CheckButton> m_xContextualCB;
+
+ // line spacing
+ std::unique_ptr<weld::ComboBox> m_xLineDist;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineDistAtPercentBox;
+ std::unique_ptr<weld::MetricSpinButton> m_xLineDistAtMetricBox;
+ std::unique_ptr<weld::Label> m_xLineDistAtLabel;
+ std::unique_ptr<weld::Label> m_xAbsDist;
+
+ // only writer
+ std::unique_ptr<weld::Widget> m_xRegisterFL;
+ std::unique_ptr<weld::CheckButton> m_xRegisterCB;
+
+ // preview
+ std::unique_ptr<weld::CustomWeld> m_xExampleWin;
+
+ void SetLineSpacing_Impl( const SvxLineSpacingItem& rAttr );
+ void Init_Impl();
+ void UpdateExample_Impl();
+ void ELRLoseFocus();
+
+ DECL_LINK(LineDistPopupHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(LineDistHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ModifyHdl_Impl, weld::MetricSpinButton&, void);
+ DECL_LINK(AutoHdl_Impl, weld::ToggleButton&, void);
+
+ bool m_bLineDistToggled = false;
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+
+public:
+ SvxStdParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxStdParagraphTabPage() override;
+
+ DECL_LINK(ELRLoseFocusHdl, weld::MetricSpinButton&, void);
+
+ static const sal_uInt16* GetRanges() { return pStdRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void EnableRelativeMode();
+ void EnableRegisterMode();
+ void EnableContextualMode();
+ void EnableAutoFirstLine();
+ void EnableAbsLineDist(long nMinTwip);
+ void EnableNegativeMode();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxParaAlignTabPage ------------------------------------------------
+
+class SvxParaAlignTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pAlignRanges[];
+
+ SvxParaPrevWindow m_aExampleWin;
+
+ // alignment
+ std::unique_ptr<weld::RadioButton> m_xLeft;
+ std::unique_ptr<weld::RadioButton> m_xRight;
+ std::unique_ptr<weld::RadioButton> m_xCenter;
+ std::unique_ptr<weld::RadioButton> m_xJustify;
+ std::unique_ptr<weld::Label> m_xLeftBottom;
+ std::unique_ptr<weld::Label> m_xRightTop;
+
+ std::unique_ptr<weld::Label> m_xLastLineFT;
+ std::unique_ptr<weld::ComboBox> m_xLastLineLB;
+ std::unique_ptr<weld::CheckButton> m_xExpandCB;
+
+ std::unique_ptr<weld::CheckButton> m_xSnapToGridCB;
+
+ //preview
+ std::unique_ptr<weld::CustomWeld> m_xExampleWin;
+ //vertical alignment
+ std::unique_ptr<weld::Widget> m_xVertAlignFL;
+ std::unique_ptr<weld::ComboBox> m_xVertAlignLB;
+
+ std::unique_ptr<weld::Widget> m_xPropertiesFL;
+ std::unique_ptr<svx::FrameDirectionListBox> m_xTextDirectionLB;
+
+ DECL_LINK(AlignHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(LastLineHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(TextDirectionHdl_Impl, weld::ComboBox&, void);
+
+ void UpdateExample_Impl();
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxParaAlignTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxParaAlignTabPage() override;
+
+ static const sal_uInt16* GetRanges() { return pAlignRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void EnableJustifyExt();
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+// class SvxExtParagraphTabPage ------------------------------------------
+/*
+ [Description]
+ With this TabPage special attributes of a paragraph can be set
+ (hyphenation, pagebreak, orphan, widow, ...).
+
+ [Items]
+ <SvxHyphenZoneItem><SID_ATTR_PARA_HYPHENZONE>
+ <SvxFormatBreakItem><SID_ATTR_PARA_PAGEBREAK>
+ <SvxFormatSplitItem><SID_ATTR_PARA_SPLIT>
+ <SvxWidowsItem><SID_ATTR_PARA_WIDOWS>
+ <SvxOrphansItem><SID_ATTR_PARA_ORPHANS>
+*/
+
+class SvxExtParagraphTabPage: public SfxTabPage
+{
+ static const sal_uInt16 pExtRanges[];
+
+public:
+ SvxExtParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet );
+ virtual ~SvxExtParagraphTabPage() override;
+
+ static const sal_uInt16* GetRanges() { return pExtRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+
+ void DisablePageBreak();
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ weld::TriStateEnabled aHyphenState;
+ weld::TriStateEnabled aPageBreakState;
+ weld::TriStateEnabled aApplyCollState;
+ weld::TriStateEnabled aPageNumState;
+ weld::TriStateEnabled aKeepTogetherState;
+ weld::TriStateEnabled aKeepParaState;
+ weld::TriStateEnabled aOrphanState;
+ weld::TriStateEnabled aWidowState;
+
+ bool bPageBreak;
+ bool bHtmlMode;
+ sal_uInt16 nStdPos;
+
+ // hyphenation
+ std::unique_ptr<weld::CheckButton> m_xHyphenBox;
+ std::unique_ptr<weld::CheckButton> m_xHyphenNoCapsBox;
+ std::unique_ptr<weld::Label> m_xBeforeText;
+ std::unique_ptr<weld::SpinButton> m_xExtHyphenBeforeBox;
+ std::unique_ptr<weld::Label> m_xAfterText;
+ std::unique_ptr<weld::SpinButton> m_xExtHyphenAfterBox;
+ std::unique_ptr<weld::Label> m_xMaxHyphenLabel;
+ std::unique_ptr<weld::SpinButton> m_xMaxHyphenEdit;
+
+ // pagebreak
+ std::unique_ptr<weld::CheckButton> m_xPageBreakBox;
+ std::unique_ptr<weld::Label> m_xBreakTypeFT;
+ std::unique_ptr<weld::ComboBox> m_xBreakTypeLB;
+ std::unique_ptr<weld::Label> m_xBreakPositionFT;
+ std::unique_ptr<weld::ComboBox> m_xBreakPositionLB;
+ std::unique_ptr<weld::CheckButton> m_xApplyCollBtn;
+ std::unique_ptr<weld::ComboBox> m_xApplyCollBox;
+ std::unique_ptr<weld::CheckButton> m_xPageNumBox;
+ std::unique_ptr<weld::SpinButton> m_xPagenumEdit;
+
+ // paragraph division
+ std::unique_ptr<weld::CheckButton> m_xKeepTogetherBox;
+ std::unique_ptr<weld::CheckButton> m_xKeepParaBox;
+
+ // orphan/widow
+ std::unique_ptr<weld::CheckButton> m_xOrphanBox;
+ std::unique_ptr<weld::SpinButton> m_xOrphanRowNo;
+ std::unique_ptr<weld::Label> m_xOrphanRowLabel;
+
+ std::unique_ptr<weld::CheckButton> m_xWidowBox;
+ std::unique_ptr<weld::SpinButton> m_xWidowRowNo;
+ std::unique_ptr<weld::Label> m_xWidowRowLabel;
+
+ void HyphenClickHdl();
+ void PageNumBoxClickHdl();
+ void ApplyCollClickHdl();
+ void PageBreakHdl();
+ void KeepTogetherHdl();
+ void OrphanHdl();
+ void WidowHdl();
+
+ DECL_LINK(PageBreakHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(KeepTogetherHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(WidowHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(OrphanHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(HyphenClickHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ApplyCollClickHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(PageBreakPosHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PageBreakTypeHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(PageNumBoxClickHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(KeepParaBoxClickHdl_Impl, weld::ToggleButton&, void);
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+class SvxAsianTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xForbiddenRulesCB;
+ std::unique_ptr<weld::CheckButton> m_xHangingPunctCB;
+ std::unique_ptr<weld::CheckButton> m_xScriptSpaceCB;
+
+public:
+ SvxAsianTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+ virtual ~SvxAsianTabPage() override;
+
+ static const sal_uInt16* GetRanges();
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void ChangesApplied() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_PARAGRPH_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/passwdomdlg.hxx b/cui/source/inc/passwdomdlg.hxx
new file mode 100644
index 000000000..1f690ca39
--- /dev/null
+++ b/cui/source/inc/passwdomdlg.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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_PASSWDOMDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_PASSWDOMDLG_HXX
+
+#include <sfx2/basedlgs.hxx>
+#include <memory>
+
+class PasswordToOpenModifyDialog : public SfxDialogController
+{
+ std::unique_ptr<weld::Entry> m_xPasswdToOpenED;
+ std::unique_ptr<weld::Label> m_xPasswdToOpenInd;
+ std::unique_ptr<weld::Entry> m_xReenterPasswdToOpenED;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToOpenInd;
+ std::unique_ptr<weld::Expander> m_xOptionsExpander;
+ std::unique_ptr<weld::Button> m_xOk;
+ std::unique_ptr<weld::CheckButton> m_xOpenReadonlyCB;
+ std::unique_ptr<weld::Label> m_xPasswdToModifyFT;
+ std::unique_ptr<weld::Entry> m_xPasswdToModifyED;
+ std::unique_ptr<weld::Label> m_xPasswdToModifyInd;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToModifyFT;
+ std::unique_ptr<weld::Entry> m_xReenterPasswdToModifyED;
+ std::unique_ptr<weld::Label> m_xReenterPasswdToModifyInd;
+
+ OUString m_aOneMismatch;
+ OUString m_aTwoMismatch;
+ OUString m_aInvalidStateForOkButton;
+ OUString m_aInvalidStateForOkButton_v2;
+ OUString m_aIndicatorTemplate;
+
+ int m_nMaxPasswdLen;
+ bool m_bIsPasswordToModify;
+
+
+ DECL_LINK(OkBtnClickHdl, weld::Button&, void);
+ DECL_LINK(ReadonlyOnOffHdl, weld::Button&, void);
+ DECL_LINK(ChangeHdl, weld::Entry&, void);
+
+ PasswordToOpenModifyDialog( const PasswordToOpenModifyDialog & ) = delete;
+ PasswordToOpenModifyDialog & operator = ( const PasswordToOpenModifyDialog & ) = delete;
+
+public:
+ PasswordToOpenModifyDialog(weld::Window* pParent,
+ sal_uInt16 nMaxPasswdLen /* 0 -> no max len enforced */,
+ bool bIsPasswordToModify );
+
+ // AbstractPasswordToOpenModifyDialog
+ OUString GetPasswordToOpen() const;
+ OUString GetPasswordToModify() const;
+ bool IsRecommendToOpenReadonly() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/pastedlg.hxx b/cui/source/inc/pastedlg.hxx
new file mode 100644
index 000000000..a9a691b4f
--- /dev/null
+++ b/cui/source/inc/pastedlg.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 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_PASTEDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_PASTEDLG_HXX
+
+#include <map>
+#include <sot/formats.hxx>
+#include <tools/globname.hxx>
+#include <vcl/transfer.hxx>
+#include <vcl/weld.hxx>
+
+struct TransferableObjectDescriptor;
+class TransferableDataHelper;
+
+class SvPasteObjectDialog : public weld::GenericDialogController
+{
+ std::map< SotClipboardFormatId, OUString > aSupplementMap;
+ // Additional UNO command to be displayed along the supported paste formats
+ std::pair<OUString, OUString> aExtraCommand;
+ SvGlobalName aObjClassName;
+ OUString aObjName;
+
+ std::unique_ptr<weld::Label> m_xFtObjectSource;
+ std::unique_ptr<weld::TreeView> m_xLbInsertList;
+ std::unique_ptr<weld::Button> m_xOKButton;
+
+ weld::TreeView& ObjectLB() { return *m_xLbInsertList; }
+
+ void SelectObject();
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+ DECL_LINK(DoubleClickHdl, weld::TreeView&, bool);
+
+public:
+ SvPasteObjectDialog(weld::Window* pParent);
+
+ void Insert( SotClipboardFormatId nFormat, const OUString & rFormatName );
+ void InsertUno( const OUString& sUnoCmd, const OUString& sLabel);
+ void SetObjName( const SvGlobalName & rClass, const OUString & rObjName );
+ /**
+ * @brief PreGetFormat Prepares the dialog for running to get format of paste as a SotClipboardFormatId value by calling GetFormatOnly()
+ * @param aHelper
+ */
+ void PreGetFormat( const TransferableDataHelper& aHelper);
+ /**
+ * @brief GetFormatOnly Returns a SotClipboardFormatId value. Should be called after actually running the dialog.
+ * @return
+ */
+ SotClipboardFormatId GetFormatOnly();
+ /**
+ * @brief GetFormat Prepares and runs the dialog, and returns a SotClipboardFormatId depending on the RET_OK result
+ * @param aHelper TransferableDataHelper containing the data to be pasted
+ * @return a SotClipboardFormatId value depending on the result of running the dialog
+ */
+ SotClipboardFormatId GetFormat( const TransferableDataHelper& aHelper);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_PASTEDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/postdlg.hxx b/cui/source/inc/postdlg.hxx
new file mode 100644
index 000000000..62a3379b9
--- /dev/null
+++ b/cui/source/inc/postdlg.hxx
@@ -0,0 +1,103 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_POSTDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_POSTDLG_HXX
+
+#include <sfx2/basedlgs.hxx>
+
+// class SvxPostItDialog -------------------------------------------------
+/*
+ [Description]
+ In this dialog a note can be created or edited. If the
+ application holds a list of notes, it can be iterated
+ over this list with links.
+
+ [Items]
+ <SvxPostItAuthorItem><SID_ATTR_POSTIT_AUTHOR>
+ <SvxPostItDateItem><SID_ATTR_POSTIT_DATE>
+ <SvxPostItTextItem><SID_ATTR_POSTIT_TEXT>
+*/
+
+class SvxPostItDialog : public SfxDialogController
+{
+public:
+ SvxPostItDialog(weld::Widget* pParent, const SfxItemSet& rCoreSet,
+ bool bPrevNext);
+ virtual ~SvxPostItDialog() override;
+
+ static const sal_uInt16* GetRanges();
+ const SfxItemSet* GetOutputItemSet() const { return m_xOutSet.get(); }
+
+ void SetPrevHdl( const Link<SvxPostItDialog&,void>& rLink )
+ { m_aPrevHdlLink = rLink; }
+ void SetNextHdl( const Link<SvxPostItDialog&,void>& rLink )
+ { m_aNextHdlLink = rLink; }
+
+ void EnableTravel(bool bNext, bool bPrev);
+ OUString GetNote() const
+ {
+ return m_xEditED->get_text();
+ }
+ void SetNote(const OUString& rTxt)
+ {
+ m_xEditED->set_text(rTxt);
+ }
+ void ShowLastAuthor(const OUString& rAuthor, const OUString& rDate);
+ void DontChangeAuthor()
+ {
+ m_xAuthorBtn->set_sensitive(false);
+ }
+ void HideAuthor()
+ {
+ m_xInsertAuthor->hide();
+ }
+ void set_title(const OUString& rTitle)
+ {
+ m_xDialog->set_title(rTitle);
+ }
+ std::shared_ptr<weld::Dialog> const & GetDialog() const
+ {
+ return m_xDialog;
+ }
+
+private:
+ const SfxItemSet& m_rSet;
+ std::unique_ptr<SfxItemSet> m_xOutSet;
+
+ Link<SvxPostItDialog&,void> m_aPrevHdlLink;
+ Link<SvxPostItDialog&,void> m_aNextHdlLink;
+
+ std::unique_ptr<weld::Label> m_xLastEditFT;
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<weld::TextView> m_xEditED;
+ std::unique_ptr<weld::Widget> m_xInsertAuthor;
+ std::unique_ptr<weld::Button> m_xAuthorBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::Button> m_xPrevBtn;
+ std::unique_ptr<weld::Button> m_xNextBtn;
+
+ DECL_LINK(Stamp, weld::Button&, void);
+ DECL_LINK(OKHdl, weld::Button&, void);
+ DECL_LINK(PrevHdl, weld::Button&, void);
+ DECL_LINK(NextHdl, weld::Button&, void);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/screenshotannotationdlg.hxx b/cui/source/inc/screenshotannotationdlg.hxx
new file mode 100644
index 000000000..94972219d
--- /dev/null
+++ b/cui/source/inc/screenshotannotationdlg.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_CUI_SOURCE_INC_SCREENSHANNDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_SCREENSHANNDLG_HXX
+
+#include <vcl/weld.hxx>
+#include <memory>
+
+class ScreenshotAnnotationDlg_Impl;
+
+class ScreenshotAnnotationDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr< ScreenshotAnnotationDlg_Impl > m_pImpl;
+
+ ScreenshotAnnotationDlg(const ScreenshotAnnotationDlg &) = delete;
+ ScreenshotAnnotationDlg& operator=(const ScreenshotAnnotationDlg &) = delete;
+
+public:
+ ScreenshotAnnotationDlg(weld::Dialog& rParentDialog);
+ virtual ~ScreenshotAnnotationDlg() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/scriptdlg.hxx b/cui/source/inc/scriptdlg.hxx
new file mode 100644
index 000000000..7ae0f3335
--- /dev/null
+++ b/cui/source/inc/scriptdlg.hxx
@@ -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 .
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_INC_SCRIPTDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_SCRIPTDLG_HXX
+
+#include <memory>
+#include <sfx2/basedlgs.hxx>
+#include <vcl/abstdlg.hxx>
+#include <vcl/weld.hxx>
+
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/script/browse/XBrowseNode.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <unordered_map>
+
+#define OBJTYPE_METHOD 2L
+#define OBJTYPE_SCRIPTCONTAINER 3L
+#define OBJTYPE_SFROOT 4L
+
+typedef std::unordered_map < OUString, OUString > Selection_hash;
+
+class SFEntry;
+
+enum class InputDialogMode {
+ NEWLIB = 1,
+ NEWMACRO = 2,
+ RENAME = 3,
+};
+
+class CuiInputDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xEdit;
+public:
+ CuiInputDialog(weld::Window * pParent, InputDialogMode nMode);
+ OUString GetObjectName() const { return m_xEdit->get_text(); }
+ void SetObjectName(const OUString& rName)
+ {
+ m_xEdit->set_text(rName);
+ m_xEdit->select_region(0, -1);
+ }
+};
+
+class SFEntry final
+{
+private:
+ bool loaded;
+ css::uno::Reference< css::script::browse::XBrowseNode > nodes;
+ css::uno::Reference< css::frame::XModel > model;
+public:
+ SFEntry( const css::uno::Reference< css::script::browse::XBrowseNode >& entryNodes ,
+ const css::uno::Reference< css::frame::XModel >& entryModel) { nodes = entryNodes; loaded=false; model = entryModel; }
+ SFEntry( const SFEntry& r ) { nodes = r.nodes; loaded = r.loaded; }
+ const css::uno::Reference< css::script::browse::XBrowseNode >& GetNode() const { return nodes ;}
+ const css::uno::Reference< css::frame::XModel >& GetModel() const { return model ;};
+ bool isLoaded() const { return loaded; }
+ void setLoaded() { loaded=true; }
+};
+
+class SvxScriptOrgDialog : public SfxDialogController
+{
+protected:
+ OUString m_sLanguage;
+ static Selection_hash m_lastSelection;
+ const OUString m_delErrStr;
+ const OUString m_delErrTitleStr;
+ const OUString m_delQueryStr;
+ const OUString m_delQueryTitleStr;
+ const OUString m_createErrStr;
+ const OUString m_createDupStr;
+ const OUString m_createErrTitleStr;
+ const OUString m_renameErrStr;
+ const OUString m_renameErrTitleStr;
+ const OUString m_sMyMacros;
+ const OUString m_sProdMacros;
+
+ std::unique_ptr<weld::TreeView> m_xScriptsBox;
+ std::unique_ptr<weld::Button> m_xRunButton;
+ std::unique_ptr<weld::Button> m_xCloseButton;
+ std::unique_ptr<weld::Button> m_xCreateButton;
+ std::unique_ptr<weld::Button> m_xEditButton;
+ std::unique_ptr<weld::Button> m_xRenameButton;
+ std::unique_ptr<weld::Button> m_xDelButton;
+
+ DECL_LINK( ScriptSelectHdl, weld::TreeView&, void );
+ DECL_LINK( ExpandingHdl, const weld::TreeIter&, bool );
+ DECL_LINK( ButtonHdl, weld::Button&, void );
+ static bool getBoolProperty( css::uno::Reference< css::beans::XPropertySet > const & xProps, OUString const & propName );
+ void CheckButtons( css::uno::Reference< css::script::browse::XBrowseNode > const & node );
+
+ void createEntry(weld::TreeIter& rEntry);
+ void renameEntry(const weld::TreeIter& rEntry);
+ void deleteEntry(weld::TreeIter& rEntry);
+ css::uno::Reference<css::script::browse::XBrowseNode> getBrowseNode(const weld::TreeIter& rEntry);
+ css::uno::Reference<css::frame::XModel> getModel(const weld::TreeIter& rEntry);
+ OUString getListOfChildren( const css::uno::Reference< css::script::browse::XBrowseNode >& node, int depth );
+ void StoreCurrentSelection();
+ void RestorePreviousSelection();
+
+ void Init(const OUString& language);
+ void delUserData(const weld::TreeIter& rIter);
+ void deleteTree(weld::TreeIter& rIter);
+ void deleteAllTree();
+ void insertEntry(OUString const & rText, OUString const & rBitmap,
+ const weld::TreeIter* pParent,
+ bool bChildrenOnDemand,
+ std::unique_ptr< SFEntry > && aUserData,
+ const OUString& factoryURL, bool bSelect);
+ void insertEntry(OUString const & rText, OUString const & rBitmap,
+ const weld::TreeIter* pParent,
+ bool bChildrenOnDemand,
+ std::unique_ptr< SFEntry > && aUserData,
+ bool bSelect);
+
+ void RequestSubEntries(const weld::TreeIter& rRootEntry,
+ css::uno::Reference< css::script::browse::XBrowseNode > const & node,
+ css::uno::Reference< css::frame::XModel>& model);
+
+ static css::uno::Reference< css::script::browse::XBrowseNode >
+ getLangNodeFromRootNode( css::uno::Reference< css::script::browse::XBrowseNode > const & root, OUString const & language );
+
+ static css::uno::Reference< css::uno::XInterface > getDocumentModel( css::uno::Reference< css::uno::XComponentContext > const & xCtx, OUString const & docName );
+
+public:
+ // prob need another arg in the ctor
+ // to specify the language or provider
+ SvxScriptOrgDialog(weld::Window* pParent, const OUString& language);
+ virtual ~SvxScriptOrgDialog() override;
+
+ virtual short run() override;
+};
+
+class SvxScriptErrorDialog : public VclAbstractDialog
+{
+private:
+
+ OUString m_sMessage;
+
+ DECL_STATIC_LINK( SvxScriptErrorDialog, ShowDialog, void*, void );
+
+public:
+
+ SvxScriptErrorDialog( css::uno::Any const & aException );
+
+ virtual ~SvxScriptErrorDialog() override;
+
+ short Execute() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_SCRIPTDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/sdrcelldlg.hxx b/cui/source/inc/sdrcelldlg.hxx
new file mode 100644
index 000000000..50ab4b39a
--- /dev/null
+++ b/cui/source/inc/sdrcelldlg.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_CUI_SOURCE_INC_SDRCELLDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_SDRCELLDLG_HXX
+
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/xtable.hxx>
+
+class SdrModel;
+class SvxFormatCellsDialog : public SfxTabDialogController
+{
+private:
+ const SfxItemSet& mrOutAttrs;
+
+ XColorListRef mpColorTab;
+ XGradientListRef mpGradientList;
+ XHatchListRef mpHatchingList;
+ XBitmapListRef mpBitmapList;
+ XPatternListRef mpPatternList;
+
+public:
+ SvxFormatCellsDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrModel& rModel);
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_SDRCELLDLG_HXX
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/showcols.hxx b/cui/source/inc/showcols.hxx
new file mode 100644
index 000000000..3b15abfd3
--- /dev/null
+++ b/cui/source/inc/showcols.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_CUI_SOURCE_INC_SHOWCOLS_HXX
+#define INCLUDED_CUI_SOURCE_INC_SHOWCOLS_HXX
+
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <vcl/weld.hxx>
+
+// FmShowColsDialog
+
+class FmShowColsDialog final : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::TreeView> m_xList;
+ std::unique_ptr<weld::Button> m_xOK;
+
+ css::uno::Reference<css::container::XIndexAccess> m_xColumns;
+
+public:
+ FmShowColsDialog(weld::Window* pParent);
+ virtual ~FmShowColsDialog() override;
+
+ void SetColumns(const css::uno::Reference<css::container::XIndexContainer>& xCols);
+
+private:
+ DECL_LINK(OnClickedOk, weld::Button&, void);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_SHOWCOLS_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/splitcelldlg.hxx b/cui/source/inc/splitcelldlg.hxx
new file mode 100644
index 000000000..b0c2fddae
--- /dev/null
+++ b/cui/source/inc/splitcelldlg.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_CUI_SOURCE_INC_SPLITCELLDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_SPLITCELLDLG_HXX
+
+#include <svx/svxdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxSplitTableDlg : public SvxAbstractSplitTableDialog, public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xCountEdit;
+ std::unique_ptr<weld::RadioButton> m_xHorzBox;
+ std::unique_ptr<weld::RadioButton> m_xVertBox;
+ std::unique_ptr<weld::CheckButton> m_xPropCB;
+
+ long mnMaxVertical;
+ long mnMaxHorizontal;
+
+public:
+ SvxSplitTableDlg(weld::Window *pParent, bool bIsTableVertical, long nMaxVertical, long nMaxHorizontal);
+
+ DECL_LINK(ClickHdl, weld::Button&, void);
+
+ virtual bool IsHorizontal() const override;
+ virtual bool IsProportional() const override;
+ virtual long GetCount() const override;
+
+ virtual short Execute() override;
+ virtual void SetSplitVerticalByDefault() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/srchxtra.hxx b/cui/source/inc/srchxtra.hxx
new file mode 100644
index 000000000..5513ae236
--- /dev/null
+++ b/cui/source/inc/srchxtra.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_CUI_SOURCE_INC_SRCHXTRA_HXX
+#define INCLUDED_CUI_SOURCE_INC_SRCHXTRA_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svx/srchdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SvxSearchFormatDialog : public SfxTabDialogController
+{
+public:
+ SvxSearchFormatDialog(weld::Window* pParent, const SfxItemSet& rSet);
+ virtual ~SvxSearchFormatDialog() override;
+
+protected:
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+private:
+ std::unique_ptr<FontList> m_pFontList;
+};
+
+// class SvxSearchFormatDialog -------------------------------------------
+
+class SvxSearchAttributeDialog : public weld::GenericDialogController
+{
+public:
+ SvxSearchAttributeDialog(weld::Window* pParent, SearchAttrItemList& rLst,
+ const sal_uInt16* pWhRanges);
+ virtual ~SvxSearchAttributeDialog() override;
+
+private:
+ SearchAttrItemList& rList;
+
+ std::unique_ptr<weld::TreeView> m_xAttrLB;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK(OKHdl, weld::Button&, void);
+};
+
+// class SvxSearchSimilarityDialog ---------------------------------------
+
+class SvxSearchSimilarityDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::SpinButton> m_xOtherFld;
+ std::unique_ptr<weld::SpinButton> m_xLongerFld;
+ std::unique_ptr<weld::SpinButton> m_xShorterFld;
+ std::unique_ptr<weld::CheckButton> m_xRelaxBox;
+
+public:
+ SvxSearchSimilarityDialog(weld::Window* pParent,
+ bool bRelax,
+ sal_uInt16 nOther,
+ sal_uInt16 nShorter,
+ sal_uInt16 nLonger);
+ virtual ~SvxSearchSimilarityDialog() override;
+
+ sal_uInt16 GetOther() const { return static_cast<sal_uInt16>(m_xOtherFld->get_value()); }
+ sal_uInt16 GetShorter() const { return static_cast<sal_uInt16>(m_xShorterFld->get_value()); }
+ sal_uInt16 GetLonger() const { return static_cast<sal_uInt16>(m_xLongerFld->get_value()); }
+ bool IsRelaxed() const { return m_xRelaxBox->get_active(); }
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/swpossizetabpage.hxx b/cui/source/inc/swpossizetabpage.hxx
new file mode 100644
index 000000000..1fe926566
--- /dev/null
+++ b/cui/source/inc/swpossizetabpage.hxx
@@ -0,0 +1,133 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_SWPOSSIZETABPAGE_HXX
+#define INCLUDED_CUI_SOURCE_INC_SWPOSSIZETABPAGE_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/swframeexample.hxx>
+#include <vcl/weld.hxx>
+
+// SvxSwPosSizeTabPage - position and size page for Writer drawing objects
+struct FrmMap;
+class SdrView;
+struct SvxSwFrameValidation;
+enum class SvxAnchorIds;
+
+class SvxSwPosSizeTabPage : public SfxTabPage
+{
+ Link<SvxSwFrameValidation&,void> m_aValidateLink;
+
+ ::tools::Rectangle m_aRect; //size of all selected objects
+ ::tools::Rectangle m_aWorkArea;
+ Point m_aAnchorPos;
+
+ FrmMap const * m_pVMap;
+ FrmMap const * m_pHMap;
+ const SdrView* m_pSdrView;
+
+ // initial values
+ short m_nOldH;
+ short m_nOldHRel;
+ short m_nOldV;
+ short m_nOldVRel;
+
+ double m_fWidthHeightRatio; //width-to-height ratio to support the KeepRatio button
+ bool m_bHtmlMode;
+ bool m_bIsVerticalFrame;
+ bool m_bPositioningDisabled;
+ bool m_bIsMultiSelection;
+ bool m_bIsInRightToLeft;
+ TriState m_nProtectSizeState;
+
+ SwFrameExample m_aExampleWN;
+
+ std::unique_ptr<weld::MetricSpinButton> m_xWidthMF;
+ std::unique_ptr<weld::MetricSpinButton> m_xHeightMF;
+ std::unique_ptr<weld::CheckButton> m_xKeepRatioCB;
+ std::unique_ptr<weld::RadioButton> m_xToPageRB;
+ std::unique_ptr<weld::RadioButton> m_xToParaRB;
+ std::unique_ptr<weld::RadioButton> m_xToCharRB;
+ std::unique_ptr<weld::RadioButton> m_xAsCharRB;
+ std::unique_ptr<weld::RadioButton> m_xToFrameRB;
+ std::unique_ptr<weld::CheckButton> m_xPositionCB;
+ std::unique_ptr<weld::CheckButton> m_xSizeCB;
+ std::unique_ptr<weld::Widget> m_xPosFrame;
+ std::unique_ptr<weld::Label> m_xHoriFT;
+ std::unique_ptr<weld::ComboBox> m_xHoriLB;
+ std::unique_ptr<weld::Label> m_xHoriByFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xHoriByMF;
+ std::unique_ptr<weld::Label> m_xHoriToFT;
+ std::unique_ptr<weld::ComboBox> m_xHoriToLB;
+ std::unique_ptr<weld::CheckButton> m_xHoriMirrorCB;
+ std::unique_ptr<weld::Label> m_xVertFT;
+ std::unique_ptr<weld::ComboBox> m_xVertLB;
+ std::unique_ptr<weld::Label> m_xVertByFT;
+ std::unique_ptr<weld::MetricSpinButton> m_xVertByMF;
+ std::unique_ptr<weld::Label> m_xVertToFT;
+ std::unique_ptr<weld::ComboBox> m_xVertToLB;
+ std::unique_ptr<weld::CheckButton> m_xFollowCB;
+ std::unique_ptr<weld::CustomWeld> m_xExampleWN;
+
+ DECL_LINK(RangeModifyHdl, weld::Widget&, void);
+ DECL_LINK(RangeModifyClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(AnchorTypeHdl, weld::ToggleButton&, void);
+ DECL_LINK(PosHdl, weld::ComboBox&, void);
+ DECL_LINK(RelHdl, weld::ComboBox&, void);
+ DECL_LINK(MirrorHdl, weld::ToggleButton&, void);
+ DECL_LINK(ModifyHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ProtectHdl, weld::ToggleButton&, void);
+
+ void InitPos(RndStdIds nAnchorType, sal_uInt16 nH, sal_uInt16 nHRel,
+ sal_uInt16 nV, sal_uInt16 nVRel,
+ long nX, long nY);
+ static sal_uInt16 GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB);
+ static short GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB);
+ static short GetRelation(const weld::ComboBox& rRelationLB);
+ RndStdIds GetAnchorType(bool* pbHasChanged = nullptr);
+ void FillRelLB(FrmMap const *pMap, sal_uInt16 nLBSelPos, sal_uInt16 nAlign, sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT);
+ sal_uInt16 FillPosLB(FrmMap const *pMap, sal_uInt16 nAlign, const sal_uInt16 _nRel, weld::ComboBox& rLB);
+
+ void UpdateExample();
+
+ void setOptimalFrmWidth();
+ void setOptimalRelWidth();
+
+public:
+ SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ virtual ~SvxSwPosSizeTabPage() override;
+
+ static const sal_uInt16* GetRanges();
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void EnableAnchorTypes(SvxAnchorIds nAnchorEnable);
+
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+ {m_aValidateLink = rLink;}
+
+ void SetView( const SdrView* pSdrView );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/tabstpge.hxx b/cui/source/inc/tabstpge.hxx
new file mode 100644
index 000000000..6c9e63b10
--- /dev/null
+++ b/cui/source/inc/tabstpge.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_TABSTPGE_HXX
+#define INCLUDED_CUI_SOURCE_INC_TABSTPGE_HXX
+
+#include <vcl/customweld.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/tabdlg.hxx>
+
+#include <editeng/tstpitem.hxx>
+#include <svx/flagsdef.hxx>
+
+class SvxTabulatorTabPage;
+
+// class TabWin_Impl -----------------------------------------------------
+
+class TabWin_Impl : public weld::CustomWidgetController
+{
+private:
+ sal_uInt16 nTabStyle;
+
+public:
+
+ TabWin_Impl() : nTabStyle(0)
+ {
+ }
+ virtual void Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& rRect) override;
+
+ void SetTabStyle(sal_uInt16 nStyle) {nTabStyle = nStyle; }
+};
+
+// class SvxTabulatorTabPage ---------------------------------------------
+/*
+ [Description]
+ In this TabPage tabulators are managed.
+
+ [Items]
+ <SvxTabStopItem><SID_ATTR_TABSTOP>
+ <SfxUInt16Item><SID_ATTR_TABSTOP_DEFAULTS>
+ <SfxUInt16Item><SID_ATTR_TABSTOP_POS>
+ <SfxInt32Item><SID_ATTR_TABSTOP_OFFSET>
+*/
+
+class SvxTabulatorTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pRanges[];
+
+public:
+ SvxTabulatorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxTabulatorTabPage() override;
+
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ void DisableControls( const TabulatorDisableFlags nFlag );
+
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+private:
+ // local variables, internal functions
+ SvxTabStop aCurrentTab;
+ std::unique_ptr<SvxTabStopItem> aNewTabs;
+ long nDefDist;
+
+ TabWin_Impl m_aLeftWin;
+ TabWin_Impl m_aRightWin;
+ TabWin_Impl m_aCenterWin;
+ TabWin_Impl m_aDezWin;
+
+ // just to format the numbers, not shown
+ std::unique_ptr<weld::MetricSpinButton> m_xTabSpin;
+ // tabulators and positions
+ std::unique_ptr<weld::EntryTreeView> m_xTabBox;
+ // TabType
+ std::unique_ptr<weld::RadioButton> m_xLeftTab;
+ std::unique_ptr<weld::RadioButton> m_xRightTab;
+ std::unique_ptr<weld::RadioButton> m_xCenterTab;
+ std::unique_ptr<weld::RadioButton> m_xDezTab;
+
+ std::unique_ptr<weld::Entry> m_xDezChar;
+ std::unique_ptr<weld::Label> m_xDezCharLabel;
+
+ std::unique_ptr<weld::RadioButton> m_xNoFillChar;
+ std::unique_ptr<weld::RadioButton> m_xFillPoints;
+ std::unique_ptr<weld::RadioButton> m_xFillDashLine ;
+ std::unique_ptr<weld::RadioButton> m_xFillSolidLine;
+ std::unique_ptr<weld::RadioButton> m_xFillSpecial;
+ std::unique_ptr<weld::Entry> m_xFillChar;
+
+ std::unique_ptr<weld::Button> m_xNewBtn;
+ std::unique_ptr<weld::Button> m_xDelAllBtn;
+ std::unique_ptr<weld::Button> m_xDelBtn;
+
+ std::unique_ptr<weld::Container> m_xTypeFrame;
+ std::unique_ptr<weld::Container> m_xFillFrame;
+
+ std::unique_ptr<weld::CustomWeld> m_xLeftWin;
+ std::unique_ptr<weld::CustomWeld> m_xRightWin;
+ std::unique_ptr<weld::CustomWeld> m_xCenterWin;
+ std::unique_ptr<weld::CustomWeld> m_xDezWin;
+
+ void InitTabPos_Impl( sal_uInt16 nPos = 0 );
+ void SetFillAndTabType_Impl();
+ void NewHdl_Impl(const weld::Button*);
+
+ OUString FormatTab();
+
+ // Handler
+ DECL_LINK(NewHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelHdl_Impl, weld::Button&, void);
+ DECL_LINK(DelAllHdl_Impl, weld::Button&, void);
+
+ DECL_LINK(FillTypeCheckHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(TabTypeCheckHdl_Impl, weld::ToggleButton&, void);
+
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(ModifyHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(ReformatHdl_Impl, weld::Widget&, void);
+ DECL_LINK(GetFillCharHdl_Impl, weld::Widget&, void);
+ DECL_LINK(GetDezCharHdl_Impl, weld::Widget&, void);
+
+ int FindCurrentTab();
+
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_TABSTPGE_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/textanim.hxx b/cui/source/inc/textanim.hxx
new file mode 100644
index 000000000..3ae2452b0
--- /dev/null
+++ b/cui/source/inc/textanim.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_CUI_SOURCE_INC_TEXTANIM_HXX
+#define INCLUDED_CUI_SOURCE_INC_TEXTANIM_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/sdtakitm.hxx>
+#include <svx/sdtaditm.hxx>
+#include <vcl/weld.hxx>
+
+class SdrView;
+
+/*************************************************************************
+|*
+|* Page for changing TextAnimations (running text etc.)
+|*
+\************************************************************************/
+
+class SvxTextAnimationPage : public SfxTabPage
+{
+private:
+ static const sal_uInt16 pRanges[];
+
+ SdrTextAniKind eAniKind;
+ FieldUnit eFUnit;
+ MapUnit eUnit;
+
+ TriState m_aUpState;
+ TriState m_aLeftState;
+ TriState m_aRightState;
+ TriState m_aDownState;
+
+ std::unique_ptr<weld::ComboBox> m_xLbEffect;
+ std::unique_ptr<weld::Widget> m_xBoxDirection;
+ std::unique_ptr<weld::ToggleButton> m_xBtnUp;
+ std::unique_ptr<weld::ToggleButton> m_xBtnLeft;
+ std::unique_ptr<weld::ToggleButton> m_xBtnRight;
+ std::unique_ptr<weld::ToggleButton> m_xBtnDown;
+
+ std::unique_ptr<weld::Frame> m_xFlProperties;
+ std::unique_ptr<weld::CheckButton> m_xTsbStartInside;
+ std::unique_ptr<weld::CheckButton> m_xTsbStopInside;
+
+ std::unique_ptr<weld::Widget> m_xBoxCount;
+ std::unique_ptr<weld::CheckButton> m_xTsbEndless;
+ std::unique_ptr<weld::SpinButton> m_xNumFldCount;
+
+ std::unique_ptr<weld::CheckButton> m_xTsbPixel;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldAmount;
+
+ std::unique_ptr<weld::CheckButton> m_xTsbAuto;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldDelay;
+
+ DECL_LINK( SelectEffectHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( ClickEndlessHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickAutoHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickPixelHdl_Impl, weld::Button&, void );
+ DECL_LINK( ClickDirectionHdl_Impl, weld::Button&, void );
+
+ void SelectDirection( SdrTextAniDirection nValue );
+ sal_uInt16 GetSelectedDirection() const;
+
+public:
+ SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTextAnimationPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+};
+
+/*************************************************************************
+|*
+|* Text-Tab-Dialog
+|*
+\************************************************************************/
+class SvxTextTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pView);
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_TEXTANIM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/textattr.hxx b/cui/source/inc/textattr.hxx
new file mode 100644
index 000000000..392794de9
--- /dev/null
+++ b/cui/source/inc/textattr.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_TEXTATTR_HXX
+#define INCLUDED_CUI_SOURCE_INC_TEXTATTR_HXX
+
+#include <svx/dlgctrl.hxx>
+#include <svx/svdobj.hxx>
+
+class SdrView;
+
+/*************************************************************************
+|*
+|* Dialog for changing TextAttributes
+|*
+\************************************************************************/
+
+class SvxTextAttrPage : public SvxTabPage
+{
+private:
+ static const sal_uInt16 pRanges[];
+
+ const SfxItemSet& rOutAttrs;
+ SdrObjKind m_eObjKind;
+
+ bool bAutoGrowSizeEnabled;
+ bool bContourEnabled;
+ bool bAutoGrowWidthEnabled;
+ bool bAutoGrowHeightEnabled;
+ bool bWordWrapTextEnabled;
+ bool bFitToSizeEnabled;
+
+ SvxRectCtl m_aCtlPosition;
+
+ std::unique_ptr<weld::Widget> m_xDrawingText;
+ std::unique_ptr<weld::Widget> m_xCustomShapeText;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowHeight;
+ std::unique_ptr<weld::CheckButton> m_xTsbFitToSize;
+ std::unique_ptr<weld::CheckButton> m_xTsbContour;
+ std::unique_ptr<weld::CheckButton> m_xTsbWordWrapText;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowSize;
+ std::unique_ptr<weld::Frame> m_xFlDistance;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldLeft;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldRight;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldTop;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrFldBottom;
+ std::unique_ptr<weld::Frame> m_xFlPosition;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPosition;
+ std::unique_ptr<weld::CheckButton> m_xTsbFullWidth;
+
+ DECL_LINK(ClickFullWidthHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClickHdl_Impl, weld::Button&, void);
+
+ /** Return whether the text direction is from left to right (</sal_True>) or
+ top to bottom (</sal_False>).
+ */
+ bool IsTextDirectionLeftToRight() const;
+
+public:
+
+ SvxTextAttrPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxTextAttrPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void PointChanged( weld::DrawingArea* pWindow, RectPoint eRP ) override;
+
+ void Construct();
+ void SetObjKind(SdrObjKind eObjKind) { m_eObjKind = eObjKind; }
+ virtual void PageCreated(const SfxAllItemSet& aSet) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_TEXTATTR_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/thesdlg.hxx b/cui/source/inc/thesdlg.hxx
new file mode 100644
index 000000000..65c4050cc
--- /dev/null
+++ b/cui/source/inc/thesdlg.hxx
@@ -0,0 +1,82 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_INC_THESDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_THESDLG_HXX
+
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+
+#include <vcl/idle.hxx>
+#include <sfx2/basedlgs.hxx>
+
+#include <memory>
+#include <stack>
+
+class SvxThesaurusDialog : public SfxDialogController
+{
+ Idle m_aModifyIdle;
+
+ css::uno::Reference< css::linguistic2::XThesaurus > xThesaurus;
+ OUString aLookUpText;
+ LanguageType nLookUpLanguage;
+ std::stack< OUString > aLookUpHistory;
+ bool m_bWordFound;
+
+ std::unique_ptr<weld::Button> m_xLeftBtn;
+ std::unique_ptr<weld::ComboBox> m_xWordCB;
+ std::unique_ptr<weld::TreeView> m_xAlternativesCT;
+ std::unique_ptr<weld::Label> m_xNotFound;
+ std::unique_ptr<weld::Entry> m_xReplaceEdit;
+ std::unique_ptr<weld::ComboBox> m_xLangLB;
+ std::unique_ptr<weld::Button> m_xReplaceBtn;
+
+public:
+ virtual ~SvxThesaurusDialog() override;
+
+ // Handler
+ DECL_LINK( ReplaceBtnHdl_Impl, weld::Button&, void );
+ DECL_LINK( LeftBtnHdl_Impl, weld::Button&, void );
+ DECL_LINK( LanguageHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( WordSelectHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK( AlternativesSelectHdl_Impl, weld::TreeView&, void );
+ DECL_LINK( AlternativesDoubleClickHdl_Impl, weld::TreeView&, bool );
+ DECL_LINK( SelectFirstHdl_Impl, void*, void );
+ DECL_LINK( ReplaceEditHdl_Impl, weld::Entry&, void );
+ DECL_LINK( ModifyTimer_Hdl, Timer *, void );
+ DECL_LINK( KeyInputHdl, const KeyEvent&, bool );
+
+ /// @throws css::lang::IllegalArgumentException
+ /// @throws css::uno::RuntimeException
+ css::uno::Sequence< css::uno::Reference< css::linguistic2::XMeaning > >
+ queryMeanings_Impl( OUString& rTerm, const css::lang::Locale& rLocale, const css::beans::PropertyValues& rProperties );
+
+ bool UpdateAlternativesBox_Impl();
+ void LookUp( const OUString &rText );
+ void LookUp_Impl();
+
+public:
+ SvxThesaurusDialog(weld::Window* pParent,
+ css::uno::Reference< css::linguistic2::XThesaurus > const & xThesaurus,
+ const OUString &rWord, LanguageType nLanguage);
+ void SetWindowTitle( LanguageType nLanguage );
+ OUString GetWord() const;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/tipofthedaydlg.hxx b/cui/source/inc/tipofthedaydlg.hxx
new file mode 100644
index 000000000..425805af6
--- /dev/null
+++ b/cui/source/inc/tipofthedaydlg.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_CUI_SOURCE_INC_TIPOFTHEDAYDLG_HXX
+#define INCLUDED_CUI_SOURCE_INC_TIPOFTHEDAYDLG_HXX
+
+#include <vcl/weld.hxx>
+
+class TipOfTheDayDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Image> m_pImage;
+ std::unique_ptr<weld::Label> m_pText;
+ std::unique_ptr<weld::CheckButton> m_pShowTip;
+ std::unique_ptr<weld::Button> m_pNext;
+ std::unique_ptr<weld::LinkButton> m_pLink;
+
+ sal_Int32 nCurrentTip;
+ sal_Int32 nNumberOfTips;
+ sal_Int32 nDay;
+ OUString aLink;
+ void UpdateTip();
+ DECL_LINK(OnNextClick, weld::Button&, void);
+ DECL_LINK(OnLinkClick, weld::LinkButton&, bool);
+
+public:
+ TipOfTheDayDialog(weld::Window* pWindow);
+ virtual ~TipOfTheDayDialog() override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_INC_TIPOFTHEDAYDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/transfrm.hxx b/cui/source/inc/transfrm.hxx
new file mode 100644
index 000000000..2c27a19fb
--- /dev/null
+++ b/cui/source/inc/transfrm.hxx
@@ -0,0 +1,251 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_TRANSFRM_HXX
+#define INCLUDED_CUI_SOURCE_INC_TRANSFRM_HXX
+
+#include <svx/dlgctrl.hxx>
+#include <svx/dialcontrol.hxx>
+#include <svx/anchorid.hxx>
+#include <basegfx/range/b2drange.hxx>
+
+// predefines
+class SdrView;
+
+/*************************************************************************
+|*
+|* Transform-Tab-Dialog
+|*
+\************************************************************************/
+
+struct SvxSwFrameValidation;
+class SvxTransformTabDialog : public SfxTabDialogController
+{
+private:
+ const SdrView* pView;
+
+ SvxAnchorIds nAnchorCtrls;
+ Link<SvxSwFrameValidation&,void> aValidateLink;
+
+ virtual void PageCreated(const OString& rId, SfxTabPage &rPage) override;
+
+public:
+ SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const SdrView* pView,
+ SvxAnchorIds nAnchorTypes);
+
+ //link for the Writer to validate positions
+ void SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink );
+};
+
+/*************************************************************************
+|*
+|* position and size tab page
+|*
+\************************************************************************/
+
+class SvxPositionSizeTabPage : public SvxTabPage
+{
+ static const sal_uInt16 pPosSizeRanges[];
+
+private:
+ const SfxItemSet& mrOutAttrs;
+
+ const SdrView* mpView;
+
+ // #i75273#
+ basegfx::B2DRange maRange;
+ basegfx::B2DRange maWorkRange;
+ basegfx::B2DPoint maAnchor;
+
+ MapUnit mePoolUnit;
+ FieldUnit meDlgUnit;
+ TriState mnProtectSizeState;
+ bool mbPageDisabled;
+ bool mbProtectDisabled;
+ bool mbSizeDisabled;
+ bool mbAdjustDisabled;
+ bool mbIgnoreAutoGrowWidth;
+ bool mbIgnoreAutoGrowHeight;
+
+ // from size
+ // #i75273#
+ double mfOldWidth;
+ double mfOldHeight;
+ RectPoint meRP;
+
+ SvxRectCtl m_aCtlPos;
+ SvxRectCtl m_aCtlSize;
+
+ // position
+ std::unique_ptr<weld::Widget> m_xFlPosition;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosY;
+ std::unique_ptr<weld::CustomWeld> m_xCtlPos;
+
+ // size
+ std::unique_ptr<weld::Widget> m_xFlSize;
+ std::unique_ptr<weld::Label> m_xFtWidth;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrWidth;
+ std::unique_ptr<weld::Label> m_xFtHeight;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrHeight;
+ std::unique_ptr<weld::CheckButton> m_xCbxScale;
+ std::unique_ptr<weld::CustomWeld> m_xCtlSize;
+
+ // protect
+ std::unique_ptr<weld::Widget> m_xFlProtect;
+ std::unique_ptr<weld::CheckButton> m_xTsbPosProtect;
+ std::unique_ptr<weld::CheckButton> m_xTsbSizeProtect;
+
+ // adjust
+ std::unique_ptr<weld::Widget> m_xFlAdjust;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowWidth;
+ std::unique_ptr<weld::CheckButton> m_xTsbAutoGrowHeight;
+
+ DECL_LINK(ChangePosProtectHdl, weld::ToggleButton&, void);
+ DECL_LINK(ChangeSizeProtectHdl, weld::ToggleButton&, void);
+
+ void SetMinMaxPosition();
+ void GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange);
+
+ DECL_LINK( ChangeWidthHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ChangeHeightHdl, weld::MetricSpinButton&, void );
+ DECL_LINK( ClickSizeProtectHdl, weld::ToggleButton&, void );
+ DECL_LINK( ClickAutoHdl, weld::ToggleButton&, void );
+
+public:
+ SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxPositionSizeTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pPosSizeRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged(weld::DrawingArea* pWindow, RectPoint eRP) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { mpView = pSdrView; }
+
+ virtual void FillUserData() override;
+
+ void DisableResize();
+ void DisableProtect();
+
+ void UpdateControlStates();
+};
+
+/*************************************************************************
+|*
+|* rotation angle tab page
+|*
+\************************************************************************/
+class SvxAngleTabPage : public SvxTabPage
+{
+ static const sal_uInt16 pAngleRanges[];
+
+private:
+ const SdrView* pView;
+
+ // #i75273#
+ basegfx::B2DRange maRange;
+ basegfx::B2DPoint maAnchor;
+
+ MapUnit ePoolUnit;
+ FieldUnit eDlgUnit;
+
+ SvxRectCtl m_aCtlRect;
+
+ std::unique_ptr<weld::Widget> m_xFlPosition;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosX;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrPosY;
+ std::unique_ptr<weld::CustomWeld> m_xCtlRect;
+ std::unique_ptr<weld::Widget> m_xFlAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xNfAngle;
+ std::unique_ptr<svx::DialControl> m_xCtlAngle;
+ std::unique_ptr<weld::CustomWeld> m_xCtlAngleWin;
+
+public:
+ SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxAngleTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pAngleRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ virtual void PointChanged(weld::DrawingArea* pWindow, RectPoint eRP) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+};
+
+/*************************************************************************
+|*
+|* slant/corner radius tab page
+|*
+\************************************************************************/
+class SvxSlantTabPage : public SfxTabPage
+{
+ static const sal_uInt16 pSlantRanges[];
+
+private:
+ const SdrView* pView;
+
+ MapUnit ePoolUnit;
+ FieldUnit eDlgUnit;
+
+ std::unique_ptr<weld::Widget> m_xFlRadius;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrRadius;
+ std::unique_ptr<weld::Widget> m_xFlAngle;
+ std::unique_ptr<weld::MetricSpinButton> m_xMtrAngle;
+ std::unique_ptr<weld::Widget> m_aControlGroups[2];
+ std::unique_ptr<weld::Widget> m_aControlGroupX[2];
+ std::unique_ptr<weld::MetricSpinButton> m_aControlX[2];
+ std::unique_ptr<weld::Widget> m_aControlGroupY[2];
+ std::unique_ptr<weld::MetricSpinButton> m_aControlY[2];
+
+public:
+ SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxSlantTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* );
+ static const sal_uInt16* GetRanges() { return pSlantRanges; }
+
+ virtual bool FillItemSet( SfxItemSet* ) override;
+ virtual void Reset( const SfxItemSet * ) override;
+
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+ void Construct();
+ void SetView( const SdrView* pSdrView ) { pView = pSdrView; }
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_INC_TRANSFRM_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/treeopt.hxx b/cui/source/inc/treeopt.hxx
new file mode 100644
index 000000000..c2aac20ee
--- /dev/null
+++ b/cui/source/inc/treeopt.hxx
@@ -0,0 +1,238 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_INC_TREEOPT_HXX
+#define INCLUDED_CUI_SOURCE_INC_TREEOPT_HXX
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <sfx2/basedlgs.hxx>
+#include <svtools/restartdialog.hxx>
+
+class SfxModule;
+class SfxShell;
+
+// struct OrderedEntry ---------------------------------------------------
+
+struct OrderedEntry
+{
+ sal_Int32 m_nIndex;
+ OUString m_sId;
+
+ OrderedEntry( sal_Int32 nIndex, const OUString& rId ) :
+ m_nIndex( nIndex ), m_sId( rId ) {}
+};
+
+
+// struct Module ---------------------------------------------------------
+
+struct Module
+{
+ bool m_bActive;
+ std::vector< std::unique_ptr<OrderedEntry> > m_aNodeList;
+
+ Module() : m_bActive( false ) {}
+};
+
+// struct OptionsLeaf ----------------------------------------------------
+
+struct OptionsLeaf
+{
+ OUString m_sLabel;
+ OUString m_sPageURL;
+ OUString m_sEventHdl;
+ OUString m_sGroupId;
+ sal_Int32 m_nGroupIndex;
+
+ OptionsLeaf( const OUString& rLabel,
+ const OUString& rPageURL,
+ const OUString& rEventHdl,
+ const OUString& rGroupId,
+ sal_Int32 nGroupIndex ) :
+ m_sLabel( rLabel ),
+ m_sPageURL( rPageURL ),
+ m_sEventHdl( rEventHdl ),
+ m_sGroupId( rGroupId ),
+ m_nGroupIndex( nGroupIndex ) {}
+};
+
+// struct OptionsNode ----------------------------------------------------
+
+struct OptionsNode
+{
+ OUString m_sId;
+ OUString m_sLabel;
+ bool m_bAllModules;
+ std::vector< std::unique_ptr<OptionsLeaf> > m_aLeaves;
+ std::vector< std::vector< std::unique_ptr<OptionsLeaf> > >
+ m_aGroupedLeaves;
+
+ OptionsNode( const OUString& rId,
+ const OUString& rLabel,
+ bool bAllModules ) :
+ m_sId( rId ),
+ m_sLabel( rLabel ),
+ m_bAllModules( bAllModules ) {}
+};
+
+typedef std::vector< std::unique_ptr<OptionsNode> > VectorOfNodes;
+
+struct LastPageSaver
+{
+ sal_uInt16 m_nLastPageId;
+ OUString m_sLastPageURL_Tools;
+ OUString m_sLastPageURL_ExtMgr;
+
+ LastPageSaver() : m_nLastPageId( USHRT_MAX ) {}
+};
+
+// class OfaTreeOptionsDialog --------------------------------------------
+
+namespace com::sun::star::frame { class XFrame; }
+namespace com::sun::star::awt { class XContainerWindowProvider; }
+
+struct OptionsPageInfo;
+struct Module;
+class ExtensionsTabPage;
+class SvxColorTabPage;
+
+class OfaTreeOptionsDialog final: public SfxOkDialogController
+{
+private:
+ std::unique_ptr<weld::Button> xOkPB;
+ std::unique_ptr<weld::Button> xApplyPB;
+ std::unique_ptr<weld::Button> xBackPB;
+
+ std::unique_ptr<weld::TreeView> xTreeLB;
+ std::unique_ptr<weld::Container> xTabBox;
+
+ weld::Window* m_pParent;
+
+ std::unique_ptr<weld::TreeIter> xCurrentPageEntry;
+
+ OUString sTitle;
+
+ bool bForgetSelection;
+ bool bIsFromExtensionManager;
+
+ // check "for the current document only" and set focus to "Western" languages box
+ bool bIsForSetDocumentLanguage;
+
+ bool bNeedsRestart;
+ svtools::RestartReason eRestartReason;
+
+ css::uno::Reference < css::awt::XContainerWindowProvider >
+ m_xContainerWinProvider;
+
+ static LastPageSaver* pLastPageSaver;
+
+ std::unique_ptr<SfxItemSet> CreateItemSet( sal_uInt16 nId );
+ static void ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet );
+ void InitTreeAndHandler();
+ void Initialize( const css::uno::Reference< css::frame::XFrame >& _xFrame );
+ void InitWidgets();
+
+ void LoadExtensionOptions( const OUString& rExtensionId );
+ static OUString GetModuleIdentifier( const css::uno::Reference<
+ css::frame::XFrame >& xFrame );
+ static std::unique_ptr<Module> LoadModule( const OUString& rModuleIdentifier );
+ static VectorOfNodes LoadNodes( Module* pModule, const OUString& rExtensionId );
+ void InsertNodes( const VectorOfNodes& rNodeList );
+
+ void ApplyOptions( bool deactivate );
+
+ DECL_LINK(ShowPageHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(BackHdl_Impl, weld::Button&, void);
+ DECL_LINK(ApplyHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ DECL_LINK(HelpHdl_Impl, weld::Widget&, bool);
+ void SelectHdl_Impl();
+
+ virtual short run() override;
+
+ virtual weld::Button& GetOKButton() const override { return *xOkPB; }
+ virtual const SfxItemSet* GetExampleSet() const override { return nullptr; }
+
+public:
+ OfaTreeOptionsDialog(weld::Window* pParent,
+ const css::uno::Reference< css::frame::XFrame >& _xFrame,
+ bool bActivateLastSelection);
+ OfaTreeOptionsDialog(weld::Window* pParent, const OUString& rExtensionId);
+ virtual ~OfaTreeOptionsDialog() override;
+
+ OptionsPageInfo* AddTabPage( sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup );
+ sal_uInt16 AddGroup( const OUString& rGroupName, SfxShell* pCreateShell,
+ SfxModule* pCreateModule, sal_uInt16 nDialogId );
+
+ void ActivateLastSelection();
+ void ActivatePage( sal_uInt16 nResId );
+ void ActivatePage( const OUString& rPageURL );
+ void ApplyItemSets();
+
+ // helper functions to call the language settings TabPage from the SpellDialog
+ static void ApplyLanguageOptions(const SfxItemSet& rSet);
+
+ void SetNeedsRestart( svtools::RestartReason eReason );
+};
+
+// class ExtensionsTabPage -----------------------------------------------
+
+namespace com::sun::star::awt { class XWindow; }
+namespace com::sun::star::awt { class XContainerWindowEventHandler; }
+
+class ExtensionsTabPage
+{
+private:
+ weld::Container* m_pContainer;
+ OUString m_sPageURL;
+ css::uno::Reference<css::awt::XWindow> m_xPageParent;
+ css::uno::Reference<css::awt::XWindow> m_xPage;
+ OUString m_sEventHdl;
+ css::uno::Reference< css::awt::XContainerWindowEventHandler >
+ m_xEventHdl;
+ css::uno::Reference< css::awt::XContainerWindowProvider >
+ m_xWinProvider;
+
+ void CreateDialogWithHandler();
+ bool DispatchAction( const OUString& rAction );
+
+public:
+ ExtensionsTabPage(
+ weld::Container* pParent,
+ const OUString& rPageURL, const OUString& rEvtHdl,
+ const css::uno::Reference<
+ css::awt::XContainerWindowProvider >& rProvider );
+
+ ~ExtensionsTabPage();
+
+ void Show();
+ void Hide();
+
+ void ActivatePage();
+ void DeactivatePage();
+
+ void ResetPage();
+ void SavePage();
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/inc/zoom.hxx b/cui/source/inc/zoom.hxx
new file mode 100644
index 000000000..f35a7bfba
--- /dev/null
+++ b/cui/source/inc/zoom.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_CUI_SOURCE_INC_ZOOM_HXX
+#define INCLUDED_CUI_SOURCE_INC_ZOOM_HXX
+
+#include <memory>
+#include <sfx2/basedlgs.hxx>
+#include <svl/itemset.hxx>
+#include <svx/zoom_def.hxx>
+#include <vcl/weld.hxx>
+
+class SvxZoomDialog : public SfxDialogController
+{
+private:
+ const SfxItemSet& m_rSet;
+ std::unique_ptr<SfxItemSet> m_pOutSet;
+ bool m_bModified;
+
+ std::unique_ptr<weld::RadioButton> m_xOptimalBtn;
+ std::unique_ptr<weld::RadioButton> m_xWholePageBtn;
+ std::unique_ptr<weld::RadioButton> m_xPageWidthBtn;
+ std::unique_ptr<weld::RadioButton> m_x100Btn;
+ std::unique_ptr<weld::RadioButton> m_xUserBtn;
+ std::unique_ptr<weld::MetricSpinButton> m_xUserEdit;
+ std::unique_ptr<weld::Widget> m_xViewFrame;
+ std::unique_ptr<weld::RadioButton> m_xAutomaticBtn;
+ std::unique_ptr<weld::RadioButton> m_xSingleBtn;
+ std::unique_ptr<weld::RadioButton> m_xColumnsBtn;
+ std::unique_ptr<weld::SpinButton> m_xColumnsEdit;
+ std::unique_ptr<weld::CheckButton> m_xBookModeChk;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+
+ DECL_LINK(UserHdl, weld::ToggleButton&, void);
+ DECL_LINK(SpinHdl, weld::MetricSpinButton&, void);
+ DECL_LINK(ViewLayoutUserHdl, weld::ToggleButton&, void);
+ DECL_LINK(ViewLayoutSpinHdl, weld::SpinButton&, void);
+ DECL_LINK(ViewLayoutCheckHdl, weld::ToggleButton&, void);
+ DECL_LINK(OKHdl, weld::Button&, void);
+
+public:
+ SvxZoomDialog(weld::Window* pParent, const SfxItemSet& rCoreSet);
+
+ const SfxItemSet* GetOutputItemSet() const;
+
+ sal_uInt16 GetFactor() const;
+ void SetFactor(sal_uInt16 nNewFactor, ZoomButtonId nButtonId = ZoomButtonId::NONE);
+
+ void HideButton(ZoomButtonId nButtonId);
+ void SetLimits(sal_uInt16 nMin, sal_uInt16 nMax);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/certpath.cxx b/cui/source/options/certpath.cxx
new file mode 100644
index 000000000..b98811dc4
--- /dev/null
+++ b/cui/source/options/certpath.cxx
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <osl/thread.h>
+#include <tools/diagnose_ex.h>
+#include "certpath.hxx"
+
+#include <com/sun/star/mozilla/MozillaBootstrap.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+
+CertPathDialog::CertPathDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/certdialog.ui", "CertDialog")
+ , m_xManualButton(m_xBuilder->weld_button("add"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xCertPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_sAddDialogText(m_xBuilder->weld_label("certdir")->get_label())
+ , m_sManualLabel(m_xBuilder->weld_label("manual")->get_label())
+{
+ // these are just used to get translated strings
+
+ m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 70,
+ m_xCertPathList->get_height_rows(6));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xCertPathList->get_checkbox_column_width());
+ aWidths.push_back(m_xCertPathList->get_approximate_digit_width() * 20);
+ m_xCertPathList->set_column_fixed_widths(aWidths);
+
+ std::vector<int> aRadioColumns;
+ aRadioColumns.push_back(0);
+ m_xCertPathList->set_toggle_columns_as_radio(aRadioColumns);
+
+ m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
+ m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
+ m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
+
+ try
+ {
+ // In the reverse order of preference for the default selected profile
+ mozilla::MozillaProductType const productTypes[3] = {
+ mozilla::MozillaProductType_Thunderbird,
+ mozilla::MozillaProductType_Firefox,
+ mozilla::MozillaProductType_Mozilla };
+ const char* const productNames[3] = {
+ "thunderbird",
+ "firefox",
+ "mozilla" };
+ bool bSelected = false;
+
+ uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap = mozilla::MozillaBootstrap::create( comphelper::getProcessComponentContext() );
+
+ for (sal_Int32 i = 0; i < sal_Int32(SAL_N_ELEMENTS(productTypes)); ++i)
+ {
+ sal_Int32 nProfileCount = xMozillaBootstrap->getProfileCount(productTypes[i]);
+ if (nProfileCount <= 0)
+ continue;
+ OUString sDefaultProfile = xMozillaBootstrap->getDefaultProfile(productTypes[i]);
+ uno::Sequence<OUString> aProfileList(nProfileCount);
+#ifndef NDEBUG
+ sal_Int32 nListLen =
+#endif
+ xMozillaBootstrap->getProfileList(productTypes[i], aProfileList);
+ assert((nProfileCount == nListLen) && (nListLen == aProfileList.getLength()));
+
+ for (const auto& sProfileName : std::as_const(aProfileList))
+ {
+ OUString sEntry = OUString::createFromAscii(productNames[i]) + ":" + sProfileName;
+ OUString sProfilePath = xMozillaBootstrap->getProfilePath(productTypes[i], sProfileName);
+ const bool bSelectDefaultProfile = !bSelected && sProfileName == sDefaultProfile;
+ AddCertPath(sEntry, sProfilePath, bSelectDefaultProfile);
+ if (bSelectDefaultProfile)
+ bSelected = true;
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ try
+ {
+ AddManualCertPath(officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString()));
+ if (m_sManualPath.isEmpty())
+ AddManualCertPath(officecfg::Office::Common::Security::Scripting::ManualCertDir::get(), false);
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::CertPathDialog()");
+ }
+
+ const char* pEnv = getenv("MOZILLA_CERTIFICATE_FOLDER");
+ if (pEnv)
+ AddCertPath("$MOZILLA_CERTIFICATE_FOLDER", OUString(pEnv, strlen(pEnv), osl_getThreadTextEncoding()));
+}
+
+void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
+{
+ if (sUserSetCertPath.isEmpty())
+ return;
+
+ // check existence
+ ::osl::DirectoryItem aUserPathItem;
+ OUString sUserSetCertURLPath;
+ osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
+ if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
+ {
+ ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
+ if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
+ // the cert path exists
+ AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
+ }
+}
+
+IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Security::Scripting::CertDir::set(
+ getDirectory(), batch);
+ officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
+ batch->commit();
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+OUString CertPathDialog::getDirectory() const
+{
+ int nEntry = m_xCertPathList->get_selected_index();
+ if (nEntry == -1)
+ return OUString();
+ return m_xCertPathList->get_id(nEntry);
+}
+
+CertPathDialog::~CertPathDialog()
+{
+}
+
+IMPL_LINK(CertPathDialog, CheckHdl_Impl, const row_col&, rRowCol, void)
+{
+ HandleEntryChecked(rRowCol.first);
+}
+
+void CertPathDialog::HandleEntryChecked(int nRow)
+{
+ const bool bChecked = m_xCertPathList->get_toggle(nRow, 0) == TRISTATE_TRUE;
+ if (bChecked)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xCertPathList->select(nRow);
+ const int nCount = m_xCertPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (i != nRow)
+ m_xCertPathList->set_toggle(i, TRISTATE_FALSE, 0);
+ }
+ }
+}
+
+void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
+{
+ int nRow = -1;
+ for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
+ {
+ OUString sCertPath = m_xCertPathList->get_id(i);
+ //already exists, just select the original one
+ if (sCertPath == rPath)
+ {
+ const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i, 0);
+ m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ HandleEntryChecked(i);
+ return;
+ }
+ else if (m_xCertPathList->get_text(i, 1) == rProfile)
+ nRow = i;
+ }
+
+ if (m_sManualLabel == rProfile)
+ m_sManualPath = rPath;
+
+ if (nRow < 0)
+ {
+ m_xCertPathList->append();
+ nRow = m_xCertPathList->n_children() - 1;
+ }
+ m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xCertPathList->set_text(nRow, rProfile, 1);
+ m_xCertPathList->set_text(nRow, rPath, 2);
+ m_xCertPathList->set_id(nRow, rPath);
+ HandleEntryChecked(nRow);
+}
+
+IMPL_LINK_NOARG(CertPathDialog, ManualHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = ui::dialogs::FolderPicker::create(comphelper::getProcessComponentContext());
+
+ OUString sURL;
+ if (!m_sManualPath.isEmpty())
+ osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
+ if (sURL.isEmpty())
+ osl::Security().getHomeDir(sURL);
+ xFolderPicker->setDisplayDirectory(sURL);
+ xFolderPicker->setDescription(m_sAddDialogText);
+
+ if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ sURL = xFolderPicker->getDirectory();
+ OUString aPath;
+ if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
+ AddCertPath(m_sManualLabel, aPath);
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/certpath.hxx b/cui/source/options/certpath.hxx
new file mode 100644
index 000000000..7ab30955d
--- /dev/null
+++ b/cui/source/options/certpath.hxx
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class CertPathDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Button> m_xManualButton;
+ std::unique_ptr<weld::Button> m_xOKButton;
+ std::unique_ptr<weld::TreeView> m_xCertPathList;
+ OUString m_sAddDialogText;
+ OUString m_sManualLabel;
+ OUString m_sManualPath;
+
+ typedef std::pair<int, int> row_col;
+ DECL_LINK(CheckHdl_Impl, const row_col&, void);
+ DECL_LINK(ManualHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+
+ void HandleEntryChecked(int nRow);
+ void AddCertPath(const OUString& rProfile, const OUString& rPath, bool bSelect = true);
+ void AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect = true);
+
+public:
+ explicit CertPathDialog(weld::Window* pParent);
+ virtual ~CertPathDialog() override;
+
+ OUString getDirectory() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.cxx b/cui/source/options/cfgchart.cxx
new file mode 100644
index 000000000..660241519
--- /dev/null
+++ b/cui/source/options/cfgchart.cxx
@@ -0,0 +1,279 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+#include "cfgchart.hxx"
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#define ROW_COLOR_COUNT 12
+
+using namespace com::sun::star;
+
+// accessors
+size_t SvxChartColorTable::size() const
+{
+ return m_aColorEntries.size();
+}
+
+const XColorEntry & SvxChartColorTable::operator[]( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::[] invalid index" );
+ return m_aColorEntries[ 0 ];
+ }
+
+ return m_aColorEntries[ _nIndex ];
+}
+
+Color SvxChartColorTable::getColor( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::getColorData invalid index" );
+ return COL_BLACK;
+ }
+
+ return m_aColorEntries[ _nIndex ].GetColor().GetRGBColor();
+}
+
+// mutators
+void SvxChartColorTable::clear()
+{
+ m_aColorEntries.clear();
+}
+
+void SvxChartColorTable::append( const XColorEntry & _rEntry )
+{
+ m_aColorEntries.push_back( _rEntry );
+}
+
+void SvxChartColorTable::remove( size_t _nIndex )
+{
+ if (!m_aColorEntries.empty())
+ m_aColorEntries.erase( m_aColorEntries.begin() + _nIndex);
+
+ for (size_t i=0 ; i<m_aColorEntries.size(); i++)
+ {
+ m_aColorEntries[ i ].SetName( getDefaultName( i ) );
+ }
+}
+
+void SvxChartColorTable::replace( size_t _nIndex, const XColorEntry & _rEntry )
+{
+ DBG_ASSERT( _nIndex <= m_aColorEntries.size(),
+ "SvxChartColorTable::replace invalid index" );
+
+ m_aColorEntries[ _nIndex ] = _rEntry;
+}
+
+void SvxChartColorTable::useDefault()
+{
+ static const Color aColors[] = {
+ Color( 0x00, 0x45, 0x86 ),
+ Color( 0xff, 0x42, 0x0e ),
+ Color( 0xff, 0xd3, 0x20 ),
+ Color( 0x57, 0x9d, 0x1c ),
+ Color( 0x7e, 0x00, 0x21 ),
+ Color( 0x83, 0xca, 0xff ),
+ Color( 0x31, 0x40, 0x04 ),
+ Color( 0xae, 0xcf, 0x00 ),
+ Color( 0x4b, 0x1f, 0x6f ),
+ Color( 0xff, 0x95, 0x0e ),
+ Color( 0xc5, 0x00, 0x0b ),
+ Color( 0x00, 0x84, 0xd1 )
+ };
+
+ clear();
+
+ for( sal_Int32 i=0; i<ROW_COLOR_COUNT; i++ )
+ {
+ append( XColorEntry( aColors[ i % sizeof( aColors ) ], getDefaultName( i ) ));
+ }
+}
+
+OUString SvxChartColorTable::getDefaultName( size_t _nIndex )
+{
+ OUString aName;
+
+ OUString sDefaultNamePrefix;
+ OUString sDefaultNamePostfix;
+ OUString aResName( CuiResId( RID_SVXSTR_DIAGRAM_ROW ) );
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ sDefaultNamePrefix = aResName.copy( 0, nPos );
+ sDefaultNamePostfix = aResName.copy( nPos + sizeof( "$(ROW)" ) - 1 );
+ }
+ else
+ {
+ sDefaultNamePrefix = aResName;
+ }
+
+ aName = sDefaultNamePrefix + OUString::number(_nIndex + 1) + sDefaultNamePostfix;
+
+ return aName;
+}
+
+// comparison
+bool SvxChartColorTable::operator==( const SvxChartColorTable & _rOther ) const
+{
+ // note: XColorEntry has no operator ==
+ bool bEqual = ( m_aColorEntries.size() == _rOther.m_aColorEntries.size() );
+
+ if( bEqual )
+ {
+ for( size_t i = 0; i < m_aColorEntries.size(); ++i )
+ {
+ if( getColor( i ) != _rOther.getColor( i ))
+ {
+ bEqual = false;
+ break;
+ }
+ }
+ }
+
+ return bEqual;
+}
+
+
+
+
+SvxChartOptions::SvxChartOptions() :
+ ::utl::ConfigItem( "Office.Chart" ),
+ mbIsInitialized( false )
+{
+ maPropertyNames.realloc( 1 );
+ maPropertyNames[ 0 ] = "DefaultColor/Series";
+}
+
+SvxChartOptions::~SvxChartOptions()
+{
+}
+
+const SvxChartColorTable& SvxChartOptions::GetDefaultColors()
+{
+ if ( !mbIsInitialized )
+ mbIsInitialized = RetrieveOptions();
+ return maDefColors;
+}
+
+void SvxChartOptions::SetDefaultColors( const SvxChartColorTable& aCol )
+{
+ maDefColors = aCol;
+ SetModified();
+}
+
+bool SvxChartOptions::RetrieveOptions()
+{
+ // get sequence containing all properties
+
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aProperties( aNames.getLength());
+ aProperties = GetProperties( aNames );
+
+ if( aProperties.getLength() == aNames.getLength())
+ {
+ // 1. default colors for series
+ maDefColors.clear();
+ uno::Sequence< sal_Int64 > aColorSeq;
+ aProperties[ 0 ] >>= aColorSeq;
+
+ sal_Int32 nCount = aColorSeq.getLength();
+ Color aCol;
+
+ // create strings for entry names
+ OUString aResName( CuiResId( RID_SVXSTR_DIAGRAM_ROW ) );
+ OUString aPrefix, aPostfix, aName;
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ aPrefix = aResName.copy( 0, nPos );
+ sal_Int32 idx = nPos + sizeof( "$(ROW)" ) - 1;
+ aPostfix = aResName.copy( idx );
+ }
+ else
+ aPrefix = aResName;
+
+ // set color values
+ for( sal_Int32 i=0; i < nCount; i++ )
+ {
+ aCol = Color(aColorSeq[ i ]);
+
+ aName = aPrefix + OUString::number(i + 1) + aPostfix;
+
+ maDefColors.append( XColorEntry( aCol, aName ));
+ }
+ return true;
+ }
+ return false;
+}
+
+void SvxChartOptions::ImplCommit()
+{
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aValues( aNames.getLength());
+
+ if( aValues.hasElements() )
+ {
+ // 1. default colors for series
+ // convert list to sequence
+ const size_t nCount = maDefColors.size();
+ uno::Sequence< sal_Int64 > aColors( nCount );
+ for( size_t i=0; i < nCount; i++ )
+ {
+ Color aData = maDefColors.getColor( i );
+ aColors[ i ] = sal_uInt32(aData);
+ }
+
+ aValues[ 0 ] <<= aColors;
+ }
+
+ PutProperties( aNames, aValues );
+}
+
+void SvxChartOptions::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+
+
+
+SvxChartColorTableItem::SvxChartColorTableItem( sal_uInt16 nWhich_, const SvxChartColorTable& aTable ) :
+ SfxPoolItem( nWhich_ ),
+ m_aColorTable( aTable )
+{
+}
+
+SvxChartColorTableItem* SvxChartColorTableItem::Clone( SfxItemPool * ) const
+{
+ return new SvxChartColorTableItem( *this );
+}
+
+bool SvxChartColorTableItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ assert(SfxPoolItem::operator==(rAttr));
+
+ return static_cast<const SvxChartColorTableItem & >( rAttr ).m_aColorTable == m_aColorTable;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.hxx b/cui/source/options/cfgchart.hxx
new file mode 100644
index 000000000..acbe41a9b
--- /dev/null
+++ b/cui/source/options/cfgchart.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <unotools/configitem.hxx>
+#include <svl/poolitem.hxx>
+#include <svx/xtable.hxx>
+
+#include <vector>
+
+class SvxChartColorTable
+{
+private:
+ std::vector< XColorEntry > m_aColorEntries;
+
+public:
+ // accessors
+ size_t size() const;
+ const XColorEntry & operator[]( size_t _nIndex ) const;
+ Color getColor( size_t _nIndex ) const;
+
+ // mutators
+ void clear();
+ void append( const XColorEntry & _rEntry );
+ void remove( size_t _nIndex );
+ void replace( size_t _nIndex, const XColorEntry & _rEntry );
+ void useDefault();
+ static OUString getDefaultName(size_t _nIndex);
+
+ // comparison
+ bool operator==( const SvxChartColorTable & _rOther ) const;
+};
+
+
+// all options
+
+class SvxChartOptions : public ::utl::ConfigItem
+{
+private:
+ SvxChartColorTable maDefColors;
+ bool mbIsInitialized;
+
+ css::uno::Sequence< OUString >
+ maPropertyNames;
+
+ const css::uno::Sequence< OUString >& GetPropertyNames() const
+ { return maPropertyNames; }
+ bool RetrieveOptions();
+
+ virtual void ImplCommit() override;
+
+public:
+ SvxChartOptions();
+ virtual ~SvxChartOptions() override;
+
+ const SvxChartColorTable& GetDefaultColors();
+ void SetDefaultColors( const SvxChartColorTable& aCol );
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+};
+
+
+// items
+// Make Item read-only (no non-const access methods). Two reasons:
+// (1) Preparation for Item refactor
+// (2) Dangerous due to SfxItem may not be what you expect (e.g. when
+// ::Set in SfxItemSet, not your instance may be used there, no control
+// about what will happen without deep knowledge about SfxItems/SfxItemSets)
+class SvxChartColorTableItem : public SfxPoolItem
+{
+public:
+ SvxChartColorTableItem( sal_uInt16 nWhich, const SvxChartColorTable& );
+
+ virtual SvxChartColorTableItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+ virtual bool operator==( const SfxPoolItem& ) const override;
+
+ const SvxChartColorTable & GetColorList() const { return m_aColorTable;}
+
+private:
+ SvxChartColorTable m_aColorTable;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.cxx b/cui/source/options/connpoolconfig.cxx
new file mode 100644
index 000000000..8bf95ee0d
--- /dev/null
+++ b/cui/source/options/connpoolconfig.cxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "connpoolconfig.hxx"
+#include "connpoolsettings.hxx"
+
+#include <svl/itemset.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <unotools/confignode.hxx>
+#include <svl/eitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include "sdbcdriverenum.hxx"
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace offapp
+{
+
+
+ using namespace ::utl;
+ using namespace ::com::sun::star::uno;
+
+
+ static OUString getConnectionPoolNodeName()
+ {
+ return "org.openoffice.Office.DataAccess/ConnectionPool";
+ }
+
+
+ static OUString getEnablePoolingNodeName()
+ {
+ return "EnablePooling";
+ }
+
+
+ static OUString getDriverSettingsNodeName()
+ {
+ return "DriverSettings";
+ }
+
+
+ static OUString getDriverNameNodeName()
+ {
+ return "DriverName";
+ }
+
+
+ static OUString getEnableNodeName()
+ {
+ return "Enable";
+ }
+
+
+ static OUString getTimeoutNodeName()
+ {
+ return "Timeout";
+ }
+
+ void ConnectionPoolConfig::GetOptions(SfxItemSet& _rFillItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName(), -1, OConfigurationTreeRoot::CM_READONLY);
+
+ // the global "enabled" flag
+ Any aEnabled = aConnectionPoolRoot.getNodeValue(getEnablePoolingNodeName());
+ bool bEnabled = true;
+ aEnabled >>= bEnabled;
+ _rFillItems.Put(SfxBoolItem(SID_SB_POOLING_ENABLED, bEnabled));
+
+ // the settings for the single drivers
+ DriverPoolingSettings aSettings;
+ // first get all the drivers register at the driver manager
+ ODriverEnumeration aEnumDrivers;
+ for (auto const& elem : aEnumDrivers)
+ {
+ aSettings.push_back(DriverPooling(elem));
+ }
+
+ // then look for which of them settings are stored in the configuration
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+
+ Sequence< OUString > aDriverKeys = aDriverSettings.getNodeNames();
+ const OUString* pDriverKeys = aDriverKeys.getConstArray();
+ const OUString* pDriverKeysEnd = pDriverKeys + aDriverKeys.getLength();
+ for (;pDriverKeys != pDriverKeysEnd; ++pDriverKeys)
+ {
+ // the name of the driver in this round
+ OConfigurationNode aThisDriverSettings = aDriverSettings.openNode(*pDriverKeys);
+ OUString sThisDriverName;
+ aThisDriverSettings.getNodeValue(getDriverNameNodeName()) >>= sThisDriverName;
+
+ // look if we (resp. the driver manager) know this driver
+ // doing O(n) search here, which is expensive, but this doesn't matter in this small case ...
+ DriverPoolingSettings::iterator aLookup;
+ for ( aLookup = aSettings.begin();
+ aLookup != aSettings.end();
+ ++aLookup
+ )
+ if (sThisDriverName == aLookup->sName)
+ break;
+
+ if (aLookup == aSettings.end())
+ { // do not know the driver - add it
+ aSettings.push_back(DriverPooling(sThisDriverName));
+
+ // and the position of the new entry
+ aLookup = aSettings.end();
+ --aLookup;
+ }
+
+ // now fill this entry with the settings from the configuration
+ aThisDriverSettings.getNodeValue(getEnableNodeName()) >>= aLookup->bEnabled;
+ aThisDriverSettings.getNodeValue(getTimeoutNodeName()) >>= aLookup->nTimeoutSeconds;
+ }
+
+ _rFillItems.Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, aSettings));
+ }
+
+
+ void ConnectionPoolConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName());
+
+ if (!aConnectionPoolRoot.isValid())
+ // already asserted by the OConfigurationTreeRoot
+ return;
+
+ bool bNeedCommit = false;
+
+ // the global "enabled" flag
+ const SfxBoolItem* pEnabled = _rSourceItems.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ if (pEnabled)
+ {
+ bool bEnabled = pEnabled->GetValue();
+ aConnectionPoolRoot.setNodeValue(getEnablePoolingNodeName(), Any(bEnabled));
+ bNeedCommit = true;
+ }
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSourceItems.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ {
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+ if (!aDriverSettings.isValid())
+ return;
+
+ OUString sThisDriverName;
+ OConfigurationNode aThisDriverSettings;
+
+ const DriverPoolingSettings& rNewSettings = pDriverSettings->getSettings();
+ for (auto const& newSetting : rNewSettings)
+ {
+ // need the name as OUString
+ sThisDriverName = newSetting.sName;
+
+ // the sub-node for this driver
+ if (aDriverSettings.hasByName(newSetting.sName))
+ aThisDriverSettings = aDriverSettings.openNode(newSetting.sName);
+ else
+ aThisDriverSettings = aDriverSettings.createNode(newSetting.sName);
+
+ // set the values
+ aThisDriverSettings.setNodeValue(getDriverNameNodeName(), Any(sThisDriverName));
+ aThisDriverSettings.setNodeValue(getEnableNodeName(), Any(newSetting.bEnabled));
+ aThisDriverSettings.setNodeValue(getTimeoutNodeName(), Any(newSetting.nTimeoutSeconds));
+ }
+ bNeedCommit = true;
+ }
+ if (bNeedCommit)
+ aConnectionPoolRoot.commit();
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.hxx b/cui/source/options/connpoolconfig.hxx
new file mode 100644
index 000000000..41ec88d5b
--- /dev/null
+++ b/cui/source/options/connpoolconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace offapp
+{
+
+ class ConnectionPoolConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.cxx b/cui/source/options/connpooloptions.cxx
new file mode 100644
index 000000000..45ca5d9f3
--- /dev/null
+++ b/cui/source/options/connpooloptions.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <osl/diagnose.h>
+#include "connpooloptions.hxx"
+#include <svtools/editbrowsebox.hxx>
+#include "connpoolsettings.hxx"
+#include <svl/eitem.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+using ::svt::EditBrowseBox;
+
+namespace offapp
+{
+ bool ConnectionPoolOptionsPage::isModifiedDriverList() const
+ {
+ if (m_aSettings.size() != m_aSavedSettings.size())
+ return true;
+
+ DriverPoolingSettings::const_iterator aSaved = m_aSavedSettings.begin();
+ for (auto const& currentSetting : m_aSettings)
+ {
+ if (currentSetting != *aSaved)
+ return true;
+ ++aSaved;
+ }
+
+ return false;
+ }
+
+ ConnectionPoolOptionsPage::ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ : SfxTabPage(pPage, pController, "cui/ui/connpooloptions.ui", "ConnPoolPage", &_rAttrSet)
+ , m_sYes(CuiResId(RID_SVXSTR_YES))
+ , m_sNo(CuiResId(RID_SVXSTR_NO))
+ , m_xEnablePooling(m_xBuilder->weld_check_button("connectionpooling"))
+ , m_xDriversLabel(m_xBuilder->weld_label("driverslabel"))
+ , m_xDriverList(m_xBuilder->weld_tree_view("driverlist"))
+ , m_xDriverLabel(m_xBuilder->weld_label("driverlabel"))
+ , m_xDriver(m_xBuilder->weld_label("driver"))
+ , m_xDriverPoolingEnabled(m_xBuilder->weld_check_button("enablepooling"))
+ , m_xTimeoutLabel(m_xBuilder->weld_label("timeoutlabel"))
+ , m_xTimeout(m_xBuilder->weld_spin_button("timeout"))
+ {
+ m_xDriverList->set_size_request(m_xDriverList->get_approximate_digit_width() * 60,
+ m_xDriverList->get_height_rows(15));
+ m_xDriverList->show();
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xDriverList->get_approximate_digit_width() * 50);
+ aWidths.push_back(m_xDriverList->get_approximate_digit_width() * 8);
+ m_xDriverList->set_column_fixed_widths(aWidths);
+
+ m_xEnablePooling->connect_clicked( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+ m_xDriverPoolingEnabled->connect_clicked( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+
+ m_xDriverList->connect_changed(LINK(this, ConnectionPoolOptionsPage, OnDriverRowChanged));
+ m_xTimeout->connect_value_changed(LINK(this, ConnectionPoolOptionsPage, OnSpinValueChanged));
+ }
+
+ void ConnectionPoolOptionsPage::updateRow(size_t nRow)
+ {
+ auto const& currentSetting = m_aSettings[nRow];
+ m_xDriverList->set_text(nRow, currentSetting.sName, 0);
+ if (currentSetting.bEnabled)
+ {
+ m_xDriverList->set_text(nRow, m_sYes, 1);
+ m_xDriverList->set_text(nRow, OUString::number(currentSetting.nTimeoutSeconds), 2);
+ }
+ else
+ {
+ m_xDriverList->set_text(nRow, m_sNo, 1);
+ m_xDriverList->set_text(nRow, "-", 2);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::updateCurrentRow()
+ {
+ int nRow = m_xDriverList->get_selected_index();
+ if (nRow == -1)
+ return;
+ updateRow(nRow);
+ }
+
+ void ConnectionPoolOptionsPage::UpdateDriverList(const DriverPoolingSettings& _rSettings)
+ {
+ m_aSettings = _rSettings;
+
+ m_xDriverList->freeze();
+ m_xDriverList->clear();
+
+ for (size_t i = 0; i < m_aSettings.size(); ++i)
+ {
+ m_xDriverList->append();
+ updateRow(i);
+ }
+
+ m_xDriverList->thaw();
+
+ if (!m_aSettings.empty())
+ {
+ m_xDriverList->select(0);
+ OnDriverRowChanged(*m_xDriverList);
+ }
+ }
+
+ ConnectionPoolOptionsPage::~ConnectionPoolOptionsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ConnectionPoolOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<ConnectionPoolOptionsPage>(pPage, pController, *_rAttrSet);
+ }
+
+ void ConnectionPoolOptionsPage::implInitControls(const SfxItemSet& _rSet)
+ {
+ // the enabled flag
+ const SfxBoolItem* pEnabled = _rSet.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ OSL_ENSURE(pEnabled, "ConnectionPoolOptionsPage::implInitControls: missing the Enabled item!");
+ m_xEnablePooling->set_active(pEnabled == nullptr || pEnabled->GetValue());
+
+ m_xEnablePooling->save_state();
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSet.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ UpdateDriverList(pDriverSettings->getSettings());
+ else
+ {
+ OSL_FAIL("ConnectionPoolOptionsPage::implInitControls: missing the DriverTimeouts item!");
+ UpdateDriverList(DriverPoolingSettings());
+ }
+ saveDriverList();
+
+ // reflect the new settings
+ OnEnabledDisabled(*m_xEnablePooling);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnSpinValueChanged, weld::SpinButton&, void)
+ {
+ commitTimeoutField();
+ }
+
+ bool ConnectionPoolOptionsPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ commitTimeoutField();
+
+ bool bModified = false;
+ // the enabled flag
+ if (m_xEnablePooling->get_state_changed_from_saved())
+ {
+ _rSet->Put(SfxBoolItem(SID_SB_POOLING_ENABLED, m_xEnablePooling->get_active()));
+ bModified = true;
+ }
+
+ // the settings for the single drivers
+ if (isModifiedDriverList())
+ {
+ _rSet->Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, m_aSettings));
+ bModified = true;
+ }
+
+ return bModified;
+ }
+
+ void ConnectionPoolOptionsPage::ActivatePage( const SfxItemSet& _rSet)
+ {
+ SfxTabPage::ActivatePage(_rSet);
+ implInitControls(_rSet);
+ }
+
+ void ConnectionPoolOptionsPage::Reset(const SfxItemSet* _rSet)
+ {
+ implInitControls(*_rSet);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnDriverRowChanged, weld::TreeView&, void)
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ bool bValidRow = (nDriverPos != -1);
+ m_xDriverPoolingEnabled->set_sensitive(bValidRow && m_xEnablePooling->get_active());
+ m_xTimeoutLabel->set_sensitive(bValidRow);
+ m_xTimeout->set_sensitive(bValidRow);
+
+ if (!bValidRow)
+ { // positioned on an invalid row
+ m_xDriver->set_label(OUString());
+ }
+ else
+ {
+ auto const& currentSetting = m_aSettings[nDriverPos];
+ m_xDriver->set_label(currentSetting.sName);
+ m_xDriverPoolingEnabled->set_active(currentSetting.bEnabled);
+ m_xTimeout->set_value(currentSetting.nTimeoutSeconds);
+
+ OnEnabledDisabled(*m_xDriverPoolingEnabled);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::commitTimeoutField()
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].nTimeoutSeconds = m_xTimeout->get_value();
+ updateCurrentRow();
+ }
+
+ IMPL_LINK( ConnectionPoolOptionsPage, OnEnabledDisabled, weld::Button&, rCheckBox, void )
+ {
+ bool bGloballyEnabled = m_xEnablePooling->get_active();
+ bool bLocalDriverChanged = m_xDriverPoolingEnabled.get() == &rCheckBox;
+
+ if (m_xEnablePooling.get() == &rCheckBox)
+ {
+ m_xDriversLabel->set_sensitive(bGloballyEnabled);
+ m_xDriverList->set_sensitive(bGloballyEnabled);
+ if (!bGloballyEnabled)
+ m_xDriverList->select(-1);
+ m_xDriverLabel->set_sensitive(bGloballyEnabled);
+ m_xDriver->set_sensitive(bGloballyEnabled);
+ m_xDriverPoolingEnabled->set_sensitive(bGloballyEnabled);
+ }
+ else
+ OSL_ENSURE(bLocalDriverChanged, "ConnectionPoolOptionsPage::OnEnabledDisabled: where did this come from?");
+
+ m_xTimeoutLabel->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+ m_xTimeout->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+
+ if (bLocalDriverChanged)
+ {
+ // update the list
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].bEnabled = m_xDriverPoolingEnabled->get_active();
+ updateCurrentRow();
+ }
+ }
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.hxx b/cui/source/options/connpooloptions.hxx
new file mode 100644
index 000000000..570ec66ab
--- /dev/null
+++ b/cui/source/options/connpooloptions.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+#include "connpoolsettings.hxx"
+
+namespace offapp
+{
+ class ConnectionPoolOptionsPage final : public SfxTabPage
+ {
+ OUString m_sYes;
+ OUString m_sNo;
+ DriverPoolingSettings m_aSettings;
+ DriverPoolingSettings m_aSavedSettings;
+
+ std::unique_ptr<weld::CheckButton> m_xEnablePooling;
+ std::unique_ptr<weld::Label> m_xDriversLabel;
+ std::unique_ptr<weld::TreeView> m_xDriverList;
+ std::unique_ptr<weld::Label> m_xDriverLabel;
+ std::unique_ptr<weld::Label> m_xDriver;
+ std::unique_ptr<weld::CheckButton> m_xDriverPoolingEnabled;
+ std::unique_ptr<weld::Label> m_xTimeoutLabel;
+ std::unique_ptr<weld::SpinButton> m_xTimeout;
+
+ public:
+ ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ virtual ~ConnectionPoolOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet);
+
+ private:
+ virtual bool FillItemSet(SfxItemSet* _rSet) override;
+ virtual void Reset(const SfxItemSet* _rSet) override;
+ virtual void ActivatePage( const SfxItemSet& _rSet) override;
+
+ void updateRow(size_t nRow);
+ void updateCurrentRow();
+ void UpdateDriverList(const DriverPoolingSettings& _rSettings);
+ bool isModifiedDriverList() const;
+ void saveDriverList() { m_aSavedSettings = m_aSettings; }
+
+ DECL_LINK(OnEnabledDisabled, weld::Button&, void);
+ DECL_LINK(OnSpinValueChanged, weld::SpinButton&, void);
+ DECL_LINK(OnDriverRowChanged, weld::TreeView&, void);
+
+ void implInitControls(const SfxItemSet& _rSet);
+
+ void commitTimeoutField();
+ };
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.cxx b/cui/source/options/connpoolsettings.cxx
new file mode 100644
index 000000000..46742d826
--- /dev/null
+++ b/cui/source/options/connpoolsettings.cxx
@@ -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 .
+ */
+
+#include "connpoolsettings.hxx"
+
+
+namespace offapp
+{
+
+ DriverPooling::DriverPooling( const OUString& _rName )
+ :sName(_rName)
+ ,bEnabled(false)
+ ,nTimeoutSeconds(120)
+ {
+ }
+
+
+ bool DriverPooling::operator == (const DriverPooling& _rR) const
+ {
+ return (sName == _rR.sName)
+ && (bEnabled == _rR.bEnabled)
+ && (nTimeoutSeconds == _rR.nTimeoutSeconds);
+ }
+
+ DriverPoolingSettings::DriverPoolingSettings()
+ {
+ }
+
+
+ DriverPoolingSettingsItem::DriverPoolingSettingsItem( sal_uInt16 _nId, const DriverPoolingSettings &_rSettings )
+ :SfxPoolItem(_nId)
+ ,m_aSettings(_rSettings)
+ {
+ }
+
+
+ bool DriverPoolingSettingsItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ assert(SfxPoolItem::operator==(_rCompare));
+ const DriverPoolingSettingsItem* pItem = static_cast<const DriverPoolingSettingsItem*>( &_rCompare );
+
+ if (m_aSettings.size() != pItem->m_aSettings.size())
+ return false;
+
+ DriverPoolingSettings::const_iterator aForeign = pItem->m_aSettings.begin();
+ for (auto const& ownSetting : m_aSettings)
+ {
+ if (ownSetting != *aForeign)
+ return false;
+
+ ++aForeign;
+ }
+
+ return true;
+ }
+
+ DriverPoolingSettingsItem* DriverPoolingSettingsItem::Clone( SfxItemPool * ) const
+ {
+ return new DriverPoolingSettingsItem(*this);
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.hxx b/cui/source/options/connpoolsettings.hxx
new file mode 100644
index 000000000..8f8c6bc3b
--- /dev/null
+++ b/cui/source/options/connpoolsettings.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <vector>
+
+#include <rtl/ustring.hxx>
+#include <svl/poolitem.hxx>
+
+
+namespace offapp
+{
+
+ struct DriverPooling
+ {
+ OUString sName;
+ bool bEnabled;
+ sal_Int32 nTimeoutSeconds;
+
+ explicit DriverPooling( const OUString& _rName );
+
+ bool operator == (const DriverPooling& _rR) const;
+ bool operator != (const DriverPooling& _rR) const { return !operator ==(_rR); }
+ };
+
+ class DriverPoolingSettings final
+ {
+ typedef std::vector<DriverPooling> DriverSettings;
+ DriverSettings m_aDrivers;
+
+ public:
+ typedef DriverSettings::const_iterator const_iterator;
+ typedef DriverSettings::iterator iterator;
+
+ DriverPoolingSettings();
+
+ size_t size() const { return m_aDrivers.size(); }
+ DriverPooling& operator[]( size_t nPos ) { return m_aDrivers[nPos]; }
+ bool empty() const { return m_aDrivers.empty(); }
+
+ const_iterator begin() const { return m_aDrivers.begin(); }
+ const_iterator end() const { return m_aDrivers.end(); }
+
+ iterator begin() { return m_aDrivers.begin(); }
+ iterator end() { return m_aDrivers.end(); }
+
+ void push_back(const DriverPooling& _rElement) { m_aDrivers.push_back(_rElement); }
+ };
+
+ class DriverPoolingSettingsItem final : public SfxPoolItem
+ {
+ DriverPoolingSettings m_aSettings;
+
+ public:
+
+ DriverPoolingSettingsItem( sal_uInt16 _nId, const DriverPoolingSettings &_rSettings );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DriverPoolingSettingsItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DriverPoolingSettings& getSettings() const { return m_aSettings; }
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cuisrchdlg.cxx b/cui/source/options/cuisrchdlg.cxx
new file mode 100644
index 000000000..f58985d90
--- /dev/null
+++ b/cui/source/options/cuisrchdlg.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/basedlgs.hxx>
+
+#include <cuisrchdlg.hxx>
+
+#include "optjsearch.hxx"
+
+
+// class SvxJSearchOptionsDialog -----------------------------------------
+
+SvxJSearchOptionsDialog::SvxJSearchOptionsDialog(weld::Window *pParent,
+ const SfxItemSet& rOptionsSet, TransliterationFlags nInitialFlags)
+ : SfxSingleTabDialogController(pParent, &rOptionsSet)
+{
+ // m_xPage will be implicitly destroyed by the
+ // SfxSingleTabDialog destructor
+ SetTabPage(SvxJSearchOptionsPage::Create(get_content_area(), this, &rOptionsSet)); //! implicitly calls m_xPage->Reset(...)!
+ m_pPage = static_cast<SvxJSearchOptionsPage*>(GetTabPage());
+ m_pPage->EnableSaveOptions(false);
+ m_pPage->SetTransliterationFlags(nInitialFlags);
+}
+
+SvxJSearchOptionsDialog::~SvxJSearchOptionsDialog()
+{
+}
+
+TransliterationFlags SvxJSearchOptionsDialog::GetTransliterationFlags() const
+{
+ return m_pPage->GetTransliterationFlags();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregister.cxx b/cui/source/options/dbregister.cxx
new file mode 100644
index 000000000..98fd6d19f
--- /dev/null
+++ b/cui/source/options/dbregister.cxx
@@ -0,0 +1,304 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <dbregister.hxx>
+#include "dbregistersettings.hxx"
+#include <svl/filenotation.hxx>
+#include <helpids.h>
+#include <tools/debug.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/itemset.hxx>
+#include "doclinkdialog.hxx"
+#include <dialmgr.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <svx/databaseregistrationui.hxx>
+
+#define COL_TYPE 0
+
+namespace svx
+{
+
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+using namespace ::svt;
+
+// class RegistrationItemSetHolder -------------------------------------------------
+
+RegistrationItemSetHolder::RegistrationItemSetHolder( const SfxItemSet& _rMasterSet )
+ :m_aRegistrationItems( _rMasterSet )
+{
+ DbRegisteredNamesConfig::GetOptions( m_aRegistrationItems );
+}
+
+RegistrationItemSetHolder::~RegistrationItemSetHolder()
+{
+}
+
+// class DatabaseRegistrationDialog ------------------------------------------------
+
+DatabaseRegistrationDialog::DatabaseRegistrationDialog(weld::Window* pParent, const SfxItemSet& rInAttrs)
+ : RegistrationItemSetHolder(rInAttrs)
+ , SfxSingleTabDialogController(pParent, &getRegistrationItems())
+{
+ SetTabPage(DbRegistrationOptionsPage::Create(get_content_area(), this, &getRegistrationItems()));
+ m_xDialog->set_title(CuiResId(RID_SVXSTR_REGISTERED_DATABASES));
+}
+
+short DatabaseRegistrationDialog::run()
+{
+ short result = SfxSingleTabDialogController::run();
+ if (result == RET_OK)
+ {
+ DBG_ASSERT( GetOutputItemSet(), "DatabaseRegistrationDialog::Execute: no output items!" );
+ if ( GetOutputItemSet() )
+ DbRegisteredNamesConfig::SetOptions( *GetOutputItemSet() );
+ }
+ return result;
+}
+
+// class DbRegistrationOptionsPage --------------------------------------------------
+
+DbRegistrationOptionsPage::DbRegistrationOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/dbregisterpage.ui", "DbRegisterPage", &rSet)
+ , m_nOldCount(0)
+ , m_bModified(false)
+ , m_xNew(m_xBuilder->weld_button("new"))
+ , m_xEdit(m_xBuilder->weld_button("edit"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("pathctrl"))
+ , m_xIter(m_xPathBox->make_iterator())
+{
+ Size aControlSize(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(12));
+ m_xPathBox->set_size_request(aControlSize.Width(), aControlSize.Height());
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xPathBox->get_approximate_digit_width() * 20);
+ m_xPathBox->set_column_fixed_widths(aWidths);
+
+ m_xNew->connect_clicked( LINK( this, DbRegistrationOptionsPage, NewHdl ) );
+ m_xEdit->connect_clicked( LINK( this, DbRegistrationOptionsPage, EditHdl ) );
+ m_xDelete->connect_clicked( LINK( this, DbRegistrationOptionsPage, DeleteHdl ) );
+
+ m_xPathBox->connect_column_clicked(LINK(this, DbRegistrationOptionsPage, HeaderSelect_Impl));
+
+ m_xPathBox->make_sorted();
+ m_xPathBox->connect_row_activated( LINK( this, DbRegistrationOptionsPage, PathBoxDoubleClickHdl ) );
+ m_xPathBox->connect_changed( LINK( this, DbRegistrationOptionsPage, PathSelect_Impl ) );
+
+ m_xPathBox->set_help_id(HID_DBPATH_CTL_PATH);
+}
+
+DbRegistrationOptionsPage::~DbRegistrationOptionsPage()
+{
+ for (int i = 0, nCount = m_xPathBox->n_children(); i < nCount; ++i )
+ delete reinterpret_cast<DatabaseRegistration*>(m_xPathBox->get_id(i).toInt64());
+}
+
+std::unique_ptr<SfxTabPage> DbRegistrationOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<DbRegistrationOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool DbRegistrationOptionsPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ // the settings for the single drivers
+ bool bModified = false;
+ DatabaseRegistrations aRegistrations;
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ DatabaseRegistration* pRegistration = reinterpret_cast<DatabaseRegistration*>(m_xPathBox->get_id(i).toInt64());
+ if ( pRegistration && !pRegistration->sLocation.isEmpty() )
+ {
+ OUString sName(m_xPathBox->get_text(i, 0));
+ OFileNotation aTransformer( pRegistration->sLocation );
+ aRegistrations[ sName ] = DatabaseRegistration( aTransformer.get( OFileNotation::N_URL ), pRegistration->bReadOnly );
+ }
+ }
+ if ( m_nOldCount != aRegistrations.size() || m_bModified )
+ {
+ rCoreSet->Put(DatabaseMapItem( SID_SB_DB_REGISTER, aRegistrations ));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void DbRegistrationOptionsPage::Reset( const SfxItemSet* rSet )
+{
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = rSet->GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ m_xPathBox->clear();
+
+ const DatabaseRegistrations& rRegistrations = pRegistrations->getRegistrations();
+ m_nOldCount = rRegistrations.size();
+ for (auto const& elem : rRegistrations)
+ {
+ OFileNotation aTransformer( elem.second.sLocation );
+ insertNewEntry( elem.first, aTransformer.get( OFileNotation::N_SYSTEM ), elem.second.bReadOnly );
+ }
+
+ OUString aUserData = GetUserData();
+ if ( !aUserData.isEmpty() )
+ {
+ sal_Int32 nIdx {0};
+ // restore column width
+ std::vector<int> aWidths;
+ aWidths.push_back(aUserData.getToken(0, ';', nIdx).toInt32());
+ m_xPathBox->set_column_fixed_widths(aWidths);
+ // restore sort direction
+ bool bUp = aUserData.getToken(0, ';', nIdx).toInt32() != 0;
+ m_xPathBox->set_sort_order(bUp);
+ m_xPathBox->set_sort_indicator(bUp ? TRISTATE_TRUE : TRISTATE_FALSE, COL_TYPE);
+ }
+}
+
+void DbRegistrationOptionsPage::FillUserData()
+{
+ OUString aUserData = OUString::number( m_xPathBox->get_column_width(COL_TYPE) ) + ";";
+ bool bUp = m_xPathBox->get_sort_order();
+ aUserData += (bUp ? OUStringLiteral("1") : OUStringLiteral("0"));
+ SetUserData( aUserData );
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, DeleteHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo, CuiResId(RID_SVXSTR_QUERY_DELETE_CONFIRM)));
+ if (xQuery->run() == RET_YES)
+ m_xPathBox->remove(nEntry);
+ }
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, NewHdl, weld::Button&, void)
+{
+ openLinkDialog(OUString(),OUString());
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathBoxDoubleClickHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEdit);
+ return true;
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ DatabaseRegistration* pOldRegistration = reinterpret_cast<DatabaseRegistration*>(m_xPathBox->get_id(nEntry).toInt64());
+ if (!pOldRegistration || pOldRegistration->bReadOnly)
+ return;
+
+ OUString sOldName = m_xPathBox->get_text(nEntry, 0);
+ openLinkDialog(sOldName, pOldRegistration->sLocation, nEntry);
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, HeaderSelect_Impl, int, nCol, void )
+{
+ if (nCol != COL_TYPE)
+ return;
+
+ bool bSortMode = m_xPathBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ bSortMode = !bSortMode;
+ m_xPathBox->set_sort_order(bSortMode);
+
+ //sort lists
+ m_xPathBox->set_sort_indicator(bSortMode ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ DatabaseRegistration* pRegistration = reinterpret_cast<DatabaseRegistration*>(m_xPathBox->get_selected_id().toInt64());
+
+ bool bReadOnly = true;
+ if (pRegistration)
+ {
+ bReadOnly = pRegistration->bReadOnly;
+ }
+
+ m_xEdit->set_sensitive( !bReadOnly );
+ m_xDelete->set_sensitive( !bReadOnly );
+}
+
+void DbRegistrationOptionsPage::insertNewEntry(const OUString& _sName,const OUString& _sLocation, const bool _bReadOnly)
+{
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(new DatabaseRegistration(_sLocation, _bReadOnly))));
+ m_xPathBox->insert(nullptr, -1, &_sName, &sId, nullptr, nullptr, nullptr, false, m_xIter.get());
+
+ if (_bReadOnly)
+ m_xPathBox->set_image(*m_xIter, RID_SVXBMP_LOCK);
+
+ m_xPathBox->set_text(*m_xIter, _sLocation, 1);
+}
+
+void DbRegistrationOptionsPage::openLinkDialog(const OUString& sOldName, const OUString& sOldLocation, int nEntry)
+{
+ ODocumentLinkDialog aDlg(GetFrameWeld(), nEntry == -1);
+
+ aDlg.setLink(sOldName, sOldLocation);
+ aDlg.setNameValidator(LINK( this, DbRegistrationOptionsPage, NameValidator ) );
+
+ if (aDlg.run() != RET_OK)
+ return;
+
+ OUString sNewName,sNewLocation;
+ aDlg.getLink(sNewName,sNewLocation);
+ if ( nEntry == -1 || sNewName != sOldName || sNewLocation != sOldLocation )
+ {
+ if (nEntry != -1)
+ {
+ delete reinterpret_cast<DatabaseRegistration*>(m_xPathBox->get_id(nEntry).toInt64());
+ m_xPathBox->remove(nEntry);
+ }
+ insertNewEntry( sNewName, sNewLocation, false );
+ m_bModified = true;
+ }
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, NameValidator, const OUString&, _rName, bool )
+{
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (m_xPathBox->get_text(i, 0) == _rName)
+ return false;
+ }
+ return true;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.cxx b/cui/source/options/dbregisterednamesconfig.cxx
new file mode 100644
index 000000000..87681866e
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregisterednamesconfig.hxx"
+#include "dbregistersettings.hxx"
+#include <svx/databaseregistrationui.hxx>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svl/itemset.hxx>
+#include <tools/diagnose_ex.h>
+
+
+namespace svx
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::container;
+
+ void DbRegisteredNamesConfig::GetOptions( SfxItemSet& _rFillItems )
+ {
+ DatabaseRegistrations aSettings;
+
+ try
+ {
+ Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(xContext) );
+
+ Sequence< OUString > aRegistrationNames( xRegistrations->getRegistrationNames() );
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ OUString sLocation( xRegistrations->getDatabaseLocation( *pRegistrationName ) );
+ aSettings[ *pRegistrationName ] =
+ DatabaseRegistration( sLocation, xRegistrations->isDatabaseRegistrationReadOnly( *pRegistrationName ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options");
+ }
+
+ _rFillItems.Put( DatabaseMapItem( SID_SB_DB_REGISTER, aSettings ) );
+ }
+
+
+ void DbRegisteredNamesConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = _rSourceItems.GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ try
+ {
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(
+ comphelper::getProcessComponentContext()));
+
+ const DatabaseRegistrations& rNewRegistrations = pRegistrations->getRegistrations();
+ for ( DatabaseRegistrations::const_iterator reg = rNewRegistrations.begin();
+ reg != rNewRegistrations.end();
+ ++reg
+ )
+ {
+ const OUString sName = reg->first;
+ const OUString sLocation = reg->second.sLocation;
+
+ if ( xRegistrations->hasRegisteredDatabase( sName ) )
+ {
+ if ( !xRegistrations->isDatabaseRegistrationReadOnly( sName ) )
+ xRegistrations->changeDatabaseLocation( sName, sLocation );
+ else
+ {
+ OSL_ENSURE( xRegistrations->getDatabaseLocation( sName ) == sLocation,
+ "DbRegisteredNamesConfig::SetOptions: somebody changed a read-only registration. How unrespectful." );
+ }
+ }
+ else
+ xRegistrations->registerDatabaseLocation( sName, sLocation );
+ }
+
+ // delete unused entries
+ Sequence< OUString > aRegistrationNames = xRegistrations->getRegistrationNames();
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ if ( rNewRegistrations.find( *pRegistrationName ) == rNewRegistrations.end() )
+ xRegistrations->revokeDatabaseLocation( *pRegistrationName );
+ }
+ }
+ catch( const Exception& )
+ {
+ //DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.hxx b/cui/source/options/dbregisterednamesconfig.hxx
new file mode 100644
index 000000000..9decf7e11
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace svx
+{
+
+ class DbRegisteredNamesConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.cxx b/cui/source/options/dbregistersettings.cxx
new file mode 100644
index 000000000..f7739a109
--- /dev/null
+++ b/cui/source/options/dbregistersettings.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregistersettings.hxx"
+
+#include <rtl/ustring.hxx>
+
+
+namespace svx
+{
+
+ DatabaseMapItem::DatabaseMapItem( sal_uInt16 _nId, const DatabaseRegistrations& _rRegistrations )
+ :SfxPoolItem( _nId )
+ ,m_aRegistrations( _rRegistrations )
+ {
+ }
+
+ bool DatabaseMapItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ if (!SfxPoolItem::operator==(_rCompare))
+ return false;
+ const DatabaseMapItem* pItem = static_cast<const DatabaseMapItem*>( &_rCompare );
+ if ( !pItem )
+ return false;
+
+ if ( m_aRegistrations.size() != pItem->m_aRegistrations.size() )
+ return false;
+
+ return m_aRegistrations == pItem->m_aRegistrations;
+ }
+
+ DatabaseMapItem* DatabaseMapItem::Clone( SfxItemPool* ) const
+ {
+ return new DatabaseMapItem( *this );
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.hxx b/cui/source/options/dbregistersettings.hxx
new file mode 100644
index 000000000..9146afe7b
--- /dev/null
+++ b/cui/source/options/dbregistersettings.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <svl/poolitem.hxx>
+
+
+namespace svx
+{
+
+
+ struct DatabaseRegistration
+ {
+ OUString sLocation;
+ bool bReadOnly;
+
+ DatabaseRegistration()
+ :sLocation()
+ ,bReadOnly( true )
+ {
+ }
+
+ DatabaseRegistration( const OUString& _rLocation, const bool _bReadOnly )
+ :sLocation( _rLocation )
+ ,bReadOnly( _bReadOnly )
+ {
+ }
+
+ bool operator==( const DatabaseRegistration& _rhs ) const
+ {
+ return ( sLocation == _rhs.sLocation );
+ // do not take the read-only-ness into account, this is not maintained everywhere, but only
+ // properly set when filling the struct from the XDatabaseRegistrations data
+ }
+
+ };
+
+ typedef std::map< OUString, DatabaseRegistration > DatabaseRegistrations;
+
+ class DatabaseMapItem final : public SfxPoolItem
+ {
+ DatabaseRegistrations m_aRegistrations;
+
+ public:
+
+ DatabaseMapItem( sal_uInt16 _nId, const DatabaseRegistrations& _rRegistrations );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DatabaseMapItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DatabaseRegistrations&
+ getRegistrations() const { return m_aRegistrations; }
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.cxx b/cui/source/options/doclinkdialog.cxx
new file mode 100644
index 000000000..4218a18a1
--- /dev/null
+++ b/cui/source/options/doclinkdialog.cxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "doclinkdialog.hxx"
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <comphelper/processfactory.hxx>
+#include <strings.hrc>
+#include <svl/filenotation.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <ucbhelper/content.hxx>
+#include <dialmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfilt.hxx>
+
+namespace svx
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::svt;
+
+ ODocumentLinkDialog::ODocumentLinkDialog(weld::Window* pParent, bool _bCreateNew)
+ : GenericDialogController(pParent, "cui/ui/databaselinkdialog.ui", "DatabaseLinkDialog")
+ , m_xBrowseFile(m_xBuilder->weld_button("browse"))
+ , m_xName(m_xBuilder->weld_entry("name"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xURL(new SvtURLBox(m_xBuilder->weld_combo_box("url")))
+ {
+ if (!_bCreateNew)
+ m_xDialog->set_title(m_xAltTitle->get_label());
+
+ m_xURL->SetSmartProtocol(INetProtocol::File);
+ m_xURL->DisableHistory();
+ m_xURL->SetFilter("*.odb");
+
+ m_xName->connect_changed( LINK(this, ODocumentLinkDialog, OnEntryModified) );
+ m_xURL->connect_changed( LINK(this, ODocumentLinkDialog, OnComboBoxModified) );
+ m_xBrowseFile->connect_clicked( LINK(this, ODocumentLinkDialog, OnBrowseFile) );
+ m_xOK->connect_clicked( LINK(this, ODocumentLinkDialog, OnOk) );
+
+ validate();
+ }
+
+ ODocumentLinkDialog::~ODocumentLinkDialog()
+ {
+ }
+
+ void ODocumentLinkDialog::setLink(const OUString& rName, const OUString& rURL)
+ {
+ m_xName->set_text(rName);
+ m_xURL->set_entry_text(rURL);
+ validate();
+ }
+
+ void ODocumentLinkDialog::getLink(OUString& rName, OUString& rURL) const
+ {
+ rName = m_xName->get_text();
+ rURL = m_xURL->get_active_text();
+ }
+
+ void ODocumentLinkDialog::validate( )
+ {
+ m_xOK->set_sensitive((!m_xName->get_text().isEmpty()) && (!m_xURL->get_active_text().isEmpty()));
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnOk, weld::Button&, void)
+ {
+ // get the current URL
+ OUString sURL = m_xURL->get_active_text();
+ OFileNotation aTransformer(sURL);
+ sURL = aTransformer.get(OFileNotation::N_URL);
+
+ // check for the existence of the selected file
+ bool bFileExists = false;
+ try
+ {
+ ::ucbhelper::Content aFile(sURL, Reference< XCommandEnvironment >(), comphelper::getProcessComponentContext());
+ if (aFile.isDocument())
+ bFileExists = true;
+ }
+ catch(Exception&)
+ {
+ }
+
+ if (!bFileExists)
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_DOESNOTEXIST);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ } // if (!bFileExists)
+ INetURLObject aURL( sURL );
+ if ( aURL.GetProtocol() != INetProtocol::File )
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_NO_SYSTEM_FILE);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ }
+
+ OUString sCurrentText = m_xName->get_text();
+ if ( m_aNameValidator.IsSet() )
+ {
+ if ( !m_aNameValidator.Call( sCurrentText ) )
+ {
+ OUString sMsg = CuiResId(STR_NAME_CONFLICT);
+ sMsg = sMsg.replaceFirst("$file$", sCurrentText);
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ return;
+ }
+ }
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnBrowseFile, weld::Button&, void)
+ {
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, FileDialogFlags::NONE, m_xDialog.get());
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName("StarOffice XML (Base)");
+ if ( pFilter )
+ {
+ aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
+ aFileDlg.SetCurrentFilter(pFilter->GetUIName());
+ }
+
+ OUString sPath = m_xURL->get_active_text();
+ if (!sPath.isEmpty())
+ {
+ OFileNotation aTransformer( sPath, OFileNotation::N_SYSTEM );
+ aFileDlg.SetDisplayDirectory( aTransformer.get( OFileNotation::N_URL ) );
+ }
+
+ if (ERRCODE_NONE != aFileDlg.Execute())
+ return;
+
+ if (m_xName->get_text().isEmpty())
+ { // default the name to the base of the chosen URL
+ INetURLObject aParser;
+
+ aParser.SetSmartProtocol(INetProtocol::File);
+ aParser.SetSmartURL(aFileDlg.GetPath());
+
+ m_xName->set_text(aParser.getBase(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset));
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ }
+ else
+ m_xURL->grab_focus();
+
+ // get the path in system notation
+ OFileNotation aTransformer(aFileDlg.GetPath(), OFileNotation::N_URL);
+ m_xURL->set_entry_text(aTransformer.get(OFileNotation::N_SYSTEM));
+
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnEntryModified, weld::Entry&, void)
+ {
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnComboBoxModified, weld::ComboBox&, void)
+ {
+ validate();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.hxx b/cui/source/options/doclinkdialog.hxx
new file mode 100644
index 000000000..371dc6504
--- /dev/null
+++ b/cui/source/options/doclinkdialog.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <svtools/inettbc.hxx>
+
+namespace svx
+{
+ /** dialog for editing document links associated with data sources
+ */
+ class ODocumentLinkDialog final : public weld::GenericDialogController
+ {
+ Link<const OUString&,bool> m_aNameValidator;
+
+ std::unique_ptr<weld::Button> m_xBrowseFile;
+ std::unique_ptr<weld::Entry> m_xName;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<SvtURLBox> m_xURL;
+
+ public:
+ ODocumentLinkDialog(weld::Window* pParent, bool bCreateNew);
+ virtual ~ODocumentLinkDialog() override;
+
+ // name validation has to be done by an external instance
+ // the validator link gets a pointer to a String, and should return 0 if the string is not
+ // acceptable
+ void setNameValidator( const Link<const OUString&,bool>& _rValidator ) { m_aNameValidator = _rValidator; }
+
+ void setLink( const OUString& _rName, const OUString& _rURL );
+ void getLink( OUString& _rName, OUString& _rURL ) const;
+
+ private:
+ DECL_LINK( OnEntryModified, weld::Entry&, void );
+ DECL_LINK( OnComboBoxModified, weld::ComboBox&, void );
+ DECL_LINK( OnBrowseFile, weld::Button&, void );
+ DECL_LINK( OnOk, weld::Button&, void );
+
+ void validate();
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.cxx b/cui/source/options/fontsubs.cxx
new file mode 100644
index 000000000..d6e724fa4
--- /dev/null
+++ b/cui/source/options/fontsubs.cxx
@@ -0,0 +1,415 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/fontsubstconfig.hxx>
+#include "fontsubs.hxx"
+#include <helpids.h>
+
+/*********************************************************************/
+/* */
+/* TabPage font replacement */
+/* */
+/*********************************************************************/
+
+SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
+ , m_xConfig(new SvtFontSubstConfig)
+ , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
+ , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
+ , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
+ , m_xApply(m_xBuilder->weld_button("apply"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
+ , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
+ , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
+ , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
+{
+ m_xFont1CB->make_sorted();
+ m_xFont1CB->set_size_request(1, -1);
+ m_xFont2CB->make_sorted();
+ m_xFont2CB->set_size_request(1, -1);
+ m_sAutomatic = m_xFontNameLB->get_text(0);
+ assert(!m_sAutomatic.isEmpty());
+
+ m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
+ m_xCheckLB->get_height_rows(8));
+ m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
+ m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
+
+ setColSizes(m_xCheckLB->get_size_request());
+ m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
+
+ m_xCheckLB->set_centered_column(1);
+ m_xCheckLB->set_centered_column(2);
+
+ Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
+ Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
+
+ m_xCheckLB->connect_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
+ m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
+ m_xUseTableCB->connect_clicked(aClickLink);
+ m_xFont1CB->connect_changed(aLink2);
+ m_xFont2CB->connect_changed(aLink2);
+ m_xApply->connect_clicked(aClickLink);
+ m_xDelete->connect_clicked(aClickLink);
+
+ m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
+
+ sal_uInt16 nHeight;
+ for(nHeight = 6; nHeight <= 16; nHeight++)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 18; nHeight <= 28; nHeight+= 2)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 32; nHeight <= 48; nHeight+= 4)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 54; nHeight <= 72; nHeight+= 6)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 80; nHeight <= 96; nHeight+= 8)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+}
+
+IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = m_xCheckLB->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xCheckLB->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xCheckLB->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
+ m_xCheckLB->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+void SvxFontSubstTabPage::setColSizes(const Size& rSize)
+{
+ int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
+ int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(4)).Width();
+ int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
+ int nMin = m_xCheckLB->get_checkbox_column_width();
+ nMax = std::max(nMax, nMin);
+ const int nDoubleMax = 2*nMax;
+ const int nRest = rSize.Width() - nDoubleMax;
+ std::vector<int> aWidths;
+ aWidths.push_back(1); // just abandon the built-in column for checkbuttons and use another
+ aWidths.push_back(nMax);
+ aWidths.push_back(nMax);
+ aWidths.push_back(nRest/2);
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
+{
+ setColSizes(rSize);
+}
+
+SvxFontSubstTabPage::~SvxFontSubstTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
+{
+ m_xConfig->ClearSubstitutions();// remove all entries
+
+ m_xConfig->Enable(m_xUseTableCB->get_active());
+
+ m_xCheckLB->all_foreach([this](weld::TreeIter& rIter) {
+ SubstitutionStruct aAdd;
+ aAdd.sFont = m_xCheckLB->get_text(rIter, 3);
+ aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 4);
+ aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 1);
+ aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 2);
+ m_xConfig->AddSubstitution(aAdd);
+ return false;
+ });
+
+ if(m_xConfig->IsModified())
+ m_xConfig->Commit();
+ m_xConfig->Apply();
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ if (m_xFontHeightLB->get_value_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
+ static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
+ batch);
+ if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::set(
+ m_xNonPropFontsOnlyCB->get_active(), batch);
+ //font name changes cannot be detected by saved values
+ OUString sFontName;
+ if (m_xFontNameLB->get_active() != -1)
+ sFontName = m_xFontNameLB->get_active_text();
+ officecfg::Office::Common::Font::SourceViewFont::FontName::set(
+ std::optional< OUString >(sFontName), batch);
+ batch->commit();
+
+ return false;
+}
+
+void SvxFontSubstTabPage::Reset( const SfxItemSet* )
+{
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ m_xFont1CB->freeze();
+ m_xFont1CB->clear();
+ m_xFont2CB->freeze();
+ m_xFont2CB->clear();
+
+ FontList aFntLst(Application::GetDefaultDevice());
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName(i);
+ m_xFont1CB->append_text(rFontMetric.GetFamilyName());
+ m_xFont2CB->append_text(rFontMetric.GetFamilyName());
+ }
+
+ m_xFont2CB->thaw();
+ m_xFont1CB->thaw();
+
+ sal_Int32 nCount = m_xConfig->SubstitutionCount();
+ if (nCount)
+ m_xUseTableCB->set_active(m_xConfig->IsEnabled());
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ m_xCheckLB->append(xIter.get());
+ const SubstitutionStruct* pSubs = m_xConfig->GetSubstitution(i);
+ m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
+ m_xCheckLB->set_toggle(*xIter, pSubs->bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 2);
+ m_xCheckLB->set_text(*xIter, pSubs->sFont, 3);
+ m_xCheckLB->set_text(*xIter, pSubs->sReplaceBy, 4);
+ }
+
+ m_xCheckLB->thaw();
+
+ m_xCheckLB->make_sorted();
+ m_xCheckLB->set_sort_column(3);
+ m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 3);
+
+ CheckEnable();
+
+ //fill font name box first
+ m_xNonPropFontsOnlyCB->set_active(
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::get());
+ NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
+ OUString sFontName(
+ officecfg::Office::Common::Font::SourceViewFont::FontName::get().
+ value_or(OUString()));
+ if(!sFontName.isEmpty())
+ m_xFontNameLB->set_active_text(sFontName);
+ else
+ m_xFontNameLB->set_active(0);
+ m_xFontHeightLB->set_active_text(
+ OUString::number(
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::
+ get()));
+ m_xNonPropFontsOnlyCB->save_state();
+ m_xFontHeightLB->save_value();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+namespace
+{
+ // search in the "font" column
+ int findText(const weld::TreeView& rTreeView, const OUString& rCol)
+ {
+ for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
+ {
+ if (rTreeView.get_text(i, 3) == rCol)
+ return i;
+ }
+ return -1;
+ }
+
+ bool findRow(const weld::TreeView& rTreeView, const OUString& rCol1, const OUString& rCol2)
+ {
+ int nRow = findText(rTreeView, rCol1);
+ if (nRow == -1)
+ return false;
+ return rTreeView.get_text(nRow, 4) == rCol2;
+ }
+}
+
+void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
+{
+ if (pWin == m_xApply.get() || pWin == m_xDelete.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+ if (pWin == m_xApply.get())
+ {
+ m_xCheckLB->unselect_all();
+ if (nPos != -1)
+ {
+ // change entry
+ m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 4);
+ m_xCheckLB->select(nPos);
+ }
+ else
+ {
+ // new entry
+ OUString sFont1 = m_xFont1CB->get_active_text();
+ OUString sFont2 = m_xFont2CB->get_active_text();
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 2);
+ m_xCheckLB->set_text(*xIter, sFont1, 3);
+ m_xCheckLB->set_text(*xIter, sFont2, 4);
+ m_xCheckLB->select(*xIter);
+ }
+ }
+ else if (pWin == m_xDelete.get())
+ {
+ m_xCheckLB->remove_selection();
+ }
+ }
+
+ if (pWin == m_xCheckLB.get())
+ {
+ if (m_xCheckLB->count_selected_rows() == 1)
+ {
+ int nRow = m_xCheckLB->get_selected_index();
+ m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
+ m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 4));
+ }
+ }
+
+ if (pWin == m_xFont1CB.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+
+ if (nPos != -1)
+ {
+ int nSelectedRow = m_xCheckLB->get_selected_index();
+ if (nPos != nSelectedRow)
+ {
+ m_xCheckLB->unselect_all();
+ m_xCheckLB->select(nPos);
+ }
+ }
+ }
+
+ CheckEnable();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::ToggleButton&, rBox, void)
+{
+ OUString sFontName = m_xFontNameLB->get_active_text();
+ bool bNonPropOnly = rBox.get_active();
+ m_xFontNameLB->clear();
+ FontList aFntLst( Application::GetDefaultDevice() );
+ m_xFontNameLB->append_text(m_sAutomatic);
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
+ if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
+ m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
+ }
+ m_xFontNameLB->set_active_text(sFontName);
+}
+
+void SvxFontSubstTabPage::CheckEnable()
+{
+ bool bEnableAll = m_xUseTableCB->get_active();
+ m_xCheckLB->set_sensitive(bEnableAll);
+ if (bEnableAll)
+ {
+ bool bApply, bDelete;
+
+ int nEntry = m_xCheckLB->get_selected_index();
+
+ // because of OS/2 optimization error (Bug #56267) a bit more intricate:
+ if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
+ bApply = false;
+ else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
+ bApply = false;
+ else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
+ bApply = false;
+ else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
+ bApply = false;
+ else
+ bApply = true;
+
+ bDelete = nEntry != -1;
+
+ m_xApply->set_sensitive(bApply);
+ m_xDelete->set_sensitive(bDelete);
+ }
+
+ if (bEnableAll)
+ {
+ if (!m_xCheckLB->get_sensitive())
+ {
+ m_xCheckLB->set_sensitive(true);
+ SelectHdl(m_xFont1CB.get());
+ }
+ }
+ else
+ {
+ if (m_xCheckLB->get_sensitive())
+ {
+ m_xCheckLB->set_sensitive(false);
+ m_xCheckLB->unselect_all();
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.hxx b/cui/source/options/fontsubs.hxx
new file mode 100644
index 000000000..7af81e211
--- /dev/null
+++ b/cui/source/options/fontsubs.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxFontSubstTabPage ----------------------------------------------------
+class SvtFontSubstConfig;
+class SvxFontSubstTabPage : public SfxTabPage
+{
+ OUString m_sAutomatic;
+ std::unique_ptr<SvtFontSubstConfig> m_xConfig;
+
+ std::unique_ptr<weld::CheckButton> m_xUseTableCB;
+ std::unique_ptr<weld::ComboBox> m_xFont1CB;
+ std::unique_ptr<weld::ComboBox> m_xFont2CB;
+ std::unique_ptr<weld::Button> m_xApply;
+ std::unique_ptr<weld::Button> m_xDelete;
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::ComboBox> m_xFontNameLB;
+ std::unique_ptr<weld::CheckButton> m_xNonPropFontsOnlyCB;
+ std::unique_ptr<weld::ComboBox> m_xFontHeightLB;
+
+ DECL_LINK(SelectComboBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(ClickHdl, weld::Button&, void);
+ DECL_LINK(TreeListBoxSelectHdl, weld::TreeView&, void);
+ DECL_LINK(NonPropFontsHdl, weld::ToggleButton&, void);
+ DECL_LINK(HeaderBarClick, int, void);
+ DECL_LINK(ResizeHdl, const Size&, void);
+
+ void SelectHdl(const weld::Widget* pWidget);
+
+ void CheckEnable();
+ void setColSizes(const Size& rSize);
+
+public:
+ SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~SvxFontSubstTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.cxx b/cui/source/options/optaboutconfig.cxx
new file mode 100644
index 000000000..7f5e73a80
--- /dev/null
+++ b/cui/source/options/optaboutconfig.cxx
@@ -0,0 +1,932 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.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 "optaboutconfig.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/textsearch.hxx>
+#include <vcl/event.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <memory>
+#include <vector>
+#include <iostream>
+
+using namespace ::com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+
+#define SHORT_LEN_LIMIT 7
+#define LONG_LEN_LIMIT 11
+#define HYPER_LEN_LIMIT 20
+
+struct Prop_Impl
+{
+ OUString Name;
+ OUString Property;
+ Any Value;
+
+ Prop_Impl( const OUString& sName, const OUString& sProperty, const Any& aValue )
+ : Name( sName )
+ , Property( sProperty )
+ , Value( aValue )
+ {}
+};
+
+struct UserData
+{
+ bool bIsPropertyPath;
+ OUString sPropertyPath;
+ int aLineage;
+ Reference<XNameAccess> aXNameAccess;
+
+ explicit UserData( OUString const & rPropertyPath )
+ : bIsPropertyPath( true )
+ , sPropertyPath(rPropertyPath)
+ , aLineage(0)
+ {}
+
+ explicit UserData( Reference<XNameAccess> const & rXNameAccess, int rIndex )
+ : bIsPropertyPath( false )
+ , aLineage(rIndex)
+ , aXNameAccess( rXNameAccess )
+ {}
+};
+
+IMPL_LINK(CuiAboutConfigValueDialog, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ bool bValid = false;
+ bool bNonSpace = rKeyEvent.GetKeyCode().GetCode() != KEY_SPACE;
+ if (m_bNumericOnly && bNonSpace )
+ {
+ const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
+ sal_uInt16 nGroup = rKeyCode.GetGroup();
+ sal_uInt16 nKey = rKeyCode.GetCode();
+
+ switch ( nGroup ) {
+ case KEYGROUP_NUM :
+ case KEYGROUP_CURSOR :
+ {
+ bValid = true;
+ break;
+ }
+
+ case KEYGROUP_MISC :
+ {
+ switch ( nKey ) {
+ case KEY_SUBTRACT :
+ case KEY_COMMA :
+ case KEY_POINT :
+ {
+ bValid = true;
+ break;
+ }
+
+ default :
+ {
+ if( nKey < KEY_ADD || nKey > KEY_EQUAL )
+ bValid = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ default :
+ {
+ bValid = false;
+ break;
+ }
+ }
+
+ //Select all, Copy, Paste, Cut, Undo Keys
+ if ( !bValid && ( rKeyCode.IsMod1() && (
+ KEY_A == nKey || KEY_C == nKey || KEY_V == nKey || KEY_X == nKey || KEY_Z == nKey ) ) )
+ bValid = true;
+ }
+ else
+ bValid = true;
+
+ //if value return true to claim that it has been handled
+ return !bValid;
+}
+
+CuiAboutConfigTabPage::CuiAboutConfigTabPage(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/aboutconfigdialog.ui", "AboutConfig")
+ , m_xResetBtn(m_xBuilder->weld_button("reset"))
+ , m_xEditBtn(m_xBuilder->weld_button("edit"))
+ , m_xSearchBtn(m_xBuilder->weld_button("searchButton"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xPrefBox(m_xBuilder->weld_tree_view("preferences"))
+ , m_xScratchIter(m_xPrefBox->make_iterator())
+ , m_vectorOfModified()
+ , m_bSorted(false)
+{
+ m_xPrefBox->set_size_request(m_xPrefBox->get_approximate_digit_width() * 100,
+ m_xPrefBox->get_height_rows(28));
+ m_xPrefBox->connect_column_clicked(LINK(this, CuiAboutConfigTabPage, HeaderBarClick));
+
+ m_xEditBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, StandardHdl_Impl));
+ m_xResetBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, ResetBtnHdl_Impl));
+ m_xPrefBox->connect_row_activated(LINK(this, CuiAboutConfigTabPage, DoubleClickHdl_Impl));
+ m_xPrefBox->connect_expanding(LINK(this, CuiAboutConfigTabPage, ExpandingHdl_Impl));
+ m_xSearchBtn->connect_clicked(LINK(this, CuiAboutConfigTabPage, SearchHdl_Impl));
+
+ m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_options.searchFlag |= (util::SearchFlags::REG_NOT_BEGINOFLINE |
+ util::SearchFlags::REG_NOT_ENDOFLINE);
+
+ float fWidth = m_xPrefBox->get_approximate_digit_width();
+ std::vector<int> aWidths;
+ aWidths.push_back(fWidth * 65);
+ aWidths.push_back(fWidth * 20);
+ aWidths.push_back(fWidth * 8);
+ m_xPrefBox->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, HeaderBarClick, int, nColumn, void)
+{
+ if (!m_bSorted)
+ {
+ m_xPrefBox->make_sorted();
+ m_bSorted = true;
+ }
+
+ bool bSortAtoZ = m_xPrefBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xPrefBox->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xPrefBox->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ int nOldSortColumn = m_xPrefBox->get_sort_column();
+ if (nOldSortColumn != -1)
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+ m_xPrefBox->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xPrefBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+CuiAboutConfigTabPage::~CuiAboutConfigTabPage()
+{
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const OUString& rPropertyPath, const OUString& rProp, const OUString& rStatus,
+ const OUString& rType, const OUString& rValue, const weld::TreeIter* pParentEntry,
+ bool bInsertToPrefBox)
+{
+ m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath));
+ if (bInsertToPrefBox)
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_vectorUserData.back().get())));
+ m_xPrefBox->insert(pParentEntry, -1, &rProp, &sId, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rValue, 3);
+ }
+ else
+ {
+ m_prefBoxEntries.push_back({rProp, rStatus, rType, rValue, m_vectorUserData.back().get()});
+ }
+}
+
+void CuiAboutConfigTabPage::Reset()
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->clear();
+ m_vectorOfModified.clear();
+ if (m_bSorted)
+ {
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, m_xPrefBox->get_sort_column());
+ m_xPrefBox->make_unsorted();
+ m_bSorted = false;
+ }
+ m_prefBoxEntries.clear();
+ m_modifiedPrefBoxEntries.clear();
+
+ m_xPrefBox->freeze();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ //Load all XNameAccess to m_prefBoxEntries
+ FillItems( xConfigAccess, nullptr, 0, true );
+ //Load xConfigAccess' children to m_prefBox
+ FillItems( xConfigAccess );
+ m_xPrefBox->thaw();
+}
+
+void CuiAboutConfigTabPage::FillItemSet()
+{
+ std::vector< std::shared_ptr< Prop_Impl > >::iterator pIter;
+ for( pIter = m_vectorOfModified.begin() ; pIter != m_vectorOfModified.end(); ++pIter )
+ {
+ Reference< XNameAccess > xUpdateAccess = getConfigAccess( (*pIter)->Name , true );
+ Reference< XNameReplace > xNameReplace( xUpdateAccess, UNO_QUERY_THROW );
+
+ xNameReplace->replaceByName( (*pIter)->Property, (*pIter)->Value );
+
+ Reference< util::XChangesBatch > xChangesBatch( xUpdateAccess, UNO_QUERY_THROW );
+ xChangesBatch->commitChanges();
+ }
+}
+
+void CuiAboutConfigTabPage::FillItems(const Reference< XNameAccess >& xNameAccess, const weld::TreeIter* pParentEntry,
+ int lineage, bool bLoadAll)
+{
+ OUString sPath = Reference< XHierarchicalName >(
+ xNameAccess, uno::UNO_QUERY_THROW )->getHierarchicalName();
+ const uno::Sequence< OUString > seqItems = xNameAccess->getElementNames();
+ for( const OUString& item : seqItems )
+ {
+ Any aNode = xNameAccess->getByName( item );
+
+ bool bNotLeaf = false;
+
+ Reference< XNameAccess > xNextNameAccess;
+ try
+ {
+ xNextNameAccess.set(aNode, uno::UNO_QUERY);
+ bNotLeaf = xNextNameAccess.is();
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "CuiAboutConfigTabPage");
+ }
+
+ if (bNotLeaf)
+ {
+ if(bLoadAll)
+ FillItems(xNextNameAccess, nullptr, lineage + 1, true);
+ else
+ {
+ // not leaf node
+ m_vectorUserData.push_back(std::make_unique<UserData>(xNextNameAccess, lineage + 1));
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(m_vectorUserData.back().get())));
+
+ m_xPrefBox->insert(pParentEntry, -1, &item, &sId, nullptr, nullptr, nullptr, true, m_xScratchIter.get());
+ //It is needed, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*m_xScratchIter, "", 1);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 2);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 3);
+ }
+ }
+ else
+ {
+ // leaf node
+ OUString sPropertyName = item;
+ auto it = std::find_if(m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&sPath, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == sPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ OUString sType = aNode.getValueTypeName();
+ OUStringBuffer sValue;
+
+ if (it != m_modifiedPrefBoxEntries.end())
+ sValue = it->sValue;
+ else
+ {
+ switch( aNode.getValueType().getTypeClass() )
+ {
+ case css::uno::TypeClass_VOID:
+ break;
+
+ case css::uno::TypeClass_BOOLEAN:
+ sValue = OUString::boolean( aNode.get<bool>() );
+ break;
+
+ case css::uno::TypeClass_SHORT:
+ case css::uno::TypeClass_LONG:
+ case css::uno::TypeClass_HYPER:
+ sValue = OUString::number( aNode.get<sal_Int64>() );
+ break;
+
+ case css::uno::TypeClass_DOUBLE:
+ sValue = OUString::number( aNode.get<double>() );
+ break;
+
+ case css::uno::TypeClass_STRING:
+ sValue = aNode.get<OUString>();
+ break;
+
+ case css::uno::TypeClass_SEQUENCE:
+ if( sType == "[]boolean" )
+ {
+ uno::Sequence<sal_Bool> seq = aNode.get< uno::Sequence<sal_Bool> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::boolean( seq[j] ));
+ }
+ }
+ else if( sType == "[]byte" )
+ {
+ uno::Sequence<sal_Int8> seq = aNode.get< uno::Sequence<sal_Int8> >();
+ for( sal_Int8 j : seq )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(j), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ else if( sType == "[][]byte" )
+ {
+ uno::Sequence< uno::Sequence<sal_Int8> > seq = aNode.get< uno::Sequence< uno::Sequence<sal_Int8> > >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ for( sal_Int8 k : seq[j] )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(k), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ }
+ else if( sType == "[]short" )
+ {
+ uno::Sequence<sal_Int16> seq = aNode.get< uno::Sequence<sal_Int16> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::number( seq[j] ));
+ }
+ }
+ else if( sType == "[]long" )
+ {
+ uno::Sequence<sal_Int32> seq = aNode.get< uno::Sequence<sal_Int32> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::number( seq[j] ));
+ }
+ }
+ else if( sType == "[]hyper" )
+ {
+ uno::Sequence<sal_Int64> seq = aNode.get< uno::Sequence<sal_Int64> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::number( seq[j] ));
+ }
+ }
+ else if( sType == "[]double" )
+ {
+ uno::Sequence<double> seq = aNode.get< uno::Sequence<double> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::number( seq[j] ));
+ }
+ }
+ else if( sType == "[]string" )
+ {
+ uno::Sequence<OUString> seq = aNode.get< uno::Sequence<OUString> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(seq[j]);
+ }
+ }
+ else
+ {
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ }
+ break;
+
+ default:
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ break;
+ }
+ }
+
+ //Short name
+ int index = 0;
+ for(int j = 1; j < lineage; ++j)
+ index = sPath.indexOf("/", index + 1);
+
+ InsertEntry(sPath, sPath.copy(index+1), item, sType, sValue.makeStringAndClear(), pParentEntry, !bLoadAll);
+ }
+ }
+}
+
+Reference< XNameAccess > CuiAboutConfigTabPage::getConfigAccess( const OUString& sNodePath, bool bUpdate )
+{
+ uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= sNodePath;
+
+ uno::Sequence< uno::Any > aArgumentList( 1 );
+ aArgumentList[0] <<= aProperty;
+
+ OUString sAccessString;
+
+ if( bUpdate )
+ sAccessString = "com.sun.star.configuration.ConfigurationUpdateAccess";
+ else
+ sAccessString = "com.sun.star.configuration.ConfigurationAccess";
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ sAccessString, aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ return xNameAccess;
+}
+
+void CuiAboutConfigTabPage::AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp )
+{
+ bool isModifiedBefore = false;
+ //Check if value modified before
+ for(std::shared_ptr<Prop_Impl> & nInd : m_vectorOfModified)
+ {
+ if( rProp->Name == nInd->Name && rProp->Property == nInd->Property )
+ {
+ //property modified before. Assign reference to the modified value
+ //do your changes on this object. They will be saved later.
+ nInd = rProp;
+ isModifiedBefore = true;
+ break;
+ }
+ }
+
+ if( !isModifiedBefore )
+ m_vectorOfModified.push_back( rProp );
+ //property is not modified before
+}
+
+std::vector< OUString > CuiAboutConfigTabPage::commaStringToSequence( const OUString& rCommaSepString )
+{
+ std::vector<OUString> tempVector;
+
+ sal_Int32 index = 0;
+ do
+ {
+ OUString word = rCommaSepString.getToken(0, u',', index);
+ word = word.trim();
+ if( !word.isEmpty())
+ tempVector.push_back(word);
+ }while( index >= 0 );
+ return tempVector;
+}
+
+CuiAboutConfigValueDialog::CuiAboutConfigValueDialog(weld::Window* pWindow,
+ const OUString& rValue,
+ int limit)
+ : GenericDialogController(pWindow, "cui/ui/aboutconfigvaluedialog.ui", "AboutConfigValueDialog")
+ , m_bNumericOnly(limit != 0)
+ , m_xEDValue(m_xBuilder->weld_entry("valuebox"))
+{
+ if (limit)
+ m_xEDValue->set_max_length(limit);
+ m_xEDValue->set_text(rValue);
+ m_xEDValue->connect_key_press(LINK(this, CuiAboutConfigValueDialog, KeyInputHdl));
+}
+
+CuiAboutConfigValueDialog::~CuiAboutConfigValueDialog()
+{
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, ResetBtnHdl_Impl, weld::Button&, void )
+{
+ Reset();
+}
+
+IMPL_LINK_NOARG(CuiAboutConfigTabPage, DoubleClickHdl_Impl, weld::TreeView&, bool)
+{
+ StandardHdl_Impl(*m_xEditBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, StandardHdl_Impl, weld::Button&, void )
+{
+ if (!m_xPrefBox->get_selected(m_xScratchIter.get()))
+ return;
+
+ UserData *pUserData = reinterpret_cast<UserData*>(m_xPrefBox->get_id(*m_xScratchIter).toInt64());
+ if (!(pUserData && pUserData->bIsPropertyPath))
+ return;
+
+ //if selection is a node
+ OUString sPropertyName = m_xPrefBox->get_text(*m_xScratchIter, 1);
+ OUString sPropertyType = m_xPrefBox->get_text(*m_xScratchIter, 2);
+ OUString sPropertyValue = m_xPrefBox->get_text(*m_xScratchIter, 3);
+
+ auto pProperty = std::make_shared<Prop_Impl>( pUserData->sPropertyPath, sPropertyName, Any( sPropertyValue ) );
+ bool bSaveChanges = false;
+
+ bool bOpenDialog = true;
+ OUString sDialogValue;
+ OUString sNewValue;
+
+ if( sPropertyType == "boolean" )
+ {
+ bool bValue;
+ if( sPropertyValue == "true" )
+ {
+ sDialogValue = "false";
+ bValue = false;
+ }
+ else
+ {
+ sDialogValue = "true";
+ bValue = true;
+ }
+
+ pProperty->Value <<= bValue;
+ bOpenDialog = false;
+ bSaveChanges = true;
+ }
+ else if ( sPropertyType == "void" )
+ {
+ bOpenDialog = false;
+ }
+ else
+ {
+ sDialogValue = sPropertyValue;
+ bOpenDialog = true;
+ }
+
+ try
+ {
+ if( bOpenDialog )
+ {
+ //Cosmetic length limit for integer values.
+ int limit=0;
+ if( sPropertyType == "short" )
+ limit = SHORT_LEN_LIMIT;
+ else if( sPropertyType == "long" )
+ limit = LONG_LEN_LIMIT;
+ else if( sPropertyType == "hyper" )
+ limit = HYPER_LEN_LIMIT;
+
+ CuiAboutConfigValueDialog aValueDialog(m_xDialog.get(), sDialogValue, limit);
+
+ if (aValueDialog.run() == RET_OK )
+ {
+ sNewValue = aValueDialog.getValue();
+ bSaveChanges = true;
+ if ( sPropertyType == "short")
+ {
+ sal_Int16 nShort;
+ sal_Int32 nNumb = sNewValue.toInt32();
+
+ //if the value is 0 and length is not 1, there is something wrong
+ if( ( nNumb==0 && sNewValue.getLength()!=1 ) || nNumb > SAL_MAX_INT16 || nNumb < SAL_MIN_INT16)
+ throw uno::Exception("out of range short", nullptr);
+ nShort = static_cast<sal_Int16>(nNumb);
+ pProperty->Value <<= nShort;
+ }
+ else if( sPropertyType == "long" )
+ {
+ sal_Int32 nLong = sNewValue.toInt32();
+ if( nLong==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range long", nullptr);
+ pProperty->Value <<= nLong;
+ }
+ else if( sPropertyType == "hyper")
+ {
+ sal_Int64 nHyper = sNewValue.toInt64();
+ if( nHyper==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range hyper", nullptr);
+ pProperty->Value <<= nHyper;
+ }
+ else if( sPropertyType == "double")
+ {
+ double nDoub = sNewValue.toDouble();
+ if( nDoub ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range double", nullptr);
+ pProperty->Value <<= nDoub;
+ }
+ else if( sPropertyType == "float")
+ {
+ float nFloat = sNewValue.toFloat();
+ if( nFloat ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range float", nullptr);
+ pProperty->Value <<= nFloat;
+ }
+ else if( sPropertyType == "string" )
+ {
+ pProperty->Value <<= sNewValue;
+ }
+ else if( sPropertyType == "[]short" )
+ {
+ //create string sequence from comma separated string
+ //uno::Sequence< OUString > seqStr;
+ std::vector< OUString > seqStr = commaStringToSequence( sNewValue );
+
+ //create appropriate sequence with same size as string sequence
+ uno::Sequence< sal_Int16 > seqShort( seqStr.size() );
+ //convert all strings to appropriate type
+ for( size_t i = 0; i < seqStr.size(); ++i )
+ {
+ seqShort[i] = static_cast<sal_Int16>(seqStr[i].toInt32());
+ }
+ pProperty->Value <<= seqShort;
+ }
+ else if( sPropertyType == "[]long" )
+ {
+ std::vector< OUString > seqStrLong = commaStringToSequence( sNewValue );
+
+ uno::Sequence< sal_Int32 > seqLong( seqStrLong.size() );
+ for( size_t i = 0; i < seqStrLong.size(); ++i )
+ {
+ seqLong[i] = seqStrLong[i].toInt32();
+ }
+ pProperty->Value <<= seqLong;
+ }
+ else if( sPropertyType == "[]hyper" )
+ {
+ std::vector< OUString > seqStrHyper = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int64 > seqHyper( seqStrHyper.size() );
+ for( size_t i = 0; i < seqStrHyper.size(); ++i )
+ {
+ seqHyper[i] = seqStrHyper[i].toInt64();
+ }
+ pProperty->Value <<= seqHyper;
+ }
+ else if( sPropertyType == "[]double" )
+ {
+ std::vector< OUString > seqStrDoub = commaStringToSequence( sNewValue );
+ uno::Sequence< double > seqDoub( seqStrDoub.size() );
+ for( size_t i = 0; i < seqStrDoub.size(); ++i )
+ {
+ seqDoub[i] = seqStrDoub[i].toDouble();
+ }
+ pProperty->Value <<= seqDoub;
+ }
+ else if( sPropertyType == "[]float" )
+ {
+ std::vector< OUString > seqStrFloat = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int16 > seqFloat( seqStrFloat.size() );
+ for( size_t i = 0; i < seqStrFloat.size(); ++i )
+ {
+ seqFloat[i] = seqStrFloat[i].toFloat();
+ }
+ pProperty->Value <<= seqFloat;
+ }
+ else if( sPropertyType == "[]string" )
+ {
+ pProperty->Value <<= comphelper::containerToSequence( commaStringToSequence( sNewValue ));
+ }
+ else //unknown
+ throw uno::Exception("unknown property type " + sPropertyType, nullptr);
+
+ sDialogValue = sNewValue;
+ }
+ }
+
+ if(bSaveChanges)
+ {
+ AddToModifiedVector( pProperty );
+
+ //update listbox value.
+ m_xPrefBox->set_text(*m_xScratchIter, sDialogValue, 3);
+ //update m_prefBoxEntries
+ auto it = std::find_if(m_prefBoxEntries.begin(), m_prefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+ if (it != m_prefBoxEntries.end())
+ {
+ it->sValue = sDialogValue;
+
+ auto modifiedIt = std::find_if(
+ m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ if (modifiedIt != m_modifiedPrefBoxEntries.end())
+ {
+ modifiedIt->sValue = sDialogValue;
+ }
+ else
+ {
+ m_modifiedPrefBoxEntries.push_back(*it);
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, SearchHdl_Impl, weld::Button&, void)
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->hide();
+ m_xPrefBox->clear();
+ m_xPrefBox->freeze();
+
+ if (m_bSorted)
+ m_xPrefBox->make_unsorted();
+
+ if (m_xSearchEdit->get_text().isEmpty())
+ {
+ m_xPrefBox->clear();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ FillItems( xConfigAccess );
+ }
+ else
+ {
+ m_options.searchString = m_xSearchEdit->get_text();
+ utl::TextSearch textSearch( m_options );
+ for (auto const& it : m_prefBoxEntries)
+ {
+ sal_Int32 endPos, startPos = 0;
+
+ for(size_t i = 0; i < 5; ++i)
+ {
+ OUString scrTxt;
+
+ if (i == 0)
+ scrTxt = it.pUserData->sPropertyPath;
+ else if (i == 1)
+ scrTxt = it.sProp;
+ else if (i == 2)
+ scrTxt = it.sStatus;
+ else if (i == 3)
+ scrTxt = it.sType;
+ else if (i == 4)
+ scrTxt = it.sValue;
+
+ endPos = scrTxt.getLength();
+ if (textSearch.SearchForward(scrTxt, &startPos, &endPos))
+ {
+ InsertEntry(it);
+ break;
+ }
+ }
+ }
+ }
+
+ m_xPrefBox->thaw();
+ if (m_bSorted)
+ m_xPrefBox->make_sorted();
+
+ m_xPrefBox->all_foreach([this](weld::TreeIter& rEntry) {
+ m_xPrefBox->expand_row(rEntry);
+ return false;
+ });
+ m_xPrefBox->show();
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const prefBoxEntry& rEntry)
+{
+ OUString sPathWithProperty = rEntry.pUserData->sPropertyPath;
+ sal_Int32 index = sPathWithProperty.lastIndexOf(rEntry.sProp);
+ OUString sPath = sPathWithProperty.copy(0, index);
+ index = 0;
+ std::unique_ptr<weld::TreeIter> xParentEntry(m_xPrefBox->make_iterator());
+ std::unique_ptr<weld::TreeIter> xGrandParentEntry;
+
+ do
+ {
+ int prevIndex = index;
+ index = sPath.indexOf("/", index+1);
+ // deal with no parent case (tdf#107811)
+ if (index < 0)
+ {
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(rEntry.pUserData)));
+ m_xPrefBox->insert(nullptr, -1, &rEntry.sProp, &sId, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+ return;
+ }
+ OUString sParentName = sPath.copy(prevIndex+1, index - prevIndex - 1);
+
+ bool hasEntry = false;
+ bool bStartOk;
+
+ if (!xGrandParentEntry)
+ bStartOk = m_xPrefBox->get_iter_first(*xParentEntry);
+ else
+ {
+ m_xPrefBox->copy_iterator(*xGrandParentEntry, *xParentEntry);
+ bStartOk = m_xPrefBox->iter_children(*xParentEntry);
+ }
+
+ if (bStartOk)
+ {
+ do
+ {
+ if (m_xPrefBox->get_text(*xParentEntry, 0) == sParentName)
+ {
+ hasEntry = true;
+ break;
+ }
+ } while (m_xPrefBox->iter_next_sibling(*xParentEntry));
+ }
+
+ if (!hasEntry)
+ {
+ m_xPrefBox->insert(xGrandParentEntry.get(), -1, &sParentName, nullptr, nullptr, nullptr, nullptr, false, xParentEntry.get());
+ //It is needed, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*xParentEntry, "", 1);
+ m_xPrefBox->set_text(*xParentEntry, "", 2);
+ m_xPrefBox->set_text(*xParentEntry, "", 3);
+ }
+
+ xGrandParentEntry = m_xPrefBox->make_iterator(xParentEntry.get());
+ } while(index < sPath.getLength() - 1);
+
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(rEntry.pUserData)));
+ m_xPrefBox->insert(xParentEntry.get(), -1, &rEntry.sProp, &sId, nullptr, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, ExpandingHdl_Impl, const weld::TreeIter&, rEntry, bool)
+{
+ if (m_xPrefBox->iter_has_child(rEntry))
+ return true;
+ UserData *pUserData = reinterpret_cast<UserData*>(m_xPrefBox->get_id(rEntry).toInt64());
+ if (pUserData && !pUserData->bIsPropertyPath)
+ {
+ assert(pUserData->aXNameAccess.is());
+ FillItems(pUserData->aXNameAccess, &rEntry, pUserData->aLineage);
+ }
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.hxx b/cui/source/options/optaboutconfig.hxx
new file mode 100644
index 000000000..69a207da6
--- /dev/null
+++ b/cui/source/options/optaboutconfig.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <i18nutil/searchopt.hxx>
+#include <vcl/weld.hxx>
+
+#include <vector>
+
+class CuiAboutConfigTabPage;
+class CuiAboutConfigValueDialog;
+struct Prop_Impl;
+struct UserData;
+
+struct prefBoxEntry
+{
+ OUString sProp;
+ OUString sStatus;
+ OUString sType;
+ OUString sValue;
+ UserData* pUserData;
+};
+
+class CuiAboutConfigTabPage : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xResetBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+ std::unique_ptr<weld::Button> m_xSearchBtn;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::TreeView> m_xPrefBox;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+ std::vector < std::unique_ptr<UserData> > m_vectorUserData;
+
+ std::vector<prefBoxEntry> m_modifiedPrefBoxEntries;
+ std::vector< std::shared_ptr< Prop_Impl > > m_vectorOfModified;
+
+ //for search
+ i18nutil::SearchOptions2 m_options;
+ std::vector<prefBoxEntry> m_prefBoxEntries;
+
+ bool m_bSorted;
+
+ void AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp );
+ static std::vector< OUString > commaStringToSequence( const OUString& rCommaSepString );
+ void InsertEntry(const prefBoxEntry& rEntry);
+
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+ DECL_LINK(DoubleClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(ResetBtnHdl_Impl, weld::Button&, void);
+ DECL_LINK(SearchHdl_Impl, weld::Button&, void);
+ DECL_LINK(ExpandingHdl_Impl, const weld::TreeIter&, bool);
+ DECL_LINK(HeaderBarClick, int, void);
+
+public:
+ explicit CuiAboutConfigTabPage(weld::Window* pParent);
+ virtual ~CuiAboutConfigTabPage() override;
+ void InsertEntry(const OUString &rPropertyPath, const OUString& rProp, const OUString& rStatus, const OUString& rType, const OUString& rValue,
+ const weld::TreeIter* pParentEntry, bool bInsertToPrefBox);
+ void Reset();
+ void FillItems(const css::uno::Reference<css::container::XNameAccess>& xNameAccess,
+ const weld::TreeIter* pParentEntry = nullptr, int lineage = 0, bool bLoadAll = false);
+ static css::uno::Reference< css::container::XNameAccess > getConfigAccess( const OUString& sNodePath, bool bUpdate );
+ void FillItemSet();
+};
+
+class CuiAboutConfigValueDialog : public weld::GenericDialogController
+{
+private:
+ bool m_bNumericOnly;
+ std::unique_ptr<weld::Entry> m_xEDValue;
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ CuiAboutConfigValueDialog(weld::Window* pWindow, const OUString& rValue , int limit);
+ virtual ~CuiAboutConfigValueDialog() override;
+
+ OUString getValue() const
+ {
+ return m_xEDValue->get_text();
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.cxx b/cui/source/options/optaccessibility.cxx
new file mode 100644
index 000000000..a394ff955
--- /dev/null
+++ b/cui/source/options/optaccessibility.cxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optaccessibility.hxx"
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <officecfg/Office/Common.hxx>
+
+SvxAccessibilityOptionsTabPage::SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optaccessibilitypage.ui", "OptAccessibilityPage", &rSet)
+ , m_xAccessibilityTool(m_xBuilder->weld_check_button("acctool"))
+ , m_xTextSelectionInReadonly(m_xBuilder->weld_check_button("textselinreadonly"))
+ , m_xAnimatedGraphics(m_xBuilder->weld_check_button("animatedgraphics"))
+ , m_xAnimatedTexts(m_xBuilder->weld_check_button("animatedtext"))
+ , m_xAutoDetectHC(m_xBuilder->weld_check_button("autodetecthc"))
+ , m_xAutomaticFontColor(m_xBuilder->weld_check_button("autofontcolor"))
+ , m_xPagePreviews(m_xBuilder->weld_check_button("systempagepreviewcolor"))
+{
+#ifdef UNX
+ // UNIX: read the gconf2 setting instead to use the checkbox
+ m_xAccessibilityTool->hide();
+#endif
+}
+
+SvxAccessibilityOptionsTabPage::~SvxAccessibilityOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAccessibilityOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAccessibilityOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAccessibilityOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch( comphelper::ConfigurationChanges::create() );
+ if ( !officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsForPagePreviews::set(m_xPagePreviews->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::set(m_xAnimatedGraphics->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedText::set(m_xAnimatedTexts->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAutomaticFontColor::set(m_xAutomaticFontColor->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsSelectionInReadonly::set(m_xTextSelectionInReadonly->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ officecfg::Office::Common::Accessibility::AutoDetectSystemHC::set(m_xAutoDetectHC->get_active(), batch);
+ batch->commit();
+
+ AllSettings aAllSettings = Application::GetSettings();
+ MiscSettings aMiscSettings = aAllSettings.GetMiscSettings();
+#ifndef UNX
+ aMiscSettings.SetEnableATToolSupport(m_xAccessibilityTool->get_active());
+#endif
+ aAllSettings.SetMiscSettings(aMiscSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+
+ return false;
+}
+
+void SvxAccessibilityOptionsTabPage::Reset( const SfxItemSet* )
+{
+ m_xPagePreviews->set_active( officecfg::Office::Common::Accessibility::IsForPagePreviews::get() );
+ if( officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ m_xPagePreviews->set_sensitive(false);
+
+ m_xAnimatedGraphics->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ m_xAnimatedGraphics->set_sensitive(false);
+
+ m_xAnimatedTexts->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ m_xAnimatedTexts->set_sensitive(false);
+
+ m_xAutomaticFontColor->set_active( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get() );
+ if( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ m_xAutomaticFontColor->set_sensitive(false);
+
+ m_xTextSelectionInReadonly->set_active( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::get() );
+ if( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ m_xTextSelectionInReadonly->set_sensitive(false);
+
+ m_xAutoDetectHC->set_active( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::get() );
+ if( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ m_xAutoDetectHC->set_sensitive(false);
+
+ AllSettings aAllSettings = Application::GetSettings();
+ const MiscSettings& aMiscSettings = aAllSettings.GetMiscSettings();
+ m_xAccessibilityTool->set_active(aMiscSettings.GetEnableATToolSupport());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.hxx b/cui/source/options/optaccessibility.hxx
new file mode 100644
index 000000000..35d5fdefd
--- /dev/null
+++ b/cui/source/options/optaccessibility.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxAccessibilityOptionsTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xAccessibilityTool;
+ std::unique_ptr<weld::CheckButton> m_xTextSelectionInReadonly;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedGraphics;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedTexts;
+ std::unique_ptr<weld::CheckButton> m_xAutoDetectHC;
+ std::unique_ptr<weld::CheckButton> m_xAutomaticFontColor;
+ std::unique_ptr<weld::CheckButton> m_xPagePreviews;
+
+public:
+ SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxAccessibilityOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optasian.cxx b/cui/source/options/optasian.cxx
new file mode 100644
index 000000000..6907eca46
--- /dev/null
+++ b/cui/source/options/optasian.cxx
@@ -0,0 +1,384 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <map>
+#include <optasian.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+#include <o3tl/any.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svl/asiancfg.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::i18n;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+
+const char cIsKernAsianPunctuation[] = "IsKernAsianPunctuation";
+const char cCharacterCompressionType[] = "CharacterCompressionType";
+
+namespace {
+
+struct SvxForbiddenChars_Impl
+{
+ bool bRemoved;
+ std::unique_ptr<ForbiddenCharacters> pCharacters;
+};
+
+}
+
+struct SvxAsianLayoutPage_Impl
+{
+ SvxAsianConfig aConfig;
+ SvxAsianLayoutPage_Impl() {}
+
+ Reference< XForbiddenCharacters > xForbidden;
+ Reference< XPropertySet > xPrSet;
+ Reference< XPropertySetInfo > xPrSetInfo;
+ std::map< LanguageType, std::unique_ptr<SvxForbiddenChars_Impl> >
+ aChangedLanguagesMap;
+
+ bool hasForbiddenCharacters(LanguageType eLang);
+ SvxForbiddenChars_Impl* getForbiddenCharacters(LanguageType eLang);
+ void addForbiddenCharacters(LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden);
+};
+
+bool SvxAsianLayoutPage_Impl::hasForbiddenCharacters(LanguageType eLang)
+{
+ return aChangedLanguagesMap.count( eLang );
+}
+
+SvxForbiddenChars_Impl* SvxAsianLayoutPage_Impl::getForbiddenCharacters(LanguageType eLang)
+{
+ auto it = aChangedLanguagesMap.find( eLang );
+ DBG_ASSERT( ( it != aChangedLanguagesMap.end() ), "language not available");
+ if( it != aChangedLanguagesMap.end() )
+ return it->second.get();
+ return nullptr;
+}
+
+void SvxAsianLayoutPage_Impl::addForbiddenCharacters(
+ LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden)
+{
+ auto itOld = aChangedLanguagesMap.find( eLang );
+ if( itOld == aChangedLanguagesMap.end() )
+ {
+ std::unique_ptr<SvxForbiddenChars_Impl> pChar(new SvxForbiddenChars_Impl);
+ pChar->bRemoved = nullptr == pForbidden;
+ pChar->pCharacters = std::move(pForbidden);
+ aChangedLanguagesMap.emplace( eLang, std::move(pChar) );
+ }
+ else
+ {
+ itOld->second->bRemoved = nullptr == pForbidden;
+ itOld->second->pCharacters = std::move(pForbidden);
+ }
+}
+
+static LanguageType eLastUsedLanguageTypeForForbiddenCharacters(USHRT_MAX);
+
+SvxAsianLayoutPage::SvxAsianLayoutPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optasianpage.ui", "OptAsianPage", &rSet)
+ , pImpl(new SvxAsianLayoutPage_Impl)
+ , m_xCharKerningRB(m_xBuilder->weld_radio_button("charkerning"))
+ , m_xCharPunctKerningRB(m_xBuilder->weld_radio_button("charpunctkerning"))
+ , m_xNoCompressionRB(m_xBuilder->weld_radio_button("nocompression"))
+ , m_xPunctCompressionRB(m_xBuilder->weld_radio_button("punctcompression"))
+ , m_xPunctKanaCompressionRB(m_xBuilder->weld_radio_button("punctkanacompression"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xStandardCB(m_xBuilder->weld_check_button("standard"))
+ , m_xStartFT(m_xBuilder->weld_label("startft"))
+ , m_xStartED(m_xBuilder->weld_entry("start"))
+ , m_xEndFT(m_xBuilder->weld_label("endft"))
+ , m_xEndED(m_xBuilder->weld_entry("end"))
+ , m_xHintFT(m_xBuilder->weld_label("hintft"))
+{
+ LanguageHdl(*m_xLanguageLB->get_widget());
+ m_xLanguageLB->connect_changed(LINK(this, SvxAsianLayoutPage, LanguageHdl));
+ m_xStandardCB->connect_toggled(LINK(this, SvxAsianLayoutPage, ChangeStandardHdl));
+ Link<weld::Entry&,void> aLk(LINK(this, SvxAsianLayoutPage, ModifyHdl));
+ m_xStartED->connect_changed(aLk);
+ m_xEndED->connect_changed(aLk);
+
+ m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::FBD_CHARS, false, false );
+}
+
+SvxAsianLayoutPage::~SvxAsianLayoutPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianLayoutPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAsianLayoutPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAsianLayoutPage::FillItemSet( SfxItemSet* )
+{
+ if(m_xCharKerningRB->get_state_changed_from_saved())
+ {
+ pImpl->aConfig.SetKerningWesternTextOnly(m_xCharKerningRB->get_active());
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ bool bVal = !m_xCharKerningRB->get_active();
+ pImpl->xPrSet->setPropertyValue(sPunct, Any(bVal));
+ }
+ }
+
+ if(m_xNoCompressionRB->get_state_changed_from_saved() ||
+ m_xPunctCompressionRB->get_state_changed_from_saved())
+ {
+ CharCompressType nSet = m_xNoCompressionRB->get_active() ? CharCompressType::NONE :
+ m_xPunctCompressionRB->get_active() ? CharCompressType::PunctuationOnly :
+ CharCompressType::PunctuationAndKana;
+ pImpl->aConfig.SetCharDistanceCompression(nSet);
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ pImpl->xPrSet->setPropertyValue(sCompress, Any(static_cast<sal_uInt16>(nSet)));
+ }
+ }
+ pImpl->aConfig.Commit();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ for (auto const& changedLanguage : pImpl->aChangedLanguagesMap)
+ {
+ Locale aLocale( LanguageTag::convertToLocale(changedLanguage.first));
+ if(changedLanguage.second->bRemoved)
+ pImpl->xForbidden->removeForbiddenCharacters( aLocale );
+ else if(changedLanguage.second->pCharacters)
+ pImpl->xForbidden->setForbiddenCharacters( aLocale, *( changedLanguage.second->pCharacters ) );
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("exception in XForbiddenCharacters");
+ }
+ }
+ eLastUsedLanguageTypeForForbiddenCharacters = m_xLanguageLB->get_active_id();
+
+ return false;
+}
+
+void SvxAsianLayoutPage::Reset( const SfxItemSet* )
+{
+ SfxViewFrame* pCurFrm = SfxViewFrame::Current();
+ SfxObjectShell* pDocSh = pCurFrm ? pCurFrm->GetObjectShell() : nullptr;
+ Reference< XModel > xModel;
+ if(pDocSh)
+ xModel = pDocSh->GetModel();
+ Reference<XMultiServiceFactory> xFact(xModel, UNO_QUERY);
+ if(xFact.is())
+ {
+ pImpl->xPrSet.set(xFact->createInstance("com.sun.star.document.Settings"), UNO_QUERY);
+ }
+ if( pImpl->xPrSet.is() )
+ pImpl->xPrSetInfo = pImpl->xPrSet->getPropertySetInfo();
+ OUString sForbidden("ForbiddenCharacters");
+ bool bKernWesternText = pImpl->aConfig.IsKerningWesternTextOnly();
+ CharCompressType nCompress = pImpl->aConfig.GetCharDistanceCompression();
+ if(pImpl->xPrSetInfo.is())
+ {
+ if(pImpl->xPrSetInfo->hasPropertyByName(sForbidden))
+ {
+ Any aForbidden = pImpl->xPrSet->getPropertyValue(sForbidden);
+ aForbidden >>= pImpl->xForbidden;
+ }
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sCompress);
+ sal_uInt16 nTmp;
+ if (aVal >>= nTmp)
+ nCompress = static_cast<CharCompressType>(nTmp);
+ }
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sPunct);
+ bKernWesternText = !*o3tl::doAccess<bool>(aVal);
+ }
+ }
+ else
+ {
+ m_xLanguageFT->set_sensitive(false);
+ m_xLanguageLB->set_sensitive(false);
+ m_xStandardCB->set_sensitive(false);
+ m_xStartFT->set_sensitive(false);
+ m_xStartED->set_sensitive(false);
+ m_xEndFT->set_sensitive(false);
+ m_xEndED->set_sensitive(false);
+ m_xHintFT->set_sensitive(false);
+ }
+ if(bKernWesternText)
+ m_xCharKerningRB->set_active(true);
+ else
+ m_xCharPunctKerningRB->set_active(true);
+ switch(nCompress)
+ {
+ case CharCompressType::NONE : m_xNoCompressionRB->set_active(true); break;
+ case CharCompressType::PunctuationOnly : m_xPunctCompressionRB->set_active(true); break;
+ default: m_xPunctKanaCompressionRB->set_active(true);
+ }
+ m_xCharKerningRB->save_state();
+ m_xNoCompressionRB->save_state();
+ m_xPunctCompressionRB->save_state();
+ m_xPunctKanaCompressionRB->save_state();
+
+ m_xLanguageLB->set_active(0);
+ //preselect the system language in the box - if available
+ if(LanguageType(USHRT_MAX) == eLastUsedLanguageTypeForForbiddenCharacters)
+ {
+ eLastUsedLanguageTypeForForbiddenCharacters =
+ Application::GetSettings().GetLanguageTag().getLanguageType();
+ if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_SIMPLIFIED;
+ else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_TRADITIONAL;
+ }
+ m_xLanguageLB->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters);
+ LanguageHdl(*m_xLanguageLB->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxAsianLayoutPage, LanguageHdl, weld::ComboBox&, void)
+{
+ //set current value
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ LanguageTag aLanguageTag( eSelectLanguage);
+ const Locale& aLocale( aLanguageTag.getLocale());
+
+ OUString sStart, sEnd;
+ bool bAvail;
+ if(pImpl->xForbidden.is())
+ {
+ bAvail = pImpl->hasForbiddenCharacters(eSelectLanguage);
+ if(bAvail)
+ {
+ SvxForbiddenChars_Impl* pElement = pImpl->getForbiddenCharacters(eSelectLanguage);
+ if(pElement->bRemoved || !pElement->pCharacters)
+ {
+ bAvail = false;
+ }
+ else
+ {
+ sStart = pElement->pCharacters->beginLine;
+ sEnd = pElement->pCharacters->endLine;
+ }
+ }
+ else
+ {
+ try
+ {
+ bAvail = pImpl->xForbidden->hasForbiddenCharacters(aLocale);
+ if(bAvail)
+ {
+ ForbiddenCharacters aForbidden = pImpl->xForbidden->getForbiddenCharacters( aLocale );
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("exception in XForbiddenCharacters");
+ }
+ }
+ }
+ else
+ {
+ bAvail = pImpl->aConfig.GetStartEndChars( aLocale, sStart, sEnd );
+ }
+ if(!bAvail)
+ {
+ LocaleDataWrapper aWrap( aLanguageTag );
+ ForbiddenCharacters aForbidden = aWrap.getForbiddenCharacters();
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ m_xStandardCB->set_active(!bAvail);
+ m_xStartED->set_sensitive(bAvail);
+ m_xEndED->set_sensitive(bAvail);
+ m_xStartFT->set_sensitive(bAvail);
+ m_xEndFT->set_sensitive(bAvail);
+ m_xStartED->set_text(sStart);
+ m_xEndED->set_text(sEnd);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ChangeStandardHdl, weld::ToggleButton&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ m_xStartED->set_sensitive(!bCheck);
+ m_xEndED->set_sensitive(!bCheck);
+ m_xStartFT->set_sensitive(!bCheck);
+ m_xEndFT->set_sensitive(!bCheck);
+
+ ModifyHdl(*m_xStartED);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ Locale aLocale( LanguageTag::convertToLocale( eSelectLanguage ));
+ OUString sStart = m_xStartED->get_text();
+ OUString sEnd = m_xEndED->get_text();
+ bool bEnable = rEdit.get_sensitive();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ if(bEnable)
+ {
+ std::unique_ptr<ForbiddenCharacters> pFCSet(new ForbiddenCharacters);
+ pFCSet->beginLine = sStart;
+ pFCSet->endLine = sEnd;
+ pImpl->addForbiddenCharacters(eSelectLanguage, std::move(pFCSet));
+ }
+ else
+ pImpl->addForbiddenCharacters(eSelectLanguage, nullptr);
+ }
+ catch (const Exception&)
+ {
+ OSL_FAIL("exception in XForbiddenCharacters");
+ }
+ }
+ pImpl->aConfig.SetStartEndChars( aLocale, bEnable ? &sStart : nullptr, bEnable ? &sEnd : nullptr);
+}
+
+const sal_uInt16* SvxAsianLayoutPage::GetRanges()
+{
+ //no items are used
+ static const sal_uInt16 pAsianLayoutRanges[] = { 0 };
+ return pAsianLayoutRanges;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.cxx b/cui/source/options/optbasic.cxx
new file mode 100644
index 000000000..c550d9440
--- /dev/null
+++ b/cui/source/options/optbasic.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optbasic.hxx"
+#include <basic/codecompletecache.hxx>
+#include <officecfg/Office/BasicIDE.hxx>
+
+SvxBasicIDEOptionsPage::SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optbasicidepage.ui", "OptBasicIDEPage", &rSet)
+ , m_xCodeCompleteChk(m_xBuilder->weld_check_button("codecomplete_enable"))
+ , m_xAutocloseProcChk(m_xBuilder->weld_check_button("autoclose_proc"))
+ , m_xAutocloseParenChk(m_xBuilder->weld_check_button("autoclose_paren"))
+ , m_xAutocloseQuotesChk(m_xBuilder->weld_check_button("autoclose_quotes"))
+ , m_xAutoCorrectChk(m_xBuilder->weld_check_button("autocorrect"))
+ , m_xUseExtendedTypesChk(m_xBuilder->weld_check_button("extendedtypes_enable"))
+{
+ LoadConfig();
+}
+
+SvxBasicIDEOptionsPage::~SvxBasicIDEOptionsPage()
+{
+}
+
+void SvxBasicIDEOptionsPage::LoadConfig()
+{
+ m_xCodeCompleteChk->set_active( officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get() );
+ m_xCodeCompleteChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::CodeComplete::isReadOnly() );
+ m_xAutocloseProcChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get() );
+ m_xAutocloseProcChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::isReadOnly() );
+ m_xAutocloseQuotesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get() );
+ m_xAutocloseQuotesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::isReadOnly() );
+ m_xAutocloseParenChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get() );
+ m_xAutocloseParenChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::isReadOnly() );
+ m_xAutoCorrectChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get() );
+ m_xAutoCorrectChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::isReadOnly() );
+ m_xUseExtendedTypesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::UseExtended::get() );
+ m_xUseExtendedTypesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::UseExtended::isReadOnly() );
+}
+
+bool SvxBasicIDEOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+ std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+
+ if( m_xAutocloseProcChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::set( m_xAutocloseProcChk->get_active(), batch );
+ CodeCompleteOptions::SetProcedureAutoCompleteOn( m_xAutocloseProcChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xCodeCompleteChk->get_state_changed_from_saved() )
+ {
+ //std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::BasicIDE::Autocomplete::CodeComplete::set( m_xCodeCompleteChk->get_active(), batch );
+ CodeCompleteOptions::SetCodeCompleteOn( m_xCodeCompleteChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xUseExtendedTypesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::UseExtended::set( m_xUseExtendedTypesChk->get_active(), batch );
+ CodeCompleteOptions::SetExtendedTypeDeclaration( m_xUseExtendedTypesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseParenChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::set( m_xAutocloseParenChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseParenthesisOn( m_xAutocloseParenChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseQuotesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::set( m_xAutocloseQuotesChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseQuotesOn( m_xAutocloseQuotesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutoCorrectChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::set( m_xAutoCorrectChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCorrectOn( m_xAutoCorrectChk->get_active() );
+ bModified = true;
+ }
+
+ if( bModified )
+ batch->commit();
+
+ return bModified;
+}
+
+void SvxBasicIDEOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ LoadConfig();
+ m_xCodeCompleteChk->save_state();
+ m_xAutocloseProcChk->save_state();
+ m_xAutocloseQuotesChk->save_state();
+ m_xAutocloseParenChk->save_state();
+ m_xAutoCorrectChk->save_state();
+ m_xUseExtendedTypesChk->save_state();
+}
+
+std::unique_ptr<SfxTabPage> SvxBasicIDEOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBasicIDEOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBasicIDEOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.hxx b/cui/source/options/optbasic.hxx
new file mode 100644
index 000000000..5510fc129
--- /dev/null
+++ b/cui/source/options/optbasic.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_CUI_SOURCE_OPTIONS_OPTBASIC_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTBASIC_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxBasicIDEOptionsPage: public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xCodeCompleteChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseProcChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseParenChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseQuotesChk;
+ std::unique_ptr<weld::CheckButton> m_xAutoCorrectChk;
+ std::unique_ptr<weld::CheckButton> m_xUseExtendedTypesChk;
+
+ void LoadConfig();
+
+public:
+ SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBasicIDEOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_OPTBASIC_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.cxx b/cui/source/options/optchart.cxx
new file mode 100644
index 000000000..c77f2e4f4
--- /dev/null
+++ b/cui/source/options/optchart.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 "optchart.hxx"
+#include <svx/SvxColorValueSet.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+#include <officecfg/Office/Common.hxx>
+
+void SvxDefaultColorOptPage::InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ const Color& rColor = rEntry.GetColor();
+ const OUString& rStr = rEntry.GetName();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Size aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
+
+ ScopedVclPtrInstance<VirtualDevice> xDevice;
+ xDevice->SetOutputSize(aImageSize);
+ const ::tools::Rectangle aRect(Point(0, 0), aImageSize);
+ xDevice->SetFillColor(rColor);
+ xDevice->SetLineColor(rStyleSettings.GetDisableColor());
+ xDevice->DrawRect(aRect);
+
+ m_xLbChartColors->insert(nullptr, nPos, &rStr, nullptr,
+ nullptr, xDevice.get(), nullptr, false, nullptr);
+
+ if (nPos == -1)
+ aColorList.push_back( rColor );
+ else
+ {
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance( it, nPos );
+ aColorList.insert( it, rColor );
+ }
+}
+
+void SvxDefaultColorOptPage::RemoveColorEntry(sal_Int32 nPos)
+{
+ m_xLbChartColors->remove(nPos);
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance(it, nPos);
+ aColorList.erase(it);
+}
+
+void SvxDefaultColorOptPage::ClearColorEntries()
+{
+ aColorList.clear();
+ m_xLbChartColors->clear();
+}
+
+void SvxDefaultColorOptPage::ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ RemoveColorEntry(nPos);
+ InsertColorEntry(rEntry, nPos);
+}
+
+void SvxDefaultColorOptPage::FillBoxChartColorLB()
+{
+ if (!m_SvxChartColorTableUniquePtr)
+ return;
+
+ m_xLbChartColors->freeze();
+ ClearColorEntries();
+ const long nCount(m_SvxChartColorTableUniquePtr->size());
+ for (long i = 0; i < nCount; ++i)
+ InsertColorEntry((*m_SvxChartColorTableUniquePtr)[i]);
+ m_xLbChartColors->thaw();
+}
+
+SvxDefaultColorOptPage::SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/optchartcolorspage.ui", "OptChartColorsPage", &rInAttrs)
+ , m_xLbChartColors(m_xBuilder->weld_tree_view("colors"))
+ , m_xLbPaletteSelector(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xPBDefault(m_xBuilder->weld_button("default"))
+ , m_xPBAdd(m_xBuilder->weld_button("add"))
+ , m_xPBRemove(m_xBuilder->weld_button("delete"))
+ , m_xValSetColorBox(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("tablewin")))
+ , m_xValSetColorBoxWin(new weld::CustomWeld(*m_xBuilder, "table", *m_xValSetColorBox))
+{
+ m_xLbChartColors->set_size_request(-1, m_xLbChartColors->get_height_rows(16));
+
+ m_xPBDefault->connect_clicked( LINK( this, SvxDefaultColorOptPage, ResetToDefaults ) );
+ m_xPBAdd->connect_clicked( LINK( this, SvxDefaultColorOptPage, AddChartColor ) );
+ m_xPBRemove->connect_clicked( LINK( this, SvxDefaultColorOptPage, RemoveChartColor ) );
+ m_xValSetColorBox->SetSelectHdl( LINK( this, SvxDefaultColorOptPage, BoxClickedHdl ) );
+ m_xLbPaletteSelector->connect_changed( LINK( this, SvxDefaultColorOptPage, SelectPaletteLbHdl ) );
+
+ m_xValSetColorBox->SetStyle( m_xValSetColorBox->GetStyle()
+ | WB_ITEMBORDER | WB_NAMEFIELD | WB_VSCROLL );
+
+ m_SvxChartOptionsUniquePtr.reset(new SvxChartOptions);
+
+ const SfxPoolItem* pItem = nullptr;
+ if ( rInAttrs.GetItemState( SID_SCH_EDITOPTIONS, false, &pItem ) == SfxItemState::SET )
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>(
+ static_cast<const SvxChartColorTableItem*>(pItem)->GetColorList());
+ }
+ else
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>();
+ m_SvxChartColorTableUniquePtr->useDefault();
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ }
+
+ Construct();
+}
+
+SvxDefaultColorOptPage::~SvxDefaultColorOptPage()
+{
+ m_xValSetColorBoxWin.reset();
+ m_xValSetColorBox.reset();
+}
+
+void SvxDefaultColorOptPage::Construct()
+{
+ FillBoxChartColorLB();
+ FillPaletteLB();
+
+ m_xLbChartColors->select( 0 );
+}
+
+std::unique_ptr<SfxTabPage> SvxDefaultColorOptPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxDefaultColorOptPage>( pPage, pController, *rAttrs );
+}
+
+bool SvxDefaultColorOptPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ rOutAttrs->Put(SvxChartColorTableItem(SID_SCH_EDITOPTIONS, *m_SvxChartColorTableUniquePtr));
+ }
+
+ return true;
+}
+
+void SvxDefaultColorOptPage::Reset( const SfxItemSet* )
+{
+ m_xLbChartColors->select( 0 );
+}
+
+void SvxDefaultColorOptPage::FillPaletteLB()
+{
+ m_xLbPaletteSelector->clear();
+ std::vector<OUString> aPaletteList = aPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ m_xLbPaletteSelector->append_text(palette);
+
+ OUString aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get());
+ m_xLbPaletteSelector->set_active_text(aPaletteName);
+ if (m_xLbPaletteSelector->get_active() != -1)
+ SelectPaletteLbHdl( *m_xLbPaletteSelector );
+}
+
+void SvxDefaultColorOptPage::SaveChartOptions()
+{
+ if (m_SvxChartOptionsUniquePtr && m_SvxChartColorTableUniquePtr)
+ {
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ m_SvxChartOptionsUniquePtr->Commit();
+ }
+}
+
+// event handlers
+
+
+// ResetToDefaults
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, ResetToDefaults, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ m_SvxChartColorTableUniquePtr->useDefault();
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select( 0 );
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// AddChartColor
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, AddChartColor, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ Color const black( 0x00, 0x00, 0x00 );
+
+ m_SvxChartColorTableUniquePtr->append(
+ XColorEntry(black, SvxChartColorTable::getDefaultName(m_SvxChartColorTableUniquePtr->size())));
+
+ FillBoxChartColorLB();
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// RemoveChartColor
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, RemoveChartColor, weld::Button&, void )
+{
+ sal_Int32 nIndex = m_xLbChartColors->get_selected_index();
+ if (nIndex == -1)
+ return;
+
+ if( !m_SvxChartColorTableUniquePtr )
+ return;
+
+ OSL_ENSURE(m_SvxChartColorTableUniquePtr->size() > 1, "don't delete the last chart color");
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletechartcolordialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteChartColorDialog"));
+
+ if (RET_YES != xQuery->run())
+ return;
+
+ m_SvxChartColorTableUniquePtr->remove(nIndex);
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+
+ if (nIndex == m_xLbChartColors->n_children() && m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ else if (m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select( nIndex );
+ else
+ m_xPBRemove->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, SelectPaletteLbHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLbPaletteSelector->get_active();
+ aPaletteManager.SetPalette( nPos );
+ aPaletteManager.ReloadColorSet( *m_xValSetColorBox );
+ m_xValSetColorBox->Resize();
+}
+
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, BoxClickedHdl, ValueSet*, void)
+{
+ sal_Int32 nIdx = m_xLbChartColors->get_selected_index();
+ if (nIdx != -1)
+ {
+ const XColorEntry aEntry(m_xValSetColorBox->GetItemColor(m_xValSetColorBox->GetSelectedItemId()), m_xLbChartColors->get_selected_text());
+
+ ModifyColorEntry(aEntry, nIdx);
+ m_SvxChartColorTableUniquePtr->replace(nIdx, aEntry);
+
+ m_xLbChartColors->select(nIdx); // reselect entry
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.hxx b/cui/source/options/optchart.hxx
new file mode 100644
index 000000000..eb9b1983b
--- /dev/null
+++ b/cui/source/options/optchart.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_CUI_SOURCE_OPTIONS_OPTCHART_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTCHART_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/xtable.hxx>
+#include <svx/PaletteManager.hxx>
+#include <vcl/customweld.hxx>
+
+#include "cfgchart.hxx"
+
+typedef std::vector<Color> ImpColorList;
+
+class SvxDefaultColorOptPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxChartOptions> m_SvxChartOptionsUniquePtr;
+ // no reason to use a cloned SfxItem here (SvxChartColorTableItem)
+ // that just leads to non-const SfxItem and potential trouble
+ std::unique_ptr<SvxChartColorTable> m_SvxChartColorTableUniquePtr;
+
+ ImpColorList aColorList;
+ PaletteManager aPaletteManager;
+
+ std::unique_ptr<weld::TreeView> m_xLbChartColors;
+ std::unique_ptr<weld::ComboBox> m_xLbPaletteSelector;
+ std::unique_ptr<weld::Button> m_xPBDefault;
+ std::unique_ptr<weld::Button> m_xPBAdd;
+ std::unique_ptr<weld::Button> m_xPBRemove;
+ std::unique_ptr<SvxColorValueSet> m_xValSetColorBox;
+ std::unique_ptr<weld::CustomWeld> m_xValSetColorBoxWin;
+
+ DECL_LINK(ResetToDefaults, weld::Button&, void);
+ DECL_LINK(AddChartColor, weld::Button&, void);
+ DECL_LINK(RemoveChartColor, weld::Button&, void);
+ DECL_LINK(BoxClickedHdl, ValueSet*, void);
+ DECL_LINK(SelectPaletteLbHdl, weld::ComboBox&, void);
+
+ void FillPaletteLB();
+
+private:
+ void InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos = -1);
+ void RemoveColorEntry(sal_Int32 nPos);
+ void ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos);
+ void ClearColorEntries();
+ void FillBoxChartColorLB();
+
+public:
+ SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxDefaultColorOptPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+ void SaveChartOptions();
+};
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_OPTCHART_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.cxx b/cui/source/options/optcolor.cxx
new file mode 100644
index 000000000..f7807adc5
--- /dev/null
+++ b/cui/source/options/optcolor.cxx
@@ -0,0 +1,888 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <bitset>
+
+#include <tools/debug.hxx>
+#include <editeng/editids.hrc>
+#include <svtools/colorcfg.hxx>
+#include <svtools/extcolorcfg.hxx>
+#include <svx/colorbox.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <helpids.h>
+#include <dialmgr.hxx>
+#include "optcolor.hxx"
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::svtools;
+
+namespace
+{
+
+// list of default groups
+enum Group
+{
+ Group_General,
+ Group_Writer,
+ Group_Html,
+ Group_Calc,
+ Group_Draw,
+ Group_Basic,
+ Group_Sql,
+
+ nGroupCount
+};
+
+// group data
+struct
+{
+ // group
+ Group eGroup;
+ // .ui group name
+ const char *pGroup;
+}
+const vGroupInfo[] =
+{
+ // the groups are in the same order as in enum Group above
+ { Group_General, "general" },
+ { Group_Writer, "writer" },
+ { Group_Html, "html" },
+ { Group_Calc, "calc" },
+ { Group_Draw, "draw" },
+ { Group_Basic, "basic" },
+ { Group_Sql, "sql" }
+};
+
+// color config entry data (see ColorConfigWindow_Impl::Entry below)
+struct
+{
+ // group
+ Group eGroup;
+ //checkbox (or simple text)
+ const char *pText;
+ //color listbox
+ const char *pColor;
+ // has checkbox?
+ bool bCheckBox;
+}
+const vEntryInfo[] =
+{
+ #define IDS(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
+
+ #define IDS_CB(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
+
+ // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
+
+ { Group_General, IDS(doccolor) },
+ { Group_General, IDS_CB(docboundaries) },
+ { Group_General, IDS(appback) },
+ { Group_General, IDS_CB(objboundaries) },
+ { Group_General, IDS_CB(tblboundaries) },
+ { Group_General, IDS(font) },
+ { Group_General, IDS_CB(unvisitedlinks) },
+ { Group_General, IDS_CB(visitedlinks) },
+ { Group_General, IDS(autospellcheck) },
+ { Group_General, IDS(smarttags) },
+ { Group_General, IDS_CB(shadows) },
+
+ { Group_Writer, IDS(writergrid) },
+ { Group_Writer, IDS_CB(field) },
+ { Group_Writer, IDS_CB(index) },
+ { Group_Writer, IDS(direct) },
+ { Group_Writer, IDS(script) },
+ { Group_Writer, IDS_CB(section) },
+ { Group_Writer, IDS(hdft) },
+ { Group_Writer, IDS(pagebreak) },
+
+ { Group_Html, IDS(sgml) },
+ { Group_Html, IDS(htmlcomment) },
+ { Group_Html, IDS(htmlkeyword) },
+ { Group_Html, IDS(unknown) },
+
+ { Group_Calc, IDS(calcgrid) },
+ { Group_Calc, IDS(brk) },
+ { Group_Calc, IDS(brkmanual) },
+ { Group_Calc, IDS(brkauto) },
+ { Group_Calc, IDS(det) },
+ { Group_Calc, IDS(deterror) },
+ { Group_Calc, IDS(ref) },
+ { Group_Calc, IDS(notes) },
+ { Group_Calc, IDS(values) },
+ { Group_Calc, IDS(formulas) },
+ { Group_Calc, IDS(text) },
+ { Group_Calc, IDS(protectedcells) },
+
+ { Group_Draw, IDS(drawgrid) },
+
+ { Group_Basic, IDS(basicid) },
+ { Group_Basic, IDS(basiccomment) },
+ { Group_Basic, IDS(basicnumber) },
+ { Group_Basic, IDS(basicstring) },
+ { Group_Basic, IDS(basicop) },
+ { Group_Basic, IDS(basickeyword) },
+ { Group_Basic, IDS(error) },
+
+ { Group_Sql, IDS(sqlid) },
+ { Group_Sql, IDS(sqlnumber) },
+ { Group_Sql, IDS(sqlstring) },
+ { Group_Sql, IDS(sqlop) },
+ { Group_Sql, IDS(sqlkeyword) },
+ { Group_Sql, IDS(sqlparam) },
+ { Group_Sql, IDS(sqlcomment) }
+
+ #undef IDS
+};
+
+// ColorConfigWindow_Impl
+
+class ColorConfigWindow_Impl
+{
+public:
+ explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
+
+public:
+ void SetLinks(Link<weld::ToggleButton&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&,
+ weld::ScrolledWindow& rScroll);
+ void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
+ void ClickHdl(EditableColorConfig*, weld::ToggleButton&);
+ void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
+
+ weld::Widget& GetWidget1()
+ {
+ return *m_xWidget1;
+ }
+
+ weld::Widget& GetWidget2()
+ {
+ return *m_xWidget2;
+ }
+
+ weld::Widget& GetBody()
+ {
+ return *m_xGrid;
+ }
+
+ void AdjustExtraWidths(int nTextWidth);
+
+private:
+ // Chapter -- horizontal group separator stripe with text
+ class Chapter
+ {
+ // text
+ std::unique_ptr<weld::Label> m_xText;
+ public:
+ Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
+ void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
+ };
+
+ // Entry -- a color config entry:
+ // text (checkbox) + color list box
+ class Entry
+ {
+ public:
+ Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor, long nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
+ public:
+ void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
+ void set_width_request(int nTextWidth) { m_xText->set_size_request(nTextWidth, -1); }
+ int get_height_request() const
+ {
+ return std::max(m_xText->get_preferred_size().Height(),
+ m_xColorList->get_widget().get_preferred_size().Height());
+ }
+ void Hide ();
+ public:
+ void SetLinks(Link<weld::ToggleButton&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&);
+ void Update (ColorConfigValue const&);
+ void Update (ExtendedColorConfigValue const&);
+ void ColorChanged (ColorConfigValue&);
+ void ColorChanged (ExtendedColorConfigValue&);
+ public:
+ bool Is(const weld::ToggleButton* pBox) const { return m_xText.get() == pBox; }
+ bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
+ private:
+ // checkbox (CheckBox) or simple text (FixedText)
+ std::unique_ptr<weld::Widget> m_xText;
+ // color list box
+ std::unique_ptr<ColorListBox> m_xColorList;
+ // default color
+ Color m_aDefaultColor;
+ };
+
+private:
+ weld::Window* m_pTopLevel;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Container> m_xGrid;
+ std::unique_ptr<weld::Widget> m_xWidget1;
+ std::unique_ptr<weld::Widget> m_xWidget2;
+
+ std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
+ std::vector<std::unique_ptr<weld::Container>> vExtContainers;
+ // vChapters -- groups (group headers)
+ std::vector<std::shared_ptr<Chapter> > vChapters;
+ // vEntries -- color options
+ std::vector<std::shared_ptr<Entry> > vEntries;
+
+ // module options
+ SvtModuleOptions aModuleOptions;
+
+ // initialization
+ void CreateEntries();
+
+private:
+
+ bool IsGroupVisible (Group) const;
+};
+
+} // namespace
+
+// ColorConfigWindow_Impl::Chapter
+
+// ctor for default groups
+// rParent: parent window (ColorConfigWindow_Impl)
+// eGroup: which group is this?
+ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
+ : m_xText(rBuilder.weld_label(pLabelWidget))
+{
+ if (!bShow)
+ m_xText->hide();
+}
+
+// ColorConfigWindow_Impl::Entry
+ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
+ const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor,
+ long nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
+ : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), pTopLevel))
+ , m_aDefaultColor(rColor)
+{
+ if (bCheckBox)
+ m_xText = rBuilder.weld_check_button(pTextWidget);
+ else
+ m_xText = rBuilder.weld_label(pTextWidget);
+
+ // color list
+ m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
+
+ if (!bCheckBox)
+ {
+ m_xText->set_margin_left(m_xText->get_margin_left() +
+ nCheckBoxLabelOffset);
+ }
+
+ if (!bShow)
+ Hide();
+}
+
+void ColorConfigWindow_Impl::Entry::Hide()
+{
+ m_xText->hide();
+ m_xColorList->hide();
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::ToggleButton&,void> const& rCheckLink,
+ Link<ColorListBox&,void> const& rColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink)
+{
+ m_xColorList->SetSelectHdl(rColorLink);
+ m_xColorList->connect_focus_in(rGetFocusLink);
+ if (weld::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(m_xText.get()))
+ {
+ pCheckBox->connect_toggled(rCheckLink);
+ pCheckBox->connect_focus_in(rGetFocusLink);
+ }
+}
+
+// updates a default color config entry
+void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
+{
+ Color aColor(rValue.nColor);
+ m_xColorList->SelectEntry(aColor);
+ if (weld::ToggleButton* pCheckBox = dynamic_cast<weld::ToggleButton*>(m_xText.get()))
+ pCheckBox->set_active(rValue.bIsVisible);
+}
+
+// updates an extended color config entry
+void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
+{
+ Color aColor(rValue.getColor());
+ if (rValue.getColor() == rValue.getDefaultColor())
+ m_xColorList->SelectEntry(COL_AUTO);
+ else
+ m_xColorList->SelectEntry(aColor);
+}
+
+// color of a default entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.nColor = aColor;
+}
+
+// color of an extended entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.setColor(aColor);
+ if (aColor == COL_AUTO)
+ {
+ rValue.setColor(rValue.getDefaultColor());
+ }
+}
+
+// ColorConfigWindow_Impl
+ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
+ : m_pTopLevel(pTopLevel)
+ , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
+ , m_xGrid(m_xBuilder->weld_container("ColorConfigWindow"))
+ , m_xWidget1(m_xBuilder->weld_widget("doccolor"))
+ , m_xWidget2(m_xBuilder->weld_widget("doccolor_lb"))
+{
+ CreateEntries();
+}
+
+void ColorConfigWindow_Impl::CreateEntries()
+{
+ std::bitset<nGroupCount> aModulesInstalled;
+ // creating group headers
+ vChapters.reserve(nGroupCount);
+ for (unsigned i = 0; i != nGroupCount; ++i)
+ {
+ aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
+ vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
+ }
+
+ // Here we want to get the amount to add to the position of a FixedText to
+ // get it to align its contents with that of a CheckBox
+ long nCheckBoxLabelOffset = 0;
+ {
+ OUString sSampleText("X");
+ std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
+ std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
+ OUString sOrigCheck(xCheckBox->get_label());
+ OUString sOrigFixed(xFixedText->get_label());
+ xCheckBox->set_label(sSampleText);
+ xFixedText->set_label(sSampleText);
+ Size aCheckSize(xCheckBox->get_preferred_size());
+ Size aFixedSize(xFixedText->get_preferred_size());
+ xCheckBox->set_label(sOrigCheck);
+ xFixedText->set_label(sOrigFixed);
+ nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
+ }
+
+ // creating entries
+ vEntries.reserve(ColorConfigEntryCount);
+ for (size_t i = 0; i < SAL_N_ELEMENTS(vEntryInfo); ++i)
+ {
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
+ vEntryInfo[i].pText, vEntryInfo[i].pColor,
+ ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
+ nCheckBoxLabelOffset,
+ vEntryInfo[i].bCheckBox,
+ aModulesInstalled[vEntryInfo[i].eGroup]));
+ }
+
+ // extended entries
+ ExtendedColorConfig aExtConfig;
+ unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
+ if (!nExtGroupCount)
+ return;
+
+ size_t nLineNum = vChapters.size() + vEntries.size() + 1;
+ for (unsigned j = 0; j != nExtGroupCount; ++j)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/chapterfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ChapterFragment"));
+
+ vExtContainers.back()->set_grid_width(3);
+ vExtContainers.back()->set_grid_left_attach(0);
+ vExtContainers.back()->set_grid_top_attach(nLineNum);
+
+ OUString const sComponentName = aExtConfig.GetComponentName(j);
+ vChapters.push_back(std::make_shared<Chapter>(
+ *vExtBuilders.back(), "chapter", true));
+ vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
+ ++nLineNum;
+ unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
+ for (unsigned i = 0; i != nColorCount; ++i)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(m_xGrid.get(), "cui/ui/colorfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
+
+ vExtContainers.back()->set_grid_width(3);
+ vExtContainers.back()->set_grid_left_attach(0);
+ vExtContainers.back()->set_grid_top_attach(nLineNum);
+
+ ExtendedColorConfigValue const aColorEntry =
+ aExtConfig.GetComponentColorConfigValue(sComponentName, i);
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
+ "label", "button", aColorEntry.getDefaultColor(),
+ nCheckBoxLabelOffset, false, true));
+ vEntries.back()->SetText(aColorEntry.getDisplayName());
+ ++nLineNum;
+ }
+ }
+}
+
+void ColorConfigWindow_Impl::AdjustExtraWidths(int nTextWidth)
+{
+ for (size_t i = SAL_N_ELEMENTS(vEntryInfo); i < vEntries.size(); ++i)
+ vEntries[i]->set_width_request(nTextWidth);
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::SetLinks(Link<weld::ToggleButton&,void> const& aCheckLink,
+ Link<ColorListBox&,void> const& aColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink,
+ weld::ScrolledWindow& rScroll)
+{
+ if (vEntries.empty())
+ return;
+ for (auto const & i: vEntries)
+ i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
+ // 6 is the spacing set on ColorConfigWindow
+ rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
+}
+
+// Update()
+void ColorConfigWindow_Impl::Update (
+ EditableColorConfig const* pConfig,
+ EditableExtendedColorConfig const* pExtConfig)
+{
+ // updating default entries
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ vEntries[i]->Update(
+ pConfig->GetColorValue(aColorEntry)
+ );
+ }
+
+ // updating extended entries
+ decltype(vEntries)::size_type i = ColorConfigEntryCount;
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
+ vEntries[i]->Update(
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k)
+ );
+ }
+}
+
+// ClickHdl()
+void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, weld::ToggleButton& rBox)
+{
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ if (vEntries[i]->Is(&rBox))
+ {
+ ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
+ aValue.bIsVisible = rBox.get_active();
+ pConfig->SetColorValue(aEntry, aValue);
+ break;
+ }
+ }
+}
+
+// ColorHdl()
+void ColorConfigWindow_Impl::ColorHdl(
+ EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
+ const ColorListBox* pBox)
+{
+ unsigned i = 0;
+
+ // default entries
+ for ( ; i != ColorConfigEntryCount; ++i)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
+ vEntries[i]->ColorChanged(aValue);
+ pConfig->SetColorValue(aColorEntry, aValue);
+ break;
+ }
+ }
+
+ // extended entries
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ i = ColorConfigEntryCount;
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ unsigned const nCount = vEntries.size();
+ for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ExtendedColorConfigValue aValue =
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k);
+ vEntries[i]->ColorChanged(aValue);
+ pExtConfig->SetColorValue(sComponentName, aValue);
+ break;
+ }
+ }
+ }
+}
+
+
+// IsGroupVisible()
+bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
+{
+ switch (eGroup)
+ {
+ case Group_Writer:
+ case Group_Html:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
+ case Group_Calc:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
+ case Group_Draw:
+ return
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
+ case Group_Sql:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
+ default:
+ return true;
+ }
+}
+
+class ColorConfigCtrl_Impl
+{
+ std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
+ std::unique_ptr<weld::Container> m_xBody;
+ std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
+
+ EditableColorConfig* pColorConfig;
+ EditableExtendedColorConfig* pExtColorConfig;
+
+ DECL_LINK(ClickHdl, weld::ToggleButton&, void);
+ DECL_LINK(ColorHdl, ColorListBox&, void);
+ DECL_LINK(ControlFocusHdl, weld::Widget&, void);
+
+public:
+ explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
+
+ void AdjustExtraWidths(int nTextWidth) { m_xScrollWindow->AdjustExtraWidths(nTextWidth); }
+ void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
+ void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
+ void Update();
+ long GetScrollPosition() const
+ {
+ return m_xVScroll->vadjustment_get_value();
+ }
+ void SetScrollPosition(long nSet)
+ {
+ m_xVScroll->vadjustment_set_value(nSet);
+ }
+ weld::Widget& GetWidget1()
+ {
+ return m_xScrollWindow->GetWidget1();
+ }
+ weld::Widget& GetWidget2()
+ {
+ return m_xScrollWindow->GetWidget2();
+ }
+};
+
+ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rBuilder)
+ : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
+ , m_xBody(rBuilder.weld_container("colorconfig"))
+ , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
+ , pColorConfig(nullptr)
+ , pExtColorConfig(nullptr)
+{
+ m_xBody->set_stack_background();
+
+ Link<weld::ToggleButton&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
+ Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
+ Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
+ m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
+}
+
+void ColorConfigCtrl_Impl::Update ()
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->Update(pColorConfig, pExtColorConfig);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::ToggleButton&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->ClickHdl(pColorConfig, rBox);
+}
+
+// a color list has changed
+IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set" );
+ m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
+{
+ // determine whether a control is completely visible
+ // and make it visible
+ unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
+
+ // calc visible area
+ auto nThumbPos = m_xVScroll->vadjustment_get_value();
+ int const nWinTop = nThumbPos;
+ int const nWinBottom = nWinTop + nWinHeight;
+
+ int x, nCtrlPosY, width, nHeight;
+ rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
+
+ int const nSelectedItemTop = nCtrlPosY;
+ int const nSelectedItemBottom = nCtrlPosY + nHeight;
+ bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
+ bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
+ bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
+
+ if (!isNeedToScroll)
+ return;
+
+ if (shouldScrollDown)
+ {
+ int nOffset = nSelectedItemBottom - nWinBottom;
+ nThumbPos += nOffset + 2;
+ }
+ else
+ {
+ int nOffset = nWinTop - nSelectedItemTop;
+ nThumbPos -= nOffset + 2;
+ if(nThumbPos < 0)
+ nThumbPos = 0;
+ }
+ m_xVScroll->vadjustment_set_value(nThumbPos);
+}
+
+// SvxColorOptionsTabPage
+SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
+ , bFillItemSetCalled(false)
+ , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
+ , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
+ , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
+ , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
+ , m_xTable(m_xBuilder->weld_widget("table"))
+ , m_xOnFT(m_xBuilder->weld_label("on"))
+ , m_xElementFT(m_xBuilder->weld_label("uielements"))
+ , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
+ , m_rWidget1(m_xColorConfigCT->GetWidget1())
+ , m_rWidget2(m_xColorConfigCT->GetWidget2())
+{
+ m_xColorSchemeLB->make_sorted();
+ m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
+ Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
+ m_xSaveSchemePB->connect_clicked(aLk);
+ m_xDeleteSchemePB->connect_clicked(aLk);
+
+ m_rWidget1.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+ m_rWidget2.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+}
+
+SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
+{
+ if (pColorConfig)
+ {
+ //when the dialog is cancelled but the color scheme ListBox has been changed these
+ //changes need to be undone
+ if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
+ if(!sOldScheme.isEmpty())
+ {
+ pColorConfig->SetCurrentSchemeName(sOldScheme);
+ pExtColorConfig->SetCurrentSchemeName(sOldScheme);
+ }
+ }
+ pColorConfig->ClearModified();
+ pColorConfig->EnableBroadcast();
+ pColorConfig.reset();
+
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->EnableBroadcast();
+ pExtColorConfig.reset();
+ }
+ m_xColorConfigCT.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ bFillItemSetCalled = true;
+ if (m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ pColorConfig->SetModified();
+ pExtColorConfig->SetModified();
+ }
+ if (pColorConfig->IsModified())
+ pColorConfig->Commit();
+ if (pExtColorConfig->IsModified())
+ pExtColorConfig->Commit();
+ return true;
+}
+
+void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
+{
+ if(pColorConfig)
+ {
+ pColorConfig->ClearModified();
+ pColorConfig->DisableBroadcast();
+ }
+ pColorConfig.reset(new EditableColorConfig);
+ m_xColorConfigCT->SetConfig(*pColorConfig);
+
+ if(pExtColorConfig)
+ {
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->DisableBroadcast();
+ }
+ pExtColorConfig.reset(new EditableExtendedColorConfig);
+ m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
+
+ OUString sUser = GetUserData();
+ //has to be called always to speed up accessibility tools
+ m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
+ m_xColorSchemeLB->clear();
+ const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
+ for(const OUString& s : aSchemes)
+ m_xColorSchemeLB->append_text(s);
+ m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
+ m_xColorSchemeLB->save_value();
+ m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
+ UpdateColorConfig();
+}
+
+DeactivateRC SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxColorOptionsTabPage::UpdateColorConfig()
+{
+ //update the color config control
+ m_xColorConfigCT->Update();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ pColorConfig->LoadScheme(rBox.get_active_text());
+ pExtColorConfig->LoadScheme(rBox.get_active_text());
+ UpdateColorConfig();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
+{
+ if (m_xSaveSchemePB.get() == &rButton)
+ {
+ OUString sName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(GetFrameWeld(),
+ sName, CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE2) ));
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ aNameDlg->SetText(CuiResId(RID_SVXSTR_COLOR_CONFIG_SAVE1));
+ aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ if(RET_OK == aNameDlg->Execute())
+ {
+ aNameDlg->GetName(sName);
+ pColorConfig->AddScheme(sName);
+ pExtColorConfig->AddScheme(sName);
+ m_xColorSchemeLB->append_text(sName);
+ m_xColorSchemeLB->set_active_text(sName);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ }
+ }
+ else
+ {
+ DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE)));
+ xQuery->set_title(CuiResId(RID_SVXSTR_COLOR_CONFIG_DELETE_TITLE));
+ if (RET_YES == xQuery->run())
+ {
+ OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
+ m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
+ m_xColorSchemeLB->set_active(0);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ //first select the new scheme and then delete the old one
+ pColorConfig->DeleteScheme(sDeleteScheme);
+ pExtColorConfig->DeleteScheme(sDeleteScheme);
+ }
+ }
+ m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
+{
+ OUString sName;
+ rDialog.GetName(sName);
+ return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
+}
+
+void SvxColorOptionsTabPage::FillUserData()
+{
+ SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
+}
+
+IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
+{
+ // horizontal positions
+ int nX0 = 0, nX1, nX2, y, width, height;
+ if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
+ return;
+ if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
+ return;
+ auto nTextWidth1 = nX1 - nX0;
+ auto nTextWidth2 = nX2 - nX1;
+ m_xOnFT->set_size_request(nTextWidth1, -1);
+ m_xElementFT->set_size_request(nTextWidth2, -1);
+ m_xColorConfigCT->AdjustExtraWidths(nTextWidth2 - 12);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.hxx b/cui/source/options/optcolor.hxx
new file mode 100644
index 000000000..de84e06b1
--- /dev/null
+++ b/cui/source/options/optcolor.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>
+
+namespace svtools {class EditableColorConfig;class EditableExtendedColorConfig;}
+class ColorConfigCtrl_Impl;
+class AbstractSvxNameDialog;
+class SvxColorOptionsTabPage : public SfxTabPage
+{
+ bool bFillItemSetCalled;
+
+ std::unique_ptr<weld::ComboBox> m_xColorSchemeLB;
+ std::unique_ptr<weld::Button> m_xSaveSchemePB;
+ std::unique_ptr<weld::Button> m_xDeleteSchemePB;
+ std::unique_ptr<ColorConfigCtrl_Impl> m_xColorConfigCT;
+ std::unique_ptr<weld::Widget> m_xTable;
+ std::unique_ptr<weld::Label> m_xOnFT;
+ std::unique_ptr<weld::Label> m_xElementFT;
+ std::unique_ptr<weld::Label> m_xColorFT;
+ weld::Widget& m_rWidget1;
+ weld::Widget& m_rWidget2;
+
+ std::unique_ptr<svtools::EditableColorConfig> pColorConfig;
+ std::unique_ptr<svtools::EditableExtendedColorConfig> pExtColorConfig;
+
+ DECL_LINK(SchemeChangedHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SaveDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNameHdl_Impl, AbstractSvxNameDialog&, bool);
+ DECL_LINK(AdjustHeaderBar, const Size&, void);
+ void UpdateColorConfig();
+
+public:
+ SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxColorOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.cxx b/cui/source/options/optctl.cxx
new file mode 100644
index 000000000..983f077e7
--- /dev/null
+++ b/cui/source/options/optctl.cxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optctl.hxx"
+#include <svl/ctloptions.hxx>
+#include <sal/log.hxx>
+#include <tools/debug.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+IMPL_LINK_NOARG(SvxCTLOptionsPage, SequenceCheckingCB_Hdl, weld::Button&, void)
+{
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+ // #i48117#: by default restricted and type&replace have to be switched on
+ if (bIsSequenceChecking)
+ {
+ m_xTypeReplaceCB->set_active(true);
+ m_xRestrictedCB->set_active(true);
+ }
+}
+
+SvxCTLOptionsPage::SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optctlpage.ui", "OptCTLPage", &rSet)
+ , m_xSequenceCheckingCB(m_xBuilder->weld_check_button("sequencechecking"))
+ , m_xRestrictedCB(m_xBuilder->weld_check_button("restricted"))
+ , m_xTypeReplaceCB(m_xBuilder->weld_check_button("typeandreplace"))
+ , m_xMovementLogicalRB(m_xBuilder->weld_radio_button("movementlogical"))
+ , m_xMovementVisualRB(m_xBuilder->weld_radio_button("movementvisual"))
+ , m_xNumeralsLB(m_xBuilder->weld_combo_box("numerals"))
+{
+ m_xSequenceCheckingCB->connect_clicked(LINK(this, SvxCTLOptionsPage, SequenceCheckingCB_Hdl));
+}
+
+SvxCTLOptionsPage::~SvxCTLOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxCTLOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxCTLOptionsPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxCTLOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvtCTLOptions aCTLOptions;
+
+ // Sequence checking
+ bool bChecked = m_xSequenceCheckingCB->get_active();
+ if ( m_xSequenceCheckingCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceChecking( bChecked );
+ bModified = true;
+ }
+
+ bChecked = m_xRestrictedCB->get_active();
+ if( m_xRestrictedCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceCheckingRestricted( bChecked );
+ bModified = true;
+ }
+ bChecked = m_xTypeReplaceCB->get_active();
+ if( m_xTypeReplaceCB->get_state_changed_from_saved())
+ {
+ aCTLOptions.SetCTLSequenceCheckingTypeAndReplace(bChecked);
+ bModified = true;
+ }
+
+ bool bLogicalChecked = m_xMovementLogicalRB->get_active();
+ if ( m_xMovementLogicalRB->get_state_changed_from_saved() ||
+ m_xMovementVisualRB->get_state_changed_from_saved() )
+ {
+ SvtCTLOptions::CursorMovement eMovement =
+ bLogicalChecked ? SvtCTLOptions::MOVEMENT_LOGICAL : SvtCTLOptions::MOVEMENT_VISUAL;
+ aCTLOptions.SetCTLCursorMovement( eMovement );
+ bModified = true;
+ }
+
+ if (m_xNumeralsLB->get_value_changed_from_saved())
+ {
+ const sal_Int32 nPos = m_xNumeralsLB->get_active();
+ aCTLOptions.SetCTLTextNumerals( static_cast<SvtCTLOptions::TextNumerals>(nPos) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxCTLOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtCTLOptions aCTLOptions;
+
+ m_xSequenceCheckingCB->set_active( aCTLOptions.IsCTLSequenceChecking() );
+ m_xRestrictedCB->set_active( aCTLOptions.IsCTLSequenceCheckingRestricted() );
+ m_xTypeReplaceCB->set_active( aCTLOptions.IsCTLSequenceCheckingTypeAndReplace() );
+
+ SvtCTLOptions::CursorMovement eMovement = aCTLOptions.GetCTLCursorMovement();
+ switch ( eMovement )
+ {
+ case SvtCTLOptions::MOVEMENT_LOGICAL :
+ m_xMovementLogicalRB->set_active(true);
+ break;
+
+ case SvtCTLOptions::MOVEMENT_VISUAL :
+ m_xMovementVisualRB->set_active(true);
+ break;
+
+ default:
+ SAL_WARN( "cui.options", "SvxCTLOptionsPage::Reset(): invalid movement enum" );
+ }
+
+ sal_uInt16 nPos = static_cast<sal_uInt16>(aCTLOptions.GetCTLTextNumerals());
+ DBG_ASSERT( nPos < m_xNumeralsLB->get_count(), "SvxCTLOptionsPage::Reset(): invalid numerals enum" );
+ m_xNumeralsLB->set_active(nPos);
+
+ m_xSequenceCheckingCB->save_state();
+ m_xRestrictedCB->save_state();
+ m_xTypeReplaceCB->save_state();
+ m_xMovementLogicalRB->save_state();
+ m_xMovementVisualRB->save_state();
+ m_xNumeralsLB->save_value();
+
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.hxx b/cui/source/options/optctl.hxx
new file mode 100644
index 000000000..5f8e807b1
--- /dev/null
+++ b/cui/source/options/optctl.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_CUI_SOURCE_OPTIONS_OPTCTL_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTCTL_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+class SvxCTLOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xSequenceCheckingCB;
+ std::unique_ptr<weld::CheckButton> m_xRestrictedCB;
+ std::unique_ptr<weld::CheckButton> m_xTypeReplaceCB;
+ std::unique_ptr<weld::RadioButton> m_xMovementLogicalRB;
+ std::unique_ptr<weld::RadioButton> m_xMovementVisualRB;
+ std::unique_ptr<weld::ComboBox> m_xNumeralsLB;
+
+ DECL_LINK( SequenceCheckingCB_Hdl, weld::Button&, void );
+
+public:
+ SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxCTLOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_OPTCTL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optdict.cxx b/cui/source/options/optdict.cxx
new file mode 100644
index 000000000..58ccf42e3
--- /dev/null
+++ b/cui/source/options/optdict.cxx
@@ -0,0 +1,773 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <editeng/unolingu.hxx>
+#include <svx/dialmgr.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <comphelper/string.hxx>
+#include <tools/debug.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <linguistic/misc.hxx>
+#include <strings.hrc>
+#include <optdict.hxx>
+#include <dialmgr.hxx>
+#include <svx/svxerr.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+using namespace linguistic;
+
+// static function -------------------------------------------------------
+
+static OUString getNormDicEntry_Impl(const OUString &rText)
+{
+ OUString aTmp(comphelper::string::stripEnd(rText, '.'));
+ // non-standard hyphenation
+ if (aTmp.indexOf('[') > -1)
+ {
+ OUStringBuffer aTmp2 ( aTmp.getLength() );
+ bool bSkip = false;
+ for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
+ {
+ sal_Unicode cTmp = aTmp[i];
+ if (cTmp == '[')
+ bSkip = true;
+ else if (!bSkip)
+ aTmp2.append( cTmp );
+ else if (cTmp == ']')
+ bSkip = false;
+ }
+ aTmp = aTmp2.makeStringAndClear();
+ }
+ return aTmp.replaceAll("=", "");
+}
+
+namespace {
+
+// Compare Dictionary Entry result
+enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
+
+}
+
+static CDE_RESULT cmpDicEntry_Impl( const OUString &rText1, const OUString &rText2 )
+{
+ CDE_RESULT eRes = CDE_DIFFERENT;
+
+ if (rText1 == rText2)
+ eRes = CDE_EQUAL;
+ else
+ { // similar = equal up to trailing '.' and hyphenation positions
+ // marked with '=' and '[' + alternative spelling pattern + ']'
+ if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
+ eRes = CDE_SIMILAR;
+ }
+
+ return eRes;
+}
+
+// class SvxNewDictionaryDialog -------------------------------------------
+
+SvxNewDictionaryDialog::SvxNewDictionaryDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/optnewdictionarydialog.ui", "OptNewDictionaryDialog")
+ , m_xNameEdit(m_xBuilder->weld_entry("nameedit"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xExceptBtn(m_xBuilder->weld_check_button("except"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ // Prevent creation of dictionary without a name.
+ m_xOKBtn->set_sensitive(false);
+
+ // install handler
+ m_xNameEdit->connect_changed(LINK(this, SvxNewDictionaryDialog, ModifyHdl_Impl));
+ m_xOKBtn->connect_clicked(LINK(this, SvxNewDictionaryDialog, OKHdl_Impl));
+
+ // display languages
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::ALL, true, true);
+ m_xLanguageLB->set_active(0);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl, weld::Button&, void)
+{
+
+ // add extension for personal dictionaries
+ OUString sDict = comphelper::string::stripEnd(m_xNameEdit->get_text(), ' ') + ".dic";
+
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+
+ Sequence< Reference< XDictionary > > aDics;
+ if (xDicList.is())
+ aDics = xDicList->getDictionaries();
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ bool bFound = false;
+ sal_Int32 i;
+ for (i = 0; !bFound && i < nCount; ++i )
+ if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
+ bFound = true;
+
+ if ( sDict.indexOf("/") != -1 || sDict.indexOf("\\") != -1 )
+ {
+ // Detected an invalid character.
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_OPT_INVALID_DICT_NAME)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ if ( bFound )
+ {
+ // duplicate names?
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_OPT_DOUBLE_DICTS)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ // create and add
+ LanguageType nLang = m_xLanguageLB->get_active_id();
+ try
+ {
+ // create new dictionary
+ DictionaryType eType = m_xExceptBtn->get_active() ?
+ DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
+ if (xDicList.is())
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
+ m_xNewDic = xDicList->createDictionary(sDict, aLocale, eType, aURL);
+ m_xNewDic->setActive(true);
+ }
+ DBG_ASSERT(m_xNewDic.is(), "NULL pointer");
+ }
+ catch(...)
+ {
+ m_xNewDic = nullptr;
+ // error: couldn't create new dictionary
+ SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
+ m_xDialog.get(), RID_SVXERRCTX, SvxResLocale() );
+ ErrorHandler::HandleError( *new StringErrorInfo(
+ ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
+ m_xDialog->response(RET_CANCEL);
+ }
+
+ if (xDicList.is() && m_xNewDic.is())
+ {
+ xDicList->addDictionary(m_xNewDic);
+
+ // refresh list of dictionaries
+ //! dictionaries may have been added/removed elsewhere too.
+ aDics = xDicList->getDictionaries();
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, ModifyHdl_Impl, weld::Entry&, void)
+{
+ m_xOKBtn->set_sensitive(!m_xNameEdit->get_text().isEmpty());
+}
+
+// class SvxEditDictionaryDialog -------------------------------------------
+
+SvxEditDictionaryDialog::SvxEditDictionaryDialog(weld::Window* pParent, const OUString& rName)
+ : GenericDialogController(pParent, "cui/ui/editdictionarydialog.ui", "EditDictionaryDialog")
+ , sModify(CuiResId(STR_MODIFY))
+ , bFirstSelect(false)
+ , bDoNothing(false)
+ , bDicIsReadonly(false)
+ , m_xAllDictsLB(m_xBuilder->weld_combo_box("book"))
+ , m_xLangFT(m_xBuilder->weld_label("lang_label"))
+ , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+ , m_xWordED(m_xBuilder->weld_entry("word"))
+ , m_xReplaceFT(m_xBuilder->weld_label("replace_label"))
+ , m_xReplaceED(m_xBuilder->weld_entry("replace"))
+ , m_xSingleColumnLB(m_xBuilder->weld_tree_view("words"))
+ , m_xDoubleColumnLB(m_xBuilder->weld_tree_view("replaces"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("newreplace"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+{
+ sReplaceFT_Text = m_xReplaceFT->get_label();
+ m_xSingleColumnLB->set_size_request(-1, m_xSingleColumnLB->get_height_rows(8));
+ m_xDoubleColumnLB->set_size_request(-1, m_xDoubleColumnLB->get_height_rows(8));
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ m_xSingleColumnLB->hide();
+
+ //set to max of both sizes to avoid resizes
+ sNew = m_xNewReplacePB->get_label();
+ auto nNewWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sModify);
+ auto nReplaceWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sNew);
+ m_xNewReplacePB->set_size_request(std::max(nNewWidth, nReplaceWidth), -1);
+
+ if (LinguMgr::GetDictionaryList().is())
+ aDics = LinguMgr::GetDictionaryList()->getDictionaries();
+
+ m_xSingleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+ m_xDoubleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xDoubleColumnLB->get_approximate_digit_width() * 22);
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+
+ // install handler
+ m_xNewReplacePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+ m_xDeletePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+
+ m_xLangLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
+ m_xAllDictsLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
+
+ m_xWordED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xReplaceED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xWordED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+ m_xReplaceED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+
+ // fill listbox with all available WB's
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ OUString aLookUpEntry;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ Reference< XDictionary > xDic = pDic[i];
+ if (xDic.is())
+ {
+ bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+ OUString aDicName( xDic->getName() );
+ const OUString aTxt( ::GetDicInfoStr( aDicName,
+ LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
+ m_xAllDictsLB->append_text(aTxt);
+
+ if (rName == aDicName)
+ aLookUpEntry = aTxt;
+ }
+ }
+
+ m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
+
+ Link<OUString&,bool> aLink = LINK(this, SvxEditDictionaryDialog, InsertTextHdl);
+ m_xReplaceED->connect_insert_text(aLink);
+ m_xWordED->connect_insert_text(aLink);
+
+ if ( nCount > 0 )
+ {
+ m_xAllDictsLB->set_active_text(aLookUpEntry);
+ int nPos = m_xAllDictsLB->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = 0;
+ m_xAllDictsLB->set_active(nPos);
+ }
+ Reference< XDictionary > xDic;
+ if (nPos != -1)
+ xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ // check if dictionary is read-only
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+ ShowWords_Impl( nPos );
+ }
+ else
+ {
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(false);
+ }
+
+ m_xWordED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, EntrySizeAllocHdl, const Size&, void)
+{
+ std::vector<int> aWidths;
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_pWordsLB, x, y, width, height))
+ {
+ aWidths.push_back(x);
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+ }
+}
+
+SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
+{
+}
+
+void SvxEditDictionaryDialog::SetDicReadonly_Impl(
+ Reference< XDictionary > const &xDic )
+{
+ // enable or disable new and delete button according to file attributes
+ bDicIsReadonly = true;
+ if (xDic.is())
+ {
+ Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( !xStor.is() // non persistent dictionary
+ || !xStor->hasLocation() // not yet persistent
+ || !xStor->isReadonly() )
+ {
+ bDicIsReadonly = false;
+ }
+ }
+}
+
+void SvxEditDictionaryDialog::SetLanguage_Impl(LanguageType nLanguage)
+{
+ // select language
+ m_xLangLB->set_active_id(nLanguage);
+}
+
+int SvxEditDictionaryDialog::GetLBInsertPos(const OUString &rDicWord)
+{
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ int j;
+ int nCount = m_pWordsLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) );
+ sal_Int32 nCmpRes = pCollator->
+ compareString( aNormEntry, getNormDicEntry_Impl( m_pWordsLB->get_text(j, 0) ) );
+ if (nCmpRes < 0)
+ break;
+ }
+
+ return j;
+}
+
+void SvxEditDictionaryDialog::RemoveDictEntry(int nEntry)
+{
+ int nLBPos = m_xAllDictsLB->get_active();
+ if (nEntry != -1 && nLBPos != -1)
+ {
+ OUString sTmpShort(m_pWordsLB->get_text(nEntry, 0));
+
+ Reference<XDictionary> xDic = aDics.getConstArray()[nLBPos];
+ if (xDic->remove(sTmpShort)) // sal_True on success
+ {
+ m_pWordsLB->remove(nEntry);
+ SelectHdl(*m_pWordsLB);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos == -1)
+ return;
+
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ // display dictionary
+ ShowWords_Impl( nPos );
+ // enable or disable new and delete button according to file attributes
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl, weld::ComboBox&, void)
+{
+ int nDicPos = m_xAllDictsLB->get_active();
+ LanguageType nLang = m_xLangLB->get_active_id();
+ Reference< XDictionary > const & xDic = aDics[ nDicPos ];
+ LanguageType nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
+
+ if ( nLang == nOldLang )
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_SVXSTR_CONFIRM_SET_LANGUAGE)));
+ OUString sTxt(xBox->get_primary_text());
+ sTxt = sTxt.replaceFirst("%1", m_xAllDictsLB->get_active_text());
+ xBox->set_primary_text(sTxt);
+
+ if (xBox->run() == RET_YES)
+ {
+ xDic->setLocale( LanguageTag::convertToLocale( nLang ) );
+ bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ const OUString sName(
+ ::GetDicInfoStr( xDic->getName(),
+ LanguageTag( xDic->getLocale() ).getLanguageType(),
+ bNegativ ) );
+ m_xAllDictsLB->remove(nDicPos);
+ m_xAllDictsLB->insert_text(nDicPos, sName);
+ m_xAllDictsLB->set_active(nDicPos);
+ }
+ else
+ SetLanguage_Impl( nOldLang );
+}
+
+void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
+{
+ Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
+
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xWordED->set_text(OUString());
+ m_xReplaceED->set_text(OUString());
+
+ bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE;
+ bool bLangNone = LanguageTag(
+ xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE;
+
+ // The label is "Replace By" only in negative dictionaries (forbidden
+ // words), otherwise "Grammar By" in language-specific dictionaries
+ // (where the optional second word is the sample word for
+ // the Hunspell based affixation/compounding of the new dictionary word)
+ if (bIsNegative)
+ {
+ m_xReplaceFT->set_label(sReplaceFT_Text);
+ } else if (!bLangNone) {
+ m_xReplaceFT->set_label(CuiResId(RID_SVXSTR_OPT_GRAMMAR_BY));
+ }
+
+ if(bIsNegative || !bLangNone)
+ {
+ // make controls for replacement text active
+ if (!m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->show();
+ m_xReplaceED->show();
+ m_xSingleColumnLB->hide();
+ m_xDoubleColumnLB->show();
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ }
+ }
+ else
+ {
+ // deactivate controls for replacement text
+ if (m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->hide();
+ m_xReplaceED->hide();
+ m_xDoubleColumnLB->hide();
+ m_xSingleColumnLB->show();
+ m_pWordsLB = m_xSingleColumnLB.get();
+ }
+ }
+
+ m_pWordsLB->clear();
+
+ Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
+ const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
+ sal_Int32 nCount = aEntries.getLength();
+ std::vector<OUString> aSortedDicEntries;
+ aSortedDicEntries.reserve(nCount);
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ OUString aStr = pEntry[i]->getDictionaryWord();
+ if(!pEntry[i]->getReplacementText().isEmpty())
+ {
+ aStr += "\t" + pEntry[i]->getReplacementText();
+ }
+ aSortedDicEntries.push_back(aStr);
+ }
+
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ std::sort(aSortedDicEntries.begin(), aSortedDicEntries.end(),
+ [&] (OUString const & lhs, OUString const & rhs)
+ {
+ sal_Int32 nCmpRes = pCollator->
+ compareString( getNormDicEntry_Impl(lhs), getNormDicEntry_Impl( rhs ) );
+ return nCmpRes < 0;
+ });
+
+ m_pWordsLB->freeze(); // speed up insert
+ int nRow = 0;
+ for (OUString const & rStr : aSortedDicEntries)
+ {
+ m_pWordsLB->append_text(rStr.getToken(0, '\t'));
+ if (m_pWordsLB == m_xDoubleColumnLB.get())
+ {
+ OUString sReplace = rStr.getToken(1, '\t');
+ m_pWordsLB->set_text(nRow, sReplace, 1);
+ ++nRow;
+ }
+ }
+ m_pWordsLB->thaw();
+
+ if (m_pWordsLB->n_children())
+ {
+ m_pWordsLB->select(0);
+ m_pWordsLB->set_cursor(0);
+ SelectHdl(*m_pWordsLB);
+ }
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (bDoNothing)
+ return;
+
+ int nEntry = rBox.get_selected_index();
+
+ if(!bFirstSelect)
+ {
+ if (nEntry != -1)
+ {
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // without this the cursor is always at the beginning of a word, if the text
+ // is set over the ModifyHdl, although you're editing there at the moment
+ if (m_xWordED->get_text() != sTmpShort)
+ m_xWordED->set_text(sTmpShort);
+ if (&rBox == m_xDoubleColumnLB.get())
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ }
+ }
+ else
+ bFirstSelect = false;
+
+ // entries in the list box should exactly correspond to those from the
+ // dictionary. Thus:
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(nEntry != -1 && !IsDicReadonly_Impl());
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelActionHdl, weld::Entry&, rDictEdit, bool)
+{
+ return NewDelHdl(&rDictEdit);
+}
+
+bool SvxEditDictionaryDialog::NewDelHdl(const weld::Widget* pBtn)
+{
+ if (pBtn == m_xDeletePB.get())
+ {
+ OUString aStr;
+
+ m_xWordED->set_text(aStr);
+ m_xReplaceED->set_text(aStr);
+ m_xDeletePB->set_sensitive(false);
+
+ int nEntry = m_pWordsLB->get_selected_index();
+ RemoveDictEntry(nEntry); // remove entry from dic and list-box
+ }
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ int nEntry = m_pWordsLB->get_selected_index();
+ OUString aNewWord(m_xWordED->get_text());
+ OUString sEntry(aNewWord);
+ OUString aReplaceStr(m_xReplaceED->get_text());
+
+ DictionaryError nAddRes = DictionaryError::UNKNOWN;
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos != -1 && !aNewWord.isEmpty())
+ {
+ DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ {
+ // make changes in dic
+
+ bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ OUString aRplcText;
+ if(!aReplaceStr.isEmpty())
+ aRplcText = aReplaceStr;
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ xDic->remove(m_pWordsLB->get_text(nEntry, 0));
+ // if remove has failed the following add should fail too
+ // and thus a warning message should be triggered...
+
+ nAddRes = linguistic::AddEntryToDic( xDic,
+ aNewWord, bIsNegEntry,
+ aRplcText, false );
+ }
+ }
+ if (DictionaryError::NONE != nAddRes)
+ SvxDicError(m_xDialog.get(), nAddRes);
+
+ if (DictionaryError::NONE == nAddRes && !sEntry.isEmpty())
+ {
+ // insert new entry in list-box etc...
+ m_pWordsLB->freeze();
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ {
+ m_pWordsLB->set_text(nEntry, sEntry);
+ if (!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+ else
+ {
+ nEntry = GetLBInsertPos(aNewWord);
+ m_pWordsLB->insert_text(nEntry, sEntry);
+ if(!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+
+ m_pWordsLB->thaw();
+ m_pWordsLB->scroll_to_row(nEntry);
+
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ m_xWordED->grab_focus();
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xWordED);
+ return true;
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ OUString rEntry = rEdt.get_text();
+
+ sal_Int32 nWordLen = rEntry.getLength();
+ const OUString& rRepString = m_xReplaceED->get_text();
+
+ bool bEnableNewReplace = false;
+ bool bEnableDelete = false;
+ OUString aNewReplaceText = sNew;
+
+ if (&rEdt == m_xWordED.get())
+ {
+ if(nWordLen>0)
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+ CDE_RESULT eCmpRes = CDE_DIFFERENT;
+
+ bool bDoubleColumn = m_pWordsLB == m_xDoubleColumnLB.get();
+
+ for (int i = 0, nCount = m_pWordsLB->n_children(); i < nCount; ++i)
+ {
+ OUString aTestStr(m_pWordsLB->get_text(i, 0));
+ eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
+ if(CDE_DIFFERENT != eCmpRes)
+ {
+ if(!rRepString.isEmpty())
+ bFirstSelect = true;
+ bDoNothing=true;
+ m_pWordsLB->set_cursor(i);
+ bDoNothing=false;
+ if (bDoubleColumn)
+ m_xReplaceED->set_text(m_pWordsLB->get_text(i, 1));
+
+ if (CDE_SIMILAR == eCmpRes)
+ {
+ aNewReplaceText = sModify;
+ bEnableNewReplace = true;
+ }
+ bFound= true;
+ break;
+ }
+ else if(getNormDicEntry_Impl(aTestStr).indexOf(
+ getNormDicEntry_Impl( rEntry ) ) == 0
+ && !bTmpSelEntry)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(i);
+ bDoNothing=false;
+ bTmpSelEntry=true;
+
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ }
+
+ if(!bFound)
+ {
+ m_pWordsLB->unselect_all();
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ bEnableDelete = CDE_DIFFERENT != eCmpRes;
+ }
+ else if (m_pWordsLB->n_children() > 0)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(0);
+ bDoNothing=false;
+ }
+ }
+ else if(&rEdt == m_xReplaceED.get())
+ {
+ OUString aReplaceText;
+ OUString aWordText;
+ int nFirstSel = m_pWordsLB->get_selected_index();
+ if (nFirstSel != -1) // a m_pWordsLB entry is selected
+ {
+ aWordText = m_pWordsLB->get_text(nFirstSel, 0);
+ aReplaceText = m_pWordsLB->get_text(nFirstSel, 1);
+
+ aNewReplaceText = sModify;
+ bEnableDelete = true;
+ }
+ bool bIsChange =
+ CDE_EQUAL != cmpDicEntry_Impl(m_xWordED->get_text(), aWordText)
+ || CDE_EQUAL != cmpDicEntry_Impl(m_xReplaceED->get_text(), aReplaceText);
+ if (!m_xWordED->get_text().isEmpty() && bIsChange)
+ bEnableNewReplace = true;
+ }
+
+ m_xNewReplacePB->set_label(aNewReplaceText);
+ m_xNewReplacePB->set_sensitive(bEnableNewReplace && !IsDicReadonly_Impl());
+ m_xDeletePB->set_sensitive(bEnableDelete && !IsDicReadonly_Impl());
+}
+
+IMPL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, rText, bool)
+{
+ rText = rText.replaceAll(" ", "");
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.cxx b/cui/source/options/optfltr.cxx
new file mode 100644
index 000000000..5708f14a3
--- /dev/null
+++ b/cui/source/options/optfltr.cxx
@@ -0,0 +1,344 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/moduleoptions.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <officecfg/Office/Common.hxx>
+#include "optfltr.hxx"
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+enum class MSFltrPg2_CheckBoxEntries {
+ Math,
+ Writer,
+ Calc,
+ Impress,
+ SmartArt,
+ Visio,
+ PDF,
+ InvalidCBEntry
+};
+
+
+OfaMSFilterTabPage::OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrpage.ui", "OptFltrPage", &rSet)
+ , m_xWBasicCodeCB(m_xBuilder->weld_check_button("wo_basic"))
+ , m_xWBasicWbctblCB(m_xBuilder->weld_check_button("wo_exec"))
+ , m_xWBasicStgCB(m_xBuilder->weld_check_button("wo_saveorig"))
+ , m_xEBasicCodeCB(m_xBuilder->weld_check_button("ex_basic"))
+ , m_xEBasicExectblCB(m_xBuilder->weld_check_button("ex_exec"))
+ , m_xEBasicStgCB(m_xBuilder->weld_check_button("ex_saveorig"))
+ , m_xPBasicCodeCB(m_xBuilder->weld_check_button("pp_basic"))
+ , m_xPBasicStgCB(m_xBuilder->weld_check_button("pp_saveorig"))
+{
+ m_xWBasicCodeCB->connect_clicked( LINK( this, OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl ) );
+ m_xEBasicCodeCB->connect_clicked( LINK( this, OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl ) );
+}
+
+OfaMSFilterTabPage::~OfaMSFilterTabPage()
+{
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl, weld::Button&, void)
+{
+ m_xWBasicWbctblCB->set_sensitive(m_xWBasicCodeCB->get_active());
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl, weld::Button&, void)
+{
+ m_xEBasicExectblCB->set_sensitive(m_xEBasicCodeCB->get_active());
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaMSFilterTabPage::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ if( m_xWBasicCodeCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicCode( m_xWBasicCodeCB->get_active() );
+ if( m_xWBasicWbctblCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicExecutable( m_xWBasicWbctblCB->get_active() );
+ if( m_xWBasicStgCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicStorage( m_xWBasicStgCB->get_active() );
+
+ if( m_xEBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicCode( m_xEBasicCodeCB->get_active() );
+ if( m_xEBasicExectblCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicExecutable( m_xEBasicExectblCB->get_active() );
+ if( m_xEBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicStorage( m_xEBasicStgCB->get_active() );
+
+ if( m_xPBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicCode( m_xPBasicCodeCB->get_active() );
+ if( m_xPBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicStorage( m_xPBasicStgCB->get_active() );
+
+ return false;
+}
+
+void OfaMSFilterTabPage::Reset( const SfxItemSet* )
+{
+ const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xWBasicCodeCB->set_active( rOpt.IsLoadWordBasicCode() );
+ m_xWBasicCodeCB->save_state();
+ m_xWBasicWbctblCB->set_active( rOpt.IsLoadWordBasicExecutable() );
+ m_xWBasicWbctblCB->save_state();
+ m_xWBasicStgCB->set_active( rOpt.IsLoadWordBasicStorage() );
+ m_xWBasicStgCB->save_state();
+ LoadWordBasicCheckHdl_Impl( *m_xWBasicCodeCB );
+
+ m_xEBasicCodeCB->set_active( rOpt.IsLoadExcelBasicCode() );
+ m_xEBasicCodeCB->save_state();
+ m_xEBasicExectblCB->set_active( rOpt.IsLoadExcelBasicExecutable() );
+ m_xEBasicExectblCB->save_state();
+ m_xEBasicStgCB->set_active( rOpt.IsLoadExcelBasicStorage() );
+ m_xEBasicStgCB->save_state();
+ LoadExcelBasicCheckHdl_Impl( *m_xEBasicCodeCB );
+
+ m_xPBasicCodeCB->set_active( rOpt.IsLoadPPointBasicCode() );
+ m_xPBasicCodeCB->save_state();
+ m_xPBasicStgCB->set_active( rOpt.IsLoadPPointBasicStorage() );
+ m_xPBasicStgCB->save_state();
+}
+
+OfaMSFilterTabPage2::OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrembedpage.ui", "OptFilterPage", &rSet)
+ , sChgToFromMath(CuiResId(RID_SVXSTR_CHG_MATH))
+ , sChgToFromWriter(CuiResId(RID_SVXSTR_CHG_WRITER))
+ , sChgToFromCalc(CuiResId(RID_SVXSTR_CHG_CALC))
+ , sChgToFromImpress(CuiResId(RID_SVXSTR_CHG_IMPRESS))
+ , sChgToFromSmartArt(CuiResId(RID_SVXSTR_CHG_SMARTART))
+ , sChgToFromVisio(CuiResId(RID_SVXSTR_CHG_VISIO))
+ , sChgToFromPDF(CuiResId(RID_SVXSTR_CHG_PDF))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklbcontainer"))
+ , m_xHighlightingRB(m_xBuilder->weld_radio_button("highlighting"))
+ , m_xShadingRB(m_xBuilder->weld_radio_button("shading"))
+ , m_xMSOLockFileCB(m_xBuilder->weld_check_button("mso_lockfile"))
+{
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xCheckLB->get_checkbox_column_width());
+ aWidths.push_back(m_xCheckLB->get_checkbox_column_width());
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+OfaMSFilterTabPage2::~OfaMSFilterTabPage2()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage2::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage2>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMSFilterTabPage2::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions:: *FnIs)() const;
+ void (SvtFilterOptions:: *FnSet)( bool bFlag );
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math,
+ &SvtFilterOptions::SetMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType,
+ &SvtFilterOptions::SetMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer,
+ &SvtFilterOptions::SetWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord,
+ &SvtFilterOptions::SetWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc,
+ &SvtFilterOptions::SetExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel,
+ &SvtFilterOptions::SetCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress,
+ &SvtFilterOptions::SetPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint,
+ &SvtFilterOptions::SetImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape,
+ &SvtFilterOptions::SetSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw,
+ &SvtFilterOptions::SetVisio2Draw },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rEntry : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type(rEntry.eType);
+ if (nEntry != -1)
+ {
+ bool bCheck = m_xCheckLB->get_toggle(nEntry, nCol);
+ if( bCheck != (rOpt.*rEntry.FnIs)() )
+ (rOpt.*rEntry.FnSet)( bCheck );
+ }
+ if (rEntry.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ int nPDFEntry = GetEntry4Type(MSFltrPg2_CheckBoxEntries::PDF);
+ bool bPDFCheck = m_xCheckLB->get_toggle(nPDFEntry, 0);
+ if (bPDFCheck != officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get())
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::set(bPDFCheck, pBatch);
+ pBatch->commit();
+ }
+
+ if( m_xHighlightingRB->get_state_changed_from_saved() )
+ {
+ if (m_xHighlightingRB->get_active())
+ rOpt.SetCharBackground2Highlighting();
+ else
+ rOpt.SetCharBackground2Shading();
+ }
+
+ if (m_xMSOLockFileCB->get_state_changed_from_saved())
+ {
+ rOpt.EnableMSOLockFileCreation(m_xMSOLockFileCB->get_active());
+ }
+
+ return true;
+}
+
+void OfaMSFilterTabPage2::Reset( const SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ SvtModuleOptions aModuleOpt;
+
+ // int the same sequence as the enums of MSFltrPg2_CheckBoxEntries
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ InsertEntry( sChgToFromMath, MSFltrPg2_CheckBoxEntries::Math );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ InsertEntry( sChgToFromWriter, MSFltrPg2_CheckBoxEntries::Writer );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ InsertEntry( sChgToFromCalc, MSFltrPg2_CheckBoxEntries::Calc );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ InsertEntry( sChgToFromImpress, MSFltrPg2_CheckBoxEntries::Impress );
+ InsertEntry( sChgToFromSmartArt, MSFltrPg2_CheckBoxEntries::SmartArt, false );
+ if (aModuleOpt.IsModuleInstalled(SvtModuleOptions::EModule::DRAW))
+ {
+ InsertEntry(sChgToFromVisio, MSFltrPg2_CheckBoxEntries::Visio, false);
+ InsertEntry(sChgToFromPDF, MSFltrPg2_CheckBoxEntries::PDF, false);
+ }
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions:: *FnIs)() const;
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw },
+ { MSFltrPg2_CheckBoxEntries::PDF, nullptr },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rArr : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type( rArr.eType );
+ if (nEntry != -1)
+ {
+ bool bCheck = false;
+ if (rArr.eType != MSFltrPg2_CheckBoxEntries::PDF)
+ {
+ bCheck = (rOpt.*rArr.FnIs)();
+ }
+ else
+ {
+ bCheck = officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get();
+ nCol = 0;
+ }
+ m_xCheckLB->set_toggle(nEntry, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+ }
+ if (rArr.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ m_xCheckLB->thaw();
+
+ if (rOpt.IsCharBackground2Highlighting())
+ m_xHighlightingRB->set_active(true);
+ else
+ m_xShadingRB->set_active(true);
+
+ m_xHighlightingRB->save_state();
+
+ m_xMSOLockFileCB->set_active(rOpt.IsMSOLockFileCreationIsEnabled());
+ m_xMSOLockFileCB->save_state();
+ m_xMSOLockFileCB->set_sensitive(!officecfg::Office::Common::Filter::Microsoft::Import::CreateMSOLockFiles::isReadOnly());
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType )
+{
+ InsertEntry( _rTxt, _nType, true );
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled )
+{
+ int nPos = m_xCheckLB->n_children();
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 0);
+ if (saveEnabled)
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(nPos, _rTxt, 2);
+ m_xCheckLB->set_id(nPos, OUString::number(static_cast<sal_Int32>(_nType)));
+}
+
+int OfaMSFilterTabPage2::GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const
+{
+ for (int i = 0, nEntryCount = m_xCheckLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (_nType == static_cast<MSFltrPg2_CheckBoxEntries>(m_xCheckLB->get_id(i).toInt32()))
+ return i;
+ }
+ return -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.hxx b/cui/source/options/optfltr.hxx
new file mode 100644
index 000000000..efc956843
--- /dev/null
+++ b/cui/source/options/optfltr.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_CUI_SOURCE_OPTIONS_OPTFLTR_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTFLTR_HXX
+
+#include <sfx2/tabdlg.hxx>
+
+class OfaMSFilterTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xWBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicWbctblCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicExectblCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicStgCB;
+
+ DECL_LINK(LoadWordBasicCheckHdl_Impl, weld::Button&, void);
+ DECL_LINK(LoadExcelBasicCheckHdl_Impl, weld::Button&, void);
+public:
+ OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~OfaMSFilterTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+enum class MSFltrPg2_CheckBoxEntries;
+
+class OfaMSFilterTabPage2 : public SfxTabPage
+{
+ OUString sChgToFromMath,
+ sChgToFromWriter,
+ sChgToFromCalc,
+ sChgToFromImpress,
+ sChgToFromSmartArt,
+ sChgToFromVisio,
+ sChgToFromPDF;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::RadioButton> m_xHighlightingRB;
+ std::unique_ptr<weld::RadioButton> m_xShadingRB;
+ std::unique_ptr<weld::CheckButton> m_xMSOLockFileCB;
+
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType );
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled );
+ int GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const;
+
+public:
+ OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~OfaMSFilterTabPage2() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
new file mode 100644
index 000000000..1972354cc
--- /dev/null
+++ b/cui/source/options/optgdlg.cxx
@@ -0,0 +1,1897 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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_vclplug.h>
+#include <svl/zforlist.hxx>
+#include <svl/currencytable.hxx>
+#include <svtools/langhelp.hxx>
+#include <unotools/lingucfg.hxx>
+#if defined(_WIN32)
+#include <unotools/resmgr.hxx>
+#endif
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <unotools/compatibility.hxx>
+#include <unotools/fontoptions.hxx>
+#include <svtools/menuoptions.hxx>
+#include <svl/languageoptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <unotools/printwarningoptions.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <svtools/langtab.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/langitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <editeng/editids.hrc>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <svtools/helpopt.hxx>
+#include <unotools/searchopt.hxx>
+#include <sal/log.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Setup.hxx>
+#include <comphelper/configuration.hxx>
+#include <tools/diagnose_ex.h>
+#if HAVE_FEATURE_BREAKPAD
+#include <desktop/crashreport.hxx>
+#endif
+
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/office/Quickstart.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+
+#include <vcl/vclenum.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/window.hxx>
+#include <vcl/IconThemeInfo.hxx>
+#if HAVE_FEATURE_OPENGL
+#include <vcl/opengl/OpenGLWrapper.hxx>
+#endif
+#include <vcl/skia/SkiaHelper.hxx>
+#include "optgdlg.hxx"
+#include <svtools/apearcfg.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svtools/restartdialog.hxx>
+#include <svtools/imgdef.hxx>
+
+#if defined(_WIN32)
+#include <o3tl/char16_t2wchar_t.hxx>
+#include <prewin.h>
+#include <shobjidl.h>
+#include <postwin.h>
+#endif
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::utl;
+
+namespace svt {
+
+class SkiaCfg
+{
+private:
+ bool mbUseSkia;
+ bool mbForceSkiaRaster;
+ bool mbModified;
+
+public:
+ SkiaCfg();
+ ~SkiaCfg();
+
+ bool useSkia() const;
+ bool forceSkiaRaster() const;
+
+ void setUseSkia(bool bSkia);
+ void setForceSkiaRaster(bool bSkia);
+
+ void reset();
+};
+
+SkiaCfg::SkiaCfg():
+ mbModified(false)
+{
+ reset();
+}
+
+void SkiaCfg::reset()
+{
+ mbUseSkia = officecfg::Office::Common::VCL::UseSkia::get();
+ mbForceSkiaRaster = officecfg::Office::Common::VCL::ForceSkiaRaster::get();
+ mbModified = false;
+}
+
+SkiaCfg::~SkiaCfg()
+{
+ if (!mbModified)
+ return;
+
+ try
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+ if (!officecfg::Office::Common::VCL::UseSkia::isReadOnly())
+ officecfg::Office::Common::VCL::UseSkia::set(mbUseSkia, batch);
+ if (!officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly())
+ officecfg::Office::Common::VCL::ForceSkiaRaster::set(mbForceSkiaRaster, batch);
+ batch->commit();
+ }
+ catch (...)
+ {
+ }
+}
+
+bool SkiaCfg::useSkia() const
+{
+ return mbUseSkia;
+}
+
+bool SkiaCfg::forceSkiaRaster() const
+{
+ return mbForceSkiaRaster;
+}
+
+void SkiaCfg::setUseSkia(bool bSkia)
+{
+ if (bSkia != mbUseSkia)
+ {
+ mbUseSkia = bSkia;
+ mbModified = true;
+ }
+}
+
+void SkiaCfg::setForceSkiaRaster(bool bSkia)
+{
+ if (mbForceSkiaRaster != bSkia)
+ {
+ mbForceSkiaRaster = bSkia;
+ mbModified = true;
+ }
+}
+
+}
+
+// class OfaMiscTabPage --------------------------------------------------
+
+DeactivateRC OfaMiscTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+OUString impl_SystemFileOpenServiceName()
+{
+ #if defined(_WIN32)
+ return "com.sun.star.ui.dialogs.SystemFilePicker";
+ #elif defined MACOSX
+ return "com.sun.star.ui.dialogs.AquaFilePicker";
+ #else
+ return OUString();
+ #endif
+}
+
+bool lcl_HasSystemFilePicker()
+{
+ if( Application::hasNativeFileSelection() )
+ return true;
+
+ // Otherwise fall-back on querying services
+ bool bRet = false;
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ Reference< XContentEnumerationAccess > xEnumAccess( xFactory, UNO_QUERY );
+ Reference< XSet > xSet( xFactory, UNO_QUERY );
+
+ if ( ! xEnumAccess.is() || ! xSet.is() )
+ return bRet;
+
+ try
+ {
+ OUString aFileService = impl_SystemFileOpenServiceName();
+ Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration( aFileService );
+ if ( xEnum.is() && xEnum->hasMoreElements() )
+ bRet = true;
+ }
+ catch (const IllegalArgumentException&)
+ {
+ }
+ catch (const ElementExistException&)
+ {
+ }
+ return bRet;
+}
+}
+
+OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optgeneralpage.ui", "OptGeneralPage", &rSet)
+ , m_xExtHelpCB(m_xBuilder->weld_check_button("exthelp"))
+ , m_xPopUpNoHelpCB(m_xBuilder->weld_check_button("popupnohelp"))
+ , m_xShowTipOfTheDay(m_xBuilder->weld_check_button("cbShowTipOfTheDay"))
+ , m_xFileDlgFrame(m_xBuilder->weld_widget("filedlgframe"))
+ , m_xPrintDlgFrame(m_xBuilder->weld_widget("printdlgframe"))
+ , m_xFileDlgROImage(m_xBuilder->weld_widget("lockimage"))
+ , m_xFileDlgCB(m_xBuilder->weld_check_button("filedlg"))
+ , m_xPrintDlgCB(m_xBuilder->weld_check_button("printdlg"))
+ , m_xDocStatusCB(m_xBuilder->weld_check_button("docstatus"))
+ , m_xYearFrame(m_xBuilder->weld_widget("yearframe"))
+ , m_xYearValueField(m_xBuilder->weld_spin_button("year"))
+ , m_xToYearFT(m_xBuilder->weld_label("toyear"))
+ , m_xCollectUsageInfo(m_xBuilder->weld_check_button("collectusageinfo"))
+ , m_xCrashReport(m_xBuilder->weld_check_button("crashreport"))
+ , m_xQuickStarterFrame(m_xBuilder->weld_widget("quickstarter"))
+#if defined(UNX)
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("systray"))
+#else
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("quicklaunch"))
+#endif
+#if defined(_WIN32)
+ , m_xFileAssocFrame(m_xBuilder->weld_widget("fileassoc"))
+ , m_xFileAssocBtn(m_xBuilder->weld_button("assocfiles"))
+#endif
+{
+ if (!lcl_HasSystemFilePicker())
+ m_xFileDlgFrame->hide();
+ else if (SvtMiscOptions().IsUseSystemFileDialogReadOnly())
+ {
+ m_xFileDlgROImage->show();
+ m_xFileDlgCB->set_sensitive(false);
+ }
+
+#if !ENABLE_GTK3
+ m_xPrintDlgFrame->hide();
+#else
+ if (!SvtMiscOptions().IsExperimentalMode())
+ {
+ m_xPrintDlgFrame->hide();
+ }
+#endif
+
+ m_xQuickLaunchCB->show();
+
+ //Only available in Win or if building the gtk systray
+#if !defined(_WIN32)
+ m_xQuickStarterFrame->hide();
+#endif
+
+#if defined(_WIN32)
+ m_xFileAssocFrame->show();
+ m_xFileAssocBtn->connect_clicked(LINK(this, OfaMiscTabPage, FileAssocClick));
+#endif
+
+ m_aStrDateInfo = m_xToYearFT->get_label();
+ m_xYearValueField->connect_value_changed( LINK( this, OfaMiscTabPage, TwoFigureHdl ) );
+
+ SetExchangeSupport();
+}
+
+OfaMiscTabPage::~OfaMiscTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMiscTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMiscTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ SvtHelpOptions aHelpOptions;
+ if ( m_xPopUpNoHelpCB->get_state_changed_from_saved() )
+ aHelpOptions.SetOfflineHelpPopUp( m_xPopUpNoHelpCB->get_active() );
+
+ if ( m_xExtHelpCB->get_state_changed_from_saved() )
+ aHelpOptions.SetExtendedHelp( m_xExtHelpCB->get_active() );
+
+ if ( m_xShowTipOfTheDay->get_state_changed_from_saved() )
+ {
+ officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_xShowTipOfTheDay->get_active(), batch);
+ bModified = true;
+ }
+
+ if ( m_xFileDlgCB->get_state_changed_from_saved() )
+ {
+ SvtMiscOptions aMiscOpt;
+ aMiscOpt.SetUseSystemFileDialog( !m_xFileDlgCB->get_active() );
+ bModified = true;
+ }
+
+ if ( m_xPrintDlgCB->get_state_changed_from_saved() )
+ {
+ SvtMiscOptions aMiscOpt;
+ aMiscOpt.SetUseSystemPrintDialog( !m_xPrintDlgCB->get_active() );
+ bModified = true;
+ }
+
+ if ( m_xDocStatusCB->get_state_changed_from_saved() )
+ {
+ SvtPrintWarningOptions aPrintOptions;
+ aPrintOptions.SetModifyDocumentOnPrintingAllowed( m_xDocStatusCB->get_active() );
+ bModified = true;
+ }
+
+ const SfxUInt16Item* pUInt16Item = dynamic_cast< const SfxUInt16Item* >( GetOldItem( *rSet, SID_ATTR_YEAR2000 ) );
+ sal_uInt16 nNum = static_cast<sal_uInt16>(m_xYearValueField->get_text().toInt32());
+ if ( pUInt16Item && pUInt16Item->GetValue() != nNum )
+ {
+ bModified = true;
+ rSet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, nNum ) );
+ }
+
+ if (m_xCollectUsageInfo->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::CollectUsageInformation::set(m_xCollectUsageInfo->get_active(), batch);
+ bModified = true;
+ }
+
+#if HAVE_FEATURE_BREAKPAD
+ if (m_xCrashReport->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::CrashReport::set(m_xCrashReport->get_active(), batch);
+ bModified = true;
+ }
+#endif
+
+ batch->commit();
+
+ if( m_xQuickLaunchCB->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(SID_ATTR_QUICKLAUNCHER, m_xQuickLaunchCB->get_active()));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void OfaMiscTabPage::Reset( const SfxItemSet* rSet )
+{
+ SvtHelpOptions aHelpOptions;
+ m_xExtHelpCB->set_active( aHelpOptions.IsHelpTips() && aHelpOptions.IsExtendedHelp() );
+ m_xExtHelpCB->save_state();
+ m_xPopUpNoHelpCB->set_active( aHelpOptions.IsOfflineHelpPopUp() );
+ m_xPopUpNoHelpCB->save_state();
+ m_xShowTipOfTheDay->set_active( officecfg::Office::Common::Misc::ShowTipOfTheDay::get() );
+ m_xShowTipOfTheDay->save_state();
+ SvtMiscOptions aMiscOpt;
+ m_xFileDlgCB->set_active( !aMiscOpt.UseSystemFileDialog() );
+ m_xFileDlgCB->save_state();
+ m_xPrintDlgCB->set_active( !aMiscOpt.UseSystemPrintDialog() );
+ m_xPrintDlgCB->save_state();
+
+ SvtPrintWarningOptions aPrintOptions;
+ m_xDocStatusCB->set_active(aPrintOptions.IsModifyDocumentOnPrintingAllowed());
+ m_xDocStatusCB->save_state();
+
+ const SfxPoolItem* pItem = nullptr;
+ if ( SfxItemState::SET == rSet->GetItemState( SID_ATTR_YEAR2000, false, &pItem ) )
+ {
+ m_xYearValueField->set_value( static_cast<const SfxUInt16Item*>(pItem)->GetValue() );
+ TwoFigureHdl(*m_xYearValueField);
+ }
+ else
+ m_xYearFrame->set_sensitive(false);
+
+ m_xCollectUsageInfo->set_active(officecfg::Office::Common::Misc::CollectUsageInformation::get());
+ m_xCollectUsageInfo->set_sensitive(!officecfg::Office::Common::Misc::CollectUsageInformation::isReadOnly());
+ m_xCollectUsageInfo->save_state();
+
+#if HAVE_FEATURE_BREAKPAD
+ m_xCrashReport->set_active(officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->set_sensitive(!officecfg::Office::Common::Misc::CrashReport::isReadOnly() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->save_state();
+#else
+ m_xCrashReport->hide();
+#endif
+
+ SfxItemState eState = rSet->GetItemState( SID_ATTR_QUICKLAUNCHER, false, &pItem );
+ if ( SfxItemState::SET == eState )
+ m_xQuickLaunchCB->set_active( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+ else if ( SfxItemState::DISABLED == eState )
+ {
+ // quickstart not installed
+ m_xQuickStarterFrame->hide();
+ }
+
+ m_xQuickLaunchCB->save_state();
+}
+
+IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void )
+{
+ OUString aOutput( m_aStrDateInfo );
+ OUString aStr( m_xYearValueField->get_text() );
+ sal_Int32 nNum = aStr.toInt32();
+ if ( aStr.getLength() != 4 || nNum < m_xYearValueField->get_min() || nNum > m_xYearValueField->get_max() )
+ aOutput += "????";
+ else
+ {
+ nNum += 99;
+ aOutput += OUString::number( nNum );
+ }
+ m_xToYearFT->set_label( aOutput );
+}
+
+#if defined(_WIN32)
+IMPL_STATIC_LINK_NOARG(OfaMiscTabPage, FileAssocClick, weld::Button&, void)
+{
+ const bool bUninit = SUCCEEDED(CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED));
+ IApplicationAssociationRegistrationUI* pIf = nullptr;
+ HRESULT res = CoCreateInstance(CLSID_ApplicationAssociationRegistrationUI, nullptr,
+ CLSCTX_INPROC_SERVER, IID_IApplicationAssociationRegistrationUI,
+ reinterpret_cast<LPVOID*>(&pIf));
+
+ if (SUCCEEDED(res) && pIf)
+ {
+ // LaunchAdvancedAssociationUI only works for applications registered under
+ // Software\RegisteredApplications. See scp2/source/ooo/registryitem_ooo.scp
+ const OUString expanded = Translate::ExpandVariables("%PRODUCTNAME %PRODUCTVERSION");
+ // This will only show "To change your default apps, go to Settings > Apps > Default apps"
+ // on Win10; this is expected. At least this will self-document it to users.
+ pIf->LaunchAdvancedAssociationUI(o3tl::toW(expanded.getStr()));
+ pIf->Release();
+ }
+ if (bUninit)
+ CoUninitialize();
+}
+#endif
+
+class CanvasSettings
+{
+public:
+ CanvasSettings();
+
+ bool IsHardwareAccelerationEnabled() const;
+ bool IsHardwareAccelerationAvailable() const;
+ bool IsHardwareAccelerationRO() const;
+ void EnabledHardwareAcceleration( bool _bEnabled ) const;
+
+private:
+ typedef std::vector< std::pair<OUString,Sequence<OUString> > > ServiceVector;
+
+ Reference<XNameAccess> mxForceFlagNameAccess;
+ ServiceVector maAvailableImplementations;
+ mutable bool mbHWAccelAvailable;
+ mutable bool mbHWAccelChecked;
+};
+
+CanvasSettings::CanvasSettings() :
+ mxForceFlagNameAccess(),
+ mbHWAccelAvailable(false),
+ mbHWAccelChecked(false)
+{
+ try
+ {
+ Reference<XMultiServiceFactory> xConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+
+ Sequence<Any> aArgs1(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas"))}
+ }));
+ mxForceFlagNameAccess.set(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgs1 ),
+ UNO_QUERY_THROW );
+
+ Sequence<Any> aArgs2(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas/CanvasServiceList"))}
+ }));
+ Reference<XNameAccess> xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess",
+ aArgs2 ), UNO_QUERY_THROW );
+ Reference<XHierarchicalNameAccess> xHierarchicalNameAccess(
+ xNameAccess, UNO_QUERY_THROW);
+
+ Sequence<OUString> serviceNames = xNameAccess->getElementNames();
+ const OUString* pCurr = serviceNames.getConstArray();
+ const OUString* const pEnd = pCurr + serviceNames.getLength();
+ while( pCurr != pEnd )
+ {
+ Reference<XNameAccess> xEntryNameAccess(
+ xHierarchicalNameAccess->getByHierarchicalName(*pCurr),
+ UNO_QUERY );
+
+ if( xEntryNameAccess.is() )
+ {
+ Sequence<OUString> preferredImplementations;
+ if( xEntryNameAccess->getByName("PreferredImplementations") >>= preferredImplementations )
+ maAvailableImplementations.emplace_back(*pCurr,preferredImplementations );
+ }
+
+ ++pCurr;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+bool CanvasSettings::IsHardwareAccelerationAvailable() const
+{
+ if (SkiaHelper::isVCLSkiaEnabled() && Application::GetToolkitName() != "gtk3")
+ {
+ mbHWAccelAvailable = false;
+ return false;
+ }
+#if HAVE_FEATURE_OPENGL
+ if (OpenGLWrapper::isVCLOpenGLEnabled() && Application::GetToolkitName() != "gtk3")
+ {
+ mbHWAccelAvailable = false;
+ return false;
+ }
+#endif
+ if( !mbHWAccelChecked )
+ {
+ mbHWAccelChecked = true;
+
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ // check whether any of the service lists has an
+ // implementation that presents the "HardwareAcceleration" property
+ for (auto const& availableImpl : maAvailableImplementations)
+ {
+ const OUString* pCurrImpl = availableImpl.second.getConstArray();
+ const OUString* const pEndImpl = pCurrImpl + availableImpl.second.getLength();
+
+ while( pCurrImpl != pEndImpl )
+ {
+ try
+ {
+ Reference<XPropertySet> xPropSet( xFactory->createInstance(
+ pCurrImpl->trim() ),
+ UNO_QUERY_THROW );
+ bool bHasAccel(false);
+ if( xPropSet->getPropertyValue("HardwareAcceleration") >>= bHasAccel )
+ if( bHasAccel )
+ {
+ mbHWAccelAvailable = true;
+ return mbHWAccelAvailable;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+
+ ++pCurrImpl;
+ }
+ }
+ }
+
+ return mbHWAccelAvailable;
+}
+
+bool CanvasSettings::IsHardwareAccelerationEnabled() const
+{
+ bool bForceLastEntry(false);
+ if( !mxForceFlagNameAccess.is() )
+ return true;
+
+ if( !(mxForceFlagNameAccess->getByName("ForceSafeServiceImpl") >>= bForceLastEntry) )
+ return true;
+
+ return !bForceLastEntry;
+}
+
+bool CanvasSettings::IsHardwareAccelerationRO() const
+{
+ Reference< XPropertySet > xSet(mxForceFlagNameAccess, UNO_QUERY);
+ if (!xSet.is())
+ return true;
+
+ Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName("ForceSafeServiceImpl");
+ return ((aProp.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY);
+}
+
+void CanvasSettings::EnabledHardwareAcceleration( bool _bEnabled ) const
+{
+ Reference< XNameReplace > xNameReplace(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xNameReplace.is() )
+ return;
+
+ xNameReplace->replaceByName( "ForceSafeServiceImpl", Any(!_bEnabled) );
+
+ Reference< XChangesBatch > xChangesBatch(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xChangesBatch.is() )
+ return;
+
+ xChangesBatch->commitChanges();
+}
+
+// class OfaViewTabPage --------------------------------------------------
+
+static bool DisplayNameCompareLessThan(const vcl::IconThemeInfo& rInfo1, const vcl::IconThemeInfo& rInfo2)
+{
+ return rInfo1.GetDisplayName().compareTo(rInfo2.GetDisplayName()) < 0;
+}
+
+OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optviewpage.ui", "OptViewPage", &rSet)
+ , nSizeLB_InitialSelection(0)
+ , nSidebarSizeLB_InitialSelection(0)
+ , nNotebookbarSizeLB_InitialSelection(0)
+ , nStyleLB_InitialSelection(0)
+ , pAppearanceCfg(new SvtTabAppearanceCfg)
+ , pCanvasSettings(new CanvasSettings)
+ , mpDrawinglayerOpt(new SvtOptionsDrawinglayer)
+ , mpSkiaConfig(new svt::SkiaCfg)
+ , m_xIconSizeLB(m_xBuilder->weld_combo_box("iconsize"))
+ , m_xSidebarIconSizeLB(m_xBuilder->weld_combo_box("sidebariconsize"))
+ , m_xNotebookbarIconSizeLB(m_xBuilder->weld_combo_box("notebookbariconsize"))
+ , m_xIconStyleLB(m_xBuilder->weld_combo_box("iconstyle"))
+ , m_xFontAntiAliasing(m_xBuilder->weld_check_button("aafont"))
+ , m_xAAPointLimitLabel(m_xBuilder->weld_label("aafrom"))
+ , m_xAAPointLimit(m_xBuilder->weld_metric_spin_button("aanf", FieldUnit::PIXEL))
+ , m_xMenuIconBox(m_xBuilder->weld_widget("menuiconsbox"))
+ , m_xMenuIconsLB(m_xBuilder->weld_combo_box("menuicons"))
+ , m_xContextMenuShortcutsLB(m_xBuilder->weld_combo_box("contextmenushortcuts"))
+ , m_xFontShowCB(m_xBuilder->weld_check_button("showfontpreview"))
+ , m_xUseHardwareAccell(m_xBuilder->weld_check_button("useaccel"))
+ , m_xUseAntiAliase(m_xBuilder->weld_check_button("useaa"))
+ , m_xUseSkia(m_xBuilder->weld_check_button("useskia"))
+ , m_xForceSkiaRaster(m_xBuilder->weld_check_button("forceskiaraster"))
+ , m_xSkiaStatusEnabled(m_xBuilder->weld_label("skiaenabled"))
+ , m_xSkiaStatusDisabled(m_xBuilder->weld_label("skiadisabled"))
+ , m_xMousePosLB(m_xBuilder->weld_combo_box("mousepos"))
+ , m_xMouseMiddleLB(m_xBuilder->weld_combo_box("mousemiddle"))
+{
+ if (Application::GetToolkitName() == "gtk3")
+ {
+ m_xUseSkia->hide();
+ m_xForceSkiaRaster->hide();
+ m_xSkiaStatusEnabled->hide();
+ m_xSkiaStatusDisabled->hide();
+ m_xMenuIconBox->hide();
+ }
+
+#if !HAVE_FEATURE_SKIA || !defined(_WIN32)
+ // Duplicated also in UpdateSkiaStatus().
+ // For now Skia is used mainly on Windows, hide the controls everywhere else.
+ // It can also be used on Linux, but only with the rarely used 'gen' backend.
+ m_xUseSkia->hide();
+ m_xForceSkiaRaster->hide();
+ m_xSkiaStatusEnabled->hide();
+ m_xSkiaStatusDisabled->hide();
+#endif
+
+ m_xFontAntiAliasing->connect_toggled( LINK( this, OfaViewTabPage, OnAntialiasingToggled ) );
+
+ m_xForceSkiaRaster->connect_toggled(LINK(this, OfaViewTabPage, OnForceSkiaRasterToggled));
+
+ // Set known icon themes
+ OUString sAutoStr( m_xIconStyleLB->get_text( 0 ) );
+ m_xIconStyleLB->clear();
+ StyleSettings aStyleSettings = Application::GetSettings().GetStyleSettings();
+ mInstalledIconThemes = aStyleSettings.GetInstalledIconThemes();
+ std::sort(mInstalledIconThemes.begin(), mInstalledIconThemes.end(), DisplayNameCompareLessThan);
+
+ // Start with the automatically chosen icon theme
+ OUString autoThemeId = aStyleSettings.GetAutomaticallyChosenIconTheme();
+ const vcl::IconThemeInfo& autoIconTheme = vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, autoThemeId);
+
+ OUString entryForAuto = sAutoStr + " (" +
+ autoIconTheme.GetDisplayName() +
+ ")";
+ m_xIconStyleLB->append("auto", entryForAuto); // index 0 means choose style automatically
+
+ // separate auto and other icon themes
+ m_xIconStyleLB->append_separator("");
+
+ for (auto const& installIconTheme : mInstalledIconThemes)
+ m_xIconStyleLB->append(installIconTheme.GetThemeId(), installIconTheme.GetDisplayName());
+
+ m_xIconStyleLB->set_active(0);
+
+ // FIXME: should really add code to show a 'lock' icon here.
+ if (officecfg::Office::Common::VCL::UseSkia::isReadOnly())
+ m_xUseSkia->set_sensitive(false);
+ if (officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly())
+ m_xForceSkiaRaster->set_sensitive(false);
+
+ UpdateSkiaStatus();
+}
+
+OfaViewTabPage::~OfaViewTabPage()
+{
+}
+
+IMPL_LINK_NOARG( OfaViewTabPage, OnAntialiasingToggled, weld::ToggleButton&, void )
+{
+ bool bAAEnabled = m_xFontAntiAliasing->get_active();
+
+ m_xAAPointLimitLabel->set_sensitive(bAAEnabled);
+ m_xAAPointLimit->set_sensitive(bAAEnabled);
+}
+
+IMPL_LINK_NOARG(OfaViewTabPage, OnForceSkiaRasterToggled, weld::ToggleButton&, void)
+{
+ if (m_xForceSkiaRaster->get_active())
+ {
+ // Forcing Skia raster implies that Skia is on.
+ m_xUseSkia->set_active(true);
+ }
+}
+
+std::unique_ptr<SfxTabPage> OfaViewTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaViewTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaViewTabPage::FillItemSet( SfxItemSet* )
+{
+ SvtFontOptions aFontOpt;
+ SvtMenuOptions aMenuOpt;
+
+ bool bModified = false;
+ bool bMenuOptModified = false;
+ bool bRepaintWindows(false);
+
+ SvtMiscOptions aMiscOptions;
+ const sal_Int32 nSizeLB_NewSelection = m_xIconSizeLB->get_active();
+ if( nSizeLB_InitialSelection != nSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ sal_Int16 eSet = SFX_SYMBOLS_SIZE_AUTO;
+ switch( nSizeLB_NewSelection )
+ {
+ case 0: eSet = SFX_SYMBOLS_SIZE_AUTO; break;
+ case 1: eSet = SFX_SYMBOLS_SIZE_SMALL; break;
+ case 2: eSet = SFX_SYMBOLS_SIZE_LARGE; break;
+ case 3: eSet = SFX_SYMBOLS_SIZE_32; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xIconSizeLB should not be possible!" );
+ }
+ aMiscOptions.SetSymbolsSize( eSet );
+ }
+
+ const sal_Int32 nSidebarSizeLB_NewSelection = m_xSidebarIconSizeLB->get_active();
+ if( nSidebarSizeLB_InitialSelection != nSidebarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nSidebarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xSidebarIconSizeLB should not be possible!" );
+ }
+ aMiscOptions.SetSidebarIconSize( eSet );
+ }
+
+ const sal_Int32 nNotebookbarSizeLB_NewSelection = m_xNotebookbarIconSizeLB->get_active();
+ if( nNotebookbarSizeLB_InitialSelection != nNotebookbarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nNotebookbarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xNotebookbarIconSizeLB should not be possible!" );
+ }
+ aMiscOptions.SetNotebookbarIconSize( eSet );
+ }
+
+ const sal_Int32 nStyleLB_NewSelection = m_xIconStyleLB->get_active();
+ if( nStyleLB_InitialSelection != nStyleLB_NewSelection )
+ {
+ aMiscOptions.SetIconTheme(m_xIconStyleLB->get_active_id());
+ nStyleLB_InitialSelection = nStyleLB_NewSelection;
+ }
+
+ bool bAppearanceChanged = false;
+
+ // Mouse Snap Mode
+ SnapType eOldSnap = pAppearanceCfg->GetSnapMode();
+ SnapType eNewSnap = static_cast<SnapType>(m_xMousePosLB->get_active());
+ if(eNewSnap > SnapType::NONE)
+ eNewSnap = SnapType::NONE;
+
+ if ( eNewSnap != eOldSnap )
+ {
+ pAppearanceCfg->SetSnapMode(eNewSnap );
+ bAppearanceChanged = true;
+ }
+
+ // Middle Mouse Button
+ MouseMiddleButtonAction eOldMiddleMouse = pAppearanceCfg->GetMiddleMouseButton();
+ short eNewMiddleMouse = m_xMouseMiddleLB->get_active();
+ if(eNewMiddleMouse > 2)
+ eNewMiddleMouse = 2;
+
+ if ( eNewMiddleMouse != static_cast<short>(eOldMiddleMouse) )
+ {
+ pAppearanceCfg->SetMiddleMouseButton( static_cast<MouseMiddleButtonAction>(eNewMiddleMouse) );
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontAntiAliasing->get_state_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntiAliasing(m_xFontAntiAliasing->get_active());
+ bAppearanceChanged = true;
+ }
+
+ if (m_xAAPointLimit->get_value_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntialiasingMinPixelHeight(m_xAAPointLimit->get_value(FieldUnit::PIXEL));
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontShowCB->get_state_changed_from_saved())
+ {
+ aFontOpt.EnableFontWYSIWYG(m_xFontShowCB->get_active());
+ bModified = true;
+ }
+
+ if (m_xMenuIconsLB->get_value_changed_from_saved())
+ {
+ aMenuOpt.SetMenuIconsState(m_xMenuIconsLB->get_active() == 0 ?
+ TRISTATE_INDET :
+ static_cast<TriState>(m_xMenuIconsLB->get_active() - 1));
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ if (m_xContextMenuShortcutsLB->get_value_changed_from_saved())
+ {
+ aMenuOpt.SetContextMenuShortcuts(m_xContextMenuShortcutsLB->get_active() == 0 ?
+ TRISTATE_INDET :
+ static_cast<TriState>(m_xContextMenuShortcutsLB->get_active() - 1));
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseHardwareAccell->get_sensitive())
+ {
+ if(m_xUseHardwareAccell->get_state_changed_from_saved())
+ {
+ pCanvasSettings->EnabledHardwareAcceleration(m_xUseHardwareAccell->get_active());
+ bModified = true;
+ }
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseAntiAliase->get_sensitive())
+ {
+ if (m_xUseAntiAliase->get_active() != mpDrawinglayerOpt->IsAntiAliasing())
+ {
+ mpDrawinglayerOpt->SetAntiAliasing(m_xUseAntiAliase->get_active());
+ bModified = true;
+ bRepaintWindows = true;
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ mpSkiaConfig->setUseSkia(m_xUseSkia->get_active());
+ mpSkiaConfig->setForceSkiaRaster(m_xForceSkiaRaster->get_active());
+ bModified = true;
+ }
+
+ if( bMenuOptModified )
+ {
+ // Set changed settings to the application instance
+ AllSettings aAllSettings = Application::GetSettings();
+ StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+ aAllSettings.SetStyleSettings(aStyleSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+ }
+
+ if ( bAppearanceChanged )
+ {
+ pAppearanceCfg->Commit();
+ pAppearanceCfg->SetApplicationDefaults ( GetpApp() );
+ }
+
+ if(bRepaintWindows)
+ {
+ vcl::Window* pAppWindow = Application::GetFirstTopLevelWindow();
+
+ while(pAppWindow)
+ {
+ pAppWindow->Invalidate();
+ pAppWindow = Application::GetNextTopLevelWindow(pAppWindow);
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ SolarMutexGuard aGuard;
+ if( svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_SKIA))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void OfaViewTabPage::Reset( const SfxItemSet* )
+{
+ SvtMiscOptions aMiscOptions;
+ mpSkiaConfig->reset();
+
+ if (aMiscOptions.GetSymbolsSize() != SFX_SYMBOLS_SIZE_AUTO)
+ {
+ nSizeLB_InitialSelection = 1;
+
+ if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
+ nSizeLB_InitialSelection = 2;
+ else if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_32)
+ nSizeLB_InitialSelection = 3;
+ }
+ m_xIconSizeLB->set_active( nSizeLB_InitialSelection );
+ m_xIconSizeLB->save_value();
+
+ if( aMiscOptions.GetSidebarIconSize() == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( aMiscOptions.GetSidebarIconSize() == ToolBoxButtonSize::Small )
+ nSidebarSizeLB_InitialSelection = 1;
+ else if( aMiscOptions.GetSidebarIconSize() == ToolBoxButtonSize::Large )
+ nSidebarSizeLB_InitialSelection = 2;
+ m_xSidebarIconSizeLB->set_active( nSidebarSizeLB_InitialSelection );
+ m_xSidebarIconSizeLB->save_value();
+ if( aMiscOptions.GetNotebookbarIconSize() == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( aMiscOptions.GetNotebookbarIconSize() == ToolBoxButtonSize::Small )
+ nNotebookbarSizeLB_InitialSelection = 1;
+ else if( aMiscOptions.GetNotebookbarIconSize() == ToolBoxButtonSize::Large )
+ nNotebookbarSizeLB_InitialSelection = 2;
+ m_xNotebookbarIconSizeLB->set_active(nNotebookbarSizeLB_InitialSelection);
+ m_xNotebookbarIconSizeLB->save_value();
+
+ if (aMiscOptions.IconThemeWasSetAutomatically()) {
+ nStyleLB_InitialSelection = 0;
+ }
+ else {
+ const OUString& selected = aMiscOptions.GetIconTheme();
+ const vcl::IconThemeInfo& selectedInfo =
+ vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, selected);
+ nStyleLB_InitialSelection = m_xIconStyleLB->find_text(selectedInfo.GetDisplayName());
+ }
+
+ m_xIconStyleLB->set_active(nStyleLB_InitialSelection);
+ m_xIconStyleLB->save_value();
+
+ // Mouse Snap
+ m_xMousePosLB->set_active(static_cast<sal_Int32>(pAppearanceCfg->GetSnapMode()));
+ m_xMousePosLB->save_value();
+
+ // Mouse Snap
+ m_xMouseMiddleLB->set_active(static_cast<short>(pAppearanceCfg->GetMiddleMouseButton()));
+ m_xMouseMiddleLB->save_value();
+
+ m_xFontAntiAliasing->set_active( pAppearanceCfg->IsFontAntiAliasing() );
+ m_xAAPointLimit->set_value(pAppearanceCfg->GetFontAntialiasingMinPixelHeight(), FieldUnit::PIXEL);
+
+ // WorkingSet
+ SvtFontOptions aFontOpt;
+ m_xFontShowCB->set_active( aFontOpt.IsFontWYSIWYGEnabled() );
+ SvtMenuOptions aMenuOpt;
+ m_xMenuIconsLB->set_active(aMenuOpt.GetMenuIconsState() == 2 ? 0 : aMenuOpt.GetMenuIconsState() + 1);
+ m_xMenuIconsLB->save_value();
+
+ TriState eContextMenuShortcuts = aMenuOpt.GetContextMenuShortcuts();
+ bool bContextMenuShortcutsNonDefault = eContextMenuShortcuts == TRISTATE_FALSE || eContextMenuShortcuts == TRISTATE_TRUE;
+ m_xContextMenuShortcutsLB->set_active(bContextMenuShortcutsNonDefault ? eContextMenuShortcuts + 1 : 0);
+ m_xContextMenuShortcutsLB->save_value();
+
+ { // #i95644# HW accel (unified to disable mechanism)
+ if(pCanvasSettings->IsHardwareAccelerationAvailable())
+ {
+ m_xUseHardwareAccell->set_active(pCanvasSettings->IsHardwareAccelerationEnabled());
+ m_xUseHardwareAccell->set_sensitive(!pCanvasSettings->IsHardwareAccelerationRO());
+ }
+ else
+ {
+ m_xUseHardwareAccell->set_active(false);
+ m_xUseHardwareAccell->set_sensitive(false);
+ }
+
+ m_xUseHardwareAccell->save_state();
+ }
+
+ { // #i95644# AntiAliasing
+ if(mpDrawinglayerOpt->IsAAPossibleOnThisSystem())
+ {
+ m_xUseAntiAliase->set_active(mpDrawinglayerOpt->IsAntiAliasing());
+ }
+ else
+ {
+ m_xUseAntiAliase->set_active(false);
+ m_xUseAntiAliase->set_sensitive(false);
+ }
+
+ m_xUseAntiAliase->save_state();
+ }
+ m_xUseSkia->set_active(mpSkiaConfig->useSkia());
+ m_xForceSkiaRaster->set_active(mpSkiaConfig->forceSkiaRaster());
+
+ m_xFontAntiAliasing->save_state();
+ m_xAAPointLimit->save_value();
+ m_xFontShowCB->save_state();
+
+ m_xUseSkia->save_state();
+ m_xForceSkiaRaster->save_state();
+
+ OnAntialiasingToggled(*m_xFontAntiAliasing);
+}
+
+void OfaViewTabPage::UpdateSkiaStatus()
+{
+ if (Application::GetToolkitName() == "gtk3")
+ return;
+#if HAVE_FEATURE_SKIA && defined(_WIN32)
+ // Easier than a custom translation string.
+ bool bEnabled = SkiaHelper::isVCLSkiaEnabled();
+ m_xSkiaStatusEnabled->set_visible(bEnabled);
+ m_xSkiaStatusDisabled->set_visible(!bEnabled);
+#endif
+}
+
+struct LanguageConfig_Impl
+{
+ SvtLanguageOptions aLanguageOptions;
+ SvtSysLocaleOptions aSysLocaleOptions;
+ SvtLinguConfig aLinguConfig;
+};
+
+static bool bLanguageCurrentDoc_Impl = false;
+
+// some things we'll need...
+static const char sAccessSrvc[] = "com.sun.star.configuration.ConfigurationAccess";
+static const char sAccessUpdSrvc[] = "com.sun.star.configuration.ConfigurationUpdateAccess";
+static const char sInstalledLocalesPath[] = "org.openoffice.Setup/Office/InstalledLocales";
+static const char sUserLocalePath[] = "org.openoffice.Office.Linguistic/General";
+static const char sUserLocaleKey[] = "UILocale";
+static Sequence< OUString > seqInstalledLanguages;
+
+static OUString lcl_getDatePatternsConfigString( const LocaleDataWrapper& rLocaleWrapper )
+{
+ Sequence< OUString > aDateAcceptancePatterns = rLocaleWrapper.getDateAcceptancePatterns();
+ sal_Int32 nPatterns = aDateAcceptancePatterns.getLength();
+ OUStringBuffer aBuf( nPatterns * 6 ); // 6 := length of Y-M-D;
+ SAL_WARN_IF( !nPatterns, "cui.options", "No date acceptance pattern");
+ if (nPatterns)
+ {
+ const OUString* pPatterns = aDateAcceptancePatterns.getConstArray();
+ aBuf.append( pPatterns[0]);
+ for (sal_Int32 i=1; i < nPatterns; ++i)
+ aBuf.append(';').append( pPatterns[i]);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+namespace
+{
+ //what ui language will be selected by default if the user override of General::UILocale is unset ?
+ LanguageTag GetInstalledLocaleForSystemUILanguage()
+ {
+ css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
+ return LanguageTag(getInstalledLocaleForSystemUILanguage(inst, false)).makeFallback();
+ }
+}
+
+OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlanguagespage.ui", "OptLanguagesPage", &rSet)
+ , pLangConfig(new LanguageConfig_Impl)
+ , m_bDatePatternsValid(false)
+ , m_xUserInterfaceLB(m_xBuilder->weld_combo_box("userinterface"))
+ , m_xLocaleSettingFT(m_xBuilder->weld_label("localesettingFT"))
+ , m_xLocaleSettingLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("localesetting")))
+ , m_xDecimalSeparatorCB(m_xBuilder->weld_check_button("decimalseparator"))
+ , m_xCurrencyFT(m_xBuilder->weld_label("defaultcurrency"))
+ , m_xCurrencyLB(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xDatePatternsFT(m_xBuilder->weld_label("dataaccpatterns"))
+ , m_xDatePatternsED(m_xBuilder->weld_entry("datepatterns"))
+ , m_xWesternLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("westernlanguage")))
+ , m_xWesternLanguageFT(m_xBuilder->weld_label("western"))
+ , m_xAsianLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("asianlanguage")))
+ , m_xComplexLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("complexlanguage")))
+ , m_xCurrentDocCB(m_xBuilder->weld_check_button("currentdoc"))
+ , m_xAsianSupportCB(m_xBuilder->weld_check_button("asiansupport"))
+ , m_xCTLSupportCB(m_xBuilder->weld_check_button("ctlsupport"))
+ , m_xIgnoreLanguageChangeCB(m_xBuilder->weld_check_button("ignorelanguagechange"))
+{
+ // tdf#125483 save original default label
+ m_sDecimalSeparatorLabel = m_xDecimalSeparatorCB->get_label();
+
+ // initialize user interface language selection
+ m_sSystemDefaultString = SvtLanguageTable::GetLanguageString( LANGUAGE_SYSTEM );
+
+ OUString aUILang = m_sSystemDefaultString +
+ " - " +
+ SvtLanguageTable::GetLanguageString(GetInstalledLocaleForSystemUILanguage().getLanguageType());
+
+ m_xUserInterfaceLB->append("0", aUILang);
+ m_xUserInterfaceLB->append_separator("");
+ try
+ {
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ Sequence< Any > theArgs(1);
+ Reference< XNameAccess > theNameAccess;
+
+ // find out which locales are currently installed and add them to the listbox
+ theArgs[0] <<= NamedValue("nodepath", Any(OUString(sInstalledLocalesPath)));
+ theNameAccess.set(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ seqInstalledLanguages = theNameAccess->getElementNames();
+ LanguageType aLang = LANGUAGE_DONTKNOW;
+ std::vector< std::pair<sal_Int32, OUString> > aUILanguages;
+ for (sal_Int32 i=0; i<seqInstalledLanguages.getLength(); i++)
+ {
+ aLang = LanguageTag::convertToLanguageTypeWithFallback(seqInstalledLanguages[i]);
+ if (aLang != LANGUAGE_DONTKNOW)
+ {
+ OUString aLangStr( SvtLanguageTable::GetLanguageString( aLang ) );
+ aUILanguages.emplace_back(i+1, aLangStr);
+ }
+ }
+
+ std::sort(aUILanguages.begin(), aUILanguages.end(), [](const auto& l1, const auto& l2) {
+ static const auto aSorter = comphelper::string::NaturalStringSorter(
+ comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetLanguageTag().getLocale());
+ return aSorter.compare(l1.second, l2.second) < 0;
+ });
+
+ // tdf#114694: append the sorted list after the default entry and separator.
+ for (const auto & [ nGroupID, sGroupName ] : aUILanguages)
+ {
+ m_xUserInterfaceLB->append(OUString::number(nGroupID), sGroupName);
+ }
+
+ m_xUserInterfaceLB->set_active(0);
+
+ // find out whether the user has a specific locale specified
+ Sequence< Any > theArgs2(1);
+ theArgs2[0] <<= NamedValue("nodepath", Any(OUString(sUserLocalePath)));
+ theNameAccess.set(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs2 ), UNO_QUERY_THROW );
+ if (theNameAccess->hasByName(sUserLocaleKey))
+ theNameAccess->getByName(sUserLocaleKey) >>= m_sUserLocaleValue;
+ // select the user specified locale in the listbox
+ if (!m_sUserLocaleValue.isEmpty())
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xUserInterfaceLB->get_count(); i < nEntryCount; ++i)
+ {
+ sal_Int32 d = m_xUserInterfaceLB->get_id(i).toInt32();
+ if ( d > 0 && seqInstalledLanguages.getLength() > d-1 && seqInstalledLanguages[d-1] == m_sUserLocaleValue)
+ m_xUserInterfaceLB->set_active(i);
+ }
+ }
+
+ }
+ catch (const Exception &)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring" );
+ }
+
+ m_xWesternLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+
+ m_xAsianLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CJK | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+
+ m_xComplexLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CTL | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+
+ m_xLocaleSettingLB->SetLanguageList(
+ SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false, false, false, true,
+ LANGUAGE_USER_SYSTEM_CONFIG, css::i18n::ScriptType::WEAK);
+
+ const NfCurrencyTable& rCurrTab = SvNumberFormatter::GetTheCurrencyTable();
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry( LANGUAGE_SYSTEM );
+ // insert SYSTEM entry
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->append("default", aDefaultCurr);
+ m_xCurrencyLB->append_separator("");
+
+ assert(m_xCurrencyLB->find_id("default") != -1);
+ // all currencies
+ OUString aTwoSpace( " " );
+ sal_uInt16 nCurrCount = rCurrTab.size();
+ std::vector< const NfCurrencyEntry* > aCurrencies;
+ // first entry is SYSTEM, skip it
+ for ( sal_uInt16 j=1; j < nCurrCount; ++j )
+ {
+ aCurrencies.push_back(&rCurrTab[j]);
+ }
+ std::sort(aCurrencies.begin(), aCurrencies.end(),
+ [](const NfCurrencyEntry* c1, const NfCurrencyEntry* c2) {
+ return c1->GetBankSymbol().compareTo(c2->GetBankSymbol()) < 0;
+ });
+
+ for (auto &v : aCurrencies)
+ {
+ OUString aStr_ = v->GetBankSymbol() +
+ aTwoSpace +
+ v->GetSymbol();
+ aStr_ = ApplyLreOrRleEmbedding( aStr_ ) +
+ aTwoSpace +
+ ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( v->GetLanguage() ) );
+ m_xCurrencyLB->append(OUString::number(reinterpret_cast<sal_Int64>(v)), aStr_);
+ }
+
+ m_xCurrencyLB->set_active(0);
+
+ m_xLocaleSettingLB->connect_changed( LINK( this, OfaLanguagesTabPage, LocaleSettingHdl ) );
+ m_xDatePatternsED->connect_changed( LINK( this, OfaLanguagesTabPage, DatePatternsHdl ) );
+
+ Link<weld::ToggleButton&,void> aLink( LINK( this, OfaLanguagesTabPage, SupportHdl ) );
+ m_xAsianSupportCB->connect_toggled( aLink );
+ m_xCTLSupportCB->connect_toggled( aLink );
+
+ m_bOldAsian = pLangConfig->aLanguageOptions.IsAnyEnabled();
+ m_xAsianSupportCB->set_active(m_bOldAsian);
+ m_xAsianSupportCB->save_state();
+ bool bReadonly = pLangConfig->aLanguageOptions.IsReadOnly(SvtLanguageOptions::E_ALLCJK);
+ m_xAsianSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xAsianSupportCB);
+
+ m_bOldCtl = pLangConfig->aLanguageOptions.IsCTLFontEnabled();
+ m_xCTLSupportCB->set_active(m_bOldCtl);
+ m_xCTLSupportCB->save_state();
+ bReadonly = pLangConfig->aLanguageOptions.IsReadOnly(SvtLanguageOptions::E_CTLFONT);
+ m_xCTLSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xCTLSupportCB);
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange() );
+}
+
+OfaLanguagesTabPage::~OfaLanguagesTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaLanguagesTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaLanguagesTabPage>(pPage, pController, *rAttrSet);
+}
+
+static void lcl_Update(std::unique_ptr<SfxVoidItem> pInvalidItems[], std::unique_ptr<SfxBoolItem> pBoolItems[], sal_uInt16 nCount)
+{
+ SfxViewFrame* pCurrentFrm = SfxViewFrame::Current();
+ SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
+ while(pViewFrm)
+ {
+ SfxBindings& rBind = pViewFrm->GetBindings();
+ for(sal_uInt16 i = 0; i < nCount; i++)
+ {
+ if(pCurrentFrm == pViewFrm)
+ rBind.InvalidateAll(false);
+ rBind.SetState( *pInvalidItems[i] );
+ rBind.SetState( *pBoolItems[i] );
+ }
+ pViewFrm = SfxViewFrame::GetNext(*pViewFrm);
+ }
+}
+
+bool OfaLanguagesTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ // lock configuration broadcasters so that we can coordinate the notifications
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( true );
+ pLangConfig->aLanguageOptions.BlockBroadcasts( true );
+ pLangConfig->aLinguConfig.BlockBroadcasts( true );
+
+ /*
+ * Sequence checking only matters when CTL support is enabled.
+ *
+ * So we only need to check for sequence checking if
+ * a) previously it was unchecked and is now checked or
+ * b) it was already checked but the CTL language has changed
+ */
+ if (
+ m_xCTLSupportCB->get_active() &&
+ (m_xCTLSupportCB->get_saved_state() != TRISTATE_TRUE ||
+ m_xComplexLanguageLB->get_active_id_changed_from_saved())
+ )
+ {
+ //sequence checking has to be switched on depending on the selected CTL language
+ LanguageType eCTLLang = m_xComplexLanguageLB->get_active_id();
+ bool bOn = MsLangId::needsSequenceChecking( eCTLLang);
+ pLangConfig->aLanguageOptions.SetCTLSequenceCheckingRestricted(bOn);
+ pLangConfig->aLanguageOptions.SetCTLSequenceChecking(bOn);
+ pLangConfig->aLanguageOptions.SetCTLSequenceCheckingTypeAndReplace(bOn);
+ }
+ try
+ {
+ // handle settings for UI Language
+ // a change of setting needs to bring up a warning message
+ OUString aLangString;
+ sal_Int32 d = m_xUserInterfaceLB->get_active_id().toInt32();
+ if( d > 0 && seqInstalledLanguages.getLength() > d-1)
+ aLangString = seqInstalledLanguages[d-1];
+
+ /*
+ if( m_xUserInterfaceLB->GetSelectedEntryPos() > 0)
+ aLangString = ConvertLanguageToIsoString(m_xUserInterfaceLB->get_active_id());
+ */
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ Sequence< Any > theArgs(1);
+ theArgs[0] <<= NamedValue("nodepath", Any(OUString(sUserLocalePath)));
+ Reference< XPropertySet >xProp(
+ theConfigProvider->createInstanceWithArguments(sAccessUpdSrvc, theArgs ), UNO_QUERY_THROW );
+ if ( m_sUserLocaleValue != aLangString)
+ {
+ // OSL_FAIL("UserInterface language was changed, restart.");
+ // write new value
+ xProp->setPropertyValue(sUserLocaleKey, Any(aLangString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ // display info
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), GetFrameWeld(),
+ svtools::RESTART_REASON_LANGUAGE_CHANGE))
+ GetDialogController()->response(RET_OK);
+
+ // tell quickstarter to stop being a veto listener
+
+ Reference< XComponentContext > xContext(
+ comphelper::getProcessComponentContext());
+ css::office::Quickstart::createAndSetVeto(xContext, false, false, false/*DisableVeto*/);
+ }
+ }
+ catch (const Exception&)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring");
+ }
+
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ LanguageType eOldLocale = (aLanguageTag.isSystemLocale() ? LANGUAGE_SYSTEM :
+ aLanguageTag.makeFallback().getLanguageType());
+ LanguageType eNewLocale = m_xLocaleSettingLB->get_active_id();
+
+ // If the "Default ..." entry was selected that means SYSTEM, the actual
+ // eNewLocale value is temporary for the dialog only, do not resolve to
+ // what system currently is.
+ if (eNewLocale == LANGUAGE_USER_SYSTEM_CONFIG)
+ eNewLocale = LANGUAGE_SYSTEM;
+
+ if ( eOldLocale != eNewLocale )
+ {
+ // an empty string denotes SYSTEM locale
+ OUString sNewLang;
+ if ( eNewLocale != LANGUAGE_SYSTEM )
+ sNewLang = LanguageTag::convertToBcp47( eNewLocale);
+
+ // locale nowadays get to AppSettings via notification
+ // this will happen after releasing the lock on the ConfigurationBroadcaster at
+ // the end of this method
+ pLangConfig->aSysLocaleOptions.SetLocaleConfigString( sNewLang );
+ rSet->Put( SfxBoolItem( SID_OPT_LOCALE_CHANGED, true ) );
+
+ SvtScriptType nNewType = SvtLanguageOptions::GetScriptTypeOfLanguage( eNewLocale );
+ bool bNewCJK = bool( nNewType & SvtScriptType::ASIAN );
+ SvtCompatibilityOptions aCompatOpts;
+ aCompatOpts.SetDefault( SvtCompatibilityEntry::Index::ExpandWordSpace, !bNewCJK );
+ }
+
+ if(m_xDecimalSeparatorCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDecimalSeparatorAsLocale(m_xDecimalSeparatorCB->get_active());
+
+ if(m_xIgnoreLanguageChangeCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetIgnoreLanguageChange(m_xIgnoreLanguageChangeCB->get_active());
+
+ // Configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default.
+ OUString sOldCurr = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ OUString sId = m_xCurrencyLB->get_active_id();
+ const NfCurrencyEntry* pCurr = sId == "default" ? nullptr : reinterpret_cast<const NfCurrencyEntry*>(sId.toInt64());
+ OUString sNewCurr;
+ if ( pCurr )
+ sNewCurr = SvtSysLocaleOptions::CreateCurrencyConfigString(
+ pCurr->GetBankSymbol(), pCurr->GetLanguage() );
+ if ( sOldCurr != sNewCurr )
+ pLangConfig->aSysLocaleOptions.SetCurrencyConfigString( sNewCurr );
+
+ // Configured date acceptance patterns, for example Y-M-D;M-D or empty for
+ // locale default.
+ if (m_bDatePatternsValid && m_xDatePatternsED->get_value_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDatePatternsConfigString( m_xDatePatternsED->get_text());
+
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ Reference< css::linguistic2::XLinguProperties > xLinguProp = LinguMgr::GetLinguPropertySet();
+ bool bCurrentDocCBChecked = m_xCurrentDocCB->get_active();
+ if (m_xCurrentDocCB->get_sensitive())
+ bLanguageCurrentDoc_Impl = bCurrentDocCBChecked;
+ bool bCurrentDocCBChanged = m_xCurrentDocCB->get_state_changed_from_saved();
+
+ bool bValChanged = m_xWesternLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xWesternLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( "DefaultLocale", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::LATIN),
+ SID_ATTR_LANGUAGE));
+ }
+ }
+ bValChanged = m_xAsianLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xAsianLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( "DefaultLocale_CJK", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CJK( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::ASIAN),
+ SID_ATTR_CHAR_CJK_LANGUAGE));
+ }
+ }
+ bValChanged = m_xComplexLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xComplexLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( "DefaultLocale_CTL", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CTL( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::COMPLEX),
+ SID_ATTR_CHAR_CTL_LANGUAGE));
+ }
+ }
+
+ if(m_xAsianSupportCB->get_state_changed_from_saved() )
+ {
+ bool bChecked = m_xAsianSupportCB->get_active();
+ pLangConfig->aLanguageOptions.SetAll(bChecked);
+
+ //iterate over all bindings to invalidate vertical text direction
+ const sal_uInt16 STATE_COUNT = 2;
+
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_VERTICALTEXT_STATE, false));
+ pBoolItems[1].reset(new SfxBoolItem(SID_TEXT_FITTOSIZE_VERTICAL, false));
+
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_VERTICALTEXT_STATE));
+ pInvalidItems[1].reset(new SfxVoidItem(SID_TEXT_FITTOSIZE_VERTICAL));
+
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( m_xCTLSupportCB->get_state_changed_from_saved() )
+ {
+ SvtSearchOptions aOpt;
+ aOpt.SetIgnoreDiacritics_CTL(true);
+ aOpt.SetIgnoreKashida_CTL(true);
+ aOpt.Commit();
+ pLangConfig->aLanguageOptions.SetCTLFontEnabled( m_xCTLSupportCB->get_active() );
+
+ const sal_uInt16 STATE_COUNT = 1;
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_CTLFONT_STATE, false));
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_CTLFONT_STATE));
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( pLangConfig->aSysLocaleOptions.IsModified() )
+ pLangConfig->aSysLocaleOptions.Commit();
+
+ // first release the lock on the ConfigurationBroadcaster for Locale changes
+ // it seems that our code relies on the fact that before other changes like e.g. currency
+ // are broadcasted locale changes have been done
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( false );
+ pLangConfig->aLanguageOptions.BlockBroadcasts( false );
+ pLangConfig->aLinguConfig.BlockBroadcasts( false );
+
+ return false;
+}
+
+void OfaLanguagesTabPage::Reset( const SfxItemSet* rSet )
+{
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ if ( aLanguageTag.isSystemLocale() )
+ m_xLocaleSettingLB->set_active_id( LANGUAGE_USER_SYSTEM_CONFIG );
+ else
+ m_xLocaleSettingLB->set_active_id( aLanguageTag.makeFallback().getLanguageType());
+ bool bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Locale);
+ m_xLocaleSettingLB->set_sensitive(!bReadonly);
+ m_xLocaleSettingFT->set_sensitive(!bReadonly);
+
+
+ m_xDecimalSeparatorCB->set_active( pLangConfig->aSysLocaleOptions.IsDecimalSeparatorAsLocale());
+ m_xDecimalSeparatorCB->save_state();
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange());
+ m_xIgnoreLanguageChangeCB->save_state();
+
+ // let LocaleSettingHdl enable/disable checkboxes for CJK/CTL support
+ // #i15812# must be done *before* the configured currency is set
+ // and update the decimal separator used for the given locale
+ LocaleSettingHdl(*m_xLocaleSettingLB->get_widget());
+
+ // configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default
+ OUString aAbbrev;
+ LanguageType eLang;
+ const NfCurrencyEntry* pCurr = nullptr;
+ OUString sCurrency = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ if ( !sCurrency.isEmpty() )
+ {
+ SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( aAbbrev, eLang, sCurrency );
+ pCurr = SvNumberFormatter::GetCurrencyEntry( aAbbrev, eLang );
+ }
+ // if pCurr==nullptr the SYSTEM entry is selected
+ OUString sId = !pCurr ? OUString("default") : OUString::number(reinterpret_cast<sal_Int64>(pCurr));
+ m_xCurrencyLB->set_active_id(sId);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Currency);
+ m_xCurrencyLB->set_sensitive(!bReadonly);
+ m_xCurrencyFT->set_sensitive(!bReadonly);
+
+ // date acceptance patterns
+ OUString aDatePatternsString = pLangConfig->aSysLocaleOptions.GetDatePatternsConfigString();
+ if (aDatePatternsString.isEmpty())
+ {
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aDatePatternsString = lcl_getDatePatternsConfigString( rLocaleWrapper);
+ }
+ // Let's assume patterns are valid at this point.
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text(aDatePatternsString);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::DatePatterns);
+ m_xDatePatternsED->set_sensitive(!bReadonly);
+ m_xDatePatternsFT->set_sensitive(!bReadonly);
+ m_xDatePatternsED->save_value();
+
+ //western/CJK/CLK language
+ LanguageType eCurLang = LANGUAGE_NONE;
+ LanguageType eCurLangCJK = LANGUAGE_NONE;
+ LanguageType eCurLangCTL = LANGUAGE_NONE;
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ //collect the configuration values first
+ m_xCurrentDocCB->set_sensitive(false);
+
+ Any aWestLang;
+ Any aCJKLang;
+ Any aCTLLang;
+ try
+ {
+ aWestLang = pLangConfig->aLinguConfig.GetProperty("DefaultLocale");
+ Locale aLocale;
+ aWestLang >>= aLocale;
+
+ eCurLang = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCJKLang = pLangConfig->aLinguConfig.GetProperty("DefaultLocale_CJK");
+ aLocale = Locale();
+ aCJKLang >>= aLocale;
+ eCurLangCJK = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCTLLang = pLangConfig->aLinguConfig.GetProperty("DefaultLocale_CTL");
+ aLocale = Locale();
+ aCTLLang >>= aLocale;
+ eCurLangCTL = LanguageTag::convertToLanguageType( aLocale, false);
+ }
+ catch (const Exception&)
+ {
+ }
+ //overwrite them by the values provided by the DocShell
+ if(pCurrentDocShell)
+ {
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(bLanguageCurrentDoc_Impl);
+ const SfxPoolItem* pLang;
+ if( SfxItemState::SET == rSet->GetItemState(SID_ATTR_LANGUAGE, false, &pLang))
+ {
+ LanguageType eTempCurLang = static_cast<const SvxLanguageItem*>(pLang)->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLang, css::i18n::ScriptType::LATIN) != eTempCurLang)
+ eCurLang = eTempCurLang;
+ }
+
+ if( SfxItemState::SET == rSet->GetItemState(SID_ATTR_CHAR_CJK_LANGUAGE, false, &pLang))
+ {
+ LanguageType eTempCurLang = static_cast<const SvxLanguageItem*>(pLang)->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCJK, css::i18n::ScriptType::ASIAN) != eTempCurLang)
+ eCurLangCJK = eTempCurLang;
+ }
+
+ if( SfxItemState::SET == rSet->GetItemState(SID_ATTR_CHAR_CTL_LANGUAGE, false, &pLang))
+ {
+ LanguageType eTempCurLang = static_cast<const SvxLanguageItem*>(pLang)->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCTL, css::i18n::ScriptType::COMPLEX) != eTempCurLang)
+ eCurLangCTL = eTempCurLang;
+ }
+ }
+ if(LANGUAGE_NONE == eCurLang || LANGUAGE_DONTKNOW == eCurLang)
+ m_xWesternLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xWesternLanguageLB->set_active_id(eCurLang);
+
+ if(LANGUAGE_NONE == eCurLangCJK || LANGUAGE_DONTKNOW == eCurLangCJK)
+ m_xAsianLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xAsianLanguageLB->set_active_id(eCurLangCJK);
+
+ if(LANGUAGE_NONE == eCurLangCTL || LANGUAGE_DONTKNOW == eCurLangCTL)
+ m_xComplexLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xComplexLanguageLB->set_active_id(eCurLangCTL);
+
+ m_xWesternLanguageLB->save_active_id();
+ m_xAsianLanguageLB->save_active_id();
+ m_xComplexLanguageLB->save_active_id();
+ m_xIgnoreLanguageChangeCB->save_state();
+ m_xCurrentDocCB->save_state();
+
+ bool bEnable = !pLangConfig->aLinguConfig.IsReadOnly( "DefaultLocale" );
+ m_xWesternLanguageFT->set_sensitive( bEnable );
+ m_xWesternLanguageLB->set_sensitive( bEnable );
+
+ // check the box "For the current document only"
+ // set the focus to the Western Language box
+ const SfxPoolItem* pLang = nullptr;
+ if ( SfxItemState::SET == rSet->GetItemState(SID_SET_DOCUMENT_LANGUAGE, false, &pLang ) && static_cast<const SfxBoolItem*>(pLang)->GetValue() )
+ {
+ m_xWesternLanguageLB->grab_focus();
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(true);
+ }
+}
+
+IMPL_LINK(OfaLanguagesTabPage, SupportHdl, weld::ToggleButton&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ if ( m_xAsianSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly("DefaultLocale_CJK");
+ bCheck = ( bCheck && !bReadonly );
+ m_xAsianLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldAsian = bCheck;
+ }
+ else if ( m_xCTLSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly("DefaultLocale_CTL");
+ bCheck = ( bCheck && !bReadonly );
+ m_xComplexLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldCtl = bCheck;
+ }
+ else
+ SAL_WARN( "cui.options", "OfaLanguagesTabPage::SupportHdl(): wrong rBox" );
+}
+
+namespace
+{
+ void lcl_checkLanguageCheckBox(weld::CheckButton& _rCB, bool _bNewValue, bool _bOldValue)
+ {
+ if ( _bNewValue )
+ _rCB.set_active(true);
+ else
+ _rCB.set_active( _bOldValue );
+// #i15082# do not call save_state() in running dialog...
+// _rCB.save_state();
+ _rCB.set_sensitive( !_bNewValue );
+ }
+}
+
+IMPL_LINK_NOARG(OfaLanguagesTabPage, LocaleSettingHdl, weld::ComboBox&, void)
+{
+ LanguageType eLang = m_xLocaleSettingLB->get_active_id();
+ SvtScriptType nType = SvtLanguageOptions::GetScriptTypeOfLanguage(eLang);
+ // first check if CTL must be enabled
+ // #103299# - if CTL font setting is not readonly
+ if(!pLangConfig->aLanguageOptions.IsReadOnly(SvtLanguageOptions::E_CTLFONT))
+ {
+ bool bIsCTLFixed = bool(nType & SvtScriptType::COMPLEX);
+ lcl_checkLanguageCheckBox(*m_xCTLSupportCB, bIsCTLFixed, m_bOldCtl);
+ SupportHdl(*m_xCTLSupportCB);
+ }
+ // second check if CJK must be enabled
+ // #103299# - if CJK support is not readonly
+ if(!pLangConfig->aLanguageOptions.IsReadOnly(SvtLanguageOptions::E_ALLCJK))
+ {
+ bool bIsCJKFixed = bool(nType & SvtScriptType::ASIAN);
+ lcl_checkLanguageCheckBox(*m_xAsianSupportCB, bIsCJKFixed, m_bOldAsian);
+ SupportHdl(*m_xAsianSupportCB);
+ }
+
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry(
+ (eLang == LANGUAGE_USER_SYSTEM_CONFIG) ? MsLangId::getSystemLanguage() : eLang);
+ const OUString aDefaultID = "default";
+ // Update the "Default ..." currency.
+ m_xCurrencyLB->remove_id(aDefaultID);
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->insert(0, aDefaultCurr, &aDefaultID, nullptr, nullptr);
+ assert(m_xCurrencyLB->find_id(aDefaultID) != -1);
+ m_xCurrencyLB->set_active_text(aDefaultCurr);
+
+ // obtain corresponding locale data
+ LanguageTag aLanguageTag( eLang);
+ LocaleDataWrapper aLocaleWrapper( aLanguageTag );
+
+ // update the decimal separator key of the related CheckBox
+ OUString sTempLabel(m_sDecimalSeparatorLabel);
+ sTempLabel = sTempLabel.replaceFirst("%1", aLocaleWrapper.getNumDecimalSep() );
+ m_xDecimalSeparatorCB->set_label(sTempLabel);
+
+ // update the date acceptance patterns
+ OUString aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper);
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text( aDatePatternsString);
+}
+
+IMPL_LINK( OfaLanguagesTabPage, DatePatternsHdl, weld::Entry&, rEd, void )
+{
+ const OUString aPatterns(rEd.get_text());
+ OUStringBuffer aBuf( aPatterns);
+ sal_Int32 nChar = 0;
+ bool bValid = true;
+ bool bModified = false;
+ if (!aPatterns.isEmpty())
+ {
+ for (sal_Int32 nIndex=0; nIndex >= 0 && bValid; ++nChar)
+ {
+ const OUString aPat( aPatterns.getToken( 0, ';', nIndex));
+ if (aPat.isEmpty() && nIndex < 0)
+ {
+ // Indicating failure when about to append a pattern is too
+ // confusing. Empty patterns are ignored anyway when sequencing
+ // to SvtSysLocale.
+ continue; // for
+ }
+ else if (aPat.getLength() < 2)
+ bValid = false;
+ else
+ {
+ bool bY, bM, bD;
+ bY = bM = bD = false;
+ bool bSep = true;
+ for (sal_Int32 i = 0; i < aPat.getLength() && bValid; /*nop*/)
+ {
+ const sal_Int32 j = i;
+ const sal_uInt32 c = aPat.iterateCodePoints( &i);
+ // Only one Y,M,D per pattern, separated by any character(s).
+ switch (c)
+ {
+ case 'y':
+ case 'Y':
+ if (bY || !bSep)
+ bValid = false;
+ else if (c == 'y')
+ {
+ aBuf[nChar] = 'Y';
+ bModified = true;
+ }
+ bY = true;
+ bSep = false;
+ break;
+ case 'm':
+ case 'M':
+ if (bM || !bSep)
+ bValid = false;
+ else if (c == 'm')
+ {
+ aBuf[nChar] = 'M';
+ bModified = true;
+ }
+ bM = true;
+ bSep = false;
+ break;
+ case 'd':
+ case 'D':
+ if (bD || !bSep)
+ bValid = false;
+ else if (c == 'd')
+ {
+ aBuf[nChar] = 'D';
+ bModified = true;
+ }
+ bD = true;
+ bSep = false;
+ break;
+ default:
+ // A pattern must not start with a separator (but
+ // may end with).
+ if (!(bY || bM || bD))
+ bValid = false;
+ bSep = true;
+ }
+ nChar += i-j;
+ }
+ // At least one of Y,M,D
+ bValid &= (bY || bM || bD);
+ }
+ }
+ }
+ if (bModified)
+ rEd.replace_selection(aBuf.makeStringAndClear());
+ if (bValid)
+ rEd.set_message_type(weld::EntryMessageType::Normal);
+ else
+ rEd.set_message_type(weld::EntryMessageType::Error);
+ m_bDatePatternsValid = bValid;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
new file mode 100644
index 000000000..e01bca949
--- /dev/null
+++ b/cui/source/options/optgdlg.hxx
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_OPTIONS_OPTGDLG_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTGDLG_HXX
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+class CanvasSettings;
+class SvtOptionsDrawinglayer;
+
+namespace vcl {
+ class IconThemeInfo;
+}
+
+namespace svt {
+ class SkiaCfg;
+}
+
+class OfaMiscTabPage : public SfxTabPage
+{
+private:
+ OUString m_aStrDateInfo;
+
+ std::unique_ptr<weld::CheckButton> m_xExtHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xPopUpNoHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xShowTipOfTheDay;
+ std::unique_ptr<weld::Widget> m_xFileDlgFrame;
+ std::unique_ptr<weld::Widget> m_xPrintDlgFrame;
+ std::unique_ptr<weld::Widget> m_xFileDlgROImage;
+ std::unique_ptr<weld::CheckButton> m_xFileDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xDocStatusCB;
+ std::unique_ptr<weld::Widget> m_xYearFrame;
+ std::unique_ptr<weld::SpinButton> m_xYearValueField;
+ std::unique_ptr<weld::Label> m_xToYearFT;
+ std::unique_ptr<weld::CheckButton> m_xCollectUsageInfo;
+ std::unique_ptr<weld::CheckButton> m_xCrashReport;
+ std::unique_ptr<weld::Widget> m_xQuickStarterFrame;
+ std::unique_ptr<weld::CheckButton> m_xQuickLaunchCB;
+#if defined(_WIN32)
+ std::unique_ptr<weld::Widget> m_xFileAssocFrame;
+ std::unique_ptr<weld::Button> m_xFileAssocBtn;
+#endif
+
+ DECL_LINK(TwoFigureHdl, weld::SpinButton&, void);
+#if defined(_WIN32)
+ DECL_STATIC_LINK(OfaMiscTabPage, FileAssocClick, weld::Button&, void);
+#endif
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaMiscTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvtTabAppearanceCfg;
+
+class OfaViewTabPage : public SfxTabPage
+{
+private:
+ sal_Int32 nSizeLB_InitialSelection;
+ sal_Int32 nSidebarSizeLB_InitialSelection;
+ sal_Int32 nNotebookbarSizeLB_InitialSelection;
+ sal_Int32 nStyleLB_InitialSelection;
+
+ std::unique_ptr<SvtTabAppearanceCfg> pAppearanceCfg;
+ std::unique_ptr<CanvasSettings> pCanvasSettings;
+ std::unique_ptr<SvtOptionsDrawinglayer> mpDrawinglayerOpt;
+ std::unique_ptr<svt::SkiaCfg> mpSkiaConfig;
+
+ std::vector<vcl::IconThemeInfo> mInstalledIconThemes;
+
+ std::unique_ptr<weld::ComboBox> m_xIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xSidebarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xNotebookbarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xIconStyleLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontAntiAliasing;
+ std::unique_ptr<weld::Label> m_xAAPointLimitLabel;
+ std::unique_ptr<weld::MetricSpinButton> m_xAAPointLimit;
+
+ std::unique_ptr<weld::Widget> m_xMenuIconBox;
+ std::unique_ptr<weld::ComboBox> m_xMenuIconsLB;
+
+ std::unique_ptr<weld::ComboBox> m_xContextMenuShortcutsLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontShowCB;
+
+ std::unique_ptr<weld::CheckButton> m_xUseHardwareAccell;
+ std::unique_ptr<weld::CheckButton> m_xUseAntiAliase;
+ std::unique_ptr<weld::CheckButton> m_xUseSkia;
+ std::unique_ptr<weld::CheckButton> m_xForceSkiaRaster;
+
+ std::unique_ptr<weld::Label> m_xSkiaStatusEnabled;
+ std::unique_ptr<weld::Label> m_xSkiaStatusDisabled;
+
+ std::unique_ptr<weld::ComboBox> m_xMousePosLB;
+ std::unique_ptr<weld::ComboBox> m_xMouseMiddleLB;
+
+ DECL_LINK(OnAntialiasingToggled, weld::ToggleButton&, void);
+ DECL_LINK(OnForceSkiaRasterToggled, weld::ToggleButton&, void);
+ void UpdateSkiaStatus();
+
+public:
+ OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaViewTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct LanguageConfig_Impl;
+
+class OfaLanguagesTabPage : public SfxTabPage
+{
+ bool m_bOldAsian;
+ bool m_bOldCtl;
+ std::unique_ptr<LanguageConfig_Impl> pLangConfig;
+
+ OUString m_sUserLocaleValue;
+ OUString m_sSystemDefaultString;
+ OUString m_sDecimalSeparatorLabel;
+
+ bool m_bDatePatternsValid;
+
+ std::unique_ptr<weld::ComboBox> m_xUserInterfaceLB;
+ std::unique_ptr<weld::Label> m_xLocaleSettingFT;
+ std::unique_ptr<SvxLanguageBox> m_xLocaleSettingLB;
+ std::unique_ptr<weld::CheckButton> m_xDecimalSeparatorCB;
+ std::unique_ptr<weld::Label> m_xCurrencyFT;
+ std::unique_ptr<weld::ComboBox> m_xCurrencyLB;
+ std::unique_ptr<weld::Label> m_xDatePatternsFT;
+ std::unique_ptr<weld::Entry> m_xDatePatternsED;
+
+ std::unique_ptr<SvxLanguageBox> m_xWesternLanguageLB;
+ std::unique_ptr<weld::Label> m_xWesternLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xAsianLanguageLB;
+ std::unique_ptr<SvxLanguageBox> m_xComplexLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xCurrentDocCB;
+ std::unique_ptr<weld::CheckButton> m_xAsianSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xCTLSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreLanguageChangeCB;
+
+ DECL_LINK(SupportHdl, weld::ToggleButton&, void);
+ DECL_LINK(LocaleSettingHdl, weld::ComboBox&, void);
+ DECL_LINK(DatePatternsHdl, weld::Entry&, void);
+
+public:
+ OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaLanguagesTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_OPTGDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgenrl.cxx b/cui/source/options/optgenrl.cxx
new file mode 100644
index 000000000..6fcef3319
--- /dev/null
+++ b/cui/source/options/optgenrl.cxx
@@ -0,0 +1,508 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <config_gpgme.h>
+#if HAVE_FEATURE_GPGME
+# include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
+# include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
+#endif
+
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/saveopt.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/settings.hxx>
+
+#include <unotools/useroptions.hxx>
+#include <cuioptgenrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/optgenrl.hxx>
+
+using namespace css;
+
+namespace
+{
+
+// rows
+enum RowType
+{
+ Row_Company,
+ Row_Name,
+ Row_Name_Russian,
+ Row_Name_Eastern,
+ Row_Street,
+ Row_Street_Russian,
+ Row_City,
+ Row_City_US,
+ Row_Country,
+ Row_TitlePos,
+ Row_Phone,
+ Row_FaxMail,
+
+ nRowCount
+};
+
+// language flags
+namespace Lang
+{
+ unsigned const Others = 1;
+ unsigned const Russian = 2;
+ unsigned const Eastern = 4;
+ unsigned const US = 8;
+ unsigned const All = static_cast<unsigned>(-1);
+}
+
+
+// vRowInfo[] -- rows (text + one or more edit boxes)
+// The order is the same as in RowType above, which is up to down.
+
+struct
+{
+ // id of the text
+ const char *pTextId;
+ // language flags (see Lang above):
+ // which language is this row for?
+ unsigned nLangFlags;
+}
+const vRowInfo[] =
+{
+ { "companyft", Lang::All },
+ { "nameft", Lang::All & ~Lang::Russian & ~Lang::Eastern },
+ { "rusnameft", Lang::Russian },
+ { "eastnameft", Lang::Eastern },
+ { "streetft", Lang::All & ~Lang::Russian },
+ { "russtreetft", Lang::Russian },
+ { "icityft", Lang::All & ~Lang::US },
+ { "cityft", Lang::US },
+ { "countryft", Lang::All },
+ { "titleft", Lang::All },
+ { "phoneft", Lang::All },
+ { "faxft", Lang::All },
+};
+
+
+// vFieldInfo[] -- edit boxes
+// The order is up to down, and then left to right.
+
+struct
+{
+ // in which row?
+ RowType eRow;
+ // id of the edit box
+ const char *pEditId;
+ // id for SvtUserOptions in unotools/useroptions.hxx
+ UserOptToken nUserOptionsId;
+ // id for settings the focus (defined in svx/optgenrl.hxx)
+ EditPosition nGrabFocusId;
+}
+const vFieldInfo[] =
+{
+ // Company
+ { Row_Company, "company", UserOptToken::Company, EditPosition::COMPANY },
+ // Name
+ { Row_Name, "firstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name, "lastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name, "shortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (russian)
+ { Row_Name_Russian, "ruslastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Russian, "rusfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Russian, "rusfathersname", UserOptToken::FathersName, EditPosition::UNKNOWN },
+ { Row_Name_Russian, "russhortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (eastern: reversed name ord
+ { Row_Name_Eastern, "eastlastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Eastern, "eastfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Eastern, "eastshortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Street
+ { Row_Street, "street", UserOptToken::Street, EditPosition::STREET },
+ // Street (russian)
+ { Row_Street_Russian, "russtreet", UserOptToken::Street, EditPosition::STREET },
+ { Row_Street_Russian, "apartnum", UserOptToken::Apartment, EditPosition::UNKNOWN },
+ // City
+ { Row_City, "izip", UserOptToken::Zip, EditPosition::PLZ },
+ { Row_City, "icity", UserOptToken::City, EditPosition::CITY },
+ // City (US)
+ { Row_City_US, "city", UserOptToken::City, EditPosition::CITY },
+ { Row_City_US, "state", UserOptToken::State, EditPosition::STATE },
+ { Row_City_US, "zip", UserOptToken::Zip, EditPosition::PLZ },
+ // Country
+ { Row_Country, "country", UserOptToken::Country, EditPosition::COUNTRY },
+ // Title/Position
+ { Row_TitlePos, "title", UserOptToken::Title, EditPosition::TITLE },
+ { Row_TitlePos, "position", UserOptToken::Position, EditPosition::POSITION },
+ // Phone
+ { Row_Phone, "home", UserOptToken::TelephoneHome, EditPosition::TELPRIV },
+ { Row_Phone, "work", UserOptToken::TelephoneWork, EditPosition::TELCOMPANY },
+ // Fax/Mail
+ { Row_FaxMail, "fax", UserOptToken::Fax, EditPosition::FAX },
+ { Row_FaxMail, "email", UserOptToken::Email, EditPosition::EMAIL },
+};
+
+
+} // namespace
+
+
+// Row
+
+struct SvxGeneralTabPage::Row
+{
+ // row label
+ std::unique_ptr<weld::Label> xLabel;
+ // first and last field in the row (last is exclusive)
+ unsigned nFirstField, nLastField;
+
+public:
+ explicit Row (std::unique_ptr<weld::Label> xLabel_)
+ : xLabel(std::move(xLabel_))
+ , nFirstField(0)
+ , nLastField(0)
+ {
+ xLabel->show();
+ }
+};
+
+
+// Field
+
+struct SvxGeneralTabPage::Field
+{
+ // which field is this? (in vFieldInfo[] above)
+ unsigned iField;
+ // edit box
+ std::unique_ptr<weld::Entry> xEdit;
+ std::unique_ptr<weld::Container> xParent;
+
+public:
+ Field (std::unique_ptr<weld::Entry> xEdit_, unsigned iField_)
+ : iField(iField_)
+ , xEdit(std::move(xEdit_))
+ , xParent(xEdit->weld_parent())
+ {
+ //We want all widgets inside a container, so each row of the toplevel
+ //grid has another container in it. To avoid adding spacing to these
+ //empty grids they all default to invisible, so show them if their
+ //children are visible
+ xParent->show();
+ xEdit->show();
+ }
+};
+
+SvxGeneralTabPage::SvxGeneralTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optuserpage.ui", "OptUserPage", &rCoreSet)
+ , m_xUseDataCB(m_xBuilder->weld_check_button("usefordocprop"))
+ , m_xCryptoFrame(m_xBuilder->weld_widget( "cryptography"))
+ , m_xSigningKeyLB(m_xBuilder->weld_combo_box("signingkey"))
+ , m_xEncryptionKeyLB(m_xBuilder->weld_combo_box("encryptionkey"))
+ , m_xEncryptToSelfCB(m_xBuilder->weld_check_button("encrypttoself"))
+{
+ InitControls();
+#if HAVE_FEATURE_GPGME
+ InitCryptography();
+#else
+ m_xCryptoFrame->hide();
+#endif
+
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ SetLinks();
+}
+
+SvxGeneralTabPage::~SvxGeneralTabPage()
+{
+}
+
+// Initializes the titles and the edit boxes,
+// according to vRowInfo[] and vFieldInfo[] above.
+void SvxGeneralTabPage::InitControls ()
+{
+ // which language bit do we use? (see Lang and vRowInfo[] above)
+ unsigned LangBit;
+ LanguageType l = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ if (l == LANGUAGE_ENGLISH_US)
+ LangBit = Lang::US;
+ else if (l == LANGUAGE_RUSSIAN)
+ LangBit = Lang::Russian;
+ else
+ {
+ if (MsLangId::isFamilyNameFirst(l))
+ LangBit = Lang::Eastern;
+ else
+ LangBit = Lang::Others;
+ }
+
+ // creating rows
+ unsigned iField = 0;
+ for (unsigned iRow = 0; iRow != nRowCount; ++iRow)
+ {
+ RowType const eRow = static_cast<RowType>(iRow);
+ // is the row visible?
+ if (!(vRowInfo[iRow].nLangFlags & LangBit))
+ continue;
+ // creating row
+ vRows.push_back(std::make_shared<Row>(
+ m_xBuilder->weld_label(vRowInfo[iRow].pTextId)));
+ Row& rRow = *vRows.back();
+ // fields in the row
+ static unsigned const nFieldCount = SAL_N_ELEMENTS(vFieldInfo);
+ // skipping other (invisible) rows
+ while (iField != nFieldCount && vFieldInfo[iField].eRow != eRow)
+ ++iField;
+ // fields in the row
+ rRow.nFirstField = vFields.size();
+ for ( ; iField != nFieldCount && vFieldInfo[iField].eRow == eRow; ++iField)
+ {
+ // creating edit field
+ vFields.push_back(std::make_shared<Field>(
+ m_xBuilder->weld_entry(vFieldInfo[iField].pEditId), iField));
+ // "short name" field?
+ if (vFieldInfo[iField].nUserOptionsId == UserOptToken::ID)
+ {
+ nNameRow = vRows.size() - 1;
+ nShortNameField = vFields.size() - 1;
+ }
+ }
+ rRow.nLastField = vFields.size();
+ }
+}
+
+void SvxGeneralTabPage::InitCryptography()
+{
+#if HAVE_FEATURE_GPGME
+ m_xCryptoFrame->show();
+
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
+ try
+ {
+ xSEInitializer = xml::crypto::GPGSEInitializer::create( comphelper::getProcessComponentContext() );
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSC = xSEInitializer->createSecurityContext( OUString() );
+ if (xSC.is())
+ {
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSC->getSecurityEnvironment();
+ uno::Sequence<uno::Reference<security::XCertificate>> xCertificates = xSE->getPersonalCertificates();
+
+ if (xCertificates.hasElements())
+ {
+ for (auto& xCert : xCertificates)
+ {
+ m_xSigningKeyLB->append_text( xCert->getIssuerName());
+ m_xEncryptionKeyLB->append_text( xCert->getIssuerName());
+ }
+ }
+
+ //tdf#115015: wrap checkbox text and listboxes if necessary
+ int nPrefWidth(m_xEncryptToSelfCB->get_preferred_size().Width());
+ int nMaxWidth = m_xEncryptToSelfCB->get_approximate_digit_width() * 40;
+ if (nPrefWidth > nMaxWidth)
+ {
+ m_xSigningKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptionKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptToSelfCB->set_label_line_wrap(true);
+ m_xEncryptToSelfCB->set_size_request(nMaxWidth, -1);
+ }
+ }
+ }
+ catch ( uno::Exception const & )
+ {}
+#endif
+
+}
+
+void SvxGeneralTabPage::SetLinks ()
+{
+ // link for updating the initials
+ Link<weld::Entry&,void> aLink = LINK( this, SvxGeneralTabPage, ModifyHdl_Impl );
+ Row& rNameRow = *vRows[nNameRow];
+ for (unsigned i = rNameRow.nFirstField; i != rNameRow.nLastField - 1; ++i)
+ vFields[i]->xEdit->connect_changed(aLink);
+}
+
+
+std::unique_ptr<SfxTabPage> SvxGeneralTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxGeneralTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxGeneralTabPage::FillItemSet( SfxItemSet* )
+{
+ // remove leading and trailing whitespaces
+ for (auto const & i: vFields)
+ i->xEdit->set_text(comphelper::string::strip(i->xEdit->get_text(), ' '));
+
+ bool bModified = false;
+ bModified |= GetData_Impl();
+ SvtSaveOptions aSaveOpt;
+ if (m_xUseDataCB->get_active() != aSaveOpt.IsUseUserData())
+ {
+ aSaveOpt.SetUseUserData(m_xUseDataCB->get_active());
+ bModified = true;
+ }
+ return bModified;
+}
+
+void SvxGeneralTabPage::Reset( const SfxItemSet* rSet )
+{
+ SetData_Impl();
+
+ sal_uInt16 const nWhich = GetWhich(SID_FIELD_GRABFOCUS);
+
+ if (rSet->GetItemState(nWhich) == SfxItemState::SET)
+ {
+ EditPosition nField = static_cast<EditPosition>(static_cast<const SfxUInt16Item&>(rSet->Get(nWhich)).GetValue());
+ if (nField != EditPosition::UNKNOWN)
+ {
+ for (auto const & i: vFields)
+ if (nField == vFieldInfo[i->iField].nGrabFocusId)
+ i->xEdit->grab_focus();
+ }
+ else
+ vFields.front()->xEdit->grab_focus();
+ }
+
+ m_xUseDataCB->set_active(SvtSaveOptions().IsUseUserData());
+}
+
+
+// ModifyHdl_Impl()
+// This handler updates the initials (short name)
+// when one of the name fields was updated.
+IMPL_LINK( SvxGeneralTabPage, ModifyHdl_Impl, weld::Entry&, rEdit, void )
+{
+ // short name field and row
+ Field& rShortName = *vFields[nShortNameField];
+ Row& rNameRow = *vRows[nNameRow];
+ // number of initials
+ unsigned const nInits = rNameRow.nLastField - rNameRow.nFirstField - 1;
+ // which field was updated? (in rNameRow)
+ unsigned nField = nInits;
+ for (unsigned i = 0; i != nInits; ++i)
+ {
+ if (vFields[rNameRow.nFirstField + i]->xEdit.get() == &rEdit)
+ nField = i;
+ }
+ // updating the initial
+ if (!(nField < nInits && rShortName.xEdit->get_sensitive()))
+ return;
+
+ OUString sShortName = rShortName.xEdit->get_text();
+ // clear short name if it contains more characters than the number of initials
+ if (o3tl::make_unsigned(sShortName.getLength()) > nInits)
+ {
+ rShortName.xEdit->set_text(OUString());
+ }
+ while (o3tl::make_unsigned(sShortName.getLength()) < nInits)
+ sShortName += " ";
+ OUString sName = rEdit.get_text();
+ OUString sLetter = sName.isEmpty()
+ ? OUString(u' ') : sName.copy(0, 1);
+ rShortName.xEdit->set_text(sShortName.replaceAt(nField, 1, sLetter).trim());
+}
+
+
+bool SvxGeneralTabPage::GetData_Impl()
+{
+ // updating
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vFields)
+ aUserOpt.SetToken(
+ vFieldInfo[i->iField].nUserOptionsId,
+ i->xEdit->get_text()
+ );
+
+ // modified?
+ bool bModified = false;
+ for (auto const & i: vFields)
+ {
+ if (i->xEdit->get_value_changed_from_saved())
+ {
+ bModified = true;
+ break;
+ }
+ }
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = m_xSigningKeyLB->get_active() == 0 ? OUString() //i.e. no key
+ : m_xSigningKeyLB->get_active_text();
+ OUString aEK = m_xEncryptionKeyLB->get_active() == 0 ? OUString()
+ : m_xEncryptionKeyLB->get_active_text();
+
+ aUserOpt.SetToken( UserOptToken::SigningKey, aSK );
+ aUserOpt.SetToken( UserOptToken::EncryptionKey, aEK );
+ aUserOpt.SetBoolValue( UserOptToken::EncryptToSelf, m_xEncryptToSelfCB->get_active() );
+
+ bModified |= m_xSigningKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptionKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptToSelfCB->get_state_changed_from_saved();
+#endif
+
+ return bModified;
+}
+
+
+void SvxGeneralTabPage::SetData_Impl()
+{
+ // updating and disabling edit boxes
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vRows)
+ {
+ Row& rRow = *i;
+ // the label is enabled if any of its edit fields are enabled
+ bool bEnableLabel = false;
+ for (unsigned iField = rRow.nFirstField; iField != rRow.nLastField; ++iField)
+ {
+ Field& rField = *vFields[iField];
+ // updating content
+ UserOptToken const nToken = vFieldInfo[rField.iField].nUserOptionsId;
+ rField.xEdit->set_text(aUserOpt.GetToken(nToken));
+ // is enabled?
+ bool const bEnableEdit = !aUserOpt.IsTokenReadonly(nToken);
+ rField.xEdit->set_sensitive(bEnableEdit);
+ bEnableLabel = bEnableLabel || bEnableEdit;
+ }
+ rRow.xLabel->set_sensitive(bEnableLabel);
+ }
+
+ // saving
+ for (auto const & i: vFields)
+ i->xEdit->save_value();
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = aUserOpt.GetToken(UserOptToken::SigningKey);
+ aSK.isEmpty() ? m_xSigningKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xSigningKeyLB->set_active_text( aSK );
+
+ OUString aEK = aUserOpt.GetToken(UserOptToken::EncryptionKey);
+ aEK.isEmpty() ? m_xEncryptionKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xEncryptionKeyLB->set_active_text( aEK );
+
+ m_xEncryptToSelfCB->set_active( aUserOpt.GetEncryptToSelf() );
+#endif
+}
+
+
+DeactivateRC SvxGeneralTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.cxx b/cui/source/options/opthtml.cxx
new file mode 100644
index 000000000..fca286ddb
--- /dev/null
+++ b/cui/source/options/opthtml.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 <svtools/langtab.hxx>
+#include <svtools/htmlcfg.hxx>
+#include "opthtml.hxx"
+
+
+OfaHtmlTabPage::OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/opthtmlpage.ui", "OptHtmlPage", &rSet)
+ , m_xSize1NF(m_xBuilder->weld_spin_button("size1"))
+ , m_xSize2NF(m_xBuilder->weld_spin_button("size2"))
+ , m_xSize3NF(m_xBuilder->weld_spin_button("size3"))
+ , m_xSize4NF(m_xBuilder->weld_spin_button("size4"))
+ , m_xSize5NF(m_xBuilder->weld_spin_button("size5"))
+ , m_xSize6NF(m_xBuilder->weld_spin_button("size6"))
+ , m_xSize7NF(m_xBuilder->weld_spin_button("size7"))
+ , m_xNumbersEnglishUSCB(m_xBuilder->weld_check_button("numbersenglishus"))
+ , m_xUnknownTagCB(m_xBuilder->weld_check_button("unknowntag"))
+ , m_xIgnoreFontNamesCB(m_xBuilder->weld_check_button("ignorefontnames"))
+ , m_xStarBasicCB(m_xBuilder->weld_check_button("starbasic"))
+ , m_xStarBasicWarningCB(m_xBuilder->weld_check_button("starbasicwarning"))
+ , m_xPrintExtensionCB(m_xBuilder->weld_check_button("printextension"))
+ , m_xSaveGrfLocalCB(m_xBuilder->weld_check_button("savegrflocal"))
+ , m_xCharSetLB(new SvxTextEncodingBox(m_xBuilder->weld_combo_box("charset")))
+{
+ // replace placeholder with UI string from language list
+ OUString aText(m_xNumbersEnglishUSCB->get_label());
+ OUString aPlaceholder("%ENGLISHUSLOCALE");
+ sal_Int32 nPos;
+ if ((nPos = aText.indexOf( aPlaceholder)) != -1)
+ {
+ const OUString& rStr = SvtLanguageTable::GetLanguageString( LANGUAGE_ENGLISH_US);
+ if (!rStr.isEmpty())
+ {
+ aText = aText.replaceAt( nPos, aPlaceholder.getLength(), rStr);
+ m_xNumbersEnglishUSCB->set_label( aText);
+ }
+ }
+
+ m_xStarBasicCB->connect_toggled(LINK(this, OfaHtmlTabPage, CheckBoxHdl_Impl));
+
+ // initialize the characterset listbox
+ m_xCharSetLB->FillWithMimeAndSelectBest();
+}
+
+OfaHtmlTabPage::~OfaHtmlTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaHtmlTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaHtmlTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaHtmlTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxHtmlOptions& rHtmlOpt = SvxHtmlOptions::Get();
+ if(m_xSize1NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(0, static_cast<sal_uInt16>(m_xSize1NF->get_value()));
+ if(m_xSize2NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(1, static_cast<sal_uInt16>(m_xSize2NF->get_value()));
+ if(m_xSize3NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(2, static_cast<sal_uInt16>(m_xSize3NF->get_value()));
+ if(m_xSize4NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(3, static_cast<sal_uInt16>(m_xSize4NF->get_value()));
+ if(m_xSize5NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(4, static_cast<sal_uInt16>(m_xSize5NF->get_value()));
+ if(m_xSize6NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(5, static_cast<sal_uInt16>(m_xSize6NF->get_value()));
+ if(m_xSize7NF->get_value_changed_from_saved())
+ rHtmlOpt.SetFontSize(6, static_cast<sal_uInt16>(m_xSize7NF->get_value()));
+
+ if(m_xNumbersEnglishUSCB->get_state_changed_from_saved())
+ rHtmlOpt.SetNumbersEnglishUS(m_xNumbersEnglishUSCB->get_active());
+
+ if(m_xUnknownTagCB->get_state_changed_from_saved())
+ rHtmlOpt.SetImportUnknown(m_xUnknownTagCB->get_active());
+
+ if(m_xIgnoreFontNamesCB->get_state_changed_from_saved())
+ rHtmlOpt.SetIgnoreFontFamily(m_xIgnoreFontNamesCB->get_active());
+
+ if(m_xStarBasicCB->get_state_changed_from_saved())
+ rHtmlOpt.SetStarBasic(m_xStarBasicCB->get_active());
+
+ if(m_xStarBasicWarningCB->get_state_changed_from_saved())
+ rHtmlOpt.SetStarBasicWarning(m_xStarBasicWarningCB->get_active());
+
+ if(m_xSaveGrfLocalCB->get_state_changed_from_saved())
+ rHtmlOpt.SetSaveGraphicsLocal(m_xSaveGrfLocalCB->get_active());
+
+ if(m_xPrintExtensionCB->get_state_changed_from_saved())
+ rHtmlOpt.SetPrintLayoutExtension(m_xPrintExtensionCB->get_active());
+
+ if( m_xCharSetLB->GetSelectTextEncoding() != rHtmlOpt.GetTextEncoding() )
+ rHtmlOpt.SetTextEncoding( m_xCharSetLB->GetSelectTextEncoding() );
+
+ return false;
+}
+
+void OfaHtmlTabPage::Reset( const SfxItemSet* )
+{
+ SvxHtmlOptions& rHtmlOpt = SvxHtmlOptions::Get();
+ m_xSize1NF->set_value(rHtmlOpt.GetFontSize(0));
+ m_xSize2NF->set_value(rHtmlOpt.GetFontSize(1));
+ m_xSize3NF->set_value(rHtmlOpt.GetFontSize(2));
+ m_xSize4NF->set_value(rHtmlOpt.GetFontSize(3));
+ m_xSize5NF->set_value(rHtmlOpt.GetFontSize(4));
+ m_xSize6NF->set_value(rHtmlOpt.GetFontSize(5));
+ m_xSize7NF->set_value(rHtmlOpt.GetFontSize(6));
+ m_xNumbersEnglishUSCB->set_active(rHtmlOpt.IsNumbersEnglishUS());
+ m_xUnknownTagCB->set_active(rHtmlOpt.IsImportUnknown());
+ m_xIgnoreFontNamesCB->set_active(rHtmlOpt.IsIgnoreFontFamily());
+
+ m_xStarBasicCB->set_active(rHtmlOpt.IsStarBasic());
+ m_xStarBasicWarningCB->set_active(rHtmlOpt.IsStarBasicWarning());
+ m_xStarBasicWarningCB->set_sensitive(!m_xStarBasicCB->get_active());
+ m_xSaveGrfLocalCB->set_active(rHtmlOpt.IsSaveGraphicsLocal());
+ m_xPrintExtensionCB->set_active(rHtmlOpt.IsPrintLayoutExtension());
+
+ m_xPrintExtensionCB->save_state();
+ m_xStarBasicCB->save_state();
+ m_xStarBasicWarningCB->save_state();
+ m_xSaveGrfLocalCB->save_state();
+ m_xSize1NF->save_value();
+ m_xSize2NF->save_value();
+ m_xSize3NF->save_value();
+ m_xSize4NF->save_value();
+ m_xSize5NF->save_value();
+ m_xSize6NF->save_value();
+ m_xSize7NF->save_value();
+ m_xNumbersEnglishUSCB->save_state();
+ m_xUnknownTagCB->save_state();
+ m_xIgnoreFontNamesCB->save_state();
+
+ if( !rHtmlOpt.IsDefaultTextEncoding() &&
+ m_xCharSetLB->GetSelectTextEncoding() != rHtmlOpt.GetTextEncoding() )
+ m_xCharSetLB->SelectTextEncoding( rHtmlOpt.GetTextEncoding() );
+}
+
+IMPL_LINK(OfaHtmlTabPage, CheckBoxHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ m_xStarBasicWarningCB->set_sensitive(!rBox.get_active());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.hxx b/cui/source/options/opthtml.hxx
new file mode 100644
index 000000000..0468518f1
--- /dev/null
+++ b/cui/source/options/opthtml.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_CUI_SOURCE_OPTIONS_OPTHTML_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTHTML_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/txencbox.hxx>
+
+class OfaHtmlTabPage : public SfxTabPage
+{
+
+ std::unique_ptr<weld::SpinButton> m_xSize1NF;
+ std::unique_ptr<weld::SpinButton> m_xSize2NF;
+ std::unique_ptr<weld::SpinButton> m_xSize3NF;
+ std::unique_ptr<weld::SpinButton> m_xSize4NF;
+ std::unique_ptr<weld::SpinButton> m_xSize5NF;
+ std::unique_ptr<weld::SpinButton> m_xSize6NF;
+ std::unique_ptr<weld::SpinButton> m_xSize7NF;
+
+ std::unique_ptr<weld::CheckButton> m_xNumbersEnglishUSCB;
+ std::unique_ptr<weld::CheckButton> m_xUnknownTagCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreFontNamesCB;
+
+ std::unique_ptr<weld::CheckButton> m_xStarBasicCB;
+ std::unique_ptr<weld::CheckButton> m_xStarBasicWarningCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintExtensionCB;
+ std::unique_ptr<weld::CheckButton> m_xSaveGrfLocalCB;
+ std::unique_ptr<SvxTextEncodingBox> m_xCharSetLB;
+
+ DECL_LINK(CheckBoxHdl_Impl, weld::ToggleButton&, void);
+
+public:
+ OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaHtmlTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+};
+
+
+#endif
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.cxx b/cui/source/options/optinet2.cxx
new file mode 100644
index 000000000..0644d84ec
--- /dev/null
+++ b/cui/source/options/optinet2.cxx
@@ -0,0 +1,936 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <officecfg/Inet.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/securityoptions.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <dialmgr.hxx>
+#include "optinet2.hxx"
+#include <strings.hrc>
+
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+
+#include <sal/types.h>
+#include <sal/log.hxx>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include "securityoptions.hxx"
+#include "webconninfo.hxx"
+#include "certpath.hxx"
+#include "tsaurls.hxx"
+
+#include <svtools/restartdialog.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sfx2;
+
+namespace {
+
+bool isValidPort(OUString const & value) {
+ if (!comphelper::string::isdigitAsciiString(value)) {
+ return false;
+ }
+ auto const n = value.toUInt64();
+ if (n > 65535) {
+ return false;
+ }
+ if (n != 0) {
+ return true;
+ }
+ // Overflow in OUString::toUInt64 returns 0, so need to check value contains only zeroes:
+ return std::u16string_view(value).find_first_not_of(u'0') == std::u16string_view::npos;
+}
+
+}
+
+IMPL_LINK(SvxProxyTabPage, PortChangedHdl, weld::Entry&, rEdit, void)
+{
+ if (!isValidPort(rEdit.get_text()))
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId( RID_SVXSTR_OPT_PROXYPORTS)));
+ xErrorBox->run();
+ }
+}
+
+static const char g_aProxyModePN[] = "ooInetProxyType";
+static const char g_aHttpProxyPN[] = "ooInetHTTPProxyName";
+static const char g_aHttpPortPN[] = "ooInetHTTPProxyPort";
+static const char g_aHttpsProxyPN[] = "ooInetHTTPSProxyName";
+static const char g_aHttpsPortPN[] = "ooInetHTTPSProxyPort";
+static const char g_aFtpProxyPN[] = "ooInetFTPProxyName";
+static const char g_aFtpPortPN[] = "ooInetFTPProxyPort";
+static const char g_aNoProxyDescPN[] = "ooInetNoProxy";
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, rTest, bool)
+{
+ OUStringBuffer sAllowed;
+ for (sal_Int32 i = 0, nLen = rTest.getLength(); i < nLen; ++i)
+ {
+ if (rTest[i] >= '0' && rTest[i] <= '9')
+ sAllowed.append(rTest[i]);
+ }
+ rTest = sAllowed.makeStringAndClear();
+ return true;
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = rTest.replaceAll(" ", "");
+ return true;
+}
+
+/********************************************************************/
+/* */
+/* SvxProxyTabPage */
+/* */
+/********************************************************************/
+SvxProxyTabPage::SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optproxypage.ui", "OptProxyPage", &rSet)
+ , m_xProxyModeLB(m_xBuilder->weld_combo_box("proxymode"))
+ , m_xHttpProxyFT(m_xBuilder->weld_label("httpft"))
+ , m_xHttpProxyED(m_xBuilder->weld_entry("http"))
+ , m_xHttpPortFT(m_xBuilder->weld_label("httpportft"))
+ , m_xHttpPortED(m_xBuilder->weld_entry("httpport"))
+ , m_xHttpsProxyFT(m_xBuilder->weld_label("httpsft"))
+ , m_xHttpsProxyED(m_xBuilder->weld_entry("https"))
+ , m_xHttpsPortFT(m_xBuilder->weld_label("httpsportft"))
+ , m_xHttpsPortED(m_xBuilder->weld_entry("httpsport"))
+ , m_xFtpProxyFT(m_xBuilder->weld_label("ftpft"))
+ , m_xFtpProxyED(m_xBuilder->weld_entry("ftp"))
+ , m_xFtpPortFT(m_xBuilder->weld_label("ftpportft"))
+ , m_xFtpPortED(m_xBuilder->weld_entry("ftpport"))
+ , m_xNoProxyForFT(m_xBuilder->weld_label("noproxyft"))
+ , m_xNoProxyForED(m_xBuilder->weld_entry("noproxy"))
+ , m_xNoProxyDescFT(m_xBuilder->weld_label("noproxydesc"))
+{
+ m_xHttpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xHttpsProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpsPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpsPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xFtpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xFtpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xFtpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+
+ Link<weld::Widget&,void> aLink = LINK( this, SvxProxyTabPage, LoseFocusHdl_Impl );
+ m_xHttpPortED->connect_focus_out( aLink );
+ m_xHttpsPortED->connect_focus_out( aLink );
+ m_xFtpPortED->connect_focus_out( aLink );
+
+ m_xProxyModeLB->connect_changed(LINK( this, SvxProxyTabPage, ProxyHdl_Impl ));
+
+ Reference< css::lang::XMultiServiceFactory >
+ xConfigurationProvider(
+ configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext() ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString( "org.openoffice.Inet/Settings" );
+
+ Sequence< Any > aArgumentList( 1 );
+ aArgumentList[0] <<= aProperty;
+
+ m_xConfigurationUpdateAccess = xConfigurationProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgumentList );
+}
+
+SvxProxyTabPage::~SvxProxyTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxProxyTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxProxyTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxProxyTabPage::ReadConfigData_Impl()
+{
+ sal_Int32 nIntValue = 0;
+
+ std::optional<sal_Int32> x(officecfg::Inet::Settings::ooInetProxyType::get());
+ if (x)
+ {
+ nIntValue = *x;
+ m_xProxyModeLB->set_active(nIntValue);
+ }
+
+ m_xHttpProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ m_xHttpsProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPSProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPSProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ m_xFtpProxyED->set_text( officecfg::Inet::Settings::ooInetFTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetFTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ m_xNoProxyForED->set_text( officecfg::Inet::Settings::ooInetNoProxy::get() );
+}
+
+void SvxProxyTabPage::ReadConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ sal_Int32 nIntValue = 0;
+ OUString aStringValue;
+
+ if( xPropertyState->getPropertyDefault(g_aHttpProxyPN) >>= aStringValue )
+ {
+ m_xHttpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpPortPN) >>= nIntValue )
+ {
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsProxyPN) >>= aStringValue )
+ {
+ m_xHttpsProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsPortPN) >>= nIntValue )
+ {
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpProxyPN) >>= aStringValue )
+ {
+ m_xFtpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpPortPN) >>= nIntValue )
+ {
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aNoProxyDescPN) >>= aStringValue )
+ {
+ m_xNoProxyForED->set_text( aStringValue );
+ }
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ SAL_WARN("cui.options", "SvxProxyTabPage::ReadConfigDefaults_Impl: UnknownPropertyException caught" );
+ }
+ catch (const css::lang::WrappedTargetException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::ReadConfigDefaults_Impl: WrappedTargetException caught" );
+ }
+ catch (const RuntimeException &)
+ {
+ SAL_WARN("cui.options", "SvxProxyTabPage::ReadConfigDefaults_Impl: RuntimeException caught" );
+ }
+}
+
+void SvxProxyTabPage::RestoreConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ xPropertyState->setPropertyToDefault(g_aProxyModePN);
+ xPropertyState->setPropertyToDefault(g_aHttpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpPortPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsPortPN);
+ xPropertyState->setPropertyToDefault(g_aFtpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aFtpPortPN);
+ xPropertyState->setPropertyToDefault(g_aNoProxyDescPN);
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ SAL_WARN("cui.options", "SvxProxyTabPage::RestoreConfigDefaults_Impl: UnknownPropertyException caught" );
+ }
+ catch (const css::lang::WrappedTargetException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::RestoreConfigDefaults_Impl: WrappedTargetException caught" );
+ }
+ catch (const RuntimeException &)
+ {
+ SAL_WARN("cui.options", "SvxProxyTabPage::RestoreConfigDefaults_Impl: RuntimeException caught" );
+ }
+}
+
+void SvxProxyTabPage::Reset(const SfxItemSet*)
+{
+ ReadConfigData_Impl();
+
+ m_xProxyModeLB->save_value();
+ m_xHttpProxyED->save_value();
+ m_xHttpPortED->save_value();
+ m_xHttpsProxyED->save_value();
+ m_xHttpsPortED->save_value();
+ m_xFtpProxyED->save_value();
+ m_xFtpPortED->save_value();
+ m_xNoProxyForED->save_value();
+
+ EnableControls_Impl();
+}
+
+bool SvxProxyTabPage::FillItemSet(SfxItemSet* )
+{
+ bool bModified = false;
+
+ try {
+ Reference< beans::XPropertySet > xPropertySet(m_xConfigurationUpdateAccess, UNO_QUERY_THROW );
+
+ sal_Int32 nSelPos = m_xProxyModeLB->get_active();
+ if(m_xProxyModeLB->get_value_changed_from_saved())
+ {
+ if( nSelPos == 1 )
+ {
+ RestoreConfigDefaults_Impl();
+ return true;
+ }
+
+ xPropertySet->setPropertyValue(g_aProxyModePN, Any(nSelPos));
+ bModified = true;
+ }
+
+ if(m_xHttpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpProxyPN, Any(m_xHttpProxyED->get_text()));
+ bModified = true;
+ }
+
+ if ( m_xHttpPortED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpPortPN, Any(m_xHttpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if( m_xHttpsProxyED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsProxyPN, Any(m_xHttpsProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xHttpsPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsPortPN, Any(m_xHttpsPortED->get_text().toInt32()) );
+ bModified = true;
+ }
+
+ if( m_xFtpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aFtpProxyPN, Any(m_xFtpProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xFtpPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aFtpPortPN, Any(m_xFtpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if ( m_xNoProxyForED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aNoProxyDescPN, Any( m_xNoProxyForED->get_text()));
+ bModified = true;
+ }
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const css::lang::IllegalArgumentException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::FillItemSet: IllegalArgumentException caught" );
+ }
+ catch (const beans::UnknownPropertyException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::FillItemSet: UnknownPropertyException caught" );
+ }
+ catch (const beans::PropertyVetoException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::FillItemSet: PropertyVetoException caught" );
+ }
+ catch (const css::lang::WrappedTargetException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::FillItemSet: WrappedTargetException caught" );
+ }
+ catch (const RuntimeException &) {
+ SAL_WARN("cui.options", "SvxProxyTabPage::FillItemSet: RuntimeException caught" );
+ }
+
+ return bModified;
+}
+
+void SvxProxyTabPage::EnableControls_Impl()
+{
+ m_xProxyModeLB->set_sensitive(!officecfg::Inet::Settings::ooInetNoProxy::isReadOnly());
+
+ const bool bManualConfig = m_xProxyModeLB->get_active() == 2;
+
+ const bool bHTTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyName::isReadOnly();
+ const bool bHTTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyPort::isReadOnly();
+ m_xHttpProxyFT->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpProxyED->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpPortFT->set_sensitive(bHTTPProxyPortEnabled);
+ m_xHttpPortED->set_sensitive(bHTTPProxyPortEnabled);
+
+ const bool bHTTPSProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyName::isReadOnly();
+ const bool bHTTPSProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyPort::isReadOnly();
+ m_xHttpsProxyFT->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsProxyED->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsPortFT->set_sensitive(bHTTPSProxyPortEnabled);
+ m_xHttpsPortED->set_sensitive(bHTTPSProxyPortEnabled);
+
+ const bool bFTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyName::isReadOnly();
+ const bool bFTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyPort::isReadOnly();
+ m_xFtpProxyFT->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpProxyED->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpPortFT->set_sensitive(bFTPProxyPortEnabled);
+ m_xFtpPortED->set_sensitive(bFTPProxyPortEnabled);
+
+ const bool bInetNoProxyEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetNoProxy::isReadOnly();
+ m_xNoProxyForFT->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyForED->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyDescFT->set_sensitive(bInetNoProxyEnabled);
+}
+
+IMPL_LINK(SvxProxyTabPage, ProxyHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+
+ // Restore original system values
+ if( nPos == 1 )
+ {
+ ReadConfigDefaults_Impl();
+ }
+
+ EnableControls_Impl();
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, rControl, void)
+{
+ weld::Entry* pEdit = dynamic_cast<weld::Entry*>(&rControl);
+ if (pEdit && !isValidPort(pEdit->get_text()))
+ pEdit->set_text(OUString('0'));
+}
+
+/********************************************************************/
+/* */
+/* SvxSecurityTabPage */
+/* */
+/********************************************************************/
+SvxSecurityTabPage::SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optsecuritypage.ui", "OptSecurityPage", &rSet)
+ , mpSecOptions(new SvtSecurityOptions)
+ , m_xSecurityOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xSavePasswordsCB(m_xBuilder->weld_check_button("savepassword"))
+ , m_xShowConnectionsPB(m_xBuilder->weld_button("connections"))
+ , m_xMasterPasswordCB(m_xBuilder->weld_check_button("usemasterpassword"))
+ , m_xMasterPasswordFT(m_xBuilder->weld_label("masterpasswordtext"))
+ , m_xMasterPasswordPB(m_xBuilder->weld_button("masterpassword"))
+ , m_xMacroSecFrame(m_xBuilder->weld_container("macrosecurity"))
+ , m_xMacroSecPB(m_xBuilder->weld_button("macro"))
+ , m_xCertFrame(m_xBuilder->weld_container("certificatepath"))
+ , m_xCertPathPB(m_xBuilder->weld_button("cert"))
+ , m_xTSAURLsFrame(m_xBuilder->weld_container("tsaurls"))
+ , m_xTSAURLsPB(m_xBuilder->weld_button("tsas"))
+ , m_xNoPasswordSaveFT(m_xBuilder->weld_label("nopasswordsave"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xSavePasswordsCB->get_preferred_size());
+ int nMaxWidth = m_xSavePasswordsCB->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xSavePasswordsCB->set_label_line_wrap(true);
+ m_xSavePasswordsCB->set_size_request(nMaxWidth, -1);
+ }
+
+ m_sPasswordStoringDeactivateStr = m_xNoPasswordSaveFT->get_label();
+
+ InitControls();
+
+ m_xSecurityOptionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, SecurityOptionsHdl ) );
+ m_xSavePasswordsCB->connect_clicked( LINK( this, SvxSecurityTabPage, SavePasswordHdl ) );
+ m_xMasterPasswordPB->connect_clicked( LINK( this, SvxSecurityTabPage, MasterPasswordHdl ) );
+ m_xMasterPasswordCB->connect_clicked( LINK( this, SvxSecurityTabPage, MasterPasswordCBHdl ) );
+ m_xShowConnectionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, ShowPasswordsHdl ) );
+ m_xMacroSecPB->connect_clicked( LINK( this, SvxSecurityTabPage, MacroSecPBHdl ) );
+ m_xCertPathPB->connect_clicked( LINK( this, SvxSecurityTabPage, CertPathPBHdl ) );
+ m_xTSAURLsPB->connect_clicked( LINK( this, SvxSecurityTabPage, TSAURLsPBHdl ) );
+
+ ActivatePage( rSet );
+}
+
+SvxSecurityTabPage::~SvxSecurityTabPage()
+{
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SecurityOptionsHdl, weld::Button&, void)
+{
+ if (!m_xSecOptDlg)
+ m_xSecOptDlg.reset(new svx::SecurityOptionsDialog(GetFrameWeld(), mpSecOptions.get()));
+ m_xSecOptDlg->run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SavePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( m_xSavePasswordsCB->get_active() )
+ {
+ bool bOldValue = xMasterPasswd->allowPersistentStoring( true );
+ xMasterPasswd->removeMasterPassword();
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->changeMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ else
+ {
+ xMasterPasswd->allowPersistentStoring( bOldValue );
+ m_xSavePasswordsCB->set_active( false );
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_sPasswordStoringDeactivateStr));
+ xQueryBox->set_default_response(RET_NO);
+
+ sal_uInt16 nRet = xQueryBox->run();
+
+ if( RET_YES == nRet )
+ {
+ xMasterPasswd->allowPersistentStoring( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+ }
+ else
+ {
+ m_xSavePasswordsCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+ xMasterPasswd->changeMasterPassword(xTmpHandler);
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordCBHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( m_xMasterPasswordCB->get_active() )
+ {
+ if (xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->changeMasterPassword(xTmpHandler))
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active( false );
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ else
+ {
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->useDefaultMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, ShowPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->authorizateWithMasterPassword(xTmpHandler) )
+ {
+ svx::WebConnectionInfoDialog aDlg(GetFrameWeld());
+ aDlg.run();
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, CertPathPBHdl, weld::Button&, void)
+{
+ if (!mpCertPathDlg)
+ mpCertPathDlg.reset(new CertPathDialog(GetFrameWeld()));
+
+ OUString sOrig = mpCertPathDlg->getDirectory();
+ short nRet = mpCertPathDlg->run();
+
+ if (nRet == RET_OK && sOrig != mpCertPathDlg->getDirectory())
+ {
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, svtools::RESTART_REASON_ADDING_PATH))
+ GetDialogController()->response(RET_OK);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, TSAURLsPBHdl, weld::Button&, void)
+{
+ // Unlike the mpCertPathDlg, we *don't* keep the same dialog object around between
+ // invocations. Seems clearer to my little brain that way.
+ TSAURLsDialog aTSAURLsDlg(GetFrameWeld());
+ aTSAURLsDlg.run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MacroSecPBHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< security::XDocumentDigitalSignatures > xD(
+ security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext() ) );
+ xD->setParentWindow(GetDialogController()->getDialog()->GetXWindow());
+ xD->manageTrustedSources();
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "");
+ }
+}
+
+void SvxSecurityTabPage::InitControls()
+{
+#ifndef UNX
+ m_xCertFrame->hide();
+#endif
+
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+
+ // initialize the password saving checkbox
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ m_xSavePasswordsCB->set_active(true);
+
+ if ( xMasterPasswd->isDefaultMasterPasswordUsed() )
+ m_xMasterPasswordCB->set_active( false );
+ else
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_sensitive( false );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSecurityTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxSecurityTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSecurityTabPage::ActivatePage( const SfxItemSet& )
+{
+}
+
+DeactivateRC SvxSecurityTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+ bool CheckAndSave( SvtSecurityOptions& _rOpt, SvtSecurityOptions::EOption _eOpt, const bool _bIsChecked, bool& _rModfied )
+ {
+ bool bModified = false;
+ if ( _rOpt.IsOptionEnabled( _eOpt ) )
+ {
+ bModified = _rOpt.IsOptionSet( _eOpt ) != _bIsChecked;
+ if ( bModified )
+ {
+ _rOpt.SetOption( _eOpt, _bIsChecked );
+ _rModfied = true;
+ }
+ }
+
+ return bModified;
+ }
+}
+
+bool SvxSecurityTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ if (m_xSecOptDlg)
+ {
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnSaveOrSend, m_xSecOptDlg->IsSaveOrSendDocsChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnSigning, m_xSecOptDlg->IsSignDocsChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnPrint, m_xSecOptDlg->IsPrintDocsChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnCreatePdf, m_xSecOptDlg->IsCreatePdfChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, m_xSecOptDlg->IsRemovePersInfoChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::DocWarnRecommendPassword, m_xSecOptDlg->IsRecommPasswdChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::CtrlClickHyperlink, m_xSecOptDlg->IsCtrlHyperlinkChecked(), bModified );
+ CheckAndSave( *mpSecOptions, SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, m_xSecOptDlg->IsBlockUntrustedRefererLinksChecked(), bModified );
+ }
+
+ return bModified;
+}
+
+/*--------------------------------------------------------------------*/
+
+void SvxSecurityTabPage::Reset( const SfxItemSet* )
+{
+}
+
+struct SvxEMailTabPage_Impl
+{
+ SvxEMailTabPage_Impl():
+ sProgram(officecfg::Office::Common::ExternalMailer::Program::get()),
+ bROProgram(
+ officecfg::Office::Common::ExternalMailer::Program::isReadOnly()),
+ bHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::get()),
+ bROHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::isReadOnly())
+ {}
+
+ OUString sProgram;
+ bool bROProgram;
+ bool bHideContent;
+ bool bROHideContent;
+};
+
+SvxEMailTabPage::SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optemailpage.ui", "OptEmailPage", &rSet)
+ , pImpl(new SvxEMailTabPage_Impl)
+ , m_xMailContainer(m_xBuilder->weld_container("program"))
+ , m_xMailerURLFI(m_xBuilder->weld_image("lockemail"))
+ , m_xMailerURLED(m_xBuilder->weld_entry("url"))
+ , m_xMailerURLPB(m_xBuilder->weld_button("browse"))
+ , m_xSuppressHiddenContainer(m_xBuilder->weld_container("suppressHiddenCont"))
+ , m_xSuppressHiddenFI(m_xBuilder->weld_image("lockSuppressHidden"))
+ , m_xSuppressHidden(m_xBuilder->weld_check_button("suppressHidden"))
+ , m_xDefaultFilterFT(m_xBuilder->weld_label("browsetitle"))
+{
+ m_sDefaultFilterName = m_xDefaultFilterFT->get_label();
+ m_xMailerURLPB->connect_clicked( LINK( this, SvxEMailTabPage, FileDialogHdl_Impl ) );
+}
+
+/* -------------------------------------------------------------------------*/
+
+SvxEMailTabPage::~SvxEMailTabPage()
+{
+}
+
+/* -------------------------------------------------------------------------*/
+
+std::unique_ptr<SfxTabPage> SvxEMailTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxEMailTabPage>(pPage, pController, *rAttrSet);
+}
+
+/* -------------------------------------------------------------------------*/
+
+bool SvxEMailTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (!pImpl->bROProgram && m_xMailerURLED->get_value_changed_from_saved())
+ {
+ pImpl->sProgram = m_xMailerURLED->get_text();
+ officecfg::Office::Common::ExternalMailer::Program::set(
+ pImpl->sProgram, batch);
+ }
+ if (!pImpl->bROHideContent
+ && pImpl->bHideContent != m_xSuppressHidden->get_active())
+ {
+ pImpl->bHideContent = m_xSuppressHidden->get_active();
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::set(
+ pImpl->bHideContent, batch);
+ }
+ batch->commit();
+ return false;
+}
+
+/* -------------------------------------------------------------------------*/
+
+void SvxEMailTabPage::Reset( const SfxItemSet* )
+{
+ m_xMailerURLED->set_sensitive(true);
+ m_xMailerURLPB->set_sensitive(true);
+
+ if (pImpl->bROProgram)
+ m_xMailerURLFI->show();
+
+ m_xMailerURLED->set_text(pImpl->sProgram);
+ m_xMailerURLED->save_value();
+
+ m_xMailContainer->set_sensitive(!pImpl->bROProgram);
+
+ if (pImpl->bROHideContent)
+ m_xSuppressHiddenFI->show();
+
+ m_xSuppressHidden->set_active(pImpl->bHideContent);
+
+ m_xSuppressHiddenContainer->set_sensitive(!pImpl->bROHideContent);
+}
+
+/* -------------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxEMailTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ if (pImpl->bROProgram)
+ return;
+
+ FileDialogHelper aHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString sPath = m_xMailerURLED->get_text();
+ if ( sPath.isEmpty() )
+ sPath = "/usr/bin";
+
+ OUString sUrl;
+ osl::FileBase::getFileURLFromSystemPath(sPath, sUrl);
+ aHelper.SetDisplayDirectory(sUrl);
+ aHelper.AddFilter( m_sDefaultFilterName, "*");
+
+ if ( ERRCODE_NONE == aHelper.Execute() )
+ {
+ sUrl = aHelper.GetPath();
+ if (osl::FileBase::getSystemPathFromFileURL(sUrl, sPath)
+ != osl::FileBase::E_None)
+ {
+ sPath.clear();
+ }
+ m_xMailerURLED->set_text(sPath);
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.hxx b/cui/source/options/optinet2.hxx
new file mode 100644
index 000000000..4d434ce8d
--- /dev/null
+++ b/cui/source/options/optinet2.hxx
@@ -0,0 +1,163 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_OPTIONS_OPTINET2_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTINET2_HXX
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+namespace svx {
+ class SecurityOptionsDialog;
+}
+
+// class SvxProxyTabPage -------------------------------------------------
+class SvxProxyTabPage : public SfxTabPage
+{
+private:
+
+ std::unique_ptr<weld::ComboBox> m_xProxyModeLB;
+
+ std::unique_ptr<weld::Label> m_xHttpProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpProxyED;
+ std::unique_ptr<weld::Label> m_xHttpPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpPortED;
+
+ std::unique_ptr<weld::Label> m_xHttpsProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpsProxyED;
+ std::unique_ptr<weld::Label> m_xHttpsPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpsPortED;
+
+ std::unique_ptr<weld::Label> m_xFtpProxyFT;
+ std::unique_ptr<weld::Entry> m_xFtpProxyED;
+ std::unique_ptr<weld::Label> m_xFtpPortFT;
+ std::unique_ptr<weld::Entry> m_xFtpPortED;
+
+ std::unique_ptr<weld::Label> m_xNoProxyForFT;
+ std::unique_ptr<weld::Entry> m_xNoProxyForED;
+ std::unique_ptr<weld::Label> m_xNoProxyDescFT;
+
+ css::uno::Reference< css::uno::XInterface > m_xConfigurationUpdateAccess;
+
+ void EnableControls_Impl();
+ void ReadConfigData_Impl();
+ void ReadConfigDefaults_Impl();
+ void RestoreConfigDefaults_Impl();
+
+ DECL_LINK(PortChangedHdl, weld::Entry&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, bool);
+ DECL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, bool);
+ DECL_LINK(ProxyHdl_Impl, weld::ComboBox&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, void);
+
+public:
+ SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxProxyTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+// class SvxSecurityTabPage ---------------------------------------------
+
+class SvtSecurityOptions;
+class CertPathDialog;
+class SvxSecurityTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvtSecurityOptions> mpSecOptions;
+ std::unique_ptr<svx::SecurityOptionsDialog> m_xSecOptDlg;
+
+ std::unique_ptr<CertPathDialog> mpCertPathDlg;
+
+ OUString m_sPasswordStoringDeactivateStr;
+
+ std::unique_ptr<weld::Button> m_xSecurityOptionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xSavePasswordsCB;
+ std::unique_ptr<weld::Button> m_xShowConnectionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xMasterPasswordCB;
+ std::unique_ptr<weld::Label> m_xMasterPasswordFT;
+ std::unique_ptr<weld::Button> m_xMasterPasswordPB;
+
+ std::unique_ptr<weld::Container> m_xMacroSecFrame;
+ std::unique_ptr<weld::Button> m_xMacroSecPB;
+
+ std::unique_ptr<weld::Container> m_xCertFrame;
+ std::unique_ptr<weld::Button> m_xCertPathPB;
+
+ std::unique_ptr<weld::Container> m_xTSAURLsFrame;
+ std::unique_ptr<weld::Button> m_xTSAURLsPB;
+
+ std::unique_ptr<weld::Label> m_xNoPasswordSaveFT;
+
+ DECL_LINK(SecurityOptionsHdl, weld::Button&, void);
+ DECL_LINK(SavePasswordHdl, weld::Button&, void);
+ DECL_LINK(MasterPasswordHdl, weld::Button&, void);
+ DECL_LINK(MasterPasswordCBHdl, weld::Button&, void);
+ DECL_LINK(ShowPasswordsHdl, weld::Button&, void);
+ DECL_LINK(MacroSecPBHdl, weld::Button&, void );
+ DECL_LINK(CertPathPBHdl, weld::Button&, void );
+ DECL_LINK(TSAURLsPBHdl, weld::Button&, void );
+
+ void InitControls();
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~SvxSecurityTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct SvxEMailTabPage_Impl;
+class SvxEMailTabPage : public SfxTabPage
+{
+ OUString m_sDefaultFilterName;
+
+ std::unique_ptr<SvxEMailTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::Container> m_xMailContainer;
+ std::unique_ptr<weld::Image> m_xMailerURLFI;
+ std::unique_ptr<weld::Entry> m_xMailerURLED;
+ std::unique_ptr<weld::Button> m_xMailerURLPB;
+ std::unique_ptr<weld::Container> m_xSuppressHiddenContainer;
+ std::unique_ptr<weld::Image> m_xSuppressHiddenFI;
+ std::unique_ptr<weld::CheckButton> m_xSuppressHidden;
+ std::unique_ptr<weld::Label> m_xDefaultFilterFT;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+
+public:
+ SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~SvxEMailTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_OPTINET2_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
new file mode 100644
index 000000000..f3c9dcfee
--- /dev/null
+++ b/cui/source/options/optjava.cxx
@@ -0,0 +1,941 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <memory>
+#include <vector>
+
+#include <config_java.h>
+
+#include "optaboutconfig.hxx"
+#include "optjava.hxx"
+#include <treeopt.hxx>
+#include <dialmgr.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <svtools/miscopt.hxx>
+
+#include <strings.hrc>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/imagemgr.hxx>
+#include <svtools/restartdialog.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/inputdlg.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ucb/XContentProvider.hpp>
+#if HAVE_FEATURE_JAVA
+#include <jvmfwk/framework.hxx>
+#endif
+
+// define ----------------------------------------------------------------
+
+#define CLASSPATH_DELIMITER SAL_PATHSEPARATOR
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+SvxJavaOptionsPage::SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optadvancedpage.ui", "OptAdvancedPage", &rSet)
+ , m_aResetIdle("cui options SvxJavaOptionsPage Reset")
+ , xDialogListener(new ::svt::DialogClosedListener())
+ , m_xJavaEnableCB(m_xBuilder->weld_check_button("javaenabled"))
+ , m_xJavaList(m_xBuilder->weld_tree_view("javas"))
+ , m_xJavaPathText(m_xBuilder->weld_label("javapath"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xParameterBtn(m_xBuilder->weld_button("parameters"))
+ , m_xClassPathBtn(m_xBuilder->weld_button("classpath"))
+ , m_xExpertConfigBtn(m_xBuilder->weld_button("expertconfig"))
+ , m_xExperimentalCB(m_xBuilder->weld_check_button("experimental"))
+ , m_xMacroCB(m_xBuilder->weld_check_button("macrorecording"))
+ , m_xAddDialogText(m_xBuilder->weld_label("selectruntime"))
+ , m_xJavaFrame(m_xBuilder->weld_widget("javaframe"))
+{
+ m_sInstallText = m_xJavaPathText->get_label();
+ m_sAddDialogText = m_xAddDialogText->get_label();
+
+ m_xJavaList->set_size_request(m_xJavaList->get_approximate_digit_width() * 30,
+ m_xJavaList->get_height_rows(8));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xJavaList->get_checkbox_column_width());
+ aWidths.push_back(m_xJavaList->get_pixel_size("Sun Microsystems Inc.").Width());
+ m_xJavaList->set_column_fixed_widths(aWidths);
+
+ std::vector<int> aRadioColumns;
+ aRadioColumns.push_back(0);
+ m_xJavaList->set_toggle_columns_as_radio(aRadioColumns);
+
+ m_xJavaEnableCB->connect_clicked( LINK( this, SvxJavaOptionsPage, EnableHdl_Impl ) );
+ m_xJavaList->connect_toggled( LINK( this, SvxJavaOptionsPage, CheckHdl_Impl ) );
+ m_xJavaList->connect_changed( LINK( this, SvxJavaOptionsPage, SelectHdl_Impl ) );
+ m_xAddBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, AddHdl_Impl ) );
+ m_xParameterBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ParameterHdl_Impl ) );
+ m_xClassPathBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ClassPathHdl_Impl ) );
+ m_aResetIdle.SetInvokeHandler( LINK( this, SvxJavaOptionsPage, ResetHdl_Impl ) );
+
+ m_xExpertConfigBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ExpertConfigHdl_Impl) );
+ if (!officecfg::Office::Common::Security::EnableExpertConfiguration::get())
+ m_xExpertConfigBtn->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::MacroRecorderMode::isReadOnly())
+ m_xMacroCB->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::ExperimentalMode::isReadOnly())
+ m_xExperimentalCB->set_sensitive(false);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxJavaOptionsPage, DialogClosedHdl ) );
+
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#if HAVE_FEATURE_JAVA
+ jfw_lock();
+#else
+ m_xJavaFrame->set_sensitive(false);
+#endif
+}
+
+SvxJavaOptionsPage::~SvxJavaOptionsPage()
+{
+ ClearJavaInfo();
+#if HAVE_FEATURE_JAVA
+ m_aAddedInfos.clear();
+
+ jfw_unlock();
+#endif
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, EnableHdl_Impl, weld::Button&, void)
+{
+ bool bEnable = m_xJavaEnableCB->get_active();
+ m_xJavaList->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxJavaOptionsPage, CheckHdl_Impl, const row_col&, rRowCol, void)
+{
+ HandleCheckEntry(rRowCol.first);
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, SelectHdl_Impl, weld::TreeView&, void)
+{
+ UpdateJavaPathText();
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, AddHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = FolderPicker::create(xContext);
+
+ OUString sWorkFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sWorkFolder );
+ xFolderPicker->setDescription( m_sAddDialogText );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener.get() );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::AddHdl_Impl()");
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ParameterHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ std::vector< OUString > aParameterList;
+ if (!m_xParamDlg)
+ {
+ m_xParamDlg.reset(new SvxJavaParameterDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getVMParameters( &m_parParameters );
+ if ( JFW_E_NONE == eErr && !m_parParameters.empty() )
+ {
+ aParameterList = m_parParameters;
+ m_xParamDlg->SetParameters( aParameterList );
+ }
+ }
+ else
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ m_xParamDlg->DisableButtons(); //disable add, edit and remove button when dialog is reopened
+ }
+
+ if (m_xParamDlg->run() == RET_OK)
+ {
+ if ( aParameterList != m_xParamDlg->GetParameters() )
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_JAVAPARAMETERS );
+ }
+ }
+ }
+ else
+ m_xParamDlg->SetParameters( aParameterList );
+#else
+ (void) this; // Silence loplugin:staticmethods
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ClassPathHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ OUString sClassPath;
+
+ if ( !m_xPathDlg )
+ {
+ m_xPathDlg.reset(new SvxJavaClassPathDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getUserClassPath( &m_pClassPath );
+ if ( JFW_E_NONE == eErr )
+ {
+ sClassPath = m_pClassPath;
+ m_xPathDlg->SetClassPath( sClassPath );
+ }
+ }
+ else
+ sClassPath = m_xPathDlg->GetClassPath();
+
+ m_xPathDlg->SetFocus();
+ if (m_xPathDlg->run() == RET_OK)
+ {
+
+ if (m_xPathDlg->GetClassPath() != sClassPath)
+ {
+ sClassPath = m_xPathDlg->GetClassPath();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_FOLDERS );
+ }
+ }
+ }
+ else
+ m_xPathDlg->SetClassPath( sClassPath );
+#else
+ (void) this;
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ResetHdl_Impl, Timer *, void)
+{
+ LoadJREs();
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, StartFolderPickerHdl, void*, void)
+{
+ try
+ {
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener.get() );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::StartFolderPickerHdl()" );
+ }
+}
+
+IMPL_LINK( SvxJavaOptionsPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if ( RET_OK == pEvt->DialogResult )
+ {
+ DBG_ASSERT( xFolderPicker.is(), "SvxJavaOptionsPage::DialogClosedHdl(): no folder picker" );
+
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ExpertConfigHdl_Impl, weld::Button&, void)
+{
+ CuiAboutConfigTabPage aExpertConfigDlg(GetFrameWeld());
+ {
+ weld::WaitObject aWait(GetFrameWeld());
+ aExpertConfigDlg.Reset();//initialize and reset function
+ }
+
+ if (RET_OK == aExpertConfigDlg.run())
+ {
+ aExpertConfigDlg.FillItemSet();//save changes if there are any
+ }
+}
+
+void SvxJavaOptionsPage::ClearJavaInfo()
+{
+#if HAVE_FEATURE_JAVA
+ m_parJavaInfo.clear();
+#else
+ (void) this;
+#endif
+}
+
+void SvxJavaOptionsPage::LoadJREs()
+{
+#if HAVE_FEATURE_JAVA
+ weld::WaitObject aWaitObj(GetFrameWeld());
+ javaFrameworkError eErr = jfw_findAllJREs( &m_parJavaInfo );
+ if ( JFW_E_NONE == eErr )
+ {
+ for (auto const & pInfo: m_parJavaInfo)
+ {
+ AddJRE( pInfo.get() );
+ }
+ }
+
+ for (auto const & pInfo: m_aAddedInfos)
+ {
+ AddJRE( pInfo.get() );
+ }
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( !(JFW_E_NONE == eErr && pSelectedJava) )
+ return;
+
+ sal_Int32 i = 0;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pSelectedJava.get() ) )
+ {
+ HandleCheckEntry(i);
+ UpdateJavaPathText();
+ break;
+ }
+ ++i;
+ }
+#else
+ (void) this;
+#endif
+}
+
+
+void SvxJavaOptionsPage::AddJRE( JavaInfo const * _pInfo )
+{
+#if HAVE_FEATURE_JAVA
+ int nPos = m_xJavaList->n_children();
+ m_xJavaList->append();
+ m_xJavaList->set_toggle(nPos, TRISTATE_FALSE, 0);
+ m_xJavaList->set_text(nPos, _pInfo->sVendor, 1);
+ m_xJavaList->set_text(nPos, _pInfo->sVersion, 2);
+
+ INetURLObject aLocObj(_pInfo->sLocation);
+ OUString sLocation = aLocObj.getFSysPath(FSysStyle::Detect);
+ m_xJavaList->set_id(nPos, sLocation);
+#else
+ (void) this;
+ (void)_pInfo;
+#endif
+}
+
+void SvxJavaOptionsPage::HandleCheckEntry(int nCheckedRow)
+{
+ m_xJavaList->select(nCheckedRow);
+ for (int i = 0, nCount = m_xJavaList->n_children(); i < nCount; ++i)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xJavaList->set_toggle(i, i == nCheckedRow ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ }
+}
+
+void SvxJavaOptionsPage::UpdateJavaPathText()
+{
+ assert(m_xJavaList->get_selected_index() != -1);
+ // set installation directory info
+ OUString sLocation = m_xJavaList->get_selected_id();
+ // tdf#80646 insert LTR mark after label
+ OUString sInfo = m_sInstallText + u"\u200E" + sLocation;
+ m_xJavaPathText->set_label(sInfo);
+}
+
+void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )
+{
+#if HAVE_FEATURE_JAVA
+ bool bStartAgain = true;
+ std::unique_ptr<JavaInfo> pInfo;
+ javaFrameworkError eErr = jfw_getJavaInfoByPath( _rFolder, &pInfo );
+ if ( JFW_E_NONE == eErr && pInfo )
+ {
+ sal_Int32 nPos = 0;
+ bool bFound = false;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+
+ if ( !bFound )
+ {
+ for (auto const & pCmpInfo: m_aAddedInfos)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+ }
+
+ if ( !bFound )
+ {
+ jfw_addJRELocation( pInfo->sLocation );
+ AddJRE( pInfo.get() );
+ m_aAddedInfos.push_back( std::move(pInfo) );
+ nPos = m_xJavaList->n_children() - 1;
+ }
+
+ HandleCheckEntry(nPos);
+ UpdateJavaPathText();
+ bStartAgain = false;
+ }
+ else if ( JFW_E_NOT_RECOGNIZED == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_JRE_NOT_RECOGNIZED)));
+ xBox->run();
+ }
+ else if ( JFW_E_FAILED_VERSION == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_SVXSTR_JRE_FAILED_VERSION)));
+ xBox->run();
+ }
+
+ if ( bStartAgain )
+ {
+ xFolderPicker->setDisplayDirectory( _rFolder );
+ Application::PostUserEvent( LINK( this, SvxJavaOptionsPage, StartFolderPickerHdl ) );
+ }
+#else
+ (void) this;
+ (void)_rFolder;
+#endif
+}
+
+void SvxJavaOptionsPage::RequestRestart(svtools::RestartReason eReason)
+{
+ OfaTreeOptionsDialog* pParentDlg(static_cast<OfaTreeOptionsDialog*>(GetDialogController()));
+ if (pParentDlg)
+ pParentDlg->SetNeedsRestart(eReason);
+}
+
+std::unique_ptr<SfxTabPage> SvxJavaOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxJavaOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxJavaOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+
+ if ( m_xExperimentalCB->get_state_changed_from_saved() )
+ {
+ SvtMiscOptions aMiscOpt;
+ aMiscOpt.SetExperimentalMode( m_xExperimentalCB->get_active() );
+ bModified = true;
+ RequestRestart( svtools::RESTART_REASON_EXP_FEATURES );
+ }
+
+ if ( m_xMacroCB->get_state_changed_from_saved() )
+ {
+ SvtMiscOptions aMiscOpt;
+ aMiscOpt.SetMacroRecorderMode(m_xMacroCB->get_active());
+ bModified = true;
+ }
+
+#if HAVE_FEATURE_JAVA
+ javaFrameworkError eErr = JFW_E_NONE;
+ if (m_xParamDlg)
+ {
+ eErr = jfw_setVMParameters(m_xParamDlg->GetParameters());
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setVMParameters");
+ bModified = true;
+ }
+
+ if (m_xPathDlg)
+ {
+ OUString sPath(m_xPathDlg->GetClassPath());
+ if (m_xPathDlg->GetOldPath() != sPath)
+ {
+ eErr = jfw_setUserClassPath( sPath );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setUserClassPath");
+ bModified = true;
+ }
+ }
+
+ sal_uInt32 nCount = m_xJavaList->n_children();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ if (m_xJavaList->get_toggle(i, 0) == TRISTATE_TRUE)
+ {
+ JavaInfo const * pInfo;
+ if ( i < m_parJavaInfo.size() )
+ pInfo = m_parJavaInfo[i].get();
+ else
+ pInfo = m_aAddedInfos[ i - m_parJavaInfo.size() ].get();
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( JFW_E_NONE == eErr || JFW_E_INVALID_SETTINGS == eErr )
+ {
+ if (!pSelectedJava || !jfw_areEqualJavaInfo( pInfo, pSelectedJava.get() ) )
+ {
+ if ( jfw_isVMRunning() ||
+ ( ( pInfo->nRequirements & JFW_REQUIRE_NEEDRESTART ) == JFW_REQUIRE_NEEDRESTART ) )
+ {
+ RequestRestart( svtools::RESTART_REASON_JAVA );
+ }
+
+ eErr = jfw_setSelectedJRE( pInfo );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setSelectedJRE");
+ bModified = true;
+ }
+ }
+ break;
+ }
+ }
+
+ bool bEnabled = false;
+ eErr = jfw_getEnabled( &bEnabled );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_getEnabled" );
+ if ( bEnabled != m_xJavaEnableCB->get_active() )
+ {
+ eErr = jfw_setEnabled( m_xJavaEnableCB->get_active() );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_setEnabled" );
+ bModified = true;
+ }
+#endif
+
+ return bModified;
+}
+
+
+void SvxJavaOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ ClearJavaInfo();
+ m_xJavaList->clear();
+
+ SvtMiscOptions aMiscOpt;
+
+#if HAVE_FEATURE_JAVA
+ bool bEnabled = false;
+ javaFrameworkError eErr = jfw_getEnabled( &bEnabled );
+ if ( eErr != JFW_E_NONE )
+ bEnabled = false;
+ m_xJavaEnableCB->set_active(bEnabled);
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#else
+ m_xJavaEnableCB->set_active(false);
+ m_xJavaEnableCB->set_sensitive(false);
+#endif
+
+ m_xExperimentalCB->set_active( aMiscOpt.IsExperimentalMode() );
+ m_xExperimentalCB->save_state();
+ m_xMacroCB->set_active(aMiscOpt.IsMacroRecorderMode());
+ m_xMacroCB->save_state();
+
+ m_aResetIdle.Start();
+}
+
+
+void SvxJavaOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+SvxJavaParameterDlg::SvxJavaParameterDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javastartparametersdialog.ui",
+ "JavaStartParameters")
+ , m_xParameterEdit(m_xBuilder->weld_entry("parameterfield"))
+ , m_xAssignBtn(m_xBuilder->weld_button("assignbtn"))
+ , m_xAssignedList(m_xBuilder->weld_tree_view("assignlist"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("removebtn"))
+ , m_xEditBtn(m_xBuilder->weld_button("editbtn"))
+{
+ m_xAssignedList->set_size_request(m_xAssignedList->get_approximate_digit_width() * 54,
+ m_xAssignedList->get_height_rows(6));
+ m_xParameterEdit->connect_changed( LINK( this, SvxJavaParameterDlg, ModifyHdl_Impl ) );
+ m_xAssignBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, AssignHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, RemoveHdl_Impl ) );
+ m_xEditBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, EditHdl_Impl ) );
+ m_xAssignedList->connect_changed( LINK( this, SvxJavaParameterDlg, SelectHdl_Impl ) );
+ m_xAssignedList->connect_row_activated( LINK( this, SvxJavaParameterDlg, DblClickHdl_Impl ) );
+
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+SvxJavaParameterDlg::~SvxJavaParameterDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, ModifyHdl_Impl, weld::Entry&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ m_xAssignBtn->set_sensitive(!sParam.isEmpty());
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, AssignHdl_Impl, weld::Button&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ if (sParam.isEmpty())
+ return;
+
+ int nPos = m_xAssignedList->find_text(sParam);
+ if (nPos == -1)
+ {
+ m_xAssignedList->append_text(sParam);
+ m_xAssignedList->select(m_xAssignedList->n_children() - 1);
+ }
+ else
+ m_xAssignedList->select(nPos);
+ m_xParameterEdit->set_text(OUString());
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, EditHdl_Impl, weld::Button&, void)
+{
+ EditParameter();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, DblClickHdl_Impl, weld::TreeView&, bool)
+{
+ EditParameter();
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xAssignedList->remove(nPos);
+ int nCount = m_xAssignedList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xAssignedList->select(nPos);
+ }
+ else
+ {
+ DisableEditButton();
+ }
+ }
+ EnableRemoveButton();
+}
+
+void SvxJavaParameterDlg::EditParameter()
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ m_xParameterEdit->set_text(OUString());
+
+ if (nPos == -1)
+ return;
+
+ InputDialog aParamEditDlg(m_xDialog.get(), CuiResId(RID_SVXSTR_JAVA_START_PARAM));
+ OUString editableClassPath = m_xAssignedList->get_selected_text();
+ aParamEditDlg.SetEntryText(editableClassPath);
+ aParamEditDlg.HideHelpBtn();
+
+ if (!aParamEditDlg.run())
+ return;
+ OUString editedClassPath = comphelper::string::strip(aParamEditDlg.GetEntryText(), ' ');
+
+ if ( !editedClassPath.isEmpty() && editableClassPath != editedClassPath )
+ {
+ m_xAssignedList->remove(nPos);
+ m_xAssignedList->insert_text(nPos, editedClassPath);
+ m_xAssignedList->select(nPos);
+ }
+}
+
+short SvxJavaParameterDlg::run()
+{
+ m_xParameterEdit->grab_focus();
+ m_xAssignedList->select(-1);
+ return GenericDialogController::run();
+}
+
+std::vector< OUString > SvxJavaParameterDlg::GetParameters() const
+{
+ int nCount = m_xAssignedList->n_children();
+ std::vector< OUString > aParamList;
+ aParamList.reserve(nCount);
+ for (int i = 0; i < nCount; ++i)
+ aParamList.push_back(m_xAssignedList->get_text(i));
+ return aParamList;
+}
+
+void SvxJavaParameterDlg::DisableButtons()
+{
+ DisableAssignButton();
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+void SvxJavaParameterDlg::SetParameters( std::vector< OUString > const & rParams )
+{
+ m_xAssignedList->clear();
+ for (auto const & sParam: rParams)
+ {
+ m_xAssignedList->append_text(sParam);
+ }
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+SvxJavaClassPathDlg::SvxJavaClassPathDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javaclasspathdialog.ui", "JavaClassPath")
+ , m_xPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddArchiveBtn(m_xBuilder->weld_button("archive"))
+ , m_xAddPathBtn(m_xBuilder->weld_button("folder"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+{
+ m_xPathList->set_size_request(m_xPathList->get_approximate_digit_width() * 54,
+ m_xPathList->get_height_rows(8));
+ m_xAddArchiveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddArchiveHdl_Impl ) );
+ m_xAddPathBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddPathHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, RemoveHdl_Impl ) );
+ m_xPathList->connect_changed( LINK( this, SvxJavaClassPathDlg, SelectHdl_Impl ) );
+
+ // set initial focus to path list
+ m_xPathList->grab_focus();
+}
+
+SvxJavaClassPathDlg::~SvxJavaClassPathDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddArchiveHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aDlg(TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get());
+ aDlg.SetTitle( CuiResId( RID_SVXSTR_ARCHIVE_TITLE ) );
+ aDlg.AddFilter( CuiResId( RID_SVXSTR_ARCHIVE_HEADLINE ), "*.jar;*.zip" );
+ OUString sFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sFolder);
+ // best effort
+ }
+ if (sFolder.isEmpty())
+ sFolder = SvtPathOptions().GetWorkPath();
+ aDlg.SetDisplayDirectory( sFolder );
+ if ( aDlg.Execute() == ERRCODE_NONE )
+ {
+ OUString sURL = aDlg.GetPath();
+ OUString sFile;
+ if (osl::FileBase::getSystemPathFromFileURL(sURL, sFile) == osl::FileBase::E_None)
+ {
+ INetURLObject aURL( sURL );
+ if ( !IsPathDuplicate( sFile ) )
+ {
+ m_xPathList->append("", sFile, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_SVXSTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFile );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_SVXSTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddPathHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = FolderPicker::create(xContext);
+
+ OUString sOldFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sOldFolder);
+ // best effort
+ }
+ if (sOldFolder.isEmpty())
+ sOldFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sOldFolder );
+ if ( xFolderPicker->execute() == ExecutableDialogResults::OK )
+ {
+ OUString sFolderURL( xFolderPicker->getDirectory() );
+ INetURLObject aURL( sFolderURL );
+ OUString sNewFolder;
+ if (osl::FileBase::getSystemPathFromFileURL(sFolderURL, sNewFolder)
+ == osl::FileBase::E_None)
+ {
+ if ( !IsPathDuplicate( sNewFolder ) )
+ {
+ m_xPathList->append("", sNewFolder, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_SVXSTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sNewFolder );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_SVXSTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFolderURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xPathList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xPathList->remove(nPos);
+ int nCount = m_xPathList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xPathList->select( nPos );
+ }
+ }
+
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableRemoveButton();
+}
+
+bool SvxJavaClassPathDlg::IsPathDuplicate( const OUString& _rPath )
+{
+ bool bRet = false;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if ( m_xPathList->get_text(i) == _rPath )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+OUString SvxJavaClassPathDlg::GetClassPath() const
+{
+ OUStringBuffer sPath;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (!sPath.isEmpty())
+ sPath.append(CLASSPATH_DELIMITER);
+ sPath.append(m_xPathList->get_text(i));
+ }
+ return sPath.makeStringAndClear();
+}
+
+void SvxJavaClassPathDlg::SetClassPath( const OUString& _rPath )
+{
+ if ( m_sOldPath.isEmpty() )
+ m_sOldPath = _rPath;
+ m_xPathList->clear();
+ if (!_rPath.isEmpty())
+ {
+ sal_Int32 nIdx = 0;
+ do
+ {
+ OUString sToken = _rPath.getToken( 0, CLASSPATH_DELIMITER, nIdx );
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath(sToken, sURL); // best effort
+ INetURLObject aURL( sURL );
+ m_xPathList->append("", sToken, SvFileInformationManager::GetImageId(aURL));
+ }
+ while (nIdx>=0);
+ // select first entry
+ m_xPathList->select(0);
+ }
+ SelectHdl_Impl(*m_xPathList);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.hxx b/cui/source/options/optjava.hxx
new file mode 100644
index 000000000..df90e2824
--- /dev/null
+++ b/cui/source/options/optjava.hxx
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <config_java.h>
+
+#include <memory>
+#include <vector>
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+#include <svtools/restartdialog.hxx>
+
+// forward ---------------------------------------------------------------
+
+#if HAVE_FEATURE_JAVA
+struct JavaInfo;
+#else
+typedef void* JavaInfo;
+#endif
+
+class SvxJavaParameterDlg;
+class SvxJavaClassPathDlg;
+class SvxJavaListBox;
+class OfaTreeOptionsDialog;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+
+class SvxJavaOptionsPage : public SfxTabPage
+{
+private:
+#if HAVE_FEATURE_JAVA
+ std::vector<std::unique_ptr<JavaInfo>> m_parJavaInfo;
+ std::vector<OUString> m_parParameters;
+ OUString m_pClassPath;
+#endif
+ OUString m_sInstallText;
+ OUString m_sAddDialogText;
+ Idle m_aResetIdle;
+
+ std::vector<std::unique_ptr<JavaInfo>> m_aAddedInfos;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ std::unique_ptr<weld::CheckButton> m_xJavaEnableCB;
+ std::unique_ptr<weld::TreeView> m_xJavaList;
+ std::unique_ptr<weld::Label> m_xJavaPathText;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xParameterBtn;
+ std::unique_ptr<weld::Button> m_xClassPathBtn;
+ std::unique_ptr<weld::Button> m_xExpertConfigBtn;
+
+ std::unique_ptr<SvxJavaParameterDlg> m_xParamDlg;
+ std::unique_ptr<SvxJavaClassPathDlg> m_xPathDlg;
+
+ std::unique_ptr<weld::CheckButton> m_xExperimentalCB;
+ std::unique_ptr<weld::CheckButton> m_xMacroCB;
+
+ std::unique_ptr<weld::Label> m_xAddDialogText;
+
+ std::unique_ptr<weld::Widget> m_xJavaFrame;
+
+ DECL_LINK(EnableHdl_Impl, weld::Button&, void);
+ typedef std::pair<int, int> row_col;
+ DECL_LINK(CheckHdl_Impl, const row_col&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ParameterHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClassPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(ResetHdl_Impl, Timer *, void);
+
+ DECL_LINK(StartFolderPickerHdl, void *, void);
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+ DECL_LINK(ExpertConfigHdl_Impl, weld::Button&, void);
+
+ void ClearJavaInfo();
+ void LoadJREs();
+ void AddJRE( JavaInfo const * _pInfo );
+ void HandleCheckEntry(int nCheckedRow);
+ void UpdateJavaPathText();
+ void AddFolder( const OUString& _rFolder );
+ void RequestRestart( svtools::RestartReason eReason );
+
+public:
+ SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJavaOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+class SvxJavaParameterDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xParameterEdit;
+ std::unique_ptr<weld::Button> m_xAssignBtn;
+ std::unique_ptr<weld::TreeView> m_xAssignedList;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(AssignHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(DblClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(EditHdl_Impl, weld::Button&, void);
+
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void EnableEditButton()
+ {
+ m_xEditBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void DisableAssignButton()
+ {
+ m_xAssignBtn->set_sensitive(false);
+ }
+
+ void DisableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ }
+
+ void DisableEditButton()
+ {
+ m_xEditBtn->set_sensitive(false);
+ }
+
+public:
+ explicit SvxJavaParameterDlg(weld::Window* pParent);
+ virtual ~SvxJavaParameterDlg() override;
+
+ virtual short run() override;
+
+ std::vector< OUString > GetParameters() const;
+ void SetParameters( std::vector< OUString > const & rParams );
+ void DisableButtons();
+ void EditParameter();
+};
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+class SvxJavaClassPathDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xPathList;
+ std::unique_ptr<weld::Button> m_xAddArchiveBtn;
+ std::unique_ptr<weld::Button> m_xAddPathBtn;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+
+ OUString m_sOldPath;
+
+ DECL_LINK(AddArchiveHdl_Impl, weld::Button&, void);
+ DECL_LINK(AddPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+
+ bool IsPathDuplicate(const OUString& _rPath);
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xPathList->get_selected_index() != -1);
+ }
+
+public:
+ explicit SvxJavaClassPathDlg(weld::Window* pParent);
+ virtual ~SvxJavaClassPathDlg() override;
+
+ const OUString& GetOldPath() const { return m_sOldPath; }
+ void SetFocus() { m_xPathList->grab_focus(); }
+
+ OUString GetClassPath() const;
+ void SetClassPath( const OUString& _rPath );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.cxx b/cui/source/options/optjsearch.cxx
new file mode 100644
index 000000000..4a2c31c49
--- /dev/null
+++ b/cui/source/options/optjsearch.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <unotools/searchopt.hxx>
+#include <i18nutil/transliteration.hxx>
+#include "optjsearch.hxx"
+
+using namespace com::sun::star::i18n;
+
+
+SvxJSearchOptionsPage::SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optjsearchpage.ui", "OptJSearchPage", &rSet)
+ , m_xMatchCase(m_xBuilder->weld_check_button("matchcase"))
+ , m_xMatchFullHalfWidth(m_xBuilder->weld_check_button("matchfullhalfwidth"))
+ , m_xMatchHiraganaKatakana(m_xBuilder->weld_check_button("matchhiraganakatakana"))
+ , m_xMatchContractions(m_xBuilder->weld_check_button("matchcontractions"))
+ , m_xMatchMinusDashChoon(m_xBuilder->weld_check_button("matchminusdashchoon"))
+ , m_xMatchRepeatCharMarks(m_xBuilder->weld_check_button("matchrepeatcharmarks"))
+ , m_xMatchVariantFormKanji(m_xBuilder->weld_check_button("matchvariantformkanji"))
+ , m_xMatchOldKanaForms(m_xBuilder->weld_check_button("matcholdkanaforms"))
+ , m_xMatchDiziDuzu(m_xBuilder->weld_check_button("matchdiziduzu"))
+ , m_xMatchBavaHafa(m_xBuilder->weld_check_button("matchbavahafa"))
+ , m_xMatchTsithichiDhizi(m_xBuilder->weld_check_button("matchtsithichidhizi"))
+ , m_xMatchHyuiyuByuvyu(m_xBuilder->weld_check_button("matchhyuiyubyuvyu"))
+ , m_xMatchSesheZeje(m_xBuilder->weld_check_button("matchseshezeje"))
+ , m_xMatchIaiya(m_xBuilder->weld_check_button("matchiaiya"))
+ , m_xMatchKiku(m_xBuilder->weld_check_button("matchkiku"))
+ , m_xMatchProlongedSoundMark(m_xBuilder->weld_check_button("matchprolongedsoundmark"))
+ , m_xIgnorePunctuation(m_xBuilder->weld_check_button("ignorepunctuation"))
+ , m_xIgnoreWhitespace(m_xBuilder->weld_check_button("ignorewhitespace"))
+ , m_xIgnoreMiddleDot(m_xBuilder->weld_check_button("ignoremiddledot"))
+ , nTransliterationFlags(TransliterationFlags::NONE)
+ , bSaveOptions(true)
+{
+}
+
+SvxJSearchOptionsPage::~SvxJSearchOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxJSearchOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxJSearchOptionsPage>(pPage, pController, *rSet);
+}
+
+void SvxJSearchOptionsPage::SetTransliterationFlags( TransliterationFlags nSettings )
+{
+ bool bVal(nSettings & TransliterationFlags::IGNORE_CASE);
+ m_xMatchCase ->set_active( bVal ); //! treat as equal uppercase/lowercase
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_WIDTH);
+ m_xMatchFullHalfWidth ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_KANA);
+ m_xMatchHiraganaKatakana ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSize_ja_JP);
+ m_xMatchContractions ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMinusSign_ja_JP);
+ m_xMatchMinusDashChoon ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIterationMark_ja_JP);
+ m_xMatchRepeatCharMarks ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKanji_ja_JP);
+ m_xMatchVariantFormKanji ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKana_ja_JP);
+ m_xMatchOldKanaForms ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreZiZu_ja_JP);
+ m_xMatchDiziDuzu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreBaFa_ja_JP);
+ m_xMatchBavaHafa ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTiJi_ja_JP);
+ m_xMatchTsithichiDhizi ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreHyuByu_ja_JP);
+ m_xMatchHyuiyuByuvyu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeZe_ja_JP);
+ m_xMatchSesheZeje ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIandEfollowedByYa_ja_JP);
+ m_xMatchIaiya ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP);
+ m_xMatchKiku ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeparator_ja_JP);
+ m_xIgnorePunctuation ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSpace_ja_JP);
+ m_xIgnoreWhitespace ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreProlongedSoundMark_ja_JP);
+ m_xMatchProlongedSoundMark->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMiddleDot_ja_JP);
+ m_xIgnoreMiddleDot ->set_active( bVal );
+
+ nTransliterationFlags = nSettings;
+}
+
+TransliterationFlags SvxJSearchOptionsPage::GetTransliterationFlags_Impl()
+{
+ TransliterationFlags nTmp = TransliterationFlags::NONE;
+ if (m_xMatchCase->get_active()) //! treat as equal uppercase/lowercase
+ nTmp |= TransliterationFlags::IGNORE_CASE;
+ if (m_xMatchFullHalfWidth->get_active())
+ nTmp |= TransliterationFlags::IGNORE_WIDTH;
+ if (m_xMatchHiraganaKatakana->get_active())
+ nTmp |= TransliterationFlags::IGNORE_KANA;
+ if (m_xMatchContractions->get_active())
+ nTmp |= TransliterationFlags::ignoreSize_ja_JP;
+ if (m_xMatchMinusDashChoon->get_active())
+ nTmp |= TransliterationFlags::ignoreMinusSign_ja_JP;
+ if (m_xMatchRepeatCharMarks->get_active())
+ nTmp |= TransliterationFlags::ignoreIterationMark_ja_JP;
+ if (m_xMatchVariantFormKanji->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKanji_ja_JP;
+ if (m_xMatchOldKanaForms->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKana_ja_JP;
+ if (m_xMatchDiziDuzu->get_active())
+ nTmp |= TransliterationFlags::ignoreZiZu_ja_JP;
+ if (m_xMatchBavaHafa->get_active())
+ nTmp |= TransliterationFlags::ignoreBaFa_ja_JP;
+ if (m_xMatchTsithichiDhizi->get_active())
+ nTmp |= TransliterationFlags::ignoreTiJi_ja_JP;
+ if (m_xMatchHyuiyuByuvyu->get_active())
+ nTmp |= TransliterationFlags::ignoreHyuByu_ja_JP;
+ if (m_xMatchSesheZeje->get_active())
+ nTmp |= TransliterationFlags::ignoreSeZe_ja_JP;
+ if (m_xMatchIaiya->get_active())
+ nTmp |= TransliterationFlags::ignoreIandEfollowedByYa_ja_JP;
+ if (m_xMatchKiku->get_active())
+ nTmp |= TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP;
+ if (m_xIgnorePunctuation->get_active())
+ nTmp |= TransliterationFlags::ignoreSeparator_ja_JP;
+ if (m_xIgnoreWhitespace->get_active())
+ nTmp |= TransliterationFlags::ignoreSpace_ja_JP;
+ if (m_xMatchProlongedSoundMark->get_active())
+ nTmp |= TransliterationFlags::ignoreProlongedSoundMark_ja_JP;
+ if (m_xIgnoreMiddleDot->get_active())
+ nTmp |= TransliterationFlags::ignoreMiddleDot_ja_JP;
+
+ nTransliterationFlags = nTmp;
+ return nTransliterationFlags;
+}
+
+
+void SvxJSearchOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtSearchOptions aOpt;
+
+ // read settings from configuration
+ m_xMatchCase ->set_active(!aOpt.IsMatchCase() ); //! treat as equal uppercase/lowercase
+ m_xMatchFullHalfWidth ->set_active( aOpt.IsMatchFullHalfWidthForms() );
+ m_xMatchHiraganaKatakana ->set_active( aOpt.IsMatchHiraganaKatakana() );
+ m_xMatchContractions ->set_active( aOpt.IsMatchContractions() );
+ m_xMatchMinusDashChoon ->set_active( aOpt.IsMatchMinusDashChoon() );
+ m_xMatchRepeatCharMarks ->set_active( aOpt.IsMatchRepeatCharMarks() );
+ m_xMatchVariantFormKanji ->set_active( aOpt.IsMatchVariantFormKanji() );
+ m_xMatchOldKanaForms ->set_active( aOpt.IsMatchOldKanaForms() );
+ m_xMatchDiziDuzu ->set_active( aOpt.IsMatchDiziDuzu() );
+ m_xMatchBavaHafa ->set_active( aOpt.IsMatchBavaHafa() );
+ m_xMatchTsithichiDhizi ->set_active( aOpt.IsMatchTsithichiDhizi() );
+ m_xMatchHyuiyuByuvyu ->set_active( aOpt.IsMatchHyuiyuByuvyu() );
+ m_xMatchSesheZeje ->set_active( aOpt.IsMatchSesheZeje() );
+ m_xMatchIaiya ->set_active( aOpt.IsMatchIaiya() );
+ m_xMatchKiku ->set_active( aOpt.IsMatchKiku() );
+ m_xIgnorePunctuation ->set_active( aOpt.IsIgnorePunctuation() );
+ m_xIgnoreWhitespace ->set_active( aOpt.IsIgnoreWhitespace() );
+ m_xMatchProlongedSoundMark ->set_active( aOpt.IsIgnoreProlongedSoundMark() );
+ m_xIgnoreMiddleDot ->set_active( aOpt.IsIgnoreMiddleDot() );
+
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ DBG_ASSERT( nTransliterationFlags == aOpt.GetTransliterationFlags(),
+ "Transliteration settings different" );
+
+ m_xMatchCase ->save_state();
+ m_xMatchFullHalfWidth ->save_state();
+ m_xMatchHiraganaKatakana ->save_state();
+ m_xMatchContractions ->save_state();
+ m_xMatchMinusDashChoon ->save_state();
+ m_xMatchRepeatCharMarks ->save_state();
+ m_xMatchVariantFormKanji ->save_state();
+ m_xMatchOldKanaForms ->save_state();
+ m_xMatchDiziDuzu ->save_state();
+ m_xMatchBavaHafa ->save_state();
+ m_xMatchTsithichiDhizi ->save_state();
+ m_xMatchHyuiyuByuvyu ->save_state();
+ m_xMatchSesheZeje ->save_state();
+ m_xMatchIaiya ->save_state();
+ m_xMatchKiku ->save_state();
+ m_xIgnorePunctuation ->save_state();
+ m_xIgnoreWhitespace ->save_state();
+ m_xMatchProlongedSoundMark ->save_state();
+ m_xIgnoreMiddleDot ->save_state();
+}
+
+
+bool SvxJSearchOptionsPage::FillItemSet( SfxItemSet* )
+{
+ TransliterationFlags nOldVal = nTransliterationFlags;
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ bool bModified = nOldVal != nTransliterationFlags;
+
+ if (!bSaveOptions)
+ return bModified;
+
+ bModified = false;
+ SvtSearchOptions aOpt;
+ bool bNewVal, bChanged;
+
+ bNewVal = m_xMatchCase->get_active(); //! treat as equal uppercase/lowercase
+ bChanged = m_xMatchCase->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchCase(!bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchFullHalfWidth->get_active();
+ bChanged = m_xMatchFullHalfWidth->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchFullHalfWidthForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHiraganaKatakana->get_active();
+ bChanged = m_xMatchHiraganaKatakana->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHiraganaKatakana( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchContractions->get_active();
+ bChanged = m_xMatchContractions->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchContractions( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchMinusDashChoon->get_active();
+ bChanged = m_xMatchMinusDashChoon->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchMinusDashChoon( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchRepeatCharMarks->get_active();
+ bChanged = m_xMatchRepeatCharMarks->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchRepeatCharMarks( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchVariantFormKanji->get_active();
+ bChanged = m_xMatchVariantFormKanji->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchVariantFormKanji( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchOldKanaForms->get_active();
+ bChanged = m_xMatchOldKanaForms->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchOldKanaForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchDiziDuzu->get_active();
+ bChanged = m_xMatchDiziDuzu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchDiziDuzu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchBavaHafa->get_active();
+ bChanged = m_xMatchBavaHafa->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchBavaHafa( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchTsithichiDhizi->get_active();
+ bChanged = m_xMatchTsithichiDhizi->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchTsithichiDhizi( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHyuiyuByuvyu->get_active();
+ bChanged = m_xMatchHyuiyuByuvyu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHyuiyuByuvyu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchSesheZeje->get_active();
+ bChanged = m_xMatchSesheZeje->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchSesheZeje( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchIaiya->get_active();
+ bChanged = m_xMatchIaiya->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchIaiya( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchKiku->get_active();
+ bChanged = m_xMatchKiku->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchKiku( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnorePunctuation->get_active();
+ bChanged = m_xIgnorePunctuation->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnorePunctuation( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreWhitespace->get_active();
+ bChanged = m_xIgnoreWhitespace->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreWhitespace( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchProlongedSoundMark->get_active();
+ bChanged = m_xMatchProlongedSoundMark->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreProlongedSoundMark( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreMiddleDot->get_active();
+ bChanged = m_xIgnoreMiddleDot->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreMiddleDot( bNewVal );
+ bModified = true;
+ }
+
+ if (bModified)
+ aOpt.Commit();
+
+ return bModified;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.hxx b/cui/source/options/optjsearch.hxx
new file mode 100644
index 000000000..f0da350ae
--- /dev/null
+++ b/cui/source/options/optjsearch.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SfxItemSet;
+
+class SvxJSearchOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xMatchCase;
+ std::unique_ptr<weld::CheckButton> m_xMatchFullHalfWidth;
+ std::unique_ptr<weld::CheckButton> m_xMatchHiraganaKatakana;
+ std::unique_ptr<weld::CheckButton> m_xMatchContractions;
+ std::unique_ptr<weld::CheckButton> m_xMatchMinusDashChoon;
+ std::unique_ptr<weld::CheckButton> m_xMatchRepeatCharMarks;
+ std::unique_ptr<weld::CheckButton> m_xMatchVariantFormKanji;
+ std::unique_ptr<weld::CheckButton> m_xMatchOldKanaForms;
+ std::unique_ptr<weld::CheckButton> m_xMatchDiziDuzu;
+ std::unique_ptr<weld::CheckButton> m_xMatchBavaHafa;
+ std::unique_ptr<weld::CheckButton> m_xMatchTsithichiDhizi;
+ std::unique_ptr<weld::CheckButton> m_xMatchHyuiyuByuvyu;
+ std::unique_ptr<weld::CheckButton> m_xMatchSesheZeje;
+ std::unique_ptr<weld::CheckButton> m_xMatchIaiya;
+ std::unique_ptr<weld::CheckButton> m_xMatchKiku;
+ std::unique_ptr<weld::CheckButton> m_xMatchProlongedSoundMark;
+
+ std::unique_ptr<weld::CheckButton> m_xIgnorePunctuation;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreWhitespace;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreMiddleDot;
+
+ TransliterationFlags nTransliterationFlags;
+ bool bSaveOptions;
+
+ TransliterationFlags GetTransliterationFlags_Impl();
+
+public:
+ SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJSearchOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+ void EnableSaveOptions( bool bVal ) { bSaveOptions = bVal; }
+
+ TransliterationFlags GetTransliterationFlags() const { return nTransliterationFlags; }
+ void SetTransliterationFlags( TransliterationFlags nSettings );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optlingu.cxx b/cui/source/options/optlingu.cxx
new file mode 100644
index 000000000..dd5cda2d9
--- /dev/null
+++ b/cui/source/options/optlingu.cxx
@@ -0,0 +1,1971 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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/settings.hxx>
+#include <vcl/weld.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <com/sun/star/lang/XServiceDisplayName.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <unotools/extendedsecurityoptions.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <svx/svxdlg.hxx>
+#include <editeng/optitems.hxx>
+#include <optlingu.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <ucbhelper/content.hxx>
+
+#include <vector>
+#include <map>
+
+using namespace ::ucbhelper;
+using namespace ::com::sun::star;
+using namespace css::lang;
+using namespace css::uno;
+using namespace css::linguistic2;
+using namespace css::beans;
+
+static const char cSpell[] = SN_SPELLCHECKER;
+static const char cGrammar[] = SN_GRAMMARCHECKER;
+static const char cHyph[] = SN_HYPHENATOR;
+static const char cThes[] = SN_THESAURUS;
+
+// static ----------------------------------------------------------------
+
+static sal_Int32 lcl_SeqGetEntryPos(
+ const Sequence< OUString > &rSeq, const OUString &rEntry )
+{
+ sal_Int32 i;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pItem = rSeq.getConstArray();
+ for (i = 0; i < nLen; ++i)
+ {
+ if (rEntry == pItem[i])
+ break;
+ }
+ return i < nLen ? i : -1;
+}
+
+static bool KillFile_Impl( const OUString& rURL )
+{
+ bool bRet = true;
+ try
+ {
+ Content aCnt( rURL, uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ aCnt.executeCommand( "delete", Any( true ) );
+ }
+ catch( ... )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "KillFile" );
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+// 0x 0p 0t 0c nn
+// p: 1 -> parent
+// t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
+// c: 1 -> checked 0 -> unchecked
+// n: index
+
+#define TYPE_SPELL sal_uInt8(1)
+#define TYPE_GRAMMAR sal_uInt8(2)
+#define TYPE_HYPH sal_uInt8(3)
+#define TYPE_THES sal_uInt8(4)
+
+namespace {
+
+class ModuleUserData_Impl
+{
+ bool bParent;
+ bool bIsChecked;
+ sal_uInt8 nType;
+ sal_uInt8 nIndex;
+ OUString sImplName;
+
+public:
+ ModuleUserData_Impl( const OUString& sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
+ bParent(bIsParent),
+ bIsChecked(bChecked),
+ nType(nSetType),
+ nIndex(nSetIndex),
+ sImplName(sImpName)
+ {
+ }
+ bool IsParent() const {return bParent;}
+ sal_uInt8 GetType() const {return nType;}
+ bool IsChecked() const {return bIsChecked;}
+ sal_uInt8 GetIndex() const {return nIndex;}
+ const OUString& GetImplName() const {return sImplName;}
+
+};
+
+
+// User for user-dictionaries (XDictionary interface)
+
+class DicUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
+ DicUserData( sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool IsChecked() const { return static_cast<bool>((nVal >> 8) & 0x01); }
+ bool IsDeletable() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+};
+
+}
+
+DicUserData::DicUserData(
+ sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ (static_cast<sal_uInt32>(bEditable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bDeletable ? 1 : 0) << 10);
+}
+
+/*--------------------------------------------------
+ Entry IDs for options listbox of dialog
+--------------------------------------------------*/
+
+namespace {
+
+enum EID_OPTIONS
+{
+ EID_SPELL_AUTO,
+ EID_GRAMMAR_AUTO,
+ EID_CAPITAL_WORDS,
+ EID_WORDS_WITH_DIGITS,
+ EID_SPELL_SPECIAL,
+ EID_NUM_MIN_WORDLEN,
+ EID_NUM_PRE_BREAK,
+ EID_NUM_POST_BREAK,
+ EID_HYPH_AUTO,
+ EID_HYPH_SPECIAL
+};
+
+}
+
+//! this array must have an entry for every value of EID_OPTIONS.
+// It is used to get the respective property name.
+static const char * aEidToPropName[] =
+{
+ UPN_IS_SPELL_AUTO, // EID_SPELL_AUTO
+ UPN_IS_GRAMMAR_AUTO, // EID_GRAMMAR_AUTO
+ UPN_IS_SPELL_UPPER_CASE, // EID_CAPITAL_WORDS
+ UPN_IS_SPELL_WITH_DIGITS, // EID_WORDS_WITH_DIGITS
+ UPN_IS_SPELL_SPECIAL, // EID_SPELL_SPECIAL
+ UPN_HYPH_MIN_WORD_LENGTH, // EID_NUM_MIN_WORDLEN,
+ UPN_HYPH_MIN_LEADING, // EID_NUM_PRE_BREAK
+ UPN_HYPH_MIN_TRAILING, // EID_NUM_POST_BREAK
+ UPN_IS_HYPH_AUTO, // EID_HYPH_AUTO
+ UPN_IS_HYPH_SPECIAL // EID_HYPH_SPECIAL
+};
+
+static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
+{
+ DBG_ASSERT( static_cast<unsigned int>(eEntryId) < SAL_N_ELEMENTS(aEidToPropName), "index out of range" );
+ return OUString::createFromAscii( aEidToPropName[ static_cast<int>(eEntryId) ] );
+}
+
+namespace {
+
+class OptionsBreakSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Widget> m_xBeforeFrame;
+ std::unique_ptr<weld::Widget> m_xAfterFrame;
+ std::unique_ptr<weld::Widget> m_xMinimalFrame;
+ std::unique_ptr<weld::SpinButton> m_xBreakNF;
+
+public:
+ OptionsBreakSet(weld::Window* pParent, sal_uInt16 nRID)
+ : GenericDialogController(pParent, "cui/ui/breaknumberoption.ui", "BreakNumberOption")
+ , m_xBeforeFrame(m_xBuilder->weld_widget("beforeframe"))
+ , m_xAfterFrame(m_xBuilder->weld_widget("afterframe"))
+ , m_xMinimalFrame(m_xBuilder->weld_widget("miniframe"))
+ {
+ assert(EID_NUM_PRE_BREAK == nRID || EID_NUM_POST_BREAK == nRID || EID_NUM_MIN_WORDLEN == nRID); //unexpected ID
+
+ if (nRID == EID_NUM_PRE_BREAK)
+ {
+ m_xBeforeFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("beforebreak");
+ }
+ else if(nRID == EID_NUM_POST_BREAK)
+ {
+ m_xAfterFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("afterbreak");
+ }
+ else if(nRID == EID_NUM_MIN_WORDLEN)
+ {
+ m_xMinimalFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("wordlength");
+ }
+ }
+
+ weld::SpinButton& GetNumericFld()
+ {
+ return *m_xBreakNF;
+ }
+};
+
+// class OptionsUserData -------------------------------------------------
+
+class OptionsUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit OptionsUserData( sal_uInt32 nUserData ) : nVal( nUserData ) {}
+ OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool HasNumericValue() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+ sal_uInt16 GetNumericValue() const { return static_cast<sal_uInt16>(nVal & 0xFF); }
+ bool IsCheckable() const { return static_cast<bool>((nVal >> 9) & 0x01); }
+ bool IsModified() const { return static_cast<bool>((nVal >> 11) & 0x01); }
+
+ void SetNumericValue( sal_uInt8 nNumVal );
+};
+
+}
+
+OptionsUserData::OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ DBG_ASSERT( nNumVal < 256, "value out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bHasNV ? 1 : 0) << 10) |
+ (static_cast<sal_uInt32>(bCheckable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ static_cast<sal_uInt32>(0xFF & nNumVal);
+}
+
+void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
+{
+ if (HasNumericValue() && (GetNumericValue() != nNumVal))
+ {
+ nVal &= 0xffffff00;
+ nVal |= nNumVal;
+ nVal |= sal_uInt32(1) << 11; // mark as modified
+ }
+}
+
+// ServiceInfo_Impl ----------------------------------------------------
+
+namespace {
+
+struct ServiceInfo_Impl
+{
+ OUString sDisplayName;
+ OUString sSpellImplName;
+ OUString sHyphImplName;
+ OUString sThesImplName;
+ OUString sGrammarImplName;
+ uno::Reference< XSpellChecker > xSpell;
+ uno::Reference< XHyphenator > xHyph;
+ uno::Reference< XThesaurus > xThes;
+ uno::Reference< XProofreader > xGrammar;
+ bool bConfigured;
+
+ ServiceInfo_Impl() : bConfigured(false) {}
+};
+
+}
+
+typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
+typedef std::map< LanguageType, Sequence< OUString > > LangImplNameTable;
+
+
+// SvxLinguData_Impl ----------------------------------------------------
+
+class SvxLinguData_Impl
+{
+ //contains services and implementation names sorted by implementation names
+ ServiceInfoArr aDisplayServiceArr;
+ sal_uInt32 nDisplayServices;
+
+ Sequence< Locale > aAllServiceLocales;
+ LangImplNameTable aCfgSpellTable;
+ LangImplNameTable aCfgHyphTable;
+ LangImplNameTable aCfgThesTable;
+ LangImplNameTable aCfgGrammarTable;
+ uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
+
+
+ static bool AddRemove( Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd );
+
+public:
+ SvxLinguData_Impl();
+
+ uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
+
+ void SetChecked( const Sequence< OUString > &rConfiguredServices );
+ void Reconfigure( const OUString &rDisplayName, bool bEnable );
+
+ const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
+
+ LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
+ LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
+ LangImplNameTable & GetThesTable() { return aCfgThesTable; }
+ LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
+
+ ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
+
+ const sal_uInt32 & GetDisplayServiceCount() const { return nDisplayServices; }
+ void SetDisplayServiceCount( sal_uInt32 nVal ) { nDisplayServices = nVal; }
+
+ // returns the list of service implementation names for the specified
+ // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
+ // the proper order for the SvxEditModulesDlg (the ones from the
+ // configuration (keeping that order!) first and then the other ones.
+ // I.e. the ones available but not configured in arbitrary order).
+ // They available ones may contain names that do not(!) support that
+ // language.
+ Sequence< OUString > GetSortedImplNames( LanguageType nLang, sal_uInt8 nType );
+
+ ServiceInfo_Impl * GetInfoByImplName( const OUString &rSvcImplName );
+};
+
+
+static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, const OUString &rTxt )
+{
+ sal_Int32 nRes = -1;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pString = rSeq.getConstArray();
+ for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
+ {
+ if (pString[i] == rTxt)
+ nRes = i;
+ }
+ return nRes;
+}
+
+
+Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( LanguageType nLang, sal_uInt8 nType )
+{
+ LangImplNameTable *pTable = nullptr;
+ switch (nType)
+ {
+ case TYPE_SPELL : pTable = &aCfgSpellTable; break;
+ case TYPE_HYPH : pTable = &aCfgHyphTable; break;
+ case TYPE_THES : pTable = &aCfgThesTable; break;
+ case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
+ }
+ Sequence< OUString > aRes;
+ if (!pTable)
+ {
+ SAL_WARN( "cui.options", "unknown linguistic type" );
+ return aRes;
+ }
+ if (pTable->count( nLang ))
+ aRes = (*pTable)[ nLang ]; // add configured services
+ sal_Int32 nIdx = aRes.getLength();
+ DBG_ASSERT( static_cast<sal_Int32>(nDisplayServices) >= nIdx, "size mismatch" );
+ aRes.realloc( nDisplayServices );
+ OUString *pRes = aRes.getArray();
+
+ // add not configured services
+ for (sal_Int32 i = 0; i < static_cast<sal_Int32>(nDisplayServices); ++i)
+ {
+ const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
+ OUString aImplName;
+ switch (nType)
+ {
+ case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
+ case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
+ case TYPE_THES : aImplName = rInfo.sThesImplName; break;
+ case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
+ }
+
+ if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
+ {
+ DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
+ if (nIdx < aRes.getLength())
+ pRes[ nIdx++ ] = aImplName;
+ }
+ }
+ // don't forget to put aRes back to its actual size just in case you allocated too much
+ // since all of the names may have already been added
+ // otherwise you get duplicate entries in the edit dialog
+ aRes.realloc( nIdx );
+ return aRes;
+}
+
+
+ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( const OUString &rSvcImplName )
+{
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
+ if (rTmp.sSpellImplName == rSvcImplName ||
+ rTmp.sHyphImplName == rSvcImplName ||
+ rTmp.sThesImplName == rSvcImplName ||
+ rTmp.sGrammarImplName == rSvcImplName)
+ {
+ return &rTmp;
+ }
+ }
+ return nullptr;
+}
+
+
+static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
+{
+ Sequence<Locale> aLocToAdd(rAdd.getLength());
+ Locale* pLocToAdd = aLocToAdd.getArray();
+ sal_Int32 nFound = 0;
+ for(const Locale& i : rAdd)
+ {
+ bool bFound = false;
+ for(const Locale& j : std::as_const(aAllLocales))
+ {
+ if (i.Language == j.Language &&
+ i.Country == j.Country &&
+ i.Variant == j.Variant)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ {
+ pLocToAdd[nFound++] = i;
+ }
+ }
+ sal_Int32 nLength = aAllLocales.getLength();
+ aAllLocales.realloc( nLength + nFound);
+ Locale* pAllLocales2 = aAllLocales.getArray();
+ for(sal_Int32 i = 0; i < nFound; i++)
+ pAllLocales2[nLength++] = pLocToAdd[i];
+}
+
+static void lcl_MergeDisplayArray(
+ SvxLinguData_Impl &rData,
+ const ServiceInfo_Impl &rToAdd )
+{
+ sal_uInt32 nCnt = 0;
+
+ ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
+ sal_uInt32 nEntries = rData.GetDisplayServiceCount();
+
+ for (sal_uInt32 i = 0; i < nEntries; ++i)
+ {
+ ServiceInfo_Impl& rEntry = rSvcInfoArr[i];
+ if (rEntry.sDisplayName == rToAdd.sDisplayName)
+ {
+ if(rToAdd.xSpell.is())
+ {
+ DBG_ASSERT( !rEntry.xSpell.is() &&
+ rEntry.sSpellImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sSpellImplName = rToAdd.sSpellImplName;
+ rEntry.xSpell = rToAdd.xSpell;
+ }
+ if(rToAdd.xGrammar.is())
+ {
+ DBG_ASSERT( !rEntry.xGrammar.is() &&
+ rEntry.sGrammarImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sGrammarImplName = rToAdd.sGrammarImplName;
+ rEntry.xGrammar = rToAdd.xGrammar;
+ }
+ if(rToAdd.xHyph.is())
+ {
+ DBG_ASSERT( !rEntry.xHyph.is() &&
+ rEntry.sHyphImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sHyphImplName = rToAdd.sHyphImplName;
+ rEntry.xHyph = rToAdd.xHyph;
+ }
+ if(rToAdd.xThes.is())
+ {
+ DBG_ASSERT( !rEntry.xThes.is() &&
+ rEntry.sThesImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sThesImplName = rToAdd.sThesImplName;
+ rEntry.xThes = rToAdd.xThes;
+ }
+ return ;
+ }
+ ++nCnt;
+ }
+ rData.GetDisplayServiceArray().push_back( rToAdd );
+ rData.SetDisplayServiceCount( nCnt + 1 );
+}
+
+SvxLinguData_Impl::SvxLinguData_Impl() :
+ nDisplayServices (0)
+{
+ uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ xLinguSrvcMgr = LinguServiceManager::create(xContext);
+
+ const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ Sequence<Any> aArgs(2);//second arguments has to be empty!
+ aArgs.getArray()[0] <<= LinguMgr::GetLinguPropertySet();
+
+ //read spell checker
+ const Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
+ cSpell, Locale() );
+
+ for(const OUString& spellName : aSpellNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sSpellImplName = spellName;
+ aInfo.xSpell.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read grammar checker
+ const Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
+ cGrammar, Locale() );
+ for(const OUString& grammarName : aGrammarNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sGrammarImplName = grammarName;
+ aInfo.xGrammar.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read hyphenator
+ const Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
+ cHyph, Locale() );
+ for(const OUString& hyphName : aHyphNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sHyphImplName = hyphName;
+ aInfo.xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read thesauri
+ const Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
+ cThes, Locale() );
+ for(const OUString& thesName : aThesNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sThesImplName = thesName;
+ aInfo.xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ Sequence< OUString > aCfgSvcs;
+ for(auto const & locale : std::as_const(aAllServiceLocales))
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgSpellTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgGrammarTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgHyphTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgThesTable[ nLang ] = aCfgSvcs;
+ }
+}
+
+void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
+{
+ for(OUString const & configService : rConfiguredServices)
+ {
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rEntry = aDisplayServiceArr[i];
+ if (!rEntry.bConfigured)
+ {
+ const OUString &rSrvcImplName = configService;
+ if (!rSrvcImplName.isEmpty() &&
+ (rEntry.sSpellImplName == rSrvcImplName ||
+ rEntry.sGrammarImplName == rSrvcImplName ||
+ rEntry.sHyphImplName == rSrvcImplName ||
+ rEntry.sThesImplName == rSrvcImplName))
+ {
+ rEntry.bConfigured = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+bool SvxLinguData_Impl::AddRemove(
+ Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd )
+{
+ bool bRet = false; // modified?
+
+ sal_Int32 nEntries = rConfigured.getLength();
+ sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
+ if (bAdd && nPos < 0) // add new entry
+ {
+ rConfigured.realloc( ++nEntries );
+ OUString *pConfigured = rConfigured.getArray();
+ pConfigured[nEntries - 1] = rImplName;
+ bRet = true;
+ }
+ else if (!bAdd && nPos >= 0) // remove existing entry
+ {
+ OUString *pConfigured = rConfigured.getArray();
+ for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
+ pConfigured[i] = pConfigured[i + 1];
+ rConfigured.realloc(--nEntries);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+
+void SvxLinguData_Impl::Reconfigure( const OUString &rDisplayName, bool bEnable )
+{
+ DBG_ASSERT( !rDisplayName.isEmpty(), "empty DisplayName" );
+
+ ServiceInfo_Impl *pInfo = nullptr;
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rTmp = aDisplayServiceArr[i];
+ if (rTmp.sDisplayName == rDisplayName)
+ {
+ pInfo = &rTmp;
+ break;
+ }
+ }
+ DBG_ASSERT( pInfo, "DisplayName entry not found" );
+ if (!pInfo)
+ return;
+
+ pInfo->bConfigured = bEnable;
+
+ Sequence< Locale > aLocales;
+ const Locale *pLocale = nullptr;
+ sal_Int32 nLocales = 0;
+ sal_Int32 i;
+
+ // update configured spellchecker entries
+ if (pInfo->xSpell.is())
+ {
+ aLocales = pInfo->xSpell->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgSpellTable.count( nLang ) && bEnable)
+ aCfgSpellTable[ nLang ] = Sequence< OUString >();
+ if (aCfgSpellTable.count( nLang ))
+ AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
+ }
+ }
+
+ // update configured grammar checker entries
+ if (pInfo->xGrammar.is())
+ {
+ aLocales = pInfo->xGrammar->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgGrammarTable.count( nLang ) && bEnable)
+ aCfgGrammarTable[ nLang ] = Sequence< OUString >();
+ if (aCfgGrammarTable.count( nLang ))
+ AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
+ }
+ }
+
+ // update configured hyphenator entries
+ if (pInfo->xHyph.is())
+ {
+ aLocales = pInfo->xHyph->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgHyphTable.count( nLang ) && bEnable)
+ aCfgHyphTable[ nLang ] = Sequence< OUString >();
+ if (aCfgHyphTable.count( nLang ))
+ AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
+ }
+ }
+
+ // update configured spellchecker entries
+ if (!pInfo->xThes.is())
+ return;
+
+ aLocales = pInfo->xThes->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgThesTable.count( nLang ) && bEnable)
+ aCfgThesTable[ nLang ] = Sequence< OUString >();
+ if (aCfgThesTable.count( nLang ))
+ AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
+ }
+}
+
+
+// class SvxLinguTabPage -------------------------------------------------
+
+SvxLinguTabPage::SvxLinguTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlingupage.ui", "OptLinguPage", &rSet)
+ , sCapitalWords (CuiResId(RID_SVXSTR_CAPITAL_WORDS))
+ , sWordsWithDigits(CuiResId(RID_SVXSTR_WORDS_WITH_DIGITS))
+ , sSpellSpecial (CuiResId(RID_SVXSTR_SPELL_SPECIAL))
+ , sSpellAuto (CuiResId(RID_SVXSTR_SPELL_AUTO))
+ , sGrammarAuto (CuiResId(RID_SVXSTR_GRAMMAR_AUTO))
+ , sNumMinWordlen (CuiResId(RID_SVXSTR_NUM_MIN_WORDLEN))
+ , sNumPreBreak (CuiResId(RID_SVXSTR_NUM_PRE_BREAK))
+ , sNumPostBreak (CuiResId(RID_SVXSTR_NUM_POST_BREAK))
+ , sHyphAuto (CuiResId(RID_SVXSTR_HYPH_AUTO))
+ , sHyphSpecial (CuiResId(RID_SVXSTR_HYPH_SPECIAL))
+ , nUPN_HYPH_MIN_WORD_LENGTH(-1)
+ , nUPN_HYPH_MIN_LEADING(-1)
+ , nUPN_HYPH_MIN_TRAILING(-1)
+ , m_nDlbClickEventId(nullptr)
+ , m_xLinguModulesFT(m_xBuilder->weld_label("lingumodulesft"))
+ , m_xLinguModulesCLB(m_xBuilder->weld_tree_view("lingumodules"))
+ , m_xLinguModulesEditPB(m_xBuilder->weld_button("lingumodulesedit"))
+ , m_xLinguDicsFT(m_xBuilder->weld_label("lingudictsft"))
+ , m_xLinguDicsCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xLinguDicsNewPB(m_xBuilder->weld_button("lingudictsnew"))
+ , m_xLinguDicsEditPB(m_xBuilder->weld_button("lingudictsedit"))
+ , m_xLinguDicsDelPB(m_xBuilder->weld_button("lingudictsdelete"))
+ , m_xLinguOptionsCLB(m_xBuilder->weld_tree_view("linguoptions"))
+ , m_xLinguOptionsEditPB(m_xBuilder->weld_button("linguoptionsedit"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+{
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xLinguModulesCLB->get_checkbox_column_width());
+
+ m_xLinguModulesCLB->set_column_fixed_widths(aWidths);
+ m_xLinguDicsCLB->set_column_fixed_widths(aWidths);
+ m_xLinguOptionsCLB->set_column_fixed_widths(aWidths);
+
+ m_xLinguModulesCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguModulesCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+ m_xLinguModulesCLB->connect_toggled(LINK(this, SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl));
+
+ m_xLinguModulesEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguOptionsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguDicsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguDicsCLB->connect_toggled(LINK(this, SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl));
+
+ m_xLinguDicsNewPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsDelPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguOptionsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguOptionsCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+
+ if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode() == SvtExtendedSecurityOptions::OPEN_NEVER )
+ m_xMoreDictsLink->hide();
+
+ xProp = LinguMgr::GetLinguPropertySet();
+ xDicList.set( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ // keep references to all **currently** available dictionaries,
+ // since the diclist may get changed meanwhile (e.g. through the API).
+ // We want the dialog to operate on the same set of dictionaries it
+ // was started with.
+ // Also we have to take care to not lose the last reference when
+ // someone else removes a dictionary from the list.
+ // removed dics will be replaced by NULL new entries be added to the end
+ // Thus we may use indices as consistent references.
+ aDics = xDicList->getDictionaries();
+
+ UpdateDicBox_Impl();
+ }
+ else
+ {
+ m_xLinguDicsFT->set_sensitive(false);
+ m_xLinguDicsCLB->set_sensitive(false);
+ m_xLinguDicsNewPB->set_sensitive(false);
+ m_xLinguDicsEditPB->set_sensitive(false);
+ m_xLinguDicsDelPB->set_sensitive(false);
+ }
+}
+
+SvxLinguTabPage::~SvxLinguTabPage()
+{
+ if (m_nDlbClickEventId)
+ {
+ Application::RemoveUserEvent(m_nDlbClickEventId);
+ m_nDlbClickEventId = nullptr;
+ }
+ pLinguData.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxLinguTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxLinguTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ bool bModified = true; // !!!!
+
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ // update spellchecker configuration entries
+ const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
+ }
+
+ // update grammar checker configuration entries
+ pTable = &pLinguData->GetGrammarTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
+ }
+
+ // update hyphenator configuration entries
+ pTable = &pLinguData->GetHyphTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
+ }
+
+ // update thesaurus configuration entries
+ pTable = &pLinguData->GetThesTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
+ }
+ }
+
+
+ // activate dictionaries according to checkbox state
+
+ Sequence< OUString > aActiveDics;
+ sal_Int32 nActiveDics = 0;
+ int nEntries = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nEntries; ++i)
+ {
+ sal_Int32 nDics = aDics.getLength();
+
+ aActiveDics.realloc( nDics );
+ OUString *pActiveDic = aActiveDics.getArray();
+
+ DicUserData aData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aData.GetEntryId() < nDics)
+ {
+ bool bChecked = m_xLinguDicsCLB->get_toggle(i, 0) == TRISTATE_TRUE;
+ uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ bChecked = true;
+ xDic->setActive( bChecked );
+
+ if (bChecked)
+ {
+ OUString aDicName( xDic->getName() );
+ pActiveDic[ nActiveDics++ ] = aDicName;
+ }
+ }
+ }
+ }
+
+ aActiveDics.realloc( nActiveDics );
+ Any aTmp;
+ aTmp <<= aActiveDics;
+ SvtLinguConfig aLngCfg;
+ aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
+
+
+ nEntries = m_xLinguOptionsCLB->n_children();
+ for (int j = 0; j < nEntries; ++j)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(j).toUInt32());
+ OUString aPropName( lcl_GetPropertyName( static_cast<EID_OPTIONS>(aData.GetEntryId()) ) );
+
+ Any aAny;
+ if (aData.IsCheckable())
+ {
+ bool bChecked = m_xLinguOptionsCLB->get_toggle(j, 0) == TRISTATE_TRUE;
+ aAny <<= bChecked;
+ }
+ else if (aData.HasNumericValue())
+ {
+ sal_Int16 nVal = aData.GetNumericValue();
+ aAny <<= nVal;
+ }
+
+ if (xProp.is())
+ xProp->setPropertyValue( aPropName, aAny );
+ aLngCfg.SetProperty( aPropName, aAny );
+ }
+
+ OptionsUserData aPreBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_PRE_BREAK).toUInt32());
+ OptionsUserData aPostBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_POST_BREAK).toUInt32());
+ if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
+ {
+ SfxHyphenRegionItem aHyp( GetWhich( SID_ATTR_HYPHENREGION ) );
+ aHyp.GetMinLead() = static_cast<sal_uInt8>(aPreBreakData.GetNumericValue());
+ aHyp.GetMinTrail() = static_cast<sal_uInt8>(aPostBreakData.GetNumericValue());
+ rCoreSet->Put( aHyp );
+ }
+
+ // automatic spell checking
+ bool bNewAutoCheck = m_xLinguOptionsCLB->get_toggle(EID_SPELL_AUTO, 0) == TRISTATE_TRUE;
+ const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
+ if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
+ {
+ rCoreSet->Put( SfxBoolItem( GetWhich( SID_AUTOSPELL_CHECK ),
+ bNewAutoCheck ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+sal_uInt32 SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
+{
+ sal_uInt32 nRes = 0;
+ DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
+ if (rxDic.is())
+ {
+ uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
+
+ bool bChecked = rxDic->isActive();
+ bool bEditable = !xStor.is() || !xStor->isReadonly();
+ bool bDeletable = bEditable;
+
+ nRes = DicUserData( nIdx,
+ bChecked, bEditable, bDeletable ).GetUserData();
+ }
+ return nRes;
+}
+
+
+void SvxLinguTabPage::AddDicBoxEntry(
+ const uno::Reference< XDictionary > &rxDic,
+ sal_uInt16 nIdx )
+{
+ m_xLinguDicsCLB->freeze();
+
+ OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
+ LanguageTag( rxDic->getLocale() ).getLanguageType(),
+ DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
+ m_xLinguDicsCLB->append(); // append at end
+ int nEntry = m_xLinguDicsCLB->n_children() - 1;
+ DicUserData aData( GetDicUserData( rxDic, nIdx ) );
+ m_xLinguDicsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ m_xLinguDicsCLB->set_toggle(nEntry, aData.IsChecked() ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguDicsCLB->set_text(nEntry, aTxt, 1); // append at end
+
+ m_xLinguDicsCLB->thaw();
+}
+
+void SvxLinguTabPage::UpdateDicBox_Impl()
+{
+ m_xLinguDicsCLB->freeze();
+ m_xLinguDicsCLB->clear();
+
+ sal_Int32 nDics = aDics.getLength();
+ const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
+ for (sal_Int32 i = 0; i < nDics; ++i)
+ {
+ const uno::Reference< XDictionary > &rDic = pDic[i];
+ if (rDic.is())
+ AddDicBoxEntry( rDic, static_cast<sal_uInt16>(i) );
+ }
+
+ m_xLinguDicsCLB->thaw();
+ if (m_xLinguDicsCLB->n_children())
+ {
+ m_xLinguDicsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguDicsCLB);
+ }
+}
+
+void SvxLinguTabPage::UpdateModulesBox_Impl()
+{
+ if (!pLinguData)
+ return;
+
+ const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
+ const sal_uInt32 nDispSrvcCount = pLinguData->GetDisplayServiceCount();
+
+ m_xLinguModulesCLB->clear();
+
+ for (sal_uInt32 i = 0; i < nDispSrvcCount; ++i)
+ {
+ const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
+ m_xLinguModulesCLB->append();
+ m_xLinguModulesCLB->set_id(i, OUString::number(reinterpret_cast<sal_Int64>(&rInfo)));
+ m_xLinguModulesCLB->set_toggle(i, rInfo.bConfigured ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguModulesCLB->set_text(i, rInfo.sDisplayName, 1);
+ }
+ if (nDispSrvcCount)
+ {
+ m_xLinguModulesCLB->select(0);
+ SelectHdl_Impl(*m_xLinguModulesCLB);
+ }
+ m_xLinguModulesEditPB->set_sensitive( nDispSrvcCount > 0 );
+}
+
+void SvxLinguTabPage::Reset( const SfxItemSet* rSet )
+{
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+ UpdateModulesBox_Impl();
+ }
+
+
+ // get data from configuration
+ SvtLinguConfig aLngCfg;
+
+ m_xLinguOptionsCLB->freeze();
+ m_xLinguOptionsCLB->clear();
+
+ sal_Int16 nVal = 0;
+ bool bVal = false;
+ sal_uInt32 nUserData = 0;
+
+ m_xLinguOptionsCLB->append();
+ int nEntry = 0;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_AUTOSPELL_CHECK );
+ if (pItem)
+ bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
+ nUserData = OptionsUserData( EID_SPELL_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellAuto, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_GRAMMAR_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sGrammarAuto, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
+ nUserData = OptionsUserData( EID_CAPITAL_WORDS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sCapitalWords, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
+ nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sWordsWithDigits, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellSpecial, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
+ nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_WORD_LENGTH = nEntry;
+
+ const SfxHyphenRegionItem *pHyp = nullptr;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_HYPHENREGION );
+ if ( rSet->GetItemState( nWhich, false ) == SfxItemState::SET )
+ pHyp = &static_cast<const SfxHyphenRegionItem &>( rSet->Get( nWhich ) );
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinLead());
+ nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_LEADING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinTrail());
+ nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_TRAILING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphAuto, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphSpecial, 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->thaw();
+
+ m_xLinguOptionsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguOptionsCLB);
+
+ m_xLinguModulesCLB->set_size_request(m_xLinguModulesCLB->get_preferred_size().Width(),
+ m_xLinguModulesCLB->get_height_rows(3));
+ m_xLinguDicsCLB->set_size_request(m_xLinguDicsCLB->get_preferred_size().Width(),
+ m_xLinguDicsCLB->get_height_rows(5));
+ m_xLinguOptionsCLB->set_size_request(m_xLinguOptionsCLB->get_preferred_size().Width(),
+ m_xLinguOptionsCLB->get_height_rows(5));
+}
+
+IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView&, rBox, bool)
+{
+ if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
+ {
+ //! in order to avoid a bug causing a GPF when double clicking
+ //! on a module entry and exiting the "Edit Modules" dialog
+ //! after that.
+ m_nDlbClickEventId = Application::PostUserEvent(LINK(this, SvxLinguTabPage, PostDblClickHdl_Impl));
+ }
+ else if (&rBox == m_xLinguOptionsCLB.get())
+ {
+ ClickHdl_Impl(*m_xLinguOptionsEditPB);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void*, void)
+{
+ m_nDlbClickEventId = nullptr;
+ ClickHdl_Impl(*m_xLinguModulesEditPB);
+}
+
+IMPL_LINK(SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl, const row_col&, rRowCol, void)
+{
+ if (!pLinguData)
+ return;
+ auto nPos = rRowCol.first;
+ pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(nPos, 1),
+ m_xLinguModulesCLB->get_toggle(nPos, 0) == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl, const row_col&, rRowCol, void)
+{
+ auto nPos = rRowCol.first;
+ const uno::Reference<XDictionary> &rDic = aDics.getConstArray()[ nPos ];
+ if (LinguMgr::GetIgnoreAllList() == rDic)
+ m_xLinguDicsCLB->set_toggle(nPos, TRISTATE_TRUE, 0);
+}
+
+IMPL_LINK(SvxLinguTabPage, ClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ if (m_xLinguModulesEditPB.get() == &rBtn)
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ SvxLinguData_Impl aOldLinguData( *pLinguData );
+ SvxEditModulesDlg aDlg(GetFrameWeld(), *pLinguData);
+ if (aDlg.run() != RET_OK)
+ *pLinguData = aOldLinguData;
+
+ // evaluate new status of 'bConfigured' flag
+ sal_uInt32 nLen = pLinguData->GetDisplayServiceCount();
+ for (sal_uInt32 i = 0; i < nLen; ++i)
+ pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
+ const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
+ sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
+ for (sal_Int32 k = 0; k < nLocales; ++k)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
+ if (pLinguData->GetSpellTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
+ if (pLinguData->GetGrammarTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
+ if (pLinguData->GetHyphTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
+ if (pLinguData->GetThesTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
+ }
+
+ // show new status of modules
+ UpdateModulesBox_Impl();
+ }
+ else if (m_xLinguDicsNewPB.get() == &rBtn)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNewDictionaryDialog> aDlg(pFact->CreateSvxNewDictionaryDialog(GetFrameWeld()));
+ uno::Reference< XDictionary > xNewDic;
+ if ( aDlg->Execute() == RET_OK )
+ xNewDic = aDlg->GetNewDictionary();
+ if ( xNewDic.is() )
+ {
+ // add new dics to the end
+ sal_Int32 nLen = aDics.getLength();
+ aDics.realloc( nLen + 1 );
+
+ aDics.getArray()[ nLen ] = xNewDic;
+
+ AddDicBoxEntry( xNewDic, static_cast<sal_uInt16>(nLen) );
+ }
+ }
+ else if (m_xLinguDicsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> aDlg(pFact->CreateSvxEditDictionaryDialog(GetFrameWeld(), xDic->getName()));
+ aDlg->Execute();
+ }
+ }
+ }
+ }
+ else if (m_xLinguDicsDelPB.get() == &rBtn)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletedictionarydialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteDictionaryDialog"));
+ if (RET_NO == xQuery->run())
+ return;
+
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ xDic->clear();
+ else
+ {
+ if (xDicList.is())
+ xDicList->removeDictionary( xDic );
+
+ uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( xStor->hasLocation() && !xStor->isReadonly() )
+ {
+ OUString sURL = xStor->getLocation();
+ INetURLObject aObj(sURL);
+ DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
+ "non-file URLs cannot be deleted" );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ {
+ KillFile_Impl( aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ }
+ }
+
+ aDics.getArray()[ nDicPos ] = nullptr;
+
+ // remove entry from checklistbox
+ int nCnt = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nCnt; ++i)
+ {
+ DicUserData aDicData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aDicData.GetEntryId() == nDicPos )
+ {
+ m_xLinguDicsCLB->remove(i);
+ break;
+ }
+ }
+ DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
+ "remove failed ?");
+ }
+ }
+ }
+ }
+ }
+ else if (m_xLinguOptionsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguOptionsCLB->get_selected_index();
+ DBG_ASSERT(nEntry != -1, "no entry selected");
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
+ if (aData.HasNumericValue())
+ {
+ sal_uInt16 nRID = aData.GetEntryId();
+ OptionsBreakSet aDlg(GetFrameWeld(), nRID);
+ aDlg.GetNumericFld().set_value(aData.GetNumericValue());
+ if (RET_OK == aDlg.run())
+ {
+ int nVal = aDlg.GetNumericFld().get_value();
+ if (-1 != nVal && aData.GetNumericValue() != nVal)
+ {
+ aData.SetNumericValue( static_cast<sal_uInt8>(nVal) ); //! sets IsModified !
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ if (nEntry == nUPN_HYPH_MIN_WORD_LENGTH)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 1);
+ else if (nEntry == nUPN_HYPH_MIN_LEADING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 1);
+ else if (nEntry == nUPN_HYPH_MIN_TRAILING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 1);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBtn unexpected value" );
+ }
+}
+
+IMPL_LINK(SvxLinguTabPage, SelectHdl_Impl, weld::TreeView&, rBox, void)
+{
+ if (m_xLinguModulesCLB.get() == &rBox)
+ {
+ }
+ else if (m_xLinguDicsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(rBox.get_id(nEntry).toUInt32());
+
+ // always allow to edit (i.e. at least view the content of the dictionary)
+ m_xLinguDicsEditPB->set_sensitive( true );
+ m_xLinguDicsDelPB->set_sensitive( aData.IsDeletable() );
+ }
+ }
+ else if (m_xLinguOptionsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(rBox.get_id(nEntry).toUInt32());
+ m_xLinguOptionsEditPB->set_sensitive( aData.HasNumericValue() );
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBox unexpected value" );
+ }
+}
+
+void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
+{
+ if ( 0 != ( GROUP_MODULES & nGrp ) )
+ {
+ m_xLinguModulesFT->hide();
+ m_xLinguModulesCLB->hide();
+ m_xLinguModulesEditPB->hide();
+
+ if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode()
+ != SvtExtendedSecurityOptions::OPEN_NEVER )
+ {
+ m_xMoreDictsLink->show();
+ }
+ }
+}
+
+SvxEditModulesDlg::SvxEditModulesDlg(weld::Window* pParent, SvxLinguData_Impl& rData)
+ : GenericDialogController(pParent, "cui/ui/editmodulesdialog.ui", "EditModulesDialog")
+ , sSpell(CuiResId(RID_SVXSTR_SPELL))
+ , sHyph(CuiResId(RID_SVXSTR_HYPH))
+ , sThes(CuiResId(RID_SVXSTR_THES))
+ , sGrammar(CuiResId(RID_SVXSTR_GRAMMAR))
+ , rLinguData(rData)
+ , m_xModulesCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xPrioUpPB(m_xBuilder->weld_button("up"))
+ , m_xPrioDownPB(m_xBuilder->weld_button("down"))
+ , m_xBackPB(m_xBuilder->weld_button("back"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+ , m_xClosePB(m_xBuilder->weld_button("close"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+{
+ m_xModulesCLB->set_size_request(m_xModulesCLB->get_approximate_digit_width() * 40,
+ m_xModulesCLB->get_height_rows(12));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xModulesCLB->get_checkbox_column_width());
+ m_xModulesCLB->set_column_fixed_widths(aWidths);
+
+ pDefaultLinguData.reset( new SvxLinguData_Impl( rLinguData ) );
+
+ m_xModulesCLB->connect_changed( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
+ m_xModulesCLB->connect_toggled(LINK(this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl));
+
+ m_xClosePB->connect_clicked( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
+ m_xPrioUpPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xPrioDownPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xBackPB->connect_clicked( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
+ // in case of not installed language modules
+ m_xPrioUpPB->set_sensitive( false );
+ m_xPrioDownPB->set_sensitive( false );
+
+ if ( SvtExtendedSecurityOptions().GetOpenHyperlinkMode() == SvtExtendedSecurityOptions::OPEN_NEVER )
+ m_xMoreDictsLink->hide();
+
+ // set that we want the checkbox shown if spellchecking is available
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY, false, false, true);
+
+ //fill language box
+ const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
+ for (Locale const & locale : rLoc)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+ m_xLanguageLB->InsertLanguage(nLang);
+ }
+ LanguageType eSysLang = MsLangId::getSystemLanguage();
+ m_xLanguageLB->set_active_id( eSysLang );
+ if (m_xLanguageLB->get_active_id() != eSysLang)
+ m_xLanguageLB->set_active(0);
+
+ m_xLanguageLB->connect_changed( LINK( this, SvxEditModulesDlg, LangSelectListBoxHdl_Impl ));
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+SvxEditModulesDlg::~SvxEditModulesDlg()
+{
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
+}
+
+IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, weld::TreeView&, rBox, void )
+{
+ int nCurPos = rBox.get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ bool bDisableUp = true;
+ bool bDisableDown = true;
+ ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos).toInt64());
+ if (!pData->IsParent() && pData->GetType() != TYPE_HYPH)
+ {
+ if (nCurPos < rBox.n_children() - 1)
+ {
+ bDisableDown = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1).toInt64())->IsParent();
+ }
+ if (nCurPos > 1)
+ {
+ bDisableUp = reinterpret_cast<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1).toInt64())->IsParent();
+ }
+ }
+ m_xPrioUpPB->set_sensitive(!bDisableUp);
+ m_xPrioDownPB->set_sensitive(!bDisableDown);
+}
+
+IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, const row_col&, rRowCol, void )
+{
+ auto nPos = rRowCol.first;
+ ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(nPos).toInt64());
+ if (!(!pData->IsParent() && pData->GetType() == TYPE_HYPH))
+ return;
+
+ // make hyphenator checkboxes function as radio-buttons
+ // (at most one box may be checked)
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
+ if (!pData->IsParent() && pData->GetType() == TYPE_HYPH && i != nPos)
+ {
+ m_xModulesCLB->set_toggle(i, TRISTATE_FALSE, 0);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, LangSelectListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+void SvxEditModulesDlg::LangSelectHdl_Impl(const SvxLanguageBox* pBox)
+{
+ LanguageType eCurLanguage = m_xLanguageLB->get_active_id();
+ static Locale aLastLocale;
+ Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
+
+ if (pBox)
+ {
+ // save old probably changed settings
+ // before switching to new language entries
+
+ LanguageType nLang = LanguageTag::convertToLanguageType( aLastLocale );
+
+ sal_Int32 nStart = 0, nLocalIndex = 0;
+ Sequence< OUString > aChange;
+ bool bChanged = false;
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ ModuleUserData_Impl* pData = reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
+ if (pData->IsParent())
+ {
+ if (bChanged)
+ {
+ LangImplNameTable *pTable = nullptr;
+ sal_uInt8 nType = pData->GetType();
+ switch (nType - 1)
+ {
+ case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
+ case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
+ case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
+ case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
+ }
+ if (pTable)
+ {
+ aChange.realloc(nStart);
+ (*pTable)[ nLang ] = aChange;
+ }
+ }
+ nLocalIndex = nStart = 0;
+ aChange.realloc(nEntryCount);
+ bChanged = false;
+ }
+ else
+ {
+ OUString* pChange = aChange.getArray();
+ pChange[nStart] = pData->GetImplName();
+ bChanged |= pData->GetIndex() != nLocalIndex ||
+ static_cast<TriState>(pData->IsChecked()) != m_xModulesCLB->get_toggle(i, 0);
+ if (m_xModulesCLB->get_toggle(i, 0))
+ nStart++;
+ ++nLocalIndex;
+ }
+ }
+ if(bChanged)
+ {
+ aChange.realloc(nStart);
+ rLinguData.GetThesTable()[ nLang ] = aChange;
+ }
+ }
+
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete reinterpret_cast<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i).toInt64());
+ m_xModulesCLB->clear();
+
+ // display entries for new selected language
+
+ if (LANGUAGE_DONTKNOW != eCurLanguage)
+ {
+ sal_Int32 n;
+ ServiceInfo_Impl* pInfo;
+
+ int nRow = 0;
+ // spellchecker entries
+
+ ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
+ OUString(), true, false, TYPE_SPELL, 0 );
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pUserData)));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sSpell, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 1);
+ ++nRow;
+
+ Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
+ const OUString *pName = aNames.getConstArray();
+ sal_Int32 nNames = aNames.getLength();
+ sal_Int32 nLocalIndex = 0; // index relative to parent
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xSpell.is() &&
+ pInfo->xSpell->hasLocale( aCurLocale );
+ aImplName = pInfo->sSpellImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetSpellTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_SPELL, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xModulesCLB->set_text(nRow, aTxt, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 1);
+ ++nRow;
+ }
+ }
+
+ // grammar checker entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sGrammar, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 1);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xGrammar.is() &&
+ pInfo->xGrammar->hasLocale( aCurLocale );
+ aImplName = pInfo->sGrammarImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetGrammarTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_GRAMMAR, static_cast<sal_uInt8>(nLocalIndex++) );
+
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xModulesCLB->set_text(nRow, aTxt, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 1);
+ ++nRow;
+ }
+ }
+
+ // hyphenator entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sHyph, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 1);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xHyph.is() &&
+ pInfo->xHyph->hasLocale( aCurLocale );
+ aImplName = pInfo->sHyphImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetHyphTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_HYPH, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xModulesCLB->set_text(nRow, aTxt, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 1);
+ ++nRow;
+ }
+ }
+
+ // thesaurus entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sThes, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 1);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xThes.is() &&
+ pInfo->xThes->hasLocale( aCurLocale );
+ aImplName = pInfo->sThesImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetThesTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_THES, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xModulesCLB->set_text(nRow, aTxt, 1);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 1);
+ ++nRow;
+ }
+ }
+ }
+ aLastLocale = aCurLocale;
+}
+
+IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, weld::Button&, rBtn, void )
+{
+ bool bUp = m_xPrioUpPB.get() == &rBtn;
+ int nCurPos = m_xModulesCLB->get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ m_xModulesCLB->freeze();
+
+ OUString sId(m_xModulesCLB->get_id(nCurPos));
+ OUString sStr(m_xModulesCLB->get_text(nCurPos));
+ bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos, nCurPos);
+
+ m_xModulesCLB->remove(nCurPos);
+
+ int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
+
+ m_xModulesCLB->insert_text(nDestPos, sStr);
+ m_xModulesCLB->set_id(nDestPos, sId);
+ m_xModulesCLB->set_toggle(nDestPos, bIsChecked ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+
+ m_xModulesCLB->thaw();
+
+ m_xModulesCLB->select(nDestPos);
+ SelectHdl_Impl(*m_xModulesCLB);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, ClickHdl_Impl, weld::Button&, void)
+{
+ // store language config
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl, weld::Button&, void)
+{
+ rLinguData = *pDefaultLinguData;
+ LangSelectHdl_Impl(nullptr);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.cxx b/cui/source/options/optopencl.cxx
new file mode 100644
index 000000000..e85ef1d7e
--- /dev/null
+++ b/cui/source/options/optopencl.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <opencl/openclconfig.hxx>
+#include <opencl/openclwrapper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <svtools/restartdialog.hxx>
+
+#include "optopencl.hxx"
+
+SvxOpenCLTabPage::SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optopenclpage.ui", "OptOpenCLPage", &rSet)
+ , maConfig(OpenCLConfig::get())
+ , mxUseOpenCL(m_xBuilder->weld_check_button("useopencl"))
+ , mxOclUsed(m_xBuilder->weld_label("openclused"))
+ , mxOclNotUsed(m_xBuilder->weld_label("openclnotused"))
+{
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->set_sensitive(!officecfg::Office::Common::Misc::UseOpenCL::isReadOnly());
+
+ bool bCLUsed = openclwrapper::GPUEnv::isOpenCLEnabled();
+ mxOclUsed->set_visible(bCLUsed);
+ mxOclNotUsed->set_visible(!bCLUsed);
+}
+
+SvxOpenCLTabPage::~SvxOpenCLTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxOpenCLTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxOpenCLTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxOpenCLTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ if (mxUseOpenCL->get_state_changed_from_saved())
+ maConfig.mbUseOpenCL = mxUseOpenCL->get_active();
+
+ if (maConfig != OpenCLConfig::get())
+ {
+ maConfig.set();
+ bModified = true;
+ }
+
+ if (bModified)
+ {
+ batch->commit();
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_OPENCL))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void SvxOpenCLTabPage::Reset( const SfxItemSet* )
+{
+ maConfig = OpenCLConfig::get();
+
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->save_state();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.hxx b/cui/source/options/optopencl.hxx
new file mode 100644
index 000000000..f7097d3fd
--- /dev/null
+++ b/cui/source/options/optopencl.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <opencl/openclconfig.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SvxOpenCLTabPage : public SfxTabPage
+{
+private:
+ OpenCLConfig maConfig;
+
+ std::unique_ptr<weld::CheckButton> mxUseOpenCL;
+ std::unique_ptr<weld::Label> mxOclUsed;
+ std::unique_ptr<weld::Label> mxOclNotUsed;
+
+public:
+ SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOpenCLTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optpath.cxx b/cui/source/options/optpath.cxx
new file mode 100644
index 000000000..809bab6b4
--- /dev/null
+++ b/cui/source/options/optpath.cxx
@@ -0,0 +1,686 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxdlg.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/app.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/defaultoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/viewoptions.hxx>
+
+#include <bitmaps.hlst>
+#include <dialmgr.hxx>
+#include <optpath.hxx>
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/FilePicker.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <tools/diagnose_ex.h>
+#include <sal/log.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::ui::dialogs;
+using namespace css::uno;
+using namespace svx;
+
+// define ----------------------------------------------------------------
+
+#define POSTFIX_INTERNAL "_internal"
+#define POSTFIX_USER "_user"
+#define POSTFIX_WRITABLE "_writable"
+#define VAR_ONE "%1"
+#define IODLG_CONFIGNAME "FilePicker_Save"
+
+// struct OptPath_Impl ---------------------------------------------------
+
+struct OptPath_Impl
+{
+ SvtDefaultOptions m_aDefOpt;
+ OUString m_sMultiPathDlg;
+ Reference< css::util::XPathSettings > m_xPathSettings;
+
+ OptPath_Impl()
+ : m_sMultiPathDlg(CuiResId(RID_SVXSTR_EDIT_PATHS))
+ {
+ }
+};
+
+namespace {
+
+struct PathUserData_Impl
+{
+ sal_uInt16 nRealId;
+ SfxItemState eState;
+ OUString sUserPath;
+ OUString sWritablePath;
+ bool bReadOnly;
+
+ explicit PathUserData_Impl(sal_uInt16 nId)
+ : nRealId(nId)
+ , eState(SfxItemState::UNKNOWN)
+ , bReadOnly(false)
+ {
+ }
+};
+
+struct Handle2CfgNameMapping_Impl
+{
+ sal_uInt16 m_nHandle;
+ const char* m_pCfgName;
+};
+
+}
+
+static Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
+{
+ { SvtPathOptions::PATH_AUTOCORRECT, "AutoCorrect" },
+ { SvtPathOptions::PATH_AUTOTEXT, "AutoText" },
+ { SvtPathOptions::PATH_BACKUP, "Backup" },
+ { SvtPathOptions::PATH_GALLERY, "Gallery" },
+ { SvtPathOptions::PATH_GRAPHIC, "Graphic" },
+ { SvtPathOptions::PATH_TEMP, "Temp" },
+ { SvtPathOptions::PATH_TEMPLATE, "Template" },
+ { SvtPathOptions::PATH_WORK, "Work" },
+ { SvtPathOptions::PATH_DICTIONARY, "Dictionary" },
+ { SvtPathOptions::PATH_CLASSIFICATION, "Classification" },
+#if OSL_DEBUG_LEVEL > 1
+ { SvtPathOptions::PATH_LINGUISTIC, "Linguistic" },
+#endif
+ { USHRT_MAX, nullptr }
+};
+
+static OUString getCfgName_Impl( sal_uInt16 _nHandle )
+{
+ OUString sCfgName;
+ sal_uInt16 nIndex = 0;
+ while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != USHRT_MAX )
+ {
+ if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
+ {
+ // config name found
+ sCfgName = OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
+ break;
+ }
+ ++nIndex;
+ }
+
+ return sCfgName;
+}
+
+#define MULTIPATH_DELIMITER ';'
+
+static OUString Convert_Impl( const OUString& rValue )
+{
+ if (rValue.isEmpty())
+ return OUString();
+
+ sal_Int32 nPos = 0;
+ OUStringBuffer aReturn;
+ for (;;)
+ {
+ OUString aValue = rValue.getToken( 0, MULTIPATH_DELIMITER, nPos );
+ INetURLObject aObj( aValue );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ aReturn.append(aObj.PathToFileName());
+ if ( nPos < 0 )
+ break;
+ aReturn.append(MULTIPATH_DELIMITER);
+ }
+
+ return aReturn.makeStringAndClear();
+}
+
+// functions -------------------------------------------------------------
+
+static bool IsMultiPath_Impl( const sal_uInt16 nIndex )
+{
+#if OSL_DEBUG_LEVEL > 1
+ return ( SvtPathOptions::PATH_AUTOCORRECT == nIndex ||
+ SvtPathOptions::PATH_AUTOTEXT == nIndex ||
+ SvtPathOptions::PATH_BASIC == nIndex ||
+ SvtPathOptions::PATH_GALLERY == nIndex ||
+ SvtPathOptions::PATH_TEMPLATE == nIndex );
+#else
+ return ( SvtPathOptions::PATH_AUTOCORRECT == nIndex ||
+ SvtPathOptions::PATH_AUTOTEXT == nIndex ||
+ SvtPathOptions::PATH_BASIC == nIndex ||
+ SvtPathOptions::PATH_GALLERY == nIndex ||
+ SvtPathOptions::PATH_TEMPLATE == nIndex ||
+ SvtPathOptions::PATH_LINGUISTIC == nIndex ||
+ SvtPathOptions::PATH_DICTIONARY == nIndex );
+#endif
+}
+
+// class SvxPathTabPage --------------------------------------------------
+
+SvxPathTabPage::SvxPathTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optpathspage.ui", "OptPathsPage", &rSet)
+ , pImpl(new OptPath_Impl)
+ , xDialogListener ( new ::svt::DialogClosedListener() )
+ , m_xStandardBtn(m_xBuilder->weld_button("default"))
+ , m_xPathBtn(m_xBuilder->weld_button("edit"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("paths"))
+{
+ m_xStandardBtn->connect_clicked(LINK(this, SvxPathTabPage, StandardHdl_Impl));
+ m_xPathBtn->connect_clicked( LINK( this, SvxPathTabPage, PathHdl_Impl ) );
+
+ m_xPathBox->set_size_request(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(20));
+
+ m_xPathBox->connect_row_activated( LINK( this, SvxPathTabPage, DoubleClickPathHdl_Impl ) );
+ m_xPathBox->connect_changed( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
+ m_xPathBox->set_selection_mode(SelectionMode::Multiple);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
+}
+
+SvxPathTabPage::~SvxPathTabPage()
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ delete reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(i).toInt64());
+}
+
+std::unique_ptr<SfxTabPage> SvxPathTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxPathTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxPathTabPage::FillItemSet( SfxItemSet* )
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ {
+ PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(i).toInt64());
+ sal_uInt16 nRealId = pPathImpl->nRealId;
+ if (pPathImpl->eState == SfxItemState::SET)
+ SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
+ }
+ return true;
+}
+
+void SvxPathTabPage::Reset( const SfxItemSet* )
+{
+ m_xPathBox->clear();
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xPathBox->make_iterator();
+ for( sal_uInt16 i = 0; i <= sal_uInt16(SvtPathOptions::PATH_CLASSIFICATION); ++i )
+ {
+ // only writer uses autotext
+ if ( i == SvtPathOptions::PATH_AUTOTEXT
+ && !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ continue;
+
+ const char* pId = nullptr;
+
+ switch (i)
+ {
+ case SvtPathOptions::PATH_AUTOCORRECT:
+ pId = RID_SVXSTR_KEY_AUTOCORRECT_DIR;
+ break;
+ case SvtPathOptions::PATH_AUTOTEXT:
+ pId = RID_SVXSTR_KEY_GLOSSARY_PATH;
+ break;
+ case SvtPathOptions::PATH_BACKUP:
+ pId = RID_SVXSTR_KEY_BACKUP_PATH;
+ break;
+ case SvtPathOptions::PATH_GALLERY:
+ pId = RID_SVXSTR_KEY_GALLERY_DIR;
+ break;
+ case SvtPathOptions::PATH_GRAPHIC:
+ pId = RID_SVXSTR_KEY_GRAPHICS_PATH;
+ break;
+ case SvtPathOptions::PATH_TEMP:
+ pId = RID_SVXSTR_KEY_TEMP_PATH;
+ break;
+ case SvtPathOptions::PATH_TEMPLATE:
+ pId = RID_SVXSTR_KEY_TEMPLATE_PATH;
+ break;
+ case SvtPathOptions::PATH_DICTIONARY:
+ pId = RID_SVXSTR_KEY_DICTIONARY_PATH;
+ break;
+ case SvtPathOptions::PATH_CLASSIFICATION:
+ pId = RID_SVXSTR_KEY_CLASSIFICATION_PATH;
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ case SvtPathOptions::PATH_LINGUISTIC:
+ pId = RID_SVXSTR_KEY_LINGUISTIC_DIR;
+ break;
+#endif
+ case SvtPathOptions::PATH_WORK:
+ pId = RID_SVXSTR_KEY_WORK_PATH;
+ break;
+ }
+
+ if (pId)
+ {
+ m_xPathBox->append(xIter.get());
+
+ OUString aStr(CuiResId(pId));
+ m_xPathBox->set_text(*xIter, aStr, 0);
+
+ OUString sInternal, sUser, sWritable;
+ bool bReadOnly = false;
+ GetPathList( i, sInternal, sUser, sWritable, bReadOnly );
+
+ if (bReadOnly)
+ m_xPathBox->set_image(*xIter, RID_SVXBMP_LOCK);
+
+ OUString sTmpPath = sUser;
+ if ( !sTmpPath.isEmpty() && !sWritable.isEmpty() )
+ sTmpPath += OUStringChar(MULTIPATH_DELIMITER);
+ sTmpPath += sWritable;
+ const OUString aValue = Convert_Impl( sTmpPath );
+
+ m_xPathBox->set_text(*xIter, aValue, 1);
+
+ const OUString aValueInternal = Convert_Impl( sInternal );
+
+ m_xPathBox->set_text(*xIter, aValueInternal, 2);
+
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 0);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 1);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 2);
+
+ PathUserData_Impl* pPathImpl = new PathUserData_Impl(i);
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ pPathImpl->bReadOnly = bReadOnly;
+
+ OUString sId = OUString::number(reinterpret_cast<sal_Int64>(pPathImpl));
+ m_xPathBox->set_id(*xIter, sId);
+ }
+ }
+
+ m_xPathBox->columns_autosize();
+ PathSelect_Impl(*m_xPathBox);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ bool bEnable = false;
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64());
+ bEnable = !pPathImpl->bReadOnly;
+ }
+ sal_uInt16 nSelCount = m_xPathBox->count_selected_rows();
+ m_xPathBtn->set_sensitive(1 == nSelCount && bEnable);
+ m_xStandardBtn->set_sensitive(nSelCount > 0 && bEnable);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ m_xPathBox->selected_foreach([this](weld::TreeIter& rEntry){
+ PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(rEntry).toInt64());
+ OUString aOldPath = pImpl->m_aDefOpt.GetDefaultPath( pPathImpl->nRealId );
+
+ if ( !aOldPath.isEmpty() )
+ {
+ OUString sInternal, sUser, sWritable, sTemp;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+
+ sal_Int32 nOldPos = 0;
+ do
+ {
+ bool bFound = false;
+ const OUString sOnePath = aOldPath.getToken( 0, MULTIPATH_DELIMITER, nOldPos );
+ if ( !sInternal.isEmpty() )
+ {
+ sal_Int32 nInternalPos = 0;
+ do
+ {
+ if ( sInternal.getToken( 0, MULTIPATH_DELIMITER, nInternalPos ) == sOnePath )
+ bFound = true;
+ }
+ while ( !bFound && nInternalPos >= 0 );
+ }
+ if ( !bFound )
+ {
+ if ( !sTemp.isEmpty() )
+ sTemp += OUStringChar(MULTIPATH_DELIMITER);
+ sTemp += sOnePath;
+ }
+ }
+ while ( nOldPos >= 0 );
+
+ OUString sWritablePath;
+ OUStringBuffer sUserPath;
+ if ( !sTemp.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken = sTemp.getToken( 0, MULTIPATH_DELIMITER, nNextPos );
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritablePath = sToken;
+ break;
+ }
+ if ( !sUserPath.isEmpty() )
+ sUserPath.append(MULTIPATH_DELIMITER);
+ sUserPath.append(sToken);
+ }
+ }
+ m_xPathBox->set_text(rEntry, Convert_Impl(sTemp), 1);
+ pPathImpl->eState = SfxItemState::SET;
+ pPathImpl->sUserPath = sUserPath.makeStringAndClear();
+ pPathImpl->sWritablePath = sWritablePath;
+ }
+ return false;
+ });
+}
+
+void SvxPathTabPage::ChangeCurrentEntry( const OUString& _rFolder )
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ if (nEntry == -1)
+ {
+ SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
+ return;
+ }
+
+ OUString sInternal, sUser, sWritable;
+ PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64());
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+
+ // old path is a URL?
+ INetURLObject aObj( sWritable );
+ bool bURL = ( aObj.GetProtocol() != INetProtocol::NotValid );
+ INetURLObject aNewObj( _rFolder );
+ aNewObj.removeFinalSlash();
+
+ // then the new path also a URL else system path
+ OUString sNewPathStr = bURL ? _rFolder : aNewObj.getFSysPath( FSysStyle::Detect );
+
+ bool bChanged =
+#ifdef UNX
+// Unix is case sensitive
+ ( sNewPathStr != sWritable );
+#else
+ !sNewPathStr.equalsIgnoreAsciiCase( sWritable );
+#endif
+
+ if ( !bChanged )
+ return;
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sNewPathStr), 1);
+ pPathImpl->eState = SfxItemState::SET;
+ pPathImpl->sWritablePath = sNewPathStr;
+ if ( SvtPathOptions::PATH_WORK == pPathImpl->nRealId )
+ {
+ // Remove view options entry so the new work path
+ // will be used for the next open dialog.
+ SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
+ aDlgOpt.Delete();
+ // Reset also last used dir in the sfx application instance
+ SfxApplication *pSfxApp = SfxGetpApp();
+ pSfxApp->ResetLastDir();
+ }
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, DoubleClickPathHdl_Impl, weld::TreeView&, bool)
+{
+ PathHdl_Impl(*m_xPathBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathHdl_Impl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ PathUserData_Impl* pPathImpl = nEntry != -1 ? reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64()) : nullptr;
+ if (!pPathImpl || pPathImpl->bReadOnly)
+ return;
+
+ sal_uInt16 nPos = pPathImpl->nRealId;
+ OUString sInternal, sUser, sWritable;
+ bool bPickFile = false;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+ bPickFile = pPathImpl->nRealId == SvtPathOptions::PATH_CLASSIFICATION;
+
+ if (IsMultiPath_Impl(nPos))
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxMultiPathDialog> pMultiDlg(
+ pFact->CreateSvxMultiPathDialog(GetFrameWeld()));
+
+ OUString sPath( sUser );
+ if ( !sPath.isEmpty() )
+ sPath += OUStringChar(MULTIPATH_DELIMITER);
+ sPath += sWritable;
+ pMultiDlg->SetPath( sPath );
+
+ const OUString sPathName = m_xPathBox->get_text(nEntry, 0);
+ const OUString sNewTitle = pImpl->m_sMultiPathDlg.replaceFirst( VAR_ONE, sPathName );
+ pMultiDlg->SetTitle( sNewTitle );
+
+ if (pMultiDlg->Execute() == RET_OK)
+ {
+ sUser.clear();
+ sWritable.clear();
+ OUString sFullPath;
+ OUString sNewPath = pMultiDlg->GetPath();
+ if ( !sNewPath.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken(sNewPath.getToken( 0, MULTIPATH_DELIMITER, nNextPos ));
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritable = sToken;
+ break;
+ }
+ if ( !sUser.isEmpty() )
+ sUser += OUStringChar(MULTIPATH_DELIMITER);
+ sUser += sToken;
+ }
+ sFullPath = sUser;
+ if ( !sFullPath.isEmpty() )
+ sFullPath += OUStringChar(MULTIPATH_DELIMITER);
+ sFullPath += sWritable;
+ }
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sFullPath), 1);
+ // save modified flag
+ pPathImpl->eState = SfxItemState::SET;
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ }
+ }
+ else if (!bPickFile)
+ {
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = FolderPicker::create(xContext);
+
+ INetURLObject aURL( sWritable, INetProtocol::File );
+ xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener.get() );
+ else
+ {
+ short nRet = xFolderPicker->execute();
+ if (ExecutableDialogResults::OK != nRet)
+ return;
+
+ OUString sFolder(xFolderPicker->getDirectory());
+ ChangeCurrentEntry(sFolder);
+ }
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
+ }
+ }
+ else
+ {
+ try
+ {
+ uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = ui::dialogs::FilePicker::createWithMode(xComponentContext, ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE);
+ xFilePicker->appendFilter(OUString(), "*.xml");
+ if (xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ uno::Sequence<OUString> aPathSeq(xFilePicker->getSelectedFiles());
+ ChangeCurrentEntry(aPathSeq[0]);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options", "exception from file picker");
+ }
+ }
+}
+
+IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if (RET_OK == pEvt->DialogResult)
+ {
+ assert(xFolderPicker.is() && "SvxPathTabPage::DialogClosedHdl(): no folder picker");
+ OUString sURL = xFolderPicker->getDirectory();
+ ChangeCurrentEntry( sURL );
+ }
+}
+
+void SvxPathTabPage::GetPathList(
+ sal_uInt16 _nPathHandle, OUString& _rInternalPath,
+ OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // load internal paths
+ Any aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_INTERNAL);
+ Sequence< OUString > aPathSeq;
+ if ( aAny >>= aPathSeq )
+ {
+ long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rInternalPath.isEmpty() )
+ _rInternalPath += ";";
+ _rInternalPath += pPaths[i];
+ }
+ }
+ // load user paths
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_USER);
+ if ( aAny >>= aPathSeq )
+ {
+ long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rUserPath.isEmpty() )
+ _rUserPath += ";";
+ _rUserPath += pPaths[i];
+ }
+ }
+ // then the writable path
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_WRITABLE);
+ OUString sWritablePath;
+ if ( aAny >>= sWritablePath )
+ _rWritablePath = sWritablePath;
+
+ // and the readonly flag
+ Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName(sCfgName);
+ _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::GetPathList()" );
+ }
+}
+
+
+void SvxPathTabPage::SetPathList(
+ sal_uInt16 _nPathHandle, const OUString& _rUserPath, const OUString& _rWritablePath )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // save user paths
+ const sal_Int32 nCount = comphelper::string::getTokenCount(_rUserPath, MULTIPATH_DELIMITER);
+ Sequence< OUString > aPathSeq( nCount );
+ OUString* pArray = aPathSeq.getArray();
+ sal_Int32 nPos = 0;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ pArray[i] = _rUserPath.getToken( 0, MULTIPATH_DELIMITER, nPos );
+ Any aValue( aPathSeq );
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_USER, aValue);
+
+ // then the writable path
+ aValue <<= _rWritablePath;
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_WRITABLE, aValue);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.cxx b/cui/source/options/optsave.cxx
new file mode 100644
index 000000000..564fabb73
--- /dev/null
+++ b/cui/source/options/optsave.cxx
@@ -0,0 +1,619 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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/eitem.hxx>
+#include <svl/intitem.hxx>
+#include "optsave.hxx"
+#include <comphelper/processfactory.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/saveopt.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/docfilt.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+
+#include <sfx2/fcontnr.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace comphelper;
+
+#define CFG_PAGE_AND_GROUP "General", "LoadSave"
+
+
+struct SvxSaveTabPage_Impl
+{
+ Reference< XNameContainer > xFact;
+ std::vector< OUString > aFilterArr[APP_COUNT];
+ std::vector< bool > aODFArr[APP_COUNT];
+ std::vector< OUString > aUIFilterArr[APP_COUNT];
+ OUString aDefaultArr[APP_COUNT];
+ bool aDefaultReadonlyArr[APP_COUNT];
+ bool bInitialized;
+
+ SvxSaveTabPage_Impl();
+};
+
+SvxSaveTabPage_Impl::SvxSaveTabPage_Impl() : bInitialized( false )
+{
+}
+
+// class SvxSaveTabPage --------------------------------------------------
+
+SvxSaveTabPage::SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optsavepage.ui", "OptSavePage", &rCoreSet )
+ , pImpl(new SvxSaveTabPage_Impl)
+ , m_xLoadUserSettingsCB(m_xBuilder->weld_check_button("load_settings"))
+ , m_xLoadDocPrinterCB(m_xBuilder->weld_check_button("load_docprinter"))
+ , m_xDocInfoCB(m_xBuilder->weld_check_button("docinfo"))
+ , m_xBackupCB(m_xBuilder->weld_check_button("backup"))
+ , m_xAutoSaveCB(m_xBuilder->weld_check_button("autosave"))
+ , m_xAutoSaveEdit(m_xBuilder->weld_spin_button("autosave_spin"))
+ , m_xMinuteFT(m_xBuilder->weld_label("autosave_mins"))
+ , m_xUserAutoSaveCB(m_xBuilder->weld_check_button("userautosave"))
+ , m_xRelativeFsysCB(m_xBuilder->weld_check_button("relative_fsys"))
+ , m_xRelativeInetCB(m_xBuilder->weld_check_button("relative_inet"))
+ , m_xODFVersionLB(m_xBuilder->weld_combo_box("odfversion"))
+ , m_xWarnAlienFormatCB(m_xBuilder->weld_check_button("warnalienformat"))
+ , m_xDocTypeLB(m_xBuilder->weld_combo_box("doctype"))
+ , m_xSaveAsFT(m_xBuilder->weld_label("saveas_label"))
+ , m_xSaveAsLB(m_xBuilder->weld_combo_box("saveas"))
+ , m_xODFWarningFI(m_xBuilder->weld_widget("odfwarning_image"))
+ , m_xODFWarningFT(m_xBuilder->weld_label("odfwarning_label"))
+{
+ m_xODFVersionLB->set_id(0, OUString::number(SvtSaveOptions::ODFVER_011)); // 1.0/1.1
+ m_xODFVersionLB->set_id(1, OUString::number(SvtSaveOptions::ODFVER_012)); // 1.2
+ m_xODFVersionLB->set_id(2, OUString::number(SvtSaveOptions::ODFVER_012_EXT_COMPAT)); // 1.2 Extended (compatibility mode)
+ m_xODFVersionLB->set_id(3, OUString::number(SvtSaveOptions::ODFVER_012_EXTENDED)); // 1.2 Extended
+ m_xODFVersionLB->set_id(4, OUString::number(SvtSaveOptions::ODFVER_013)); // 1.3
+ m_xODFVersionLB->set_id(5, OUString::number(SvtSaveOptions::ODFVER_LATEST)); // 1.3 Extended (recommended)
+
+ m_xDocTypeLB->set_id(0, OUString::number(APP_WRITER) );
+ m_xDocTypeLB->set_id(1, OUString::number(APP_WRITER_WEB) );
+ m_xDocTypeLB->set_id(2, OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->set_id(3, OUString::number(APP_CALC) );
+ m_xDocTypeLB->set_id(4, OUString::number(APP_IMPRESS) );
+ m_xDocTypeLB->set_id(5, OUString::number(APP_DRAW) );
+ m_xDocTypeLB->set_id(6, OUString::number(APP_MATH) );
+
+ m_xAutoSaveCB->connect_clicked( LINK( this, SvxSaveTabPage, AutoClickHdl_Impl ) );
+
+ SvtModuleOptions aModuleOpt;
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_MATH));
+ m_xDocTypeLB->remove_id(OUString::number(APP_MATH));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_MATH] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH);
+ pImpl->aDefaultReadonlyArr[APP_MATH] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::MATH);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_DRAW));
+ m_xDocTypeLB->remove_id(OUString::number(APP_DRAW));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_DRAW] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW);
+ pImpl->aDefaultReadonlyArr[APP_DRAW] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::DRAW);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_IMPRESS));
+ m_xDocTypeLB->remove_id(OUString::number(APP_IMPRESS));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_IMPRESS] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS);
+ pImpl->aDefaultReadonlyArr[APP_IMPRESS] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::IMPRESS);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_CALC));
+ m_xDocTypeLB->remove_id(OUString::number(APP_CALC));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_CALC] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC);
+ pImpl->aDefaultReadonlyArr[APP_CALC] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::CALC);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_WRITER] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultArr[APP_WRITER_WEB] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ pImpl->aDefaultReadonlyArr[APP_WRITER] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_WEB] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_GLOBAL] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ }
+
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxSaveTabPage, ODFVersionHdl_Impl );
+ m_xODFVersionLB->connect_changed( aLink );
+ aLink = LINK( this, SvxSaveTabPage, FilterHdl_Impl );
+ m_xDocTypeLB->connect_changed( aLink );
+ m_xSaveAsLB->connect_changed( aLink );
+
+ DetectHiddenControls();
+}
+
+SvxSaveTabPage::~SvxSaveTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxSaveTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSaveTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSaveTabPage::DetectHiddenControls()
+{
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+
+ if ( aOptionsDlgOpt.IsOptionHidden( "Backup", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "Backup"
+ m_xBackupCB->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( "AutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "AutoSave"
+ m_xAutoSaveCB->hide();
+ m_xAutoSaveEdit->hide();
+ m_xMinuteFT->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( "UserAutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "UserAutoSave"
+ m_xUserAutoSaveCB->hide();
+ }
+
+}
+
+bool SvxSaveTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ SvtSaveOptions aSaveOpt;
+ if(m_xLoadUserSettingsCB->get_state_changed_from_saved())
+ {
+ aSaveOpt.SetLoadUserSettings(m_xLoadUserSettingsCB->get_active());
+ }
+
+ if ( m_xLoadDocPrinterCB->get_state_changed_from_saved() )
+ aSaveOpt.SetLoadDocumentPrinter( m_xLoadDocPrinterCB->get_active() );
+
+ if ( m_xODFVersionLB->get_value_changed_from_saved() )
+ {
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ aSaveOpt.SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion( nVersion ) );
+ }
+
+ if ( m_xDocInfoCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_DOCINFO ),
+ m_xDocInfoCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xBackupCB->get_sensitive() && m_xBackupCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_BACKUP ),
+ m_xBackupCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_AUTOSAVE ),
+ m_xAutoSaveCB->get_active() ) );
+ bModified = true;
+ }
+ if ( m_xWarnAlienFormatCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_WARNALIENFORMAT ),
+ m_xWarnAlienFormatCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveEdit->get_value_changed_from_saved() )
+ {
+ rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_AUTOSAVEMINUTE ),
+ static_cast<sal_uInt16>(m_xAutoSaveEdit->get_value()) ) );
+ bModified = true;
+ }
+
+ if ( m_xUserAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_USERAUTOSAVE ),
+ m_xUserAutoSaveCB->get_active() ) );
+ bModified = true;
+ }
+ // save relatively
+ if ( m_xRelativeFsysCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_SAVEREL_FSYS ),
+ m_xRelativeFsysCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xRelativeInetCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( GetWhich( SID_SAVEREL_INET ),
+ m_xRelativeInetCB->get_active() ) );
+ bModified = true;
+ }
+
+ SvtModuleOptions aModuleOpt;
+ if(!pImpl->aDefaultArr[APP_MATH].isEmpty() &&
+ pImpl->aDefaultArr[APP_MATH] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH, pImpl->aDefaultArr[APP_MATH]);
+
+ if( !pImpl->aDefaultArr[APP_DRAW].isEmpty() &&
+ pImpl->aDefaultArr[APP_DRAW] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW, pImpl->aDefaultArr[APP_DRAW]);
+
+ if(!pImpl->aDefaultArr[APP_IMPRESS].isEmpty() &&
+ pImpl->aDefaultArr[APP_IMPRESS] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS, pImpl->aDefaultArr[APP_IMPRESS]);
+
+ if(!pImpl->aDefaultArr[APP_CALC].isEmpty() &&
+ pImpl->aDefaultArr[APP_CALC] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC, pImpl->aDefaultArr[APP_CALC]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER, pImpl->aDefaultArr[APP_WRITER]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_WEB].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_WEB] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB, pImpl->aDefaultArr[APP_WRITER_WEB]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_GLOBAL].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL, pImpl->aDefaultArr[APP_WRITER_GLOBAL]);
+
+ return bModified;
+}
+
+static bool isODFFormat( const OUString& sFilter )
+{
+ static const char* aODFFormats[] =
+ {
+ "writer8",
+ "writer8_template",
+ "writerglobal8",
+ "writerglobal8_writer",
+ "calc8",
+ "calc8_template",
+ "draw8",
+ "draw8_template",
+ "impress8",
+ "impress8_template",
+ "impress8_draw",
+ "chart8",
+ "math8",
+ nullptr
+ };
+
+ bool bRet = false;
+ int i = 0;
+ while ( aODFFormats[i] != nullptr )
+ {
+ if ( sFilter.equalsAscii( aODFFormats[i++] ) )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+void SvxSaveTabPage::Reset( const SfxItemSet* )
+{
+ SvtSaveOptions aSaveOpt;
+ m_xLoadUserSettingsCB->set_active(aSaveOpt.IsLoadUserSettings());
+ m_xLoadUserSettingsCB->save_state();
+ m_xLoadUserSettingsCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::UseUserData));
+ m_xLoadDocPrinterCB->set_active( aSaveOpt.IsLoadDocumentPrinter() );
+ m_xLoadDocPrinterCB->save_state();
+ m_xLoadDocPrinterCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::LoadDocPrinter));
+
+ if ( !pImpl->bInitialized )
+ {
+ try
+ {
+ Reference< XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
+ pImpl->xFact.set(xMSF->createInstance("com.sun.star.document.FilterFactory"), UNO_QUERY);
+
+ DBG_ASSERT(pImpl->xFact.is(), "service com.sun.star.document.FilterFactory unavailable");
+ Reference< XContainerQuery > xQuery(pImpl->xFact, UNO_QUERY);
+ if(xQuery.is())
+ {
+ for (sal_Int32 n = 0, nEntryCount = m_xDocTypeLB->get_count(); n < nEntryCount; ++n)
+ {
+ int nData = m_xDocTypeLB->get_id(n).toInt32();
+ OUString sCommand = "getSortedFilterList():module=%1:iflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::IMPORT|SfxFilterFlags::EXPORT)) +
+ ":eflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::NOTINFILEDLG));
+ OUString sReplace;
+ switch(nData)
+ {
+ case APP_WRITER : sReplace = "com.sun.star.text.TextDocument"; break;
+ case APP_WRITER_WEB : sReplace = "com.sun.star.text.WebDocument"; break;
+ case APP_WRITER_GLOBAL : sReplace = "com.sun.star.text.GlobalDocument"; break;
+ case APP_CALC : sReplace = "com.sun.star.sheet.SpreadsheetDocument";break;
+ case APP_IMPRESS : sReplace = "com.sun.star.presentation.PresentationDocument";break;
+ case APP_DRAW : sReplace = "com.sun.star.drawing.DrawingDocument";break;
+ case APP_MATH : sReplace = "com.sun.star.formula.FormulaProperties";break;
+ default: OSL_FAIL("illegal user data");
+ }
+ sCommand = sCommand.replaceFirst("%1", sReplace);
+ Reference< XEnumeration > xList = xQuery->createSubSetEnumerationByQuery(sCommand);
+ std::vector< OUString > lList;
+ std::vector<bool> lODFList;
+ while(xList->hasMoreElements())
+ {
+ SequenceAsHashMap aFilter(xList->nextElement());
+ OUString sFilter = aFilter.getUnpackedValueOrDefault("Name",OUString());
+ if (!sFilter.isEmpty())
+ {
+ lList.push_back(sFilter);
+ lODFList.push_back( isODFFormat( sFilter ) );
+ }
+ }
+ pImpl->aFilterArr[nData] = lList;
+ pImpl->aODFArr[nData] = lODFList;
+ }
+ }
+ m_xDocTypeLB->set_active(0);
+ FilterHdl_Impl(*m_xDocTypeLB);
+ }
+ catch(Exception const &)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "exception in FilterFactory access" );
+ }
+
+ pImpl->bInitialized = true;
+ }
+
+ m_xDocInfoCB->set_active(aSaveOpt.IsDocInfoSave());
+ m_xDocInfoCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::DocInfSave));
+
+ m_xBackupCB->set_active(aSaveOpt.IsBackup());
+ m_xBackupCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::Backup));
+
+ m_xAutoSaveCB->set_active(aSaveOpt.IsAutoSave());
+ m_xAutoSaveCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::AutoSave));
+
+ m_xUserAutoSaveCB->set_active(aSaveOpt.IsUserAutoSave());
+ m_xUserAutoSaveCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::UserAutoSave));
+
+ m_xWarnAlienFormatCB->set_active(aSaveOpt.IsWarnAlienFormat());
+ m_xWarnAlienFormatCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::WarnAlienFormat));
+
+ m_xAutoSaveEdit->set_value(aSaveOpt.GetAutoSaveTime());
+ m_xAutoSaveEdit->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::AutoSaveTime));
+
+ // save relatively
+ m_xRelativeFsysCB->set_active(aSaveOpt.IsSaveRelFSys());
+ m_xRelativeFsysCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::SaveRelFsys));
+
+ m_xRelativeInetCB->set_active(aSaveOpt.IsSaveRelINet());
+ m_xRelativeInetCB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::SaveRelInet));
+
+ sal_Int32 nDefaultVersion = aSaveOpt.GetODFDefaultVersion();
+ m_xODFVersionLB->set_active_id(OUString::number(nDefaultVersion));
+ m_xODFVersionLB->set_sensitive(!aSaveOpt.IsReadOnly(SvtSaveOptions::EOption::OdfDefaultVersion));
+
+ AutoClickHdl_Impl(*m_xAutoSaveCB);
+ ODFVersionHdl_Impl(*m_xODFVersionLB);
+
+ m_xDocInfoCB->save_state();
+ m_xBackupCB->save_state();
+ m_xWarnAlienFormatCB->save_state();
+ m_xAutoSaveCB->save_state();
+ m_xAutoSaveEdit->save_value();
+
+ m_xUserAutoSaveCB->save_state();
+
+ m_xRelativeFsysCB->save_state();
+ m_xRelativeInetCB->save_state();
+ m_xODFVersionLB->save_value();
+}
+
+IMPL_LINK(SvxSaveTabPage, AutoClickHdl_Impl, weld::Button&, rBox, void)
+{
+ if (&rBox != m_xAutoSaveCB.get())
+ return;
+
+ if (m_xAutoSaveCB->get_active())
+ {
+ m_xAutoSaveEdit->set_sensitive(true);
+ m_xMinuteFT->set_sensitive(true);
+ m_xUserAutoSaveCB->set_sensitive(true);
+ }
+ else
+ {
+ m_xAutoSaveEdit->set_sensitive(false);
+ m_xMinuteFT->set_sensitive(false);
+ m_xUserAutoSaveCB->set_sensitive(false);
+ }
+}
+
+static OUString lcl_ExtracUIName(const Sequence<PropertyValue> &rProperties, const OUString& rExtension)
+{
+ OUString sName;
+ const PropertyValue* pPropVal = rProperties.getConstArray();
+ const PropertyValue* const pEnd = pPropVal + rProperties.getLength();
+ for( ; pPropVal != pEnd; pPropVal++ )
+ {
+ const OUString &rName = pPropVal->Name;
+ if (rName == "UIName")
+ {
+ OUString sUIName;
+ if ( ( pPropVal->Value >>= sUIName ) && sUIName.getLength() )
+ {
+ if (!rExtension.isEmpty())
+ {
+ return sUIName + " (" + rExtension + ")";
+ }
+ else
+ {
+ return sUIName;
+ }
+ }
+ }
+ else if (rName == "Name")
+ {
+ pPropVal->Value >>= sName;
+ }
+ }
+
+ OSL_ENSURE( false, "Filter without UIName!" );
+
+ return sName;
+}
+
+IMPL_LINK( SvxSaveTabPage, FilterHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ const int nCurPos = m_xDocTypeLB->get_active();
+
+ int nData = -1;
+ if (nCurPos < APP_COUNT)
+ nData = m_xDocTypeLB->get_id(nCurPos).toInt32();
+
+ if ( nData >= 0 && nData < APP_COUNT )
+ {
+ if(m_xDocTypeLB.get() == &rBox)
+ {
+ m_xSaveAsLB->clear();
+ auto & rFilters = pImpl->aFilterArr[nData];
+ if(pImpl->aUIFilterArr[nData].empty())
+ {
+ pImpl->aUIFilterArr[nData].resize(pImpl->aFilterArr[nData].size());
+ auto & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t nFilter = 0; nFilter < pImpl->aFilterArr[nData].size(); nFilter++)
+ {
+ Any aProps = pImpl->xFact->getByName(rFilters[nFilter]);
+ // get the extension of the filter
+ OUString extension;
+ SfxFilterMatcher matcher;
+ std::shared_ptr<const SfxFilter> pFilter = matcher.GetFilter4FilterName(rFilters[nFilter]);
+ if (pFilter)
+ {
+ extension = pFilter->GetWildcard().getGlob().getToken(0, ';');
+ }
+ Sequence<PropertyValue> aProperties;
+ aProps >>= aProperties;
+ rUIFilters[nFilter] = lcl_ExtracUIName(aProperties, extension);
+ }
+ }
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ OUString sSelect;
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ {
+ OUString sId;
+ if (pImpl->aODFArr[nData][i])
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pImpl.get()));
+ m_xSaveAsLB->append(sId, rUIFilters[i]);
+ if (rFilters[i] == pImpl->aDefaultArr[nData])
+ sSelect = rUIFilters[i];
+ }
+ if (!sSelect.isEmpty())
+ {
+ m_xSaveAsLB->set_active_text(sSelect);
+ }
+
+ m_xSaveAsFT->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ m_xSaveAsLB->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ }
+ else
+ {
+ OUString sSelect = rBox.get_active_text();
+ auto const & rFilters = pImpl->aFilterArr[nData];
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ if(rUIFilters[i] == sSelect)
+ {
+ sSelect = rFilters[i];
+ break;
+ }
+
+ pImpl->aDefaultArr[nData] = sSelect;
+ }
+ }
+
+ ODFVersionHdl_Impl( *m_xSaveAsLB );
+}
+
+IMPL_LINK_NOARG(SvxSaveTabPage, ODFVersionHdl_Impl, weld::ComboBox&, void)
+{
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ bool bShown = SvtSaveOptions::ODFDefaultVersion(nVersion) != SvtSaveOptions::ODFVER_LATEST;
+ if ( bShown )
+ {
+ bool bHasODFFormat = false;
+ const int nCount = m_xSaveAsLB->get_count();
+ for (int i = 0; i < nCount; ++i )
+ {
+ if ( m_xSaveAsLB->get_id(i).toInt64() != 0 )
+ {
+ bHasODFFormat = true;
+ break;
+ }
+ }
+
+ bShown = !bHasODFFormat
+ || ( m_xSaveAsLB->get_active_id().toInt64() != 0);
+ }
+
+ m_xODFWarningFI->set_visible(bShown);
+ m_xODFWarningFT->set_visible(bShown);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.hxx b/cui/source/options/optsave.hxx
new file mode 100644
index 000000000..f916963e4
--- /dev/null
+++ b/cui/source/options/optsave.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+#define APP_WRITER 0
+#define APP_WRITER_WEB 1
+#define APP_WRITER_GLOBAL 2
+#define APP_CALC 3
+#define APP_IMPRESS 4
+#define APP_DRAW 5
+#define APP_MATH 6
+#define APP_COUNT 7
+
+namespace com::sun::star::beans { struct PropertyValue; }
+
+// class SvxSaveTabPage --------------------------------------------------
+
+struct SvxSaveTabPage_Impl;
+
+class SvxSaveTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxSaveTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::CheckButton> m_xLoadUserSettingsCB;
+ std::unique_ptr<weld::CheckButton> m_xLoadDocPrinterCB;
+ std::unique_ptr<weld::CheckButton> m_xDocInfoCB;
+ std::unique_ptr<weld::CheckButton> m_xBackupCB;
+ std::unique_ptr<weld::CheckButton> m_xAutoSaveCB;
+ std::unique_ptr<weld::SpinButton> m_xAutoSaveEdit;
+ std::unique_ptr<weld::Label> m_xMinuteFT;
+ std::unique_ptr<weld::CheckButton> m_xUserAutoSaveCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeFsysCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeInetCB;
+ std::unique_ptr<weld::ComboBox> m_xODFVersionLB;
+ std::unique_ptr<weld::CheckButton> m_xWarnAlienFormatCB;
+ std::unique_ptr<weld::ComboBox> m_xDocTypeLB;
+ std::unique_ptr<weld::Label> m_xSaveAsFT;
+ std::unique_ptr<weld::ComboBox> m_xSaveAsLB;
+ std::unique_ptr<weld::Widget> m_xODFWarningFI;
+ std::unique_ptr<weld::Label> m_xODFWarningFT;
+
+ DECL_LINK( AutoClickHdl_Impl, weld::Button&, void );
+ DECL_LINK( FilterHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK(ODFVersionHdl_Impl, weld::ComboBox&, void );
+
+ void DetectHiddenControls();
+
+public:
+ SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxSaveTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.cxx b/cui/source/options/optupdt.cxx
new file mode 100644
index 000000000..2f39687cc
--- /dev/null
+++ b/cui/source/options/optupdt.cxx
@@ -0,0 +1,396 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/zforlist.hxx>
+#include "optupdt.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/deployment/UpdateInformationProvider.hpp>
+#include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/setup/UpdateCheckConfig.hpp>
+#include <com/sun/star/configuration/ReadWriteAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <tools/diagnose_ex.h>
+
+using namespace ::css;
+
+SvxOnlineUpdateTabPage::SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optonlineupdatepage.ui", "OptOnlineUpdatePage", &rSet)
+ , m_xNeverChecked(m_xBuilder->weld_label("neverchecked"))
+ , m_xAutoCheckCheckBox(m_xBuilder->weld_check_button("autocheck"))
+ , m_xEveryDayButton(m_xBuilder->weld_radio_button("everyday"))
+ , m_xEveryWeekButton(m_xBuilder->weld_radio_button("everyweek"))
+ , m_xEveryMonthButton(m_xBuilder->weld_radio_button("everymonth"))
+ , m_xCheckNowButton(m_xBuilder->weld_button("checknow"))
+ , m_xAutoDownloadCheckBox(m_xBuilder->weld_check_button("autodownload"))
+ , m_xDestPathLabel(m_xBuilder->weld_label("destpathlabel"))
+ , m_xDestPath(m_xBuilder->weld_label("destpath"))
+ , m_xChangePathButton(m_xBuilder->weld_button("changepath"))
+ , m_xLastChecked(m_xBuilder->weld_label("lastchecked"))
+ , m_xExtrasCheckBox(m_xBuilder->weld_check_button("extrabits"))
+ , m_xUserAgentLabel(m_xBuilder->weld_label("useragent"))
+{
+ m_aNeverChecked = m_xNeverChecked->get_label();
+
+ m_xAutoCheckCheckBox->connect_toggled( LINK( this, SvxOnlineUpdateTabPage, AutoCheckHdl_Impl ) );
+ m_xExtrasCheckBox->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl ) );
+ m_xCheckNowButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, CheckNowHdl_Impl ) );
+ m_xChangePathButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, FileDialogHdl_Impl ) );
+
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ m_xUpdateAccess = setup::UpdateCheckConfig::create( xContext );
+ m_xReadWriteAccess = css::configuration::ReadWriteAccess::create(xContext, "*");
+
+ bool bDownloadSupported = false;
+ m_xUpdateAccess->getByName( "DownloadSupported" ) >>= bDownloadSupported;
+
+ m_xAutoDownloadCheckBox->set_visible(bDownloadSupported);
+ m_xDestPathLabel->set_visible(bDownloadSupported);
+ m_xDestPath->set_visible(bDownloadSupported);
+ m_xChangePathButton->set_visible(bDownloadSupported);
+
+ m_aLastCheckedTemplate = m_xLastChecked->get_label();
+
+ UpdateLastCheckedText();
+ UpdateUserAgent();
+}
+
+SvxOnlineUpdateTabPage::~SvxOnlineUpdateTabPage()
+{
+}
+
+void SvxOnlineUpdateTabPage::UpdateLastCheckedText()
+{
+ OUString aDateStr;
+ OUString aTimeStr;
+ OUString aText;
+ sal_Int64 lastChecked = 0;
+
+ m_xUpdateAccess->getByName("LastCheck") >>= lastChecked;
+
+ if( lastChecked == 0 ) // never checked
+ {
+ aText = m_aNeverChecked;
+ }
+ else
+ {
+ TimeValue lastCheckedTV;
+ oslDateTime lastCheckedDT;
+
+ Date aDate( Date::EMPTY );
+ tools::Time aTime( tools::Time::EMPTY );
+
+ lastCheckedTV.Seconds = static_cast<sal_uInt32>(lastChecked);
+ osl_getLocalTimeFromSystemTime( &lastCheckedTV, &lastCheckedTV );
+
+ if ( osl_getDateTimeFromTimeValue( &lastCheckedTV, &lastCheckedDT ) )
+ {
+ aDate = Date( lastCheckedDT.Day, lastCheckedDT.Month, lastCheckedDT.Year );
+ aTime = ::tools::Time( lastCheckedDT.Hours, lastCheckedDT.Minutes );
+ }
+
+ LanguageType eUILang = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ std::unique_ptr<SvNumberFormatter> pNumberFormatter(new SvNumberFormatter( ::comphelper::getProcessComponentContext(), eUILang ));
+ Color* pColor = nullptr;
+ const Date& rNullDate = pNumberFormatter->GetNullDate();
+ sal_uInt32 nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::DATE, eUILang );
+
+ pNumberFormatter->GetOutputString( aDate - rNullDate, nFormat, aDateStr, &pColor );
+
+ nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::TIME, eUILang );
+ pNumberFormatter->GetOutputString( aTime.GetTimeInDays(), nFormat, aTimeStr, &pColor );
+
+ pNumberFormatter.reset();
+
+ aText = m_aLastCheckedTemplate;
+ sal_Int32 nIndex = aText.indexOf( "%DATE%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aDateStr );
+
+ nIndex = aText.indexOf( "%TIME%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aTimeStr );
+ }
+
+ m_xLastChecked->set_label(aText);
+}
+
+void SvxOnlineUpdateTabPage::UpdateUserAgent()
+{
+ try {
+ uno::Reference< ucb::XWebDAVCommandEnvironment > xDav(
+ css::deployment::UpdateInformationProvider::create(
+ ::comphelper::getProcessComponentContext() ),
+ css::uno::UNO_QUERY_THROW );
+
+ OUString aPseudoURL = "useragent:normal";
+ if( m_xExtrasCheckBox->get_active() )
+ aPseudoURL = "useragent:extended";
+ const uno::Sequence< beans::StringPair > aHeaders
+ = xDav->getUserRequestHeaders( aPseudoURL, ucb::WebDAVHTTPMethod(0) );
+
+ for (const css::beans::StringPair & aHeader : aHeaders)
+ {
+ if ( aHeader.First == "User-Agent" )
+ {
+ OUString aText = aHeader.Second;
+ aText = aText.replaceAll(";", ";\n");
+ aText = aText.replaceAll("(", "\n(");
+ m_xUserAgentLabel->set_label(aText);
+ break;
+ }
+ }
+ } catch (const uno::Exception &) {
+ TOOLS_WARN_EXCEPTION( "cui.options", "Unexpected exception fetching User Agent" );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxOnlineUpdateTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxOnlineUpdateTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxOnlineUpdateTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ bool bValue;
+ sal_Int64 nValue;
+
+ if( m_xAutoCheckCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoCheckCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoCheckEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ nValue = 0;
+ if( m_xEveryDayButton->get_active() )
+ {
+ if( !m_xEveryDayButton->get_saved_state() )
+ nValue = 86400;
+ }
+ else if( m_xEveryWeekButton->get_active() )
+ {
+ if( !m_xEveryWeekButton->get_saved_state() )
+ nValue = 604800;
+ }
+ else if( m_xEveryMonthButton->get_active() )
+ {
+ if( !m_xEveryMonthButton->get_saved_state() )
+ nValue = 2592000;
+ }
+
+ if( nValue > 0 )
+ {
+ m_xUpdateAccess->replaceByName( "CheckInterval", uno::Any( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xAutoDownloadCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoDownloadCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoDownloadEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ OUString sValue, aURL;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+
+ if( ( osl::FileBase::E_None == osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) ) &&
+ ( aURL != sValue ) )
+ {
+ m_xUpdateAccess->replaceByName( "DownloadDestination", uno::Any( aURL ) );
+ bModified = true;
+ }
+
+ if( m_xExtrasCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xExtrasCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "ExtendedUserAgent", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ uno::Reference< util::XChangesBatch > xChangesBatch(m_xUpdateAccess, uno::UNO_QUERY);
+ if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+
+ return bModified;
+}
+
+void SvxOnlineUpdateTabPage::Reset( const SfxItemSet* )
+{
+ bool bValue = false;
+ m_xUpdateAccess->getByName( "AutoCheckEnabled" ) >>= bValue;
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoCheckEnabled");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+
+ m_xAutoCheckCheckBox->set_active(bValue);
+ m_xAutoCheckCheckBox->set_sensitive(!bReadOnly);
+
+ sal_Int64 nValue = 0;
+ m_xUpdateAccess->getByName( "CheckInterval" ) >>= nValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly2 = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryWeekButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryMonthButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+
+ if( nValue == 86400 )
+ m_xEveryDayButton->set_active(true);
+ else if( nValue == 604800 )
+ m_xEveryWeekButton->set_active(true);
+ else
+ m_xEveryMonthButton->set_active(true);
+
+ m_xAutoCheckCheckBox->save_state();
+ m_xEveryDayButton->save_state();
+ m_xEveryWeekButton->save_state();
+ m_xEveryMonthButton->save_state();
+
+ m_xUpdateAccess->getByName( "AutoDownloadEnabled" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoDownloadEnabled");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xAutoDownloadCheckBox->set_active(bValue);
+ m_xAutoDownloadCheckBox->set_sensitive(!bReadOnly);
+ m_xDestPathLabel->set_sensitive(true);
+ m_xDestPath->set_sensitive(true);
+
+ OUString sValue, aPath;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/DownloadDestination");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xChangePathButton->set_sensitive(!bReadOnly);
+
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sValue, aPath) )
+ m_xDestPath->set_label(aPath);
+
+ m_xUpdateAccess->getByName( "ExtendedUserAgent" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/ExtendedUserAgent");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xExtrasCheckBox->set_active(bValue);
+ m_xExtrasCheckBox->set_sensitive(!bReadOnly);
+ m_xExtrasCheckBox->save_state();
+ UpdateUserAgent();
+
+ m_xAutoDownloadCheckBox->save_state();
+}
+
+void SvxOnlineUpdateTabPage::FillUserData()
+{
+}
+
+IMPL_LINK(SvxOnlineUpdateTabPage, AutoCheckHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ bool bEnabled = rBox.get_active();
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryWeekButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryMonthButton->set_sensitive(bEnabled && !bReadOnly);
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl, weld::Button&, void)
+{
+ UpdateUserAgent();
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = ui::dialogs::FolderPicker::create(xContext);
+
+ OUString aURL;
+ if( osl::FileBase::E_None != osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) )
+ osl::Security().getHomeDir(aURL);
+
+ xFolderPicker->setDisplayDirectory( aURL );
+ sal_Int16 nRet = xFolderPicker->execute();
+
+ if ( ui::dialogs::ExecutableDialogResults::OK == nRet )
+ {
+ OUString aFolder;
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(xFolderPicker->getDirectory(), aFolder))
+ m_xDestPath->set_label(aFolder);
+ }
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, CheckNowHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob");
+
+ uno::Sequence< uno::Any > aArgumentList( 1 );
+ aArgumentList[0] <<= aProperty;
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess", aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ util::URL aURL;
+ xNameAccess->getByName("URL") >>= aURL.Complete;
+
+ uno::Reference < util::XURLTransformer > xTransformer( util::URLTransformer::create( xContext ) );
+
+ xTransformer->parseStrict(aURL);
+
+ uno::Reference < frame::XDesktop2 > xDesktop = frame::Desktop::create( xContext );
+
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider(
+ xDesktop->getCurrentFrame(), uno::UNO_QUERY );
+
+ uno::Reference< frame::XDispatch > xDispatch;
+ if( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch(aURL, OUString(), 0);
+
+ if( xDispatch.is() )
+ xDispatch->dispatch(aURL, uno::Sequence< beans::PropertyValue > ());
+
+ UpdateLastCheckedText();
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "Caught exception, thread terminated");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.hxx b/cui/source/options/optupdt.hxx
new file mode 100644
index 000000000..bd418991c
--- /dev/null
+++ b/cui/source/options/optupdt.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_CUI_SOURCE_OPTIONS_OPTUPDT_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_OPTUPDT_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/configuration/XReadWriteAccess.hpp>
+
+// class SvxPathTabPage --------------------------------------------------
+
+class SvxOnlineUpdateTabPage : public SfxTabPage
+{
+private:
+ OUString m_aNeverChecked;
+ OUString m_aLastCheckedTemplate;
+
+ css::uno::Reference< css::container::XNameReplace > m_xUpdateAccess;
+ css::uno::Reference<css::configuration::XReadWriteAccess> m_xReadWriteAccess;
+
+ std::unique_ptr<weld::Label> m_xNeverChecked;
+ std::unique_ptr<weld::CheckButton> m_xAutoCheckCheckBox;
+ std::unique_ptr<weld::RadioButton> m_xEveryDayButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryWeekButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryMonthButton;
+ std::unique_ptr<weld::Button> m_xCheckNowButton;
+ std::unique_ptr<weld::CheckButton> m_xAutoDownloadCheckBox;
+ std::unique_ptr<weld::Label> m_xDestPathLabel;
+ std::unique_ptr<weld::Label> m_xDestPath;
+ std::unique_ptr<weld::Button> m_xChangePathButton;
+ std::unique_ptr<weld::Label> m_xLastChecked;
+ std::unique_ptr<weld::CheckButton> m_xExtrasCheckBox;
+ std::unique_ptr<weld::Label> m_xUserAgentLabel;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNowHdl_Impl, weld::Button&, void);
+ DECL_LINK(AutoCheckHdl_Impl, weld::ToggleButton&, void);
+ DECL_LINK(ExtrasCheckHdl_Impl, weld::Button&, void);
+
+ void UpdateLastCheckedText();
+ void UpdateUserAgent();
+
+public:
+ SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOnlineUpdateTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.cxx b/cui/source/options/personalization.cxx
new file mode 100644
index 000000000..a732053ba
--- /dev/null
+++ b/cui/source/options/personalization.cxx
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_folders.h>
+
+#include "personalization.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/virdev.hxx>
+
+#include <vector>
+
+using namespace com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+// persona
+SvxPersonalizationTabPage::SvxPersonalizationTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/personalization_tab.ui", "PersonalizationTabPage",
+ &rSet)
+ , m_xNoPersona(m_xBuilder->weld_radio_button("no_persona"))
+ , m_xDefaultPersona(m_xBuilder->weld_radio_button("default_persona"))
+{
+ for (sal_uInt32 i = 0; i < MAX_DEFAULT_PERSONAS; ++i)
+ {
+ OString sDefaultId("default" + OString::number(i));
+ m_vDefaultPersonaImages[i] = m_xBuilder->weld_toggle_button(sDefaultId);
+ m_vDefaultPersonaImages[i]->connect_clicked(
+ LINK(this, SvxPersonalizationTabPage, DefaultPersona));
+ }
+
+ LoadDefaultImages();
+}
+
+SvxPersonalizationTabPage::~SvxPersonalizationTabPage() {}
+
+std::unique_ptr<SfxTabPage> SvxPersonalizationTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxPersonalizationTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxPersonalizationTabPage::FillItemSet(SfxItemSet*)
+{
+ // persona
+ OUString aPersona("default");
+ if (m_xNoPersona->get_active())
+ aPersona = "no";
+
+ bool bModified = false;
+ uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+ if (xContext.is()
+ && (aPersona != officecfg::Office::Common::Misc::Persona::get(xContext)
+ || m_aPersonaSettings
+ != officecfg::Office::Common::Misc::PersonaSettings::get(xContext)))
+ {
+ bModified = true;
+ }
+
+ // write
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (aPersona == "no")
+ m_aPersonaSettings.clear();
+ officecfg::Office::Common::Misc::Persona::set(aPersona, batch);
+ officecfg::Office::Common::Misc::PersonaSettings::set(m_aPersonaSettings, batch);
+ batch->commit();
+
+ if (bModified)
+ {
+ // broadcast the change
+ DataChangedEvent aDataChanged(DataChangedEventType::SETTINGS, nullptr,
+ AllSettingsFlags::STYLE);
+ Application::NotifyAllWindows(aDataChanged);
+ }
+
+ return bModified;
+}
+
+void SvxPersonalizationTabPage::Reset(const SfxItemSet*)
+{
+ uno::Reference<uno::XComponentContext> xContext(comphelper::getProcessComponentContext());
+
+ // persona
+ OUString aPersona("default");
+ if (xContext.is())
+ {
+ aPersona = officecfg::Office::Common::Misc::Persona::get(xContext);
+ m_aPersonaSettings = officecfg::Office::Common::Misc::PersonaSettings::get(xContext);
+ }
+
+ if (aPersona == "no")
+ m_xNoPersona->set_active(true);
+ else
+ m_xDefaultPersona->set_active(true);
+}
+
+void SvxPersonalizationTabPage::LoadDefaultImages()
+{
+ // Load the pre saved personas
+
+ OUString gallery = "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/gallery/personas/";
+ rtl::Bootstrap::expandMacros(gallery);
+ OUString aPersonasList = gallery + "personas_list.txt";
+ SvFileStream aStream(aPersonasList, StreamMode::READ);
+ GraphicFilter aFilter;
+ Graphic aGraphic;
+ sal_Int32 nIndex = 0;
+ bool foundOne = false;
+
+ while (aStream.IsOpen() && !aStream.eof() && nIndex < MAX_DEFAULT_PERSONAS)
+ {
+ OString aLine;
+ OUString aPersonaSetting, aPreviewFile, aName;
+ sal_Int32 nParseIndex = 0;
+
+ aStream.ReadLine(aLine);
+ aPersonaSetting = OStringToOUString(aLine, RTL_TEXTENCODING_UTF8);
+ aName = aPersonaSetting.getToken(1, ';', nParseIndex);
+ aPreviewFile = aPersonaSetting.getToken(0, ';', nParseIndex);
+
+ if (aPreviewFile.isEmpty())
+ break;
+
+ m_vDefaultPersonaSettings.push_back(aPersonaSetting);
+
+ INetURLObject aURLObj(gallery + aPreviewFile);
+ aFilter.ImportGraphic(aGraphic, aURLObj);
+
+ Size aSize(aGraphic.GetSizePixel());
+ aSize.setWidth(aSize.Width() / 4);
+ aSize.setHeight(aSize.Height() / 1.5);
+ ScopedVclPtr<VirtualDevice> xVirDev
+ = m_vDefaultPersonaImages[nIndex]->create_virtual_device();
+ xVirDev->SetOutputSizePixel(aSize);
+ aGraphic.Draw(xVirDev.get(), Point(0, 0));
+ m_vDefaultPersonaImages[nIndex]->set_image(xVirDev.get());
+ xVirDev.disposeAndClear();
+
+ m_vDefaultPersonaImages[nIndex]->set_tooltip_text(aName);
+ m_vDefaultPersonaImages[nIndex++]->show();
+ foundOne = true;
+ }
+
+ m_xDefaultPersona->set_sensitive(foundOne);
+}
+
+IMPL_LINK(SvxPersonalizationTabPage, DefaultPersona, weld::Button&, rButton, void)
+{
+ m_xDefaultPersona->set_active(true);
+ for (sal_Int32 nIndex = 0; nIndex < MAX_DEFAULT_PERSONAS; ++nIndex)
+ {
+ if (&rButton == m_vDefaultPersonaImages[nIndex].get())
+ m_aPersonaSettings = m_vDefaultPersonaSettings[nIndex];
+ else
+ m_vDefaultPersonaImages[nIndex]->set_active(false);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.hxx b/cui/source/options/personalization.hxx
new file mode 100644
index 000000000..072a89b81
--- /dev/null
+++ b/cui/source/options/personalization.hxx
@@ -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/.
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_OPTIONS_PERSONALIZATION_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_PERSONALIZATION_HXX
+
+#include <sfx2/tabdlg.hxx>
+#include <vector>
+
+#define MAX_DEFAULT_PERSONAS 6 // Maximum number of default personas
+
+class SvxPersonalizationTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::RadioButton> m_xNoPersona; ///< Just the default look, without any bitmap
+ std::unique_ptr<weld::RadioButton> m_xDefaultPersona; ///< Use the built-in bitmap
+ std::unique_ptr<weld::ToggleButton> m_vDefaultPersonaImages
+ [MAX_DEFAULT_PERSONAS]; ///< Buttons to show the default persona images
+ OUString m_aPersonaSettings; ///< Header and footer images + color to be set in the settings.
+
+ std::vector<OUString> m_vDefaultPersonaSettings;
+
+public:
+ SvxPersonalizationTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SvxPersonalizationTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ /// Apply the settings ([OK] button).
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+
+ /// Reset to default settings ([Revert] button).
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ /*
+ * Loads the default personas from the shared personas directory
+ * which resides in the shared gallery.
+ * There needs to be a separate subdirectory for each default persona,
+ * which includes the preview, header, and footer images.
+ * And there needs to be a personas_list.txt file in the personas directory
+ * which keeps the index/info of the default personas, one persona per line.
+ * A line should look like this:
+ * persona_slug;Persona Name;subdir/preview.jpg;subdir/header.jpg;subdir/footer.jpg;#textcolor
+ * (It is recommended to keep the subdir name the same as the slug)
+ * Example line:
+ * abstract;Abstract;abstract/preview.jpg;abstract/Header2.jpg;abstract/Footer2.jpg;#ffffff
+ */
+ void LoadDefaultImages();
+
+private:
+ /// Handle the default Persona selection
+ DECL_LINK(DefaultPersona, weld::Button&, void);
+};
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_PERSONALIZATION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.cxx b/cui/source/options/sdbcdriverenum.cxx
new file mode 100644
index 000000000..1370c93c2
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.cxx
@@ -0,0 +1,98 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "sdbcdriverenum.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+
+
+namespace offapp
+{
+
+
+ using namespace css::uno;
+ using namespace css::lang;
+ using namespace css::container;
+ using namespace css::sdbc;
+
+ class ODriverEnumerationImpl
+ {
+ protected:
+ std::vector< OUString > m_aImplNames;
+
+ public:
+ ODriverEnumerationImpl();
+
+ const std::vector< OUString >& getDriverImplNames() const { return m_aImplNames; }
+ };
+
+
+ ODriverEnumerationImpl::ODriverEnumerationImpl()
+ {
+ try
+ {
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XDriverManager2 > xEnumAccess = DriverManager::create( xContext );
+
+ Reference< XEnumeration > xEnumDrivers = xEnumAccess->createEnumeration();
+ OSL_ENSURE(xEnumDrivers.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: invalid enumeration object!");
+
+ Reference< XServiceInfo > xDriverSI;
+ while (xEnumDrivers->hasMoreElements())
+ {
+ xEnumDrivers->nextElement() >>= xDriverSI;
+ OSL_ENSURE(xDriverSI.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: driver without service info!");
+ if (xDriverSI.is())
+ m_aImplNames.push_back(xDriverSI->getImplementationName());
+ }
+ }
+ catch(const Exception&)
+ {
+ OSL_FAIL("ODriverEnumerationImpl::ODriverEnumerationImpl: caught an exception while enumerating the drivers!");
+ }
+ }
+
+ ODriverEnumeration::ODriverEnumeration() throw()
+ :m_pImpl(new ODriverEnumerationImpl)
+ {
+ }
+
+
+ ODriverEnumeration::~ODriverEnumeration() throw()
+ {
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::begin() const throw()
+ {
+ return m_pImpl->getDriverImplNames().begin();
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::end() const throw()
+ {
+ return m_pImpl->getDriverImplNames().end();
+ }
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.hxx b/cui/source/options/sdbcdriverenum.hxx
new file mode 100644
index 000000000..ef25bca00
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+#include <vector>
+#include <memory>
+
+
+namespace offapp
+{
+
+ class ODriverEnumerationImpl;
+ /** simple class for accessing SDBC drivers registered within the office
+ <p>Rather small, introduced to not contaminate other instances with the
+ exception handling (code-size-bloating) implementations here.
+ </p>
+ */
+ class ODriverEnumeration
+ {
+ private:
+ std::unique_ptr<ODriverEnumerationImpl> m_pImpl;
+
+ public:
+ ODriverEnumeration() throw();
+ ~ODriverEnumeration() throw();
+ typedef std::vector< OUString >::const_iterator const_iterator;
+
+ const_iterator begin() const throw();
+ const_iterator end() const throw();
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.cxx b/cui/source/options/securityoptions.cxx
new file mode 100644
index 000000000..202128b99
--- /dev/null
+++ b/cui/source/options/securityoptions.cxx
@@ -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 .
+ */
+
+#include <tools/debug.hxx>
+#include <unotools/securityoptions.hxx>
+#include "securityoptions.hxx"
+
+namespace
+{
+ bool enableAndSet(const SvtSecurityOptions& rOptions,
+ SvtSecurityOptions::EOption eOption,
+ weld::CheckButton& rCheckBox, weld::Widget& rFixedImage)
+ {
+ bool bEnable = rOptions.IsOptionEnabled(eOption);
+ rCheckBox.set_sensitive(bEnable);
+ rFixedImage.set_visible(!bEnable);
+ rCheckBox.set_active(rOptions.IsOptionSet(eOption));
+ return bEnable;
+ }
+}
+
+namespace svx
+{
+
+SecurityOptionsDialog::SecurityOptionsDialog(weld::Window* pParent, SvtSecurityOptions const * pOptions)
+ : GenericDialogController(pParent, "cui/ui/securityoptionsdialog.ui", "SecurityOptionsDialog")
+ , m_xSaveOrSendDocsCB(m_xBuilder->weld_check_button("savesenddocs"))
+ , m_xSaveOrSendDocsImg(m_xBuilder->weld_widget("locksavesenddocs"))
+ , m_xSignDocsCB(m_xBuilder->weld_check_button("whensigning"))
+ , m_xSignDocsImg(m_xBuilder->weld_widget("lockwhensigning"))
+ , m_xPrintDocsCB(m_xBuilder->weld_check_button("whenprinting"))
+ , m_xPrintDocsImg(m_xBuilder->weld_widget("lockwhenprinting"))
+ , m_xCreatePdfCB(m_xBuilder->weld_check_button("whenpdf"))
+ , m_xCreatePdfImg(m_xBuilder->weld_widget("lockwhenpdf"))
+ , m_xRemovePersInfoCB(m_xBuilder->weld_check_button("removepersonal"))
+ , m_xRemovePersInfoImg(m_xBuilder->weld_widget("lockremovepersonal"))
+ , m_xRecommPasswdCB(m_xBuilder->weld_check_button("password"))
+ , m_xRecommPasswdImg(m_xBuilder->weld_widget("lockpassword"))
+ , m_xCtrlHyperlinkCB(m_xBuilder->weld_check_button("ctrlclick"))
+ , m_xCtrlHyperlinkImg(m_xBuilder->weld_widget("lockctrlclick"))
+ , m_xBlockUntrustedRefererLinksCB(m_xBuilder->weld_check_button("blockuntrusted"))
+ , m_xBlockUntrustedRefererLinksImg(m_xBuilder->weld_widget("lockblockuntrusted"))
+{
+ DBG_ASSERT( pOptions, "SecurityOptionsDialog::SecurityOptionsDialog(): invalid SvtSecurityOptions" );
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnSaveOrSend, *m_xSaveOrSendDocsCB,
+ *m_xSaveOrSendDocsImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnSigning, *m_xSignDocsCB,
+ *m_xSignDocsImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnPrint, *m_xPrintDocsCB,
+ *m_xPrintDocsImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnCreatePdf, *m_xCreatePdfCB,
+ *m_xCreatePdfImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, *m_xRemovePersInfoCB,
+ *m_xRemovePersInfoImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::DocWarnRecommendPassword, *m_xRecommPasswdCB,
+ *m_xRecommPasswdImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::CtrlClickHyperlink, *m_xCtrlHyperlinkCB,
+ *m_xCtrlHyperlinkImg);
+ enableAndSet(*pOptions, SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, *m_xBlockUntrustedRefererLinksCB,
+ *m_xBlockUntrustedRefererLinksImg);
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.hxx b/cui/source/options/securityoptions.hxx
new file mode 100644
index 000000000..d5ed7b01a
--- /dev/null
+++ b/cui/source/options/securityoptions.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 <vcl/weld.hxx>
+
+class SvtSecurityOptions;
+
+namespace svx
+{
+
+ class SecurityOptionsDialog : public weld::GenericDialogController
+ {
+ private:
+ std::unique_ptr<weld::CheckButton> m_xSaveOrSendDocsCB;
+ std::unique_ptr<weld::Widget> m_xSaveOrSendDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xSignDocsCB;
+ std::unique_ptr<weld::Widget> m_xSignDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xPrintDocsCB;
+ std::unique_ptr<weld::Widget> m_xPrintDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xCreatePdfCB;
+ std::unique_ptr<weld::Widget> m_xCreatePdfImg;
+
+ std::unique_ptr<weld::CheckButton> m_xRemovePersInfoCB;
+ std::unique_ptr<weld::Widget> m_xRemovePersInfoImg;
+ std::unique_ptr<weld::CheckButton> m_xRecommPasswdCB;
+ std::unique_ptr<weld::Widget> m_xRecommPasswdImg;
+ std::unique_ptr<weld::CheckButton> m_xCtrlHyperlinkCB;
+ std::unique_ptr<weld::Widget> m_xCtrlHyperlinkImg;
+ std::unique_ptr<weld::CheckButton> m_xBlockUntrustedRefererLinksCB;
+ std::unique_ptr<weld::Widget> m_xBlockUntrustedRefererLinksImg;
+
+ public:
+ SecurityOptionsDialog(weld::Window* pParent, SvtSecurityOptions const * pOptions);
+
+ bool IsSaveOrSendDocsChecked() const { return m_xSaveOrSendDocsCB->get_active(); }
+ bool IsSignDocsChecked() const { return m_xSignDocsCB->get_active(); }
+ bool IsPrintDocsChecked() const { return m_xPrintDocsCB->get_active(); }
+ bool IsCreatePdfChecked() const { return m_xCreatePdfCB->get_active(); }
+ bool IsRemovePersInfoChecked() const { return m_xRemovePersInfoCB->get_active(); }
+ bool IsRecommPasswdChecked() const { return m_xRecommPasswdCB->get_active(); }
+ bool IsCtrlHyperlinkChecked() const { return m_xCtrlHyperlinkCB->get_active(); }
+ bool IsBlockUntrustedRefererLinksChecked() const { return m_xBlockUntrustedRefererLinksCB->get_active(); }
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/treeopt.cxx b/cui/source/options/treeopt.cxx
new file mode 100644
index 000000000..0e63a774d
--- /dev/null
+++ b/cui/source/options/treeopt.cxx
@@ -0,0 +1,2104 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * 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 <config_features.h>
+#include <config_feature_opencl.h>
+#include <config_feature_desktop.h>
+#include <config_gpgme.h>
+
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+
+#include <treeopt.hrc>
+#include <helpids.h>
+
+#include "cfgchart.hxx"
+#include "connpoolconfig.hxx"
+#include "connpooloptions.hxx"
+#include <cuioptgenrl.hxx>
+#include <dbregister.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <dialmgr.hxx>
+#include "fontsubs.hxx"
+#include "optaccessibility.hxx"
+#include <optasian.hxx>
+#include "optchart.hxx"
+#include "optcolor.hxx"
+#include "optctl.hxx"
+#include "optfltr.hxx"
+#include "optgdlg.hxx"
+#include "opthtml.hxx"
+#include "optinet2.hxx"
+#include "optjava.hxx"
+#include "optjsearch.hxx"
+#include <optlingu.hxx>
+#if HAVE_FEATURE_OPENCL
+#include "optopencl.hxx"
+#endif
+#include <optpath.hxx>
+#include "optsave.hxx"
+#include "optupdt.hxx"
+#include "personalization.hxx"
+#include <treeopt.hxx>
+#include "optbasic.hxx"
+
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/awt/ContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/linguistic2/LinguProperties.hpp>
+#include <com/sun/star/setup/UpdateCheck.hpp>
+#include <comphelper/getexpandeduri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/optitems.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <officecfg/Office/OptionsDialog.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/printopt.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/flagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/languageoptions.hxx>
+#include <svtools/helpopt.hxx>
+#include <svtools/miscopt.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+#include <unotools/misccfg.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <unotools/viewoptions.hxx>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/window.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+LastPageSaver* OfaTreeOptionsDialog::pLastPageSaver = nullptr;
+
+// some stuff for easier changes for SvtViewOptions
+static const OUString VIEWOPT_DATANAME = "page data";
+
+static void SetViewOptUserItem( SvtViewOptions& rOpt, const OUString& rData )
+{
+ rOpt.SetUserItem( VIEWOPT_DATANAME, Any( rData ) );
+}
+
+static OUString GetViewOptUserItem( const SvtViewOptions& rOpt )
+{
+ Any aAny( rOpt.GetUserItem( VIEWOPT_DATANAME ) );
+ OUString aUserData;
+ aAny >>= aUserData;
+
+ return aUserData;
+}
+
+namespace {
+
+struct ModuleToGroupNameMap_Impl
+{
+ OUStringLiteral m_pModule;
+ OUString m_sGroupName;
+ sal_uInt16 m_nNodeId;
+};
+}
+
+static ModuleToGroupNameMap_Impl ModuleMap[] =
+{
+ { "ProductName", OUString(), SID_GENERAL_OPTIONS },
+ { "LanguageSettings", OUString(), SID_LANGUAGE_OPTIONS },
+ { "Internet", OUString(), SID_INET_DLG },
+ { "LoadSave", OUString(), SID_FILTER_DLG },
+ { "Writer", OUString(), SID_SW_EDITOPTIONS },
+ { "WriterWeb", OUString(), SID_SW_ONLINEOPTIONS },
+ { "Math", OUString(), SID_SM_EDITOPTIONS },
+ { "Calc", OUString(), SID_SC_EDITOPTIONS },
+ { "Impress", OUString(), SID_SD_EDITOPTIONS },
+ { "Draw", OUString(), SID_SD_GRAPHIC_OPTIONS },
+ { "Charts", OUString(), SID_SCH_EDITOPTIONS },
+ { "Base", OUString(), SID_SB_STARBASEOPTIONS },
+};
+
+static void setGroupName( const OUString& rModule, const OUString& rGroupName )
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ rEntry.m_sGroupName = rGroupName;
+ break;
+ }
+ }
+}
+
+static OUString getGroupName( const OUString& rModule, bool bForced )
+{
+ OUString sGroupName;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ sGroupName = rEntry.m_sGroupName;
+ break;
+ }
+ }
+
+ if ( sGroupName.isEmpty() && bForced )
+ {
+ if ( rModule == "Writer" )
+ sGroupName = CuiResId(SID_SW_EDITOPTIONS_RES[0].first);
+ else if ( rModule == "WriterWeb" )
+ sGroupName = CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first);
+ else if ( rModule == "Calc" )
+ sGroupName = CuiResId(SID_SC_EDITOPTIONS_RES[0].first);
+ else if ( rModule == "Impress" )
+ sGroupName = CuiResId(SID_SD_EDITOPTIONS_RES[0].first);
+ else if ( rModule == "Draw" )
+ sGroupName = CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first);
+ else if ( rModule == "Math" )
+ sGroupName = CuiResId(SID_SM_EDITOPTIONS_RES[0].first);
+ else if ( rModule == "Base" )
+ sGroupName = CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first);
+ }
+ return sGroupName;
+}
+
+static void deleteGroupNames()
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ rEntry.m_sGroupName.clear();
+}
+
+static sal_uInt16 getGroupNodeId( const OUString& rModule )
+{
+ sal_uInt16 nNodeId = 0xFFFF;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ nNodeId = rEntry.m_nNodeId;
+ break;
+ }
+ }
+
+ return nNodeId;
+}
+
+namespace {
+
+class MailMergeCfg_Impl : public utl::ConfigItem
+{
+private:
+ // variables
+ bool bIsEmailSupported;
+
+ virtual void ImplCommit() override;
+
+public:
+ MailMergeCfg_Impl();
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+
+ bool IsEmailSupported() const {return bIsEmailSupported;}
+
+};
+
+}
+
+MailMergeCfg_Impl::MailMergeCfg_Impl() :
+ utl::ConfigItem("Office.Writer/MailMergeWizard"),
+ bIsEmailSupported(false)
+{
+ Sequence<OUString> aNames { "EMailSupported" };
+ const Sequence< Any > aValues = GetProperties(aNames);
+ const Any* pValues = aValues.getConstArray();
+ if(aValues.hasElements() && pValues[0].hasValue())
+ pValues[0] >>= bIsEmailSupported;
+}
+
+void MailMergeCfg_Impl::ImplCommit()
+{
+}
+
+void MailMergeCfg_Impl::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+//typedef SfxTabPage* (*FNCreateTabPage)(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet);
+static std::unique_ptr<SfxTabPage> CreateGeneralTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case RID_SFXPAGE_SAVE: fnCreate = &SvxSaveTabPage::Create; break;
+ case RID_SFXPAGE_PATH: fnCreate = &SvxPathTabPage::Create; break;
+ case RID_SFXPAGE_GENERAL: fnCreate = &SvxGeneralTabPage::Create; break;
+ case RID_SFXPAGE_PRINTOPTIONS: fnCreate = &SfxCommonPrintOptionsTabPage::Create; break;
+ case OFA_TP_LANGUAGES: fnCreate = &OfaLanguagesTabPage::Create; break;
+ case RID_SFXPAGE_LINGU: fnCreate = &SvxLinguTabPage::Create; break;
+ case OFA_TP_VIEW: fnCreate = &OfaViewTabPage::Create; break;
+ case OFA_TP_MISC: fnCreate = &OfaMiscTabPage::Create; break;
+ case RID_SVXPAGE_ASIAN_LAYOUT: fnCreate = &SvxAsianLayoutPage::Create; break;
+ case RID_SVX_FONT_SUBSTITUTION: fnCreate = &SvxFontSubstTabPage::Create; break;
+ case RID_SVXPAGE_INET_PROXY: fnCreate = &SvxProxyTabPage::Create; break;
+ case RID_SVXPAGE_INET_SECURITY: fnCreate = &SvxSecurityTabPage::Create; break;
+ case RID_SVXPAGE_INET_MAIL: fnCreate = &SvxEMailTabPage::Create; break;
+#if HAVE_FEATURE_DESKTOP
+ case RID_SVXPAGE_PERSONALIZATION: fnCreate = &SvxPersonalizationTabPage::Create; break;
+#endif
+ case RID_SVXPAGE_COLORCONFIG: fnCreate = &SvxColorOptionsTabPage::Create; break;
+ case RID_OFAPAGE_HTMLOPT: fnCreate = &OfaHtmlTabPage::Create; break;
+ case SID_OPTFILTER_MSOFFICE: fnCreate = &OfaMSFilterTabPage::Create; break;
+ case RID_OFAPAGE_MSFILTEROPT2: fnCreate = &OfaMSFilterTabPage2::Create; break;
+ case RID_SVXPAGE_JSEARCH_OPTIONS: fnCreate = &SvxJSearchOptionsPage::Create ; break;
+ case SID_SB_CONNECTIONPOOLING: fnCreate = &::offapp::ConnectionPoolOptionsPage::Create; break;
+ case SID_SB_DBREGISTEROPTIONS: fnCreate = &svx::DbRegistrationOptionsPage::Create; break;
+ case RID_SVXPAGE_ACCESSIBILITYCONFIG: fnCreate = &SvxAccessibilityOptionsTabPage::Create; break;
+ case RID_SVXPAGE_OPTIONS_CTL: fnCreate = &SvxCTLOptionsPage::Create ; break;
+ case RID_SVXPAGE_OPTIONS_JAVA: fnCreate = &SvxJavaOptionsPage::Create ; break;
+#if HAVE_FEATURE_OPENCL
+ case RID_SVXPAGE_OPENCL: fnCreate = &SvxOpenCLTabPage::Create ; break;
+#endif
+ case RID_SVXPAGE_ONLINEUPDATE: fnCreate = &SvxOnlineUpdateTabPage::Create; break;
+ case RID_OPTPAGE_CHART_DEFCOLORS: fnCreate = &SvxDefaultColorOptPage::Create; break;
+#if HAVE_FEATURE_SCRIPTING
+ case RID_SVXPAGE_BASICIDE_OPTIONS: fnCreate = &SvxBasicIDEOptionsPage::Create; break;
+#endif
+ }
+
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+namespace {
+
+struct OptionsMapping_Impl
+{
+ const char* m_pGroupName;
+ const char* m_pPageName;
+ sal_uInt16 m_nPageId;
+};
+
+}
+
+static OptionsMapping_Impl const OptionsMap_Impl[] =
+{
+// GROUP PAGE PAGE-ID
+ { "ProductName", nullptr, SID_GENERAL_OPTIONS },
+ { "ProductName", "UserData", RID_SFXPAGE_GENERAL },
+ { "ProductName", "General", OFA_TP_MISC },
+ { "ProductName", "View", OFA_TP_VIEW },
+ { "ProductName", "Print", RID_SFXPAGE_PRINTOPTIONS },
+ { "ProductName", "Paths", RID_SFXPAGE_PATH },
+ { "ProductName", "Fonts", RID_SVX_FONT_SUBSTITUTION },
+ { "ProductName", "Security", RID_SVXPAGE_INET_SECURITY },
+ { "ProductName", "Personalization", RID_SVXPAGE_PERSONALIZATION },
+ { "ProductName", "Appearance", RID_SVXPAGE_COLORCONFIG },
+ { "ProductName", "Accessibility", RID_SVXPAGE_ACCESSIBILITYCONFIG },
+ { "ProductName", "Java", RID_SVXPAGE_OPTIONS_JAVA },
+ { "ProductName", "BasicIDEOptions", RID_SVXPAGE_BASICIDE_OPTIONS },
+ { "ProductName", "OnlineUpdate", RID_SVXPAGE_ONLINEUPDATE },
+ { "LanguageSettings", nullptr, SID_LANGUAGE_OPTIONS },
+ { "LanguageSettings", "Languages", OFA_TP_LANGUAGES },
+ { "LanguageSettings", "WritingAids", RID_SFXPAGE_LINGU },
+ { "LanguageSettings", "SearchingInJapanese", RID_SVXPAGE_JSEARCH_OPTIONS },
+ { "LanguageSettings", "AsianLayout", RID_SVXPAGE_ASIAN_LAYOUT },
+ { "LanguageSettings", "ComplexTextLayout", RID_SVXPAGE_OPTIONS_CTL },
+ { "Internet", nullptr, SID_INET_DLG },
+ { "Internet", "Proxy", RID_SVXPAGE_INET_PROXY },
+ { "Internet", "Email", RID_SVXPAGE_INET_MAIL },
+ { "LoadSave", nullptr, SID_FILTER_DLG },
+ { "LoadSave", "General", RID_SFXPAGE_SAVE },
+ { "LoadSave", "VBAProperties", SID_OPTFILTER_MSOFFICE },
+ { "LoadSave", "MicrosoftOffice", RID_OFAPAGE_MSFILTEROPT2 },
+ { "LoadSave", "HTMLCompatibility", RID_OFAPAGE_HTMLOPT },
+ { "Writer", nullptr, SID_SW_EDITOPTIONS },
+ { "Writer", "General", RID_SW_TP_OPTLOAD_PAGE },
+ { "Writer", "View", RID_SW_TP_CONTENT_OPT },
+ { "Writer", "FormattingAids", RID_SW_TP_OPTSHDWCRSR },
+ { "Writer", "Grid", RID_SVXPAGE_GRID },
+ { "Writer", "BasicFontsWestern", RID_SW_TP_STD_FONT },
+ { "Writer", "BasicFontsAsian", RID_SW_TP_STD_FONT_CJK },
+ { "Writer", "BasicFontsCTL", RID_SW_TP_STD_FONT_CTL },
+ { "Writer", "Print", RID_SW_TP_OPTPRINT_PAGE },
+ { "Writer", "Table", RID_SW_TP_OPTTABLE_PAGE },
+ { "Writer", "Changes", RID_SW_TP_REDLINE_OPT },
+ { "Writer", "Comparison", RID_SW_TP_COMPARISON_OPT },
+ { "Writer", "Compatibility", RID_SW_TP_OPTCOMPATIBILITY_PAGE },
+ { "Writer", "AutoCaption", RID_SW_TP_OPTCAPTION_PAGE },
+ { "Writer", "MailMerge", RID_SW_TP_MAILCONFIG },
+ { "WriterWeb", nullptr, SID_SW_ONLINEOPTIONS },
+ { "WriterWeb", "View", RID_SW_TP_HTML_CONTENT_OPT },
+ { "WriterWeb", "FormattingAids", RID_SW_TP_HTML_OPTSHDWCRSR },
+ { "WriterWeb", "Grid", RID_SW_TP_HTML_OPTGRID_PAGE },
+ { "WriterWeb", "Print", RID_SW_TP_HTML_OPTPRINT_PAGE },
+ { "WriterWeb", "Table", RID_SW_TP_HTML_OPTTABLE_PAGE },
+ { "WriterWeb", "Background", RID_SW_TP_BACKGROUND },
+ { "Math", nullptr, SID_SM_EDITOPTIONS },
+ { "Math", "Settings", SID_SM_TP_PRINTOPTIONS },
+ { "Calc", nullptr, SID_SC_EDITOPTIONS },
+ { "Calc", "General", SID_SC_TP_LAYOUT },
+ { "Calc", "View", SID_SC_TP_CONTENT },
+ { "Calc", "Calculate", SID_SC_TP_CALC },
+ { "Calc", "Formula", SID_SC_TP_FORMULA },
+ { "Calc", "SortLists", SID_SC_TP_USERLISTS },
+ { "Calc", "Changes", SID_SC_TP_CHANGES },
+ { "Calc", "Compatibility", SID_SC_TP_COMPATIBILITY },
+ { "Calc", "Grid", SID_SC_TP_GRID },
+ { "Calc", "Print", RID_SC_TP_PRINT },
+ { "Impress", nullptr, SID_SD_EDITOPTIONS },
+ { "Impress", "General", SID_SI_TP_MISC },
+ { "Impress", "View", SID_SI_TP_CONTENTS },
+ { "Impress", "Grid", SID_SI_TP_SNAP },
+ { "Impress", "Print", SID_SI_TP_PRINT },
+ { "Draw", nullptr, SID_SD_GRAPHIC_OPTIONS },
+ { "Draw", "General", SID_SD_TP_MISC },
+ { "Draw", "View", SID_SD_TP_CONTENTS },
+ { "Draw", "Grid", SID_SD_TP_SNAP },
+ { "Draw", "Print", SID_SD_TP_PRINT },
+ { "Charts", nullptr, SID_SCH_EDITOPTIONS },
+ { "Charts", "DefaultColors", RID_OPTPAGE_CHART_DEFCOLORS },
+ { "Base", nullptr, SID_SB_STARBASEOPTIONS },
+ { "Base", "Connections", SID_SB_CONNECTIONPOOLING },
+ { "Base", "Databases", SID_SB_DBREGISTEROPTIONS },
+ { nullptr, nullptr, 0 }
+};
+
+static bool lcl_getStringFromID( sal_uInt16 _nPageId, OUString& _rGroupName, OUString& _rPageName )
+{
+ bool bRet = false;
+
+ sal_uInt16 nIdx = 0;
+ while ( OptionsMap_Impl[nIdx].m_pGroupName != nullptr )
+ {
+ if ( _nPageId == OptionsMap_Impl[nIdx].m_nPageId )
+ {
+ bRet = true;
+ _rGroupName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pGroupName );
+ if ( OptionsMap_Impl[nIdx].m_pPageName != nullptr )
+ _rPageName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pPageName );
+ break;
+ }
+ ++nIdx;
+ }
+
+ return bRet;
+}
+
+static bool lcl_isOptionHidden( sal_uInt16 _nPageId, const SvtOptionsDialogOptions& _rOptOptions )
+{
+ bool bIsHidden = false;
+ OUString sGroupName, sPageName;
+ if ( lcl_getStringFromID( _nPageId, sGroupName, sPageName ) )
+ {
+ if ( sPageName.isEmpty() )
+ bIsHidden = _rOptOptions.IsGroupHidden( sGroupName );
+ else
+ bIsHidden = _rOptOptions.IsPageHidden( sPageName, sGroupName );
+ }
+ return bIsHidden;
+}
+
+struct OptionsPageInfo
+{
+ std::unique_ptr<SfxTabPage> m_xPage;
+ sal_uInt16 m_nPageId;
+ OUString m_sPageURL;
+ OUString m_sEventHdl;
+ std::unique_ptr<ExtensionsTabPage> m_xExtPage;
+
+ explicit OptionsPageInfo( sal_uInt16 nId ) : m_nPageId( nId ) {}
+};
+
+namespace {
+
+struct OptionsGroupInfo
+{
+ std::unique_ptr<SfxItemSet> m_pInItemSet;
+ std::unique_ptr<SfxItemSet> m_pOutItemSet;
+ SfxShell* m_pShell; // used to create the page
+ SfxModule* m_pModule; // used to create the ItemSet
+ sal_uInt16 m_nDialogId; // Id of the former dialog
+
+ OptionsGroupInfo( SfxShell* pSh, SfxModule* pMod, sal_uInt16 nId ) :
+ m_pShell( pSh ),
+ m_pModule( pMod ), m_nDialogId( nId ) {}
+};
+
+}
+
+#define INI_LIST() \
+ , m_pParent ( pParent )\
+ , sTitle ( m_xDialog->get_title() )\
+ , bForgetSelection ( false )\
+ , bIsFromExtensionManager( false ) \
+ , bIsForSetDocumentLanguage( false ) \
+ , bNeedsRestart ( false ) \
+ , eRestartReason( svtools::RESTART_REASON_NONE )
+
+
+void OfaTreeOptionsDialog::InitWidgets()
+{
+ xOkPB = m_xBuilder->weld_button("ok");
+ xApplyPB = m_xBuilder->weld_button("apply");
+ xBackPB = m_xBuilder->weld_button("revert");
+ xTreeLB = m_xBuilder->weld_tree_view("pages");
+ xTabBox = m_xBuilder->weld_container("box");
+ Size aSize(xTreeLB->get_approximate_digit_width() * 82, xTreeLB->get_height_rows(30));
+#if HAVE_FEATURE_GPGME
+ {
+ // load this little .ui just to measure the height of an Entry
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xDialog.get(), "cui/ui/namedialog.ui"));
+ std::unique_ptr<weld::Entry> xEntry(xBuilder->weld_entry("name_entry"));
+ // tdf#115015: make enough space for crypto settings (approx. 14 text edits + padding)
+ aSize.setHeight((xEntry->get_preferred_size().Height() + 6) * 14);
+ }
+#endif
+ xTabBox->set_size_request(aSize.Width(), aSize.Height());
+ xTreeLB->set_size_request(xTreeLB->get_approximate_digit_width() * 30, aSize.Height());
+}
+
+// Ctor() with Frame -----------------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, const Reference< XFrame >& _xFrame, bool bActivateLastSelection)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ InitTreeAndHandler();
+ Initialize( _xFrame );
+ LoadExtensionOptions( OUString() );
+ if (bActivateLastSelection)
+ ActivateLastSelection();
+
+ xTreeLB->set_accessible_name(m_xDialog->get_title());
+}
+
+// Ctor() with ExtensionId -----------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, const OUString& rExtensionId)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ bIsFromExtensionManager = ( !rExtensionId.isEmpty() );
+ InitTreeAndHandler();
+ LoadExtensionOptions( rExtensionId );
+ ActivateLastSelection();
+}
+
+OfaTreeOptionsDialog::~OfaTreeOptionsDialog()
+{
+ xCurrentPageEntry.reset();
+
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ // first children
+ while (bEntry)
+ {
+ // if Child (has parent), then OptionsPageInfo
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo *pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xEntry).toInt64());
+ if(pPageInfo->m_xPage)
+ {
+ pPageInfo->m_xPage->FillUserData();
+ OUString aPageData(pPageInfo->m_xPage->GetUserData());
+ if ( !aPageData.isEmpty() )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ SetViewOptUserItem( aTabPageOpt, aPageData );
+ }
+ pPageInfo->m_xPage.reset();
+ }
+
+ if (pPageInfo->m_nPageId == RID_SFXPAGE_LINGU)
+ {
+ // write personal dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ linguistic::SaveDictionaries( xDicList );
+ }
+ }
+
+ pPageInfo->m_xExtPage.reset();
+
+ delete pPageInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+
+ // and parents
+ bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry).toInt64());
+ delete pGroupInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ deleteGroupNames();
+}
+
+OptionsPageInfo* OfaTreeOptionsDialog::AddTabPage(
+ sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup )
+{
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xParent))
+ return nullptr;
+ xTreeLB->iter_nth_sibling(*xParent, nGroup);
+
+ OptionsPageInfo* pPageInfo = new OptionsPageInfo( nId );
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pPageInfo)));
+ xTreeLB->insert(xParent.get(), -1, &rPageName, &sId, nullptr, nullptr, nullptr, false, nullptr);
+ return pPageInfo;
+}
+
+// the ItemSet* is passed on to the dialog's ownership
+sal_uInt16 OfaTreeOptionsDialog::AddGroup(const OUString& rGroupName,
+ SfxShell* pCreateShell,
+ SfxModule* pCreateModule,
+ sal_uInt16 nDialogId )
+{
+ OptionsGroupInfo* pInfo =
+ new OptionsGroupInfo( pCreateShell, pCreateModule, nDialogId );
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pInfo)));
+ xTreeLB->append(sId, rGroupName);
+
+ sal_uInt16 nRet = 0;
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ nRet++;
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ return nRet - 1;
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, ShowPageHdl_Impl, weld::TreeView&, void)
+{
+ SelectHdl_Impl();
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, BackHdl_Impl, weld::Button&, void)
+{
+ if (!(xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry)))
+ return;
+
+ OptionsPageInfo* pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry).toInt64());
+ if (pPageInfo->m_xPage)
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xParent).toInt64());
+ pPageInfo->m_xPage->Reset( pGroupInfo->m_pInItemSet.get() );
+ }
+ else if ( pPageInfo->m_xExtPage )
+ pPageInfo->m_xExtPage->ResetPage();
+}
+
+void OfaTreeOptionsDialog::ApplyOptions(bool deactivate)
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo* pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xEntry).toInt64());
+ if ( pPageInfo->m_xPage && !pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xParent).toInt64());
+ pPageInfo->m_xPage->FillItemSet(pGroupInfo->m_pOutItemSet.get());
+ }
+
+ if ( pPageInfo->m_xExtPage )
+ {
+ if ( deactivate )
+ {
+ pPageInfo->m_xExtPage->DeactivatePage();
+ }
+ pPageInfo->m_xExtPage->SavePage();
+ }
+ if ( pPageInfo->m_xPage && RID_OPTPAGE_CHART_DEFCOLORS == pPageInfo->m_nPageId )
+ {
+ SvxDefaultColorOptPage* pPage = static_cast<SvxDefaultColorOptPage *>(pPageInfo->m_xPage.get());
+ pPage->SaveChartOptions();
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, ApplyHdl_Impl, weld::Button&, void)
+{
+ ApplyOptions(/*deactivate =*/false);
+
+ if ( bNeedsRestart )
+ {
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
+ m_xDialog.get(), eRestartReason))
+ m_xDialog->response(RET_OK);
+ }
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, HelpHdl_Impl, weld::Widget&, bool)
+{
+ Help* pHelp = Application::GetHelp();
+ if (pHelp && xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry).toInt64());
+ if (pPageInfo->m_xPage)
+ {
+ OString sHelpId(pPageInfo->m_xPage->GetHelpId());
+ pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), m_xDialog.get());
+ return false;
+ }
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, OKHdl_Impl, weld::Button&, void)
+{
+ if (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry).toInt64());
+ if ( pPageInfo->m_xPage )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+
+ OptionsGroupInfo* pGroupInfo = reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xParent).toInt64());
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId
+ && pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ DeactivateRC nLeave = pPageInfo->m_xPage->DeactivatePage(pGroupInfo->m_pOutItemSet.get());
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // the page mustn't be left
+ xTreeLB->select(*xCurrentPageEntry);
+ return;
+ }
+ }
+ pPageInfo->m_xPage->set_visible(false);
+ }
+ }
+
+ ApplyOptions(/*deactivate =*/ true);
+ m_xDialog->response(RET_OK);
+
+ if ( bNeedsRestart )
+ {
+ SolarMutexGuard aGuard;
+ ::svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
+ m_pParent, eRestartReason);
+ }
+}
+
+void OfaTreeOptionsDialog::ApplyItemSets()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry).toInt64());
+ if(pGroupInfo->m_pOutItemSet)
+ {
+ if(pGroupInfo->m_pShell)
+ pGroupInfo->m_pShell->ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ else
+ ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+void OfaTreeOptionsDialog::InitTreeAndHandler()
+{
+ xTreeLB->set_help_id(HID_OFADLG_TREELISTBOX);
+ xTreeLB->connect_changed( LINK( this, OfaTreeOptionsDialog, ShowPageHdl_Impl ) );
+ xBackPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, BackHdl_Impl ) );
+ xApplyPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, ApplyHdl_Impl ) );
+ xOkPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, OKHdl_Impl ) );
+ m_xDialog->connect_help( LINK( this, OfaTreeOptionsDialog, HelpHdl_Impl ) );
+}
+
+void OfaTreeOptionsDialog::ActivatePage( sal_uInt16 nResId )
+{
+ bIsForSetDocumentLanguage = false;
+ if ( nResId == OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE )
+ {
+ bIsForSetDocumentLanguage = true;
+ nResId = OFA_TP_LANGUAGES;
+ }
+
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ sal_uInt16 nTemp = pLastPageSaver->m_nLastPageId;
+ pLastPageSaver->m_nLastPageId = nResId;
+ ActivateLastSelection();
+ pLastPageSaver->m_nLastPageId = nTemp;
+}
+
+void OfaTreeOptionsDialog::ActivatePage( const OUString& rPageURL )
+{
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ pLastPageSaver->m_nLastPageId = 0;
+ pLastPageSaver->m_sLastPageURL_Tools = rPageURL;
+ ActivateLastSelection();
+}
+
+void OfaTreeOptionsDialog::ActivateLastSelection()
+{
+ std::unique_ptr<weld::TreeIter> xEntry;
+
+ if (pLastPageSaver)
+ {
+ OUString sLastURL = bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ if ( sLastURL.isEmpty() )
+ {
+ sLastURL = !bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ }
+
+ bool bMustExpand = ( INetURLObject( sLastURL ).GetProtocol() == INetProtocol::File );
+
+ std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
+ bool bTemp = xTreeLB->get_iter_first(*xTemp);
+ while (bTemp)
+ {
+ // restore only selection of a leaf
+ if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
+ {
+ OptionsPageInfo* pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xTemp).toInt64());
+ OUString sPageURL = pPageInfo->m_sPageURL;
+ if ( bMustExpand )
+ {
+ sPageURL = comphelper::getExpandedUri(
+ comphelper::getProcessComponentContext(), sPageURL);
+ }
+
+ if ( ( !bIsFromExtensionManager
+ && pPageInfo->m_nPageId && pPageInfo->m_nPageId == pLastPageSaver->m_nLastPageId )
+ || ( !pPageInfo->m_nPageId && sLastURL == sPageURL ) )
+ {
+ xEntry = xTreeLB->make_iterator(xTemp.get());
+ break;
+ }
+ }
+ bTemp = xTreeLB->iter_next(*xTemp);
+ }
+ }
+
+ if (!xEntry)
+ {
+ xEntry = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xEntry) || !xTreeLB->iter_next(*xEntry))
+ xEntry.reset();
+ }
+
+ if (!xEntry)
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ xTreeLB->iter_parent(*xParent);
+ xTreeLB->expand_row(*xParent);
+ xTreeLB->scroll_to_row(*xParent);
+ xTreeLB->scroll_to_row(*xEntry);
+ xTreeLB->set_cursor(*xEntry);
+ xTreeLB->select(*xEntry);
+ xTreeLB->grab_focus();
+ SelectHdl_Impl();
+}
+
+void OfaTreeOptionsDialog::SelectHdl_Impl()
+{
+ std::unique_ptr<weld::TreeIter> xEntry(xTreeLB->make_iterator());
+
+ if (!xTreeLB->get_cursor(xEntry.get()))
+ return;
+
+ if (xCurrentPageEntry && xCurrentPageEntry->equal(*xEntry))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ bool bParent = xTreeLB->iter_parent(*xParent);
+
+ // If the user has selected a category, automatically switch to a suitable
+ // default sub-page instead.
+ if (!bParent)
+ return;
+
+ BuilderPage* pNewPage = nullptr;
+ OptionsPageInfo* pOptPageInfo = (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ ? reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry).toInt64()) : nullptr;
+
+ if (pOptPageInfo && pOptPageInfo->m_xPage && pOptPageInfo->m_xPage->IsVisible())
+ {
+ std::unique_ptr<weld::TreeIter> xCurParent(xTreeLB->make_iterator(xCurrentPageEntry.get()));
+ xTreeLB->iter_parent(*xCurParent);
+
+ OptionsGroupInfo* pGroupInfo = reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xCurParent).toInt64());
+ DeactivateRC nLeave = DeactivateRC::LeavePage;
+ if ( RID_SVXPAGE_COLOR != pOptPageInfo->m_nPageId && pOptPageInfo->m_xPage->HasExchangeSupport() )
+ nLeave = pOptPageInfo->m_xPage->DeactivatePage( pGroupInfo->m_pOutItemSet.get() );
+
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // we cannot leave this page
+ xTreeLB->select(*xCurrentPageEntry);
+ return;
+ }
+ else
+ pOptPageInfo->m_xPage->set_visible(false);
+ }
+ else if ( pOptPageInfo && pOptPageInfo->m_xExtPage )
+ {
+ pOptPageInfo->m_xExtPage->Hide();
+ pOptPageInfo->m_xExtPage->DeactivatePage();
+ }
+
+ OptionsPageInfo *pPageInfo = reinterpret_cast<OptionsPageInfo*>(xTreeLB->get_id(*xEntry).toInt64());
+ OptionsGroupInfo* pGroupInfo = reinterpret_cast<OptionsGroupInfo*>(xTreeLB->get_id(*xParent).toInt64());
+ if(!pPageInfo->m_xPage && pPageInfo->m_nPageId > 0)
+ {
+ if(!pGroupInfo->m_pInItemSet)
+ pGroupInfo->m_pInItemSet = pGroupInfo->m_pShell
+ ? pGroupInfo->m_pShell->CreateItemSet( pGroupInfo->m_nDialogId )
+ : CreateItemSet( pGroupInfo->m_nDialogId );
+ if(!pGroupInfo->m_pOutItemSet)
+ pGroupInfo->m_pOutItemSet = std::make_unique<SfxItemSet>(
+ *pGroupInfo->m_pInItemSet->GetPool(),
+ pGroupInfo->m_pInItemSet->GetRanges());
+
+ pPageInfo->m_xPage = ::CreateGeneralTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ if(!pPageInfo->m_xPage && pGroupInfo->m_pModule)
+ pPageInfo->m_xPage = pGroupInfo->m_pModule->CreateTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ DBG_ASSERT( pPageInfo->m_xPage, "tabpage could not created");
+ if ( pPageInfo->m_xPage )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ pPageInfo->m_xPage->SetUserData( GetViewOptUserItem( aTabPageOpt ) );
+ pPageInfo->m_xPage->Reset( pGroupInfo->m_pInItemSet.get() );
+ }
+ }
+ else if ( 0 == pPageInfo->m_nPageId && !pPageInfo->m_xExtPage )
+ {
+ if ( !m_xContainerWinProvider.is() )
+ {
+ m_xContainerWinProvider = awt::ContainerWindowProvider::create( ::comphelper::getProcessComponentContext() );
+ }
+
+ pPageInfo->m_xExtPage = std::make_unique<ExtensionsTabPage>(
+ xTabBox.get(), pPageInfo->m_sPageURL, pPageInfo->m_sEventHdl, m_xContainerWinProvider);
+ }
+
+ if ( pPageInfo->m_xPage )
+ {
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId &&
+ pPageInfo->m_xPage->HasExchangeSupport())
+ {
+ pPageInfo->m_xPage->ActivatePage(*pGroupInfo->m_pOutItemSet);
+ }
+ pPageInfo->m_xPage->set_visible(true);
+ }
+ else if ( pPageInfo->m_xExtPage )
+ {
+ pPageInfo->m_xExtPage->Show();
+ pPageInfo->m_xExtPage->ActivatePage();
+ }
+
+ {
+ OUString sTitleText = sTitle
+ + " - " + xTreeLB->get_text(*xParent)
+ + " - " + xTreeLB->get_text(*xEntry);
+ m_xDialog->set_title(sTitleText);
+ }
+
+ xCurrentPageEntry = std::move(xEntry);
+
+ if ( !bForgetSelection )
+ {
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ if ( !bIsFromExtensionManager )
+ pLastPageSaver->m_nLastPageId = pPageInfo->m_nPageId;
+ if ( pPageInfo->m_xExtPage )
+ {
+ if ( bIsFromExtensionManager )
+ pLastPageSaver->m_sLastPageURL_ExtMgr = pPageInfo->m_sPageURL;
+ else
+ pLastPageSaver->m_sLastPageURL_Tools = pPageInfo->m_sPageURL;
+ }
+ }
+ pNewPage = pPageInfo->m_xPage.get();
+
+ // fdo#58170 use current page's layout child HelpId, unless there isn't a current page
+ OString sHelpId(pNewPage ? pNewPage->GetHelpId() : OString());
+ if (sHelpId.isEmpty())
+ sHelpId = HID_OFADLG_TREELISTBOX;
+ xTreeLB->set_help_id(sHelpId);
+}
+
+std::unique_ptr<SfxItemSet> OfaTreeOptionsDialog::CreateItemSet( sal_uInt16 nId )
+{
+ Reference< XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
+ std::unique_ptr<SfxItemSet> pRet;
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ pRet = std::make_unique<SfxItemSet>(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_METRIC, SID_ATTR_METRIC,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER,
+ SID_ATTR_YEAR2000, SID_ATTR_YEAR2000>{} );
+
+ SfxItemSet aOptSet( SfxGetpApp()->GetPool(), svl::Items<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER>{} );
+ SfxGetpApp()->GetOptions(aOptSet);
+ pRet->Put(aOptSet);
+
+ utl::MiscCfg aMisc;
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SfxPoolItem* pItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+
+ // miscellaneous - Year2000
+ if( SfxItemState::DEFAULT <= pDispatch->QueryState( SID_ATTR_YEAR2000, pItem ) )
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, static_cast<const SfxUInt16Item*>(pItem)->GetValue() ) );
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, static_cast<sal_uInt16>(aMisc.GetYear2000()) ) );
+ }
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, static_cast<sal_uInt16>(aMisc.GetYear2000()) ) );
+
+
+ // miscellaneous - Tabulator
+ pRet->Put(SfxBoolItem(SID_PRINTER_NOTFOUND_WARN, aMisc.IsNotFoundWarning()));
+
+ SfxPrinterChangeFlags nFlag = aMisc.IsPaperSizeWarning() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE;
+ nFlag |= aMisc.IsPaperOrientationWarning() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE;
+ pRet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlag) ));
+
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ pRet = std::make_unique<SfxItemSet>(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_CHAR_CJK_LANGUAGE, SID_ATTR_CHAR_CJK_LANGUAGE,
+ SID_ATTR_CHAR_CTL_LANGUAGE, SID_ATTR_CHAR_CTL_LANGUAGE,
+ SID_SET_DOCUMENT_LANGUAGE, SID_SET_DOCUMENT_LANGUAGE,
+ SID_ATTR_LANGUAGE, SID_ATTR_LANGUAGE,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_OPT_LOCALE_CHANGED, SID_OPT_LOCALE_CHANGED>{});
+
+ // for linguistic
+ SfxHyphenRegionItem aHyphen( SID_ATTR_HYPHENREGION );
+
+ sal_Int16 nMinLead = 2,
+ nMinTrail = 2;
+ if (xProp.is())
+ {
+ nMinLead = xProp->getHyphMinLeading();
+ nMinTrail = xProp->getHyphMinTrailing();
+ }
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(nMinLead);
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(nMinTrail);
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SfxPoolItem* pItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_LANGUAGE, pItem))
+ pRet->Put(
+ SvxLanguageItem(
+ (static_cast<const SvxLanguageItem*>(pItem)
+ ->GetLanguage()),
+ SID_ATTR_LANGUAGE));
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CJK_LANGUAGE, pItem))
+ pRet->Put(
+ SvxLanguageItem(
+ (static_cast<const SvxLanguageItem*>(pItem)
+ ->GetLanguage()),
+ SID_ATTR_CHAR_CJK_LANGUAGE));
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CTL_LANGUAGE, pItem))
+ pRet->Put(
+ SvxLanguageItem(
+ (static_cast<const SvxLanguageItem*>(pItem)
+ ->GetLanguage()),
+ SID_ATTR_CHAR_CTL_LANGUAGE));
+
+ pRet->Put(aHyphen);
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_AUTOSPELL_CHECK, pItem))
+ {
+ pRet->Put(std::unique_ptr<SfxPoolItem>(pItem->Clone()));
+ }
+ else
+ {
+ bool bVal = false;
+ if (xProp.is())
+ {
+ bVal = xProp->getIsSpellAuto();
+ }
+
+ pRet->Put(SfxBoolItem(SID_AUTOSPELL_CHECK, bVal));
+ }
+ }
+ pRet->Put( SfxBoolItem( SID_SET_DOCUMENT_LANGUAGE, bIsForSetDocumentLanguage ) );
+ }
+ break;
+ case SID_INET_DLG :
+ pRet = std::make_unique<SfxItemSet>( SfxGetpApp()->GetPool(),
+ svl::Items<SID_BASIC_ENABLED, SID_BASIC_ENABLED,
+ //SID_OPTIONS_START - ..END
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_INET_NOPROXY, SID_INET_FTP_PROXY_PORT,
+ SID_SECURE_URL, SID_SECURE_URL>{} );
+ SfxGetpApp()->GetOptions(*pRet);
+ break;
+ case SID_FILTER_DLG:
+ pRet = std::make_unique<SfxItemSet>(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_WARNALIENFORMAT, SID_ATTR_WARNALIENFORMAT,
+ SID_ATTR_DOCINFO, SID_ATTR_AUTOSAVEMINUTE,
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_ATTR_PRETTYPRINTING, SID_ATTR_PRETTYPRINTING>{} );
+ SfxGetpApp()->GetOptions(*pRet);
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ pRet = std::make_unique<SfxItemSet>( SfxGetpApp()->GetPool(),
+ svl::Items<SID_SB_POOLING_ENABLED, SID_SB_DB_REGISTER>{} );
+ ::offapp::ConnectionPoolConfig::GetOptions(*pRet);
+ svx::DbRegisteredNamesConfig::GetOptions(*pRet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ {
+ SvxChartOptions aChartOpt;
+ pRet = std::make_unique<SfxItemSet>( SfxGetpApp()->GetPool(), svl::Items<SID_SCH_EDITOPTIONS, SID_SCH_EDITOPTIONS>{} );
+ pRet->Put( SvxChartColorTableItem( SID_SCH_EDITOPTIONS, aChartOpt.GetDefaultColors() ) );
+ break;
+ }
+ }
+ return pRet;
+}
+
+void OfaTreeOptionsDialog::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
+{
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ utl::MiscCfg aMisc;
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemSet aOptSet(SfxGetpApp()->GetPool(), svl::Items<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER>{} );
+ aOptSet.Put(rSet);
+ if(aOptSet.Count())
+ SfxGetpApp()->SetOptions( aOptSet );
+ // get dispatcher anew, because SetOptions() might have destroyed the dispatcher
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+
+// evaluate Year2000
+
+ sal_uInt16 nY2K = USHRT_MAX;
+ if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_YEAR2000, false, &pItem ) )
+ nY2K = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ if( USHRT_MAX != nY2K )
+ {
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pDispatch->ExecuteList(SID_ATTR_YEAR2000,
+ SfxCallMode::ASYNCHRON, { pItem });
+ }
+ aMisc.SetYear2000(nY2K);
+ }
+
+
+// evaluate print
+
+ if(SfxItemState::SET == rSet.GetItemState(SID_PRINTER_NOTFOUND_WARN, false, &pItem))
+ aMisc.SetNotFoundWarning(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ if(SfxItemState::SET == rSet.GetItemState(SID_PRINTER_CHANGESTODOC, false, &pItem))
+ {
+ const SfxFlagItem* pFlag = static_cast<const SfxFlagItem*>(pItem);
+ aMisc.SetPaperSizeWarning(bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE ));
+ aMisc.SetPaperOrientationWarning(bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION ));
+ }
+
+// evaluate help options
+
+ if ( SvtHelpOptions().IsHelpTips() != Help::IsQuickHelpEnabled() )
+ SvtHelpOptions().IsHelpTips() ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
+ if ( SvtHelpOptions().IsExtendedHelp() != Help::IsBalloonHelpEnabled() )
+ SvtHelpOptions().IsExtendedHelp() ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ OfaTreeOptionsDialog::ApplyLanguageOptions(rSet);
+ }
+ break;
+ case SID_INET_DLG :
+ case SID_FILTER_DLG:
+ SfxGetpApp()->SetOptions( rSet );
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ ::offapp::ConnectionPoolConfig::SetOptions( rSet );
+ svx::DbRegisteredNamesConfig::SetOptions(rSet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ // nothing to do. Chart options only apply to newly created charts
+ break;
+
+ default:
+ {
+ OSL_FAIL( "Unhandled option in ApplyItemSet" );
+ }
+ break;
+ }
+
+}
+void OfaTreeOptionsDialog::ApplyLanguageOptions(const SfxItemSet& rSet)
+{
+ bool bSaveSpellCheck = false;
+ const SfxPoolItem* pItem = nullptr;
+
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XLinguProperties > xProp = LinguProperties::create( xContext );
+ if ( SfxItemState::SET == rSet.GetItemState(SID_ATTR_HYPHENREGION, false, &pItem ) )
+ {
+ const SfxHyphenRegionItem* pHyphenItem = static_cast<const SfxHyphenRegionItem*>(pItem);
+
+ xProp->setHyphMinLeading( static_cast<sal_Int16>(pHyphenItem->GetMinLead()) );
+ xProp->setHyphMinTrailing( static_cast<sal_Int16>(pHyphenItem->GetMinTrail()) );
+ bSaveSpellCheck = true;
+ }
+
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pItem = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::ASYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CTL_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::ASYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CJK_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::ASYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_AUTOSPELL_CHECK, false, &pItem ))
+ {
+ bool bOnlineSpelling = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ pDispatch->ExecuteList(SID_AUTOSPELL_CHECK,
+ SfxCallMode::ASYNCHRON|SfxCallMode::RECORD, { pItem });
+
+ xProp->setIsSpellAuto( bOnlineSpelling );
+ }
+
+ if( bSaveSpellCheck )
+ {
+ //! the config item has changed since we modified the
+ //! property set it uses
+ pDispatch->Execute(SID_SPELLCHECKER_CHANGED, SfxCallMode::ASYNCHRON);
+ }
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_OPT_LOCALE_CHANGED, false, &pItem ))
+ {
+ SfxViewFrame* _pViewFrame = SfxViewFrame::GetFirst();
+ while ( _pViewFrame )
+ {
+ _pViewFrame->GetDispatcher()->ExecuteList(pItem->Which(),
+ SfxCallMode::ASYNCHRON, { pItem });
+ _pViewFrame = SfxViewFrame::GetNext( *_pViewFrame );
+ }
+ }
+}
+
+static OUString getCurrentFactory_Impl( const Reference< XFrame >& _xFrame )
+{
+ OUString sIdentifier;
+ Reference < XFrame > xCurrentFrame( _xFrame );
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(::comphelper::getProcessComponentContext());
+ if ( !xCurrentFrame.is() )
+ {
+ Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sIdentifier = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "getActiveModule_Impl(): exception of XModuleManager::identify()" );
+ }
+ }
+
+ return sIdentifier;
+}
+
+void OfaTreeOptionsDialog::Initialize( const Reference< XFrame >& _xFrame )
+{
+ sal_uInt16 nGroup = 0;
+
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+ sal_uInt16 nPageId;
+
+ // %PRODUCTNAME options
+ if ( !lcl_isOptionHidden( SID_GENERAL_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName("ProductName", CuiResId(SID_GENERAL_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_GENERAL_OPTIONS_RES[0].first), nullptr, nullptr, SID_GENERAL_OPTIONS );
+ const sal_uInt16 nEnd = static_cast<sal_uInt16>(SAL_N_ELEMENTS(SID_GENERAL_OPTIONS_RES));
+
+ for (sal_uInt16 i = 1; i < nEnd; ++i)
+ {
+ OUString sNewTitle = CuiResId(SID_GENERAL_OPTIONS_RES[i].first);
+ nPageId = SID_GENERAL_OPTIONS_RES[i].second;
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ // Disable Online Update page if service not installed
+ if( RID_SVXPAGE_ONLINEUPDATE == nPageId )
+ {
+ try
+ {
+ Reference < XInterface > xService( setup::UpdateCheck::create( ::comphelper::getProcessComponentContext() ) );
+ if( ! xService.is() )
+ continue;
+ }
+ catch ( css::uno::DeploymentException& )
+ {
+ continue;
+ }
+ }
+
+ // Disable Basic IDE options, if experimental features are not enabled
+ if( RID_SVXPAGE_BASICIDE_OPTIONS == nPageId )
+ {
+ SvtMiscOptions aMiscOpt;
+ if( ! aMiscOpt.IsExperimentalMode() )
+ continue;
+ }
+
+ AddTabPage( nPageId, sNewTitle, nGroup );
+ }
+ }
+
+ // Load and Save options
+ if ( !lcl_isOptionHidden( SID_FILTER_DLG, aOptionsDlgOpt ) )
+ {
+ setGroupName( "LoadSave", CuiResId(SID_FILTER_DLG_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_FILTER_DLG_RES[0].first), nullptr, nullptr, SID_FILTER_DLG );
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_FILTER_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_FILTER_DLG_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_FILTER_DLG_RES[i].first), nGroup );
+ }
+ }
+
+ // Language options
+ SvtLanguageOptions aLanguageOptions;
+ if ( !lcl_isOptionHidden( SID_LANGUAGE_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName("LanguageSettings", CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first), nullptr, nullptr, SID_LANGUAGE_OPTIONS );
+ for (size_t i = 1; i < SAL_N_ELEMENTS(SID_LANGUAGE_OPTIONS_RES); ++i)
+ {
+ nPageId = static_cast<sal_uInt16>(SID_LANGUAGE_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SVXPAGE_JSEARCH_OPTIONS != nPageId || aLanguageOptions.IsJapaneseFindEnabled() ) &&
+ ( RID_SVXPAGE_ASIAN_LAYOUT != nPageId || aLanguageOptions.IsAsianTypographyEnabled() ) &&
+ ( RID_SVXPAGE_OPTIONS_CTL != nPageId || aLanguageOptions.IsCTLFontEnabled() ) )
+ AddTabPage(nPageId, CuiResId(SID_LANGUAGE_OPTIONS_RES[i].first), nGroup);
+ }
+ }
+
+ OUString aFactory = getCurrentFactory_Impl( _xFrame );
+ DBG_ASSERT( GetModuleIdentifier( _xFrame ) == aFactory, "S H I T!!!" );
+
+ // Writer and Writer/Web options
+ SvtModuleOptions aModuleOpt;
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ // text document
+ if ( aFactory == "com.sun.star.text.TextDocument"
+ || aFactory == "com.sun.star.text.WebDocument"
+ || aFactory == "com.sun.star.text.GlobalDocument" )
+ {
+ SfxModule* pSwMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ if ( !lcl_isOptionHidden( SID_SW_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ if ( aFactory == "com.sun.star.text.WebDocument" )
+ setGroupName( "WriterWeb", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ else
+ setGroupName( "Writer", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SW_EDITOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_EDITOPTIONS );
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_SW_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SW_TP_STD_FONT_CJK != nPageId || aLanguageOptions.IsCJKFontEnabled() ) &&
+ ( RID_SW_TP_STD_FONT_CTL != nPageId || aLanguageOptions.IsCTLFontEnabled() ) &&
+ ( RID_SW_TP_MAILCONFIG != nPageId || MailMergeCfg_Impl().IsEmailSupported() ) )
+ AddTabPage( nPageId, CuiResId(SID_SW_EDITOPTIONS_RES[i].first), nGroup );
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+
+ // HTML documents
+ if ( !lcl_isOptionHidden( SID_SW_ONLINEOPTIONS, aOptionsDlgOpt ) )
+ {
+ nGroup = AddGroup(CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_ONLINEOPTIONS );
+ for( size_t i = 1; i < SAL_N_ELEMENTS(SID_SW_ONLINEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_ONLINEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage(nPageId, CuiResId(SID_SW_ONLINEOPTIONS_RES[i].first), nGroup);
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+ }
+ }
+
+ // Calc options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ if ( aFactory == "com.sun.star.sheet.SpreadsheetDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SC_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pScMod = SfxApplication::GetModule( SfxToolsModule::Calc );
+ setGroupName( "Calc", CuiResId(SID_SC_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SC_EDITOPTIONS_RES[0].first), pScMod, pScMod, SID_SC_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(SAL_N_ELEMENTS(SID_SC_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SC_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SC_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Impress options
+ SfxModule* pSdMod = SfxApplication::GetModule( SfxToolsModule::Draw );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ if ( aFactory == "com.sun.star.presentation.PresentationDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( "Impress", CuiResId(SID_SD_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_EDITOPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(SAL_N_ELEMENTS(SID_SD_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Draw options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ if ( aFactory == "com.sun.star.drawing.DrawingDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_GRAPHIC_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( "Draw", CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_GRAPHIC_OPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(SAL_N_ELEMENTS(SID_SD_GRAPHIC_OPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_GRAPHIC_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Math options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ if ( aFactory == "com.sun.star.formula.FormulaProperties" )
+ {
+ if ( !lcl_isOptionHidden( SID_SM_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pSmMod = SfxApplication::GetModule(SfxToolsModule::Math);
+ setGroupName( "Math", CuiResId(SID_SM_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SM_EDITOPTIONS_RES[0].first), pSmMod, pSmMod, SID_SM_EDITOPTIONS );
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_SM_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SM_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SM_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Database - needed only if there is an application which integrates with databases
+ if ( !lcl_isOptionHidden( SID_SB_STARBASEOPTIONS, aOptionsDlgOpt ) &&
+ ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC )
+ ) )
+ {
+ setGroupName( "Base", CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first), nullptr, nullptr, SID_SB_STARBASEOPTIONS );
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_SB_STARBASEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SB_STARBASEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SB_STARBASEOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Chart options (always installed and active)
+ if ( !lcl_isOptionHidden( SID_SCH_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( "Charts", CuiResId(SID_SCH_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SCH_EDITOPTIONS_RES[0].first), nullptr, nullptr, SID_SCH_EDITOPTIONS );
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_SCH_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SCH_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SCH_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Internet options
+ if ( lcl_isOptionHidden( SID_INET_DLG, aOptionsDlgOpt ) )
+ return;
+
+ setGroupName("Internet", CuiResId(SID_INET_DLG_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_INET_DLG_RES[0].first), nullptr, nullptr, SID_INET_DLG );
+
+ for ( size_t i = 1; i < SAL_N_ELEMENTS(SID_INET_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_INET_DLG_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+#if defined(_WIN32)
+ // Disable E-mail tab-page on Windows
+ if ( nPageId == RID_SVXPAGE_INET_MAIL )
+ continue;
+#endif
+ AddTabPage( nPageId, CuiResId(SID_INET_DLG_RES[i].first), nGroup );
+ }
+}
+
+static bool isNodeActive( OptionsNode const * pNode, Module* pModule )
+{
+ if ( pNode )
+ {
+ // Node for all modules active?
+ if ( pNode->m_bAllModules )
+ return true;
+
+ // OOo-Nodes (Writer, Calc, Impress...) are active if node is already inserted
+ if ( !getGroupName( pNode->m_sId, false ).isEmpty() )
+ return true;
+
+ // no module -> not active
+ if ( !pModule )
+ return false;
+
+ // search node in active module
+ if ( pModule->m_bActive )
+ {
+ for (auto const& j : pModule->m_aNodeList)
+ if ( j->m_sId == pNode->m_sId )
+ return true;
+ }
+ }
+ return false;
+}
+
+void OfaTreeOptionsDialog::LoadExtensionOptions( const OUString& rExtensionId )
+{
+ std::unique_ptr<Module> pModule;
+
+ // when called by Tools - Options then load nodes of active module
+ if ( rExtensionId.isEmpty() )
+ {
+ pModule = LoadModule( GetModuleIdentifier( Reference< XFrame >() ) );
+ }
+
+ VectorOfNodes aNodeList = LoadNodes( pModule.get(), rExtensionId );
+ InsertNodes( aNodeList );
+}
+
+OUString OfaTreeOptionsDialog::GetModuleIdentifier( const Reference< XFrame >& rFrame )
+{
+ OUString sModule;
+ Reference < XFrame > xCurrentFrame( rFrame );
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
+
+ if ( !xCurrentFrame.is() )
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( xContext );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sModule = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "OfaTreeOptionsDialog::GetModuleIdentifier(): exception of XModuleManager::identify()");
+ }
+ }
+ return sModule;
+}
+
+std::unique_ptr<Module> OfaTreeOptionsDialog::LoadModule(
+ const OUString& rModuleIdentifier )
+{
+ std::unique_ptr<Module> pModule;
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Modules::get());
+
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+ for ( const OUString& rModule : seqNames )
+ {
+ if ( rModuleIdentifier == rModule )
+ {
+ // current active module found
+ pModule.reset(new Module);
+ pModule->m_bActive = true;
+
+ Reference< XNameAccess > xModAccess;
+ xSet->getByName( rModule ) >>= xModAccess;
+ if ( xModAccess.is() )
+ {
+ // load the nodes of this module
+ Reference< XNameAccess > xNodeAccess;
+ xModAccess->getByName( "Nodes" ) >>= xNodeAccess;
+ if ( xNodeAccess.is() )
+ {
+ const Sequence< OUString > xTemp = xNodeAccess->getElementNames();
+ Reference< XNameAccess > xAccess;
+ sal_Int32 nIndex = -1;
+ for ( const OUString& rNode : xTemp)
+ {
+ xNodeAccess->getByName( rNode ) >>= xAccess;
+ if ( xAccess.is() )
+ {
+ xAccess->getByName( "Index" ) >>= nIndex;
+ if ( nIndex < 0 )
+ // append nodes with index < 0
+ pModule->m_aNodeList.push_back(
+ std::unique_ptr<OrderedEntry>(new OrderedEntry(nIndex, rNode)));
+ else
+ {
+ // search position of the node
+ std::vector<OrderedEntry *>::size_type y = 0;
+ for ( ; y < pModule->m_aNodeList.size(); ++y )
+ {
+ sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
+ if ( nNodeIdx < 0 || nNodeIdx > nIndex )
+ break;
+ }
+ // and insert the node on this position
+ pModule->m_aNodeList.insert(
+ pModule->m_aNodeList.begin() + y,
+ std::unique_ptr<OrderedEntry>(new OrderedEntry( nIndex, rNode )) );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ return pModule;
+}
+
+VectorOfNodes OfaTreeOptionsDialog::LoadNodes(
+ Module* pModule, const OUString& rExtensionId)
+{
+ VectorOfNodes aOutNodeList;
+
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Nodes::get());
+ VectorOfNodes aNodeList;
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+
+ for ( OUString const & sGroupName : seqNames )
+ {
+ Reference< XNameAccess > xNodeAccess;
+ xSet->getByName( sGroupName ) >>= xNodeAccess;
+
+ if ( xNodeAccess.is() )
+ {
+ OUString sNodeId, sLabel, sPageURL;
+ bool bAllModules = false;
+
+ sNodeId = sGroupName;
+ xNodeAccess->getByName( "Label" ) >>= sLabel;
+ xNodeAccess->getByName( "OptionsPage" ) >>= sPageURL;
+ xNodeAccess->getByName( "AllModules" ) >>= bAllModules;
+
+ if ( sLabel.isEmpty() )
+ sLabel = sGroupName;
+ OUString sTemp = getGroupName( sLabel, !rExtensionId.isEmpty() );
+ if ( !sTemp.isEmpty() )
+ sLabel = sTemp;
+ std::unique_ptr<OptionsNode> pNode(new OptionsNode(sNodeId, sLabel, bAllModules));
+
+ if ( rExtensionId.isEmpty() && !isNodeActive( pNode.get(), pModule ) )
+ {
+ continue;
+ }
+
+ Reference< XNameAccess > xLeavesSet;
+ xNodeAccess->getByName( "Leaves" ) >>= xLeavesSet;
+ if ( xLeavesSet.is() )
+ {
+ const Sequence< OUString > seqLeaves = xLeavesSet->getElementNames();
+ for ( OUString const & leafName : seqLeaves )
+ {
+ Reference< XNameAccess > xLeaveAccess;
+ xLeavesSet->getByName( leafName ) >>= xLeaveAccess;
+
+ if ( xLeaveAccess.is() )
+ {
+ OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
+ sal_Int32 nLeafGrpIdx = 0;
+
+ xLeaveAccess->getByName( "Id" ) >>= sId;
+ xLeaveAccess->getByName( "Label" ) >>= sLeafLabel;
+ xLeaveAccess->getByName( "OptionsPage" ) >>= sLeafURL;
+ xLeaveAccess->getByName( "EventHandlerService" ) >>= sEventHdl;
+ xLeaveAccess->getByName( "GroupId" ) >>= sLeafGrpId;
+ xLeaveAccess->getByName( "GroupIndex" ) >>= nLeafGrpIdx;
+
+ if ( rExtensionId.isEmpty() || sId == rExtensionId )
+ {
+ std::unique_ptr<OptionsLeaf> pLeaf(new OptionsLeaf(
+ sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx ));
+
+ if ( !sLeafGrpId.isEmpty() )
+ {
+ bool bAlreadyOpened = false;
+ if ( !pNode->m_aGroupedLeaves.empty() )
+ {
+ for (auto & rGroup : pNode->m_aGroupedLeaves)
+ {
+ if ( !rGroup.empty() &&
+ rGroup[0]->m_sGroupId == sLeafGrpId )
+ {
+ std::vector<std::unique_ptr<OptionsLeaf>>::size_type l = 0;
+ for ( ; l < rGroup.size(); ++l )
+ {
+ if ( rGroup[l]->m_nGroupIndex >= nLeafGrpIdx )
+ break;
+ }
+ rGroup.insert( rGroup.begin() + l, std::move(pLeaf) );
+ bAlreadyOpened = true;
+ break;
+ }
+ }
+ }
+ if ( !bAlreadyOpened )
+ {
+ std::vector< std::unique_ptr<OptionsLeaf> > aGroupedLeaves;
+ aGroupedLeaves.push_back( std::move(pLeaf) );
+ pNode->m_aGroupedLeaves.push_back( std::move(aGroupedLeaves) );
+ }
+ }
+ else
+ pNode->m_aLeaves.push_back( std::move(pLeaf) );
+ }
+ }
+ }
+ }
+
+ // do not insert nodes without leaves
+ if ( !pNode->m_aLeaves.empty() || !pNode->m_aGroupedLeaves.empty() )
+ {
+ pModule ? aNodeList.push_back( std::move(pNode) ) : aOutNodeList.push_back( std::move(pNode) );
+ }
+ }
+ }
+
+ if ( pModule && !aNodeList.empty() )
+ {
+ for ( auto const & i: pModule->m_aNodeList )
+ {
+ OUString sNodeId = i->m_sId;
+ for ( auto j = aNodeList.begin(); j != aNodeList.end(); ++j )
+ {
+ if ( (*j)->m_sId == sNodeId )
+ {
+ aOutNodeList.push_back( std::move(*j) );
+ aNodeList.erase( j );
+ break;
+ }
+ }
+ }
+
+ for ( auto & i: aNodeList )
+ aOutNodeList.push_back( std::move(i) );
+ }
+ return aOutNodeList;
+}
+
+static sal_uInt16 lcl_getGroupId( const OUString& rGroupName, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nRet = 0;
+
+ std::unique_ptr<weld::TreeIter> xEntry = rTreeLB.make_iterator();
+ bool bEntry = rTreeLB.get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!rTreeLB.get_iter_depth(*xEntry))
+ {
+ OUString sTemp(rTreeLB.get_text(*xEntry));
+ if (sTemp == rGroupName)
+ return nRet;
+ nRet++;
+ }
+ bEntry = rTreeLB.iter_next(*xEntry);
+ }
+
+ return USHRT_MAX;
+}
+
+static void lcl_insertLeaf(
+ OfaTreeOptionsDialog* pDlg, OptionsNode const * pNode, OptionsLeaf const * pLeaf, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nGrpId = lcl_getGroupId( pNode->m_sLabel, rTreeLB );
+ if ( USHRT_MAX == nGrpId )
+ {
+ sal_uInt16 nNodeGrpId = getGroupNodeId( pNode->m_sId );
+ nGrpId = pDlg->AddGroup( pNode->m_sLabel, nullptr, nullptr, nNodeGrpId );
+ }
+ OptionsPageInfo* pInfo = pDlg->AddTabPage( 0, pLeaf->m_sLabel, nGrpId );
+ pInfo->m_sPageURL = pLeaf->m_sPageURL;
+ pInfo->m_sEventHdl = pLeaf->m_sEventHdl;
+}
+
+void OfaTreeOptionsDialog::InsertNodes( const VectorOfNodes& rNodeList )
+{
+ for (auto const& node : rNodeList)
+ {
+ if ( !node->m_aLeaves.empty() || !node->m_aGroupedLeaves.empty() )
+ {
+ for ( auto const & j: node->m_aGroupedLeaves )
+ {
+ for ( size_t k = 0; k < j.size(); ++k )
+ {
+ lcl_insertLeaf( this, node.get(), j[k].get(), *xTreeLB );
+ }
+ }
+
+ for ( auto const & j: node->m_aLeaves )
+ {
+ lcl_insertLeaf( this, node.get(), j.get(), *xTreeLB );
+ }
+ }
+ }
+}
+
+void OfaTreeOptionsDialog::SetNeedsRestart( svtools::RestartReason eReason)
+{
+ bNeedsRestart = true;
+ eRestartReason = eReason;
+}
+
+short OfaTreeOptionsDialog::run()
+{
+ std::unique_ptr< SvxDicListChgClamp > pClamp;
+ if ( !bIsFromExtensionManager )
+ {
+ // collect all DictionaryList Events while the dialog is executed
+ Reference<css::linguistic2::XSearchableDictionaryList> xDictionaryList(LinguMgr::GetDictionaryList());
+ pClamp.reset( new SvxDicListChgClamp( xDictionaryList ) );
+ }
+
+ short nRet = SfxOkDialogController::run();
+
+ if( RET_OK == nRet )
+ {
+ ApplyItemSets();
+ utl::ConfigManager::storeConfigItems();
+ }
+
+ return nRet;
+}
+
+// class ExtensionsTabPage -----------------------------------------------
+ExtensionsTabPage::ExtensionsTabPage(
+ weld::Container* pParent, const OUString& rPageURL,
+ const OUString& rEvtHdl, const Reference< awt::XContainerWindowProvider >& rProvider )
+ : m_pContainer(pParent)
+ , m_sPageURL(rPageURL)
+ , m_sEventHdl(rEvtHdl)
+ , m_xWinProvider(rProvider)
+{
+}
+
+ExtensionsTabPage::~ExtensionsTabPage()
+{
+ Hide();
+ DeactivatePage();
+
+ if ( m_xPage.is() )
+ {
+ try
+ {
+ m_xPage->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPage.clear();
+ }
+
+ if ( m_xPageParent.is() )
+ {
+ try
+ {
+ m_xPageParent->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPageParent.clear();
+ }
+}
+
+void ExtensionsTabPage::CreateDialogWithHandler()
+{
+ try
+ {
+ bool bWithHandler = !m_sEventHdl.isEmpty();
+ if ( bWithHandler )
+ {
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ m_xEventHdl.set( xFactory->createInstance( m_sEventHdl ), UNO_QUERY );
+ }
+
+ if ( !bWithHandler || m_xEventHdl.is() )
+ {
+ m_xPageParent = m_pContainer->CreateChildFrame();
+ Reference<awt::XWindowPeer> xParent(m_xPageParent, UNO_QUERY);
+ m_xPage =
+ m_xWinProvider->createContainerWindow(
+ m_sPageURL, OUString(), xParent, m_xEventHdl );
+
+ Reference< awt::XControl > xPageControl( m_xPage, UNO_QUERY );
+ if ( xPageControl.is() )
+ {
+ Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
+ if ( xWinPeer.is() )
+ {
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWinPeer );
+ if ( pWindow )
+ pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::CreateDialogWithHandler(): exception of XDialogProvider2::createDialogWithHandler()");
+ }
+}
+
+bool ExtensionsTabPage::DispatchAction( const OUString& rAction )
+{
+ bool bRet = false;
+ if ( m_xEventHdl.is() )
+ {
+ try
+ {
+ bRet = m_xEventHdl->callHandlerMethod( m_xPage, Any( rAction ), "external_event" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::DispatchAction(): exception of XDialogEventHandler::callHandlerMethod()" );
+ }
+ }
+ return bRet;
+}
+
+void ExtensionsTabPage::Show()
+{
+ if (!m_xPageParent.is())
+ return;
+
+ VclPtr<vcl::Window> xPageParent = VCLUnoHelper::GetWindow(m_xPageParent);
+ if (xPageParent)
+ {
+ // NoActivate otherwise setVisible will call Window::Show which will grab
+ // focus to the page by default
+ xPageParent->Show(true, ShowFlags::NoActivate);
+ }
+
+ m_xPageParent->setVisible(true);
+}
+
+void ExtensionsTabPage::Hide()
+{
+ if (!m_xPageParent.is())
+ return;
+ m_xPageParent->setVisible(false);
+}
+
+void ExtensionsTabPage::ActivatePage()
+{
+ if ( !m_xPage.is() )
+ {
+ CreateDialogWithHandler();
+
+ if ( m_xPage.is() )
+ {
+ auto aWindowRect = m_xPageParent->getPosSize();
+ m_xPage->setPosSize(0, 0, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POSSIZE);
+ if ( !m_sEventHdl.isEmpty() )
+ DispatchAction( "initialize" );
+ }
+ }
+
+ if ( m_xPage.is() )
+ {
+ m_xPage->setVisible( true );
+ }
+}
+
+void ExtensionsTabPage::DeactivatePage()
+{
+ if ( m_xPage.is() )
+ m_xPage->setVisible( false );
+}
+
+void ExtensionsTabPage::ResetPage()
+{
+ DispatchAction( "back" );
+ ActivatePage();
+}
+
+void ExtensionsTabPage::SavePage()
+{
+ DispatchAction( "ok" );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.cxx b/cui/source/options/tsaurls.cxx
new file mode 100644
index 000000000..62f08298d
--- /dev/null
+++ b/cui/source/options/tsaurls.cxx
@@ -0,0 +1,126 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <svx/svxdlg.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include "tsaurls.hxx"
+
+using namespace ::com::sun::star;
+
+TSAURLsDialog::TSAURLsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/tsaurldialog.ui", "TSAURLDialog")
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xURLListBox(m_xBuilder->weld_tree_view("urls"))
+ , m_xEnterAUrl(m_xBuilder->weld_label("enteraurl"))
+{
+ m_xURLListBox->set_size_request(m_xURLListBox->get_approximate_digit_width() * 28,
+ m_xURLListBox->get_height_rows(8));
+ m_xOKBtn->set_sensitive(false);
+
+ m_xAddBtn->connect_clicked( LINK( this, TSAURLsDialog, AddHdl_Impl ) );
+ m_xDeleteBtn->connect_clicked( LINK( this, TSAURLsDialog, DeleteHdl_Impl ) );
+ m_xOKBtn->connect_clicked( LINK( this, TSAURLsDialog, OKHdl_Impl ) );
+ m_xURLListBox->connect_changed( LINK( this, TSAURLsDialog, SelectHdl ) );
+
+ try
+ {
+ std::optional<css::uno::Sequence<OUString>> aUserSetTSAURLs(officecfg::Office::Common::Security::Scripting::TSAURLs::get());
+ if (aUserSetTSAURLs)
+ {
+ const css::uno::Sequence<OUString>& rUserSetTSAURLs = *aUserSetTSAURLs;
+ for (auto const& userSetTSAURL : rUserSetTSAURLs)
+ {
+ AddTSAURL(userSetTSAURL);
+ }
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "TSAURLsDialog::TSAURLsDialog()");
+ }
+
+ if (m_xURLListBox->get_selected_index() == -1)
+ {
+ m_xDeleteBtn->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, OKHdl_Impl, weld::Button&, void)
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ officecfg::Office::Common::Security::Scripting::TSAURLs::set(comphelper::containerToSequence(m_aURLs), batch);
+ batch->commit();
+
+ m_xDialog->response(RET_OK);
+}
+
+TSAURLsDialog::~TSAURLsDialog()
+{
+}
+
+void TSAURLsDialog::AddTSAURL(const OUString& rURL)
+{
+ m_aURLs.insert(rURL);
+
+ m_xURLListBox->freeze();
+ m_xURLListBox->clear();
+
+ for (auto const& url : m_aURLs)
+ {
+ m_xURLListBox->append_text(url);
+ }
+
+ m_xURLListBox->thaw();
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, AddHdl_Impl, weld::Button&, void)
+{
+ OUString aURL;
+ OUString aDesc(m_xEnterAUrl->get_label());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(m_xDialog.get(), aURL, aDesc));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName(aURL);
+ AddTSAURL(aURL);
+ m_xOKBtn->set_sensitive(true);
+ }
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, SelectHdl, weld::TreeView&, void)
+{
+ m_xDeleteBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ int nSel = m_xURLListBox->get_selected_index();
+ if (nSel == -1)
+ return;
+
+ m_aURLs.erase(m_xURLListBox->get_text(nSel));
+ m_xURLListBox->remove(nSel);
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+ m_xOKBtn->set_sensitive(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.hxx b/cui/source/options/tsaurls.hxx
new file mode 100644
index 000000000..ddec756bd
--- /dev/null
+++ b/cui/source/options/tsaurls.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/.
+ */
+
+#ifndef INCLUDED_CUI_SOURCE_OPTIONS_TSAURLS_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_TSAURLS_HXX
+
+#include <vcl/weld.hxx>
+
+#include <set>
+
+class TSAURLsDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDeleteBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::TreeView> m_xURLListBox;
+ std::unique_ptr<weld::Label> m_xEnterAUrl;
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ // After operations in a TreeView we have nothing selected
+ // Is Selected element handler for the TreeView
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+ std::set<OUString> m_aURLs;
+
+ void AddTSAURL(const OUString& rURL);
+
+public:
+ explicit TSAURLsDialog(weld::Window* pParent);
+ virtual ~TSAURLsDialog() override;
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.cxx b/cui/source/options/webconninfo.cxx
new file mode 100644
index 000000000..1d3abe82f
--- /dev/null
+++ b/cui/source/options/webconninfo.cxx
@@ -0,0 +1,227 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "webconninfo.hxx"
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/UrlRecord.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/docpasswordrequest.hxx>
+
+using namespace ::com::sun::star;
+
+
+namespace svx
+{
+
+// class WebConnectionInfoDialog -----------------------------------------
+
+WebConnectionInfoDialog::WebConnectionInfoDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/storedwebconnectiondialog.ui", "StoredWebConnectionDialog")
+ , m_nPos( -1 )
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+ , m_xRemoveAllBtn(m_xBuilder->weld_button("removeall"))
+ , m_xChangeBtn(m_xBuilder->weld_button("change"))
+ , m_xPasswordsLB(m_xBuilder->weld_tree_view("logins"))
+{
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xPasswordsLB->get_approximate_digit_width() * 50);
+ m_xPasswordsLB->set_column_fixed_widths(aWidths);
+ m_xPasswordsLB->set_size_request(m_xPasswordsLB->get_approximate_digit_width() * 70,
+ m_xPasswordsLB->get_height_rows(8));
+
+ m_xPasswordsLB->connect_column_clicked(LINK(this, WebConnectionInfoDialog, HeaderBarClickedHdl));
+
+ FillPasswordList();
+
+ m_xRemoveBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemovePasswordHdl ) );
+ m_xRemoveAllBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemoveAllPasswordsHdl ) );
+ m_xChangeBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, ChangePasswordHdl ) );
+ m_xPasswordsLB->connect_changed( LINK( this, WebConnectionInfoDialog, EntrySelectedHdl ) );
+
+ m_xRemoveBtn->set_sensitive( false );
+ m_xChangeBtn->set_sensitive( false );
+
+ m_xPasswordsLB->make_sorted();
+}
+
+WebConnectionInfoDialog::~WebConnectionInfoDialog()
+{
+}
+
+IMPL_LINK(WebConnectionInfoDialog, HeaderBarClickedHdl, int, nColumn, void)
+{
+ if (nColumn == 0) // only the first column is sorted
+ {
+ m_xPasswordsLB->set_sort_order(!m_xPasswordsLB->get_sort_order());
+ }
+}
+
+void WebConnectionInfoDialog::FillPasswordList()
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr);
+
+ const uno::Sequence< task::UrlRecord > aURLEntries = xMasterPasswd->getAllPersistent( xInteractionHandler );
+ sal_Int32 nCount = 0;
+ for ( task::UrlRecord const & urlEntry : aURLEntries )
+ {
+ for ( auto const & user : urlEntry.UserList )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), urlEntry.Url);
+ m_xPasswordsLB->set_text(nCount, user.UserName, 1);
+ ++nCount;
+ }
+ }
+
+ // remember pos of first url container entry.
+ m_nPos = nCount;
+
+ const uno::Sequence< OUString > aUrls
+ = xMasterPasswd->getUrls( true /* OnlyPersistent */ );
+
+ for ( OUString const & url : aUrls )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), url);
+ m_xPasswordsLB->set_text(nCount, "*");
+ ++nCount;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemovePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ if ( nPos < m_nPos )
+ {
+ xPasswdContainer->removePersistent( aURL, aUserName );
+ }
+ else
+ {
+ xPasswdContainer->removeUrl( aURL );
+ }
+
+ m_xPasswordsLB->remove(nEntry);
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemoveAllPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ // should the master password be requested before?
+ xPasswdContainer->removeAllPersistent();
+
+ const uno::Sequence< OUString > aUrls
+ = xPasswdContainer->getUrls( true /* OnlyPersistent */ );
+ for ( OUString const & url : aUrls )
+ xPasswdContainer->removeUrl( url );
+
+ m_xPasswordsLB->clear();
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, ChangePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ ::comphelper::SimplePasswordRequest* pPasswordRequest
+ = new ::comphelper::SimplePasswordRequest;
+ uno::Reference< task::XInteractionRequest > rRequest( pPasswordRequest );
+
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), m_xDialog->GetXWindow());
+ xInteractionHandler->handle( rRequest );
+
+ if ( pPasswordRequest->isPassword() )
+ {
+ OUString aNewPass = pPasswordRequest->getPassword();
+ uno::Sequence<OUString> aPasswd { aNewPass };
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+ xPasswdContainer->addPersistent(
+ aURL, aUserName, aPasswd, xInteractionHandler );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, EntrySelectedHdl, weld::TreeView&, void)
+{
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry == -1)
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ m_xChangeBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveBtn->set_sensitive(true);
+
+ // url container entries (-> use system credentials) have
+ // no password
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ m_xChangeBtn->set_sensitive(nPos < m_nPos);
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.hxx b/cui/source/options/webconninfo.hxx
new file mode 100644
index 000000000..95d524c8a
--- /dev/null
+++ b/cui/source/options/webconninfo.hxx
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this 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_CUI_SOURCE_OPTIONS_WEBCONNINFO_HXX
+#define INCLUDED_CUI_SOURCE_OPTIONS_WEBCONNINFO_HXX
+
+#include <vcl/weld.hxx>
+
+namespace svx
+{
+ class WebConnectionInfoDialog : public weld::GenericDialogController
+ {
+ private:
+ sal_Int32 m_nPos;
+
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xRemoveAllBtn;
+ std::unique_ptr<weld::Button> m_xChangeBtn;
+ std::unique_ptr<weld::TreeView> m_xPasswordsLB;
+
+ DECL_LINK( HeaderBarClickedHdl, int, void );
+ DECL_LINK( RemovePasswordHdl, weld::Button&, void );
+ DECL_LINK( RemoveAllPasswordsHdl, weld::Button&, void );
+ DECL_LINK( ChangePasswordHdl, weld::Button&, void );
+ DECL_LINK( EntrySelectedHdl, weld::TreeView&, void );
+
+ void FillPasswordList();
+
+ public:
+ explicit WebConnectionInfoDialog(weld::Window* pParent);
+ virtual ~WebConnectionInfoDialog() override;
+ };
+
+
+}
+
+
+#endif // INCLUDED_CUI_SOURCE_OPTIONS_WEBCONNINFO_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/align.cxx b/cui/source/tabpages/align.cxx
new file mode 100644
index 000000000..30965cf9c
--- /dev/null
+++ b/cui/source/tabpages/align.cxx
@@ -0,0 +1,774 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <align.hxx>
+
+#include <editeng/svxenum.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <bitmaps.hlst>
+#include <svx/rotmodit.hxx>
+#include <svx/sdangitm.hxx>
+
+#include <editeng/frmdiritem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/image.hxx>
+
+#define IID_BOTTOMLOCK 1
+#define IID_TOPLOCK 2
+#define IID_CELLLOCK 3
+
+namespace svx {
+
+const sal_uInt16 AlignmentTabPage::s_pRanges[] =
+{
+ SID_ATTR_ALIGN_HOR_JUSTIFY,SID_ATTR_ALIGN_VER_JUSTIFY,
+ SID_ATTR_ALIGN_STACKED,SID_ATTR_ALIGN_LINEBREAK,
+ SID_ATTR_ALIGN_INDENT,SID_ATTR_ALIGN_INDENT,
+ SID_ATTR_ALIGN_DEGREES,SID_ATTR_ALIGN_DEGREES,
+ SID_ATTR_ALIGN_LOCKPOS,SID_ATTR_ALIGN_LOCKPOS,
+ SID_ATTR_ALIGN_HYPHENATION,SID_ATTR_ALIGN_HYPHENATION,
+ SID_ATTR_ALIGN_ASIANVERTICAL,SID_ATTR_ALIGN_ASIANVERTICAL,
+ SID_ATTR_FRAMEDIRECTION,SID_ATTR_FRAMEDIRECTION,
+ SID_ATTR_ALIGN_SHRINKTOFIT,SID_ATTR_ALIGN_SHRINKTOFIT,
+ 0
+};
+
+
+namespace {
+
+template<typename JustContainerType, typename JustEnumType>
+void lcl_MaybeResetAlignToDistro(
+ weld::ComboBox& rLB, sal_uInt16 nListPos, const SfxItemSet& rCoreAttrs, sal_uInt16 nWhichAlign, sal_uInt16 nWhichJM, JustEnumType eBlock)
+{
+ const SfxPoolItem* pItem;
+ if (rCoreAttrs.GetItemState(nWhichAlign, true, &pItem) != SfxItemState::SET)
+ // alignment not set.
+ return;
+
+ const SfxEnumItemInterface* p = static_cast<const SfxEnumItemInterface*>(pItem);
+ JustContainerType eVal = static_cast<JustContainerType>(p->GetEnumValue());
+ if (eVal != eBlock)
+ // alignment is not 'justify'. No need to go further.
+ return;
+
+ if (rCoreAttrs.GetItemState(nWhichJM, true, &pItem) != SfxItemState::SET)
+ // justification method is not set.
+ return;
+
+ p = static_cast<const SfxEnumItemInterface*>(pItem);
+ SvxCellJustifyMethod eMethod = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ if (eMethod == SvxCellJustifyMethod::Distribute)
+ {
+ // Select the 'distribute' entry in the specified list box.
+ rLB.set_active(nListPos);
+ }
+}
+
+void lcl_SetJustifyMethodToItemSet(SfxItemSet& rSet, const SfxItemSet& rOldSet, sal_uInt16 nWhichJM, const weld::ComboBox& rLB, sal_uInt16 nListPos)
+{
+ SvxCellJustifyMethod eJM = SvxCellJustifyMethod::Auto;
+ if (rLB.get_active() == nListPos)
+ eJM = SvxCellJustifyMethod::Distribute;
+
+ // tdf#129300 If it would create no change, don't force it
+ const SvxJustifyMethodItem& rOldItem = static_cast<const SvxJustifyMethodItem&>(rOldSet.Get(nWhichJM));
+ if (rOldItem.GetValue() == eJM)
+ {
+ rSet.InvalidateItem(nWhichJM);
+ return;
+ }
+
+ SvxJustifyMethodItem aItem(eJM, nWhichJM);
+ rSet.Put(aItem);
+}
+
+}//namespace
+
+AlignmentTabPage::AlignmentTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/cellalignment.ui", "CellAlignPage", &rCoreAttrs)
+ , m_aVsRefEdge(nullptr)
+ // text alignment
+ , m_xLbHorAlign(m_xBuilder->weld_combo_box("comboboxHorzAlign"))
+ , m_xFtIndent(m_xBuilder->weld_label("labelIndent"))
+ , m_xEdIndent(m_xBuilder->weld_metric_spin_button("spinIndentFrom", FieldUnit::POINT))
+ , m_xFtVerAlign(m_xBuilder->weld_label("labelVertAlign"))
+ , m_xLbVerAlign(m_xBuilder->weld_combo_box("comboboxVertAlign"))
+ //text rotation
+ , m_xFtRotate(m_xBuilder->weld_label("labelDegrees"))
+ , m_xNfRotate(m_xBuilder->weld_metric_spin_button("spinDegrees", FieldUnit::DEGREE))
+ , m_xFtRefEdge(m_xBuilder->weld_label("labelRefEdge"))
+ //Asian mode
+ , m_xCbStacked(m_xBuilder->weld_check_button("checkVertStack"))
+ , m_xCbAsianMode(m_xBuilder->weld_check_button("checkAsianMode"))
+ // Properties
+ , m_xBoxDirection(m_xBuilder->weld_widget("boxDirection"))
+ , m_xBtnWrap(m_xBuilder->weld_check_button("checkWrapTextAuto"))
+ , m_xBtnHyphen(m_xBuilder->weld_check_button("checkHyphActive"))
+ , m_xBtnShrink(m_xBuilder->weld_check_button("checkShrinkFitCellSize"))
+ , m_xLbFrameDir(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextDirBox")))
+ //ValueSet hover strings
+ , m_xFtBotLock(m_xBuilder->weld_label("labelSTR_BOTTOMLOCK"))
+ , m_xFtTopLock(m_xBuilder->weld_label("labelSTR_TOPLOCK"))
+ , m_xFtCelLock(m_xBuilder->weld_label("labelSTR_CELLLOCK"))
+ , m_xFtABCD(m_xBuilder->weld_label("labelABCD"))
+ , m_xAlignmentFrame(m_xBuilder->weld_widget("alignment"))
+ , m_xOrientFrame(m_xBuilder->weld_widget("orientation"))
+ , m_xPropertiesFrame(m_xBuilder->weld_widget("properties"))
+ , m_xVsRefEdge(new weld::CustomWeld(*m_xBuilder, "references", m_aVsRefEdge))
+ , m_xCtrlDial(new DialControl)
+ , m_xCtrlDialWin(new weld::CustomWeld(*m_xBuilder, "dialcontrol", *m_xCtrlDial))
+{
+ m_xCtrlDial->SetLinkedField(m_xNfRotate.get());
+ m_xCtrlDial->SetText(m_xFtABCD->get_label());
+
+ InitVsRefEgde();
+
+ m_xLbHorAlign->connect_changed(LINK(this, AlignmentTabPage, UpdateEnableHdl));
+
+ m_xCbStacked->connect_toggled(LINK(this, AlignmentTabPage, StackedClickHdl));
+ m_xCbAsianMode->connect_toggled(LINK(this, AlignmentTabPage, AsianModeClickHdl));
+ m_xBtnWrap->connect_toggled(LINK(this, AlignmentTabPage, WrapClickHdl));
+ m_xBtnHyphen->connect_toggled(LINK(this, AlignmentTabPage, HyphenClickHdl));
+ m_xBtnShrink->connect_toggled(LINK(this, AlignmentTabPage, ShrinkClickHdl));
+
+ // Asian vertical mode
+ m_xCbAsianMode->set_visible(SvtCJKOptions().IsVerticalTextEnabled());
+
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xLbFrameDir->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+ m_xLbFrameDir->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+
+ // This page needs ExchangeSupport.
+ SetExchangeSupport();
+}
+
+AlignmentTabPage::~AlignmentTabPage()
+{
+ m_xCtrlDialWin.reset();
+ m_xCtrlDial.reset();
+ m_xVsRefEdge.reset();
+ m_xLbFrameDir.reset();
+}
+
+std::unique_ptr<SfxTabPage> AlignmentTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<AlignmentTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool AlignmentTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ bool bChanged = SfxTabPage::FillItemSet(rSet);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ if (m_xLbHorAlign->get_value_changed_from_saved())
+ {
+ SvxCellHorJustify eJustify(SvxCellHorJustify::Standard);
+ switch (m_xLbHorAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_HORALIGN_STD:
+ eJustify = SvxCellHorJustify::Standard;
+ break;
+ case ALIGNDLG_HORALIGN_LEFT:
+ eJustify = SvxCellHorJustify::Left;
+ break;
+ case ALIGNDLG_HORALIGN_CENTER:
+ eJustify = SvxCellHorJustify::Center;
+ break;
+ case ALIGNDLG_HORALIGN_RIGHT:
+ eJustify = SvxCellHorJustify::Right;
+ break;
+ case ALIGNDLG_HORALIGN_BLOCK:
+ case ALIGNDLG_HORALIGN_DISTRIBUTED:
+ eJustify = SvxCellHorJustify::Block;
+ break;
+ case ALIGNDLG_HORALIGN_FILL:
+ eJustify = SvxCellHorJustify::Repeat;
+ break;
+ }
+ rSet->Put(SvxHorJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ if (m_xEdIndent->get_value_changed_from_saved())
+ {
+ const SfxUInt16Item* pIndentItem = static_cast<const SfxUInt16Item*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_INDENT));
+ assert(pIndentItem);
+ std::unique_ptr<SfxUInt16Item> pNewIndentItem(pIndentItem->Clone());
+ pNewIndentItem->SetValue(m_xEdIndent->get_value(FieldUnit::TWIP));
+ rSet->Put(*pNewIndentItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ if (m_xLbVerAlign->get_value_changed_from_saved())
+ {
+ SvxCellVerJustify eJustify(SvxCellVerJustify::Standard);
+ switch (m_xLbVerAlign->get_active_id().toInt32())
+ {
+ case ALIGNDLG_VERALIGN_STD:
+ eJustify = SvxCellVerJustify::Standard;
+ break;
+ case ALIGNDLG_VERALIGN_TOP:
+ eJustify = SvxCellVerJustify::Top;
+ break;
+ case ALIGNDLG_VERALIGN_MID:
+ eJustify = SvxCellVerJustify::Center;
+ break;
+ case ALIGNDLG_VERALIGN_BOTTOM:
+ eJustify = SvxCellVerJustify::Bottom;
+ break;
+ case ALIGNDLG_VERALIGN_BLOCK:
+ case ALIGNDLG_VERALIGN_DISTRIBUTED:
+ eJustify = SvxCellVerJustify::Block;
+ break;
+ }
+ rSet->Put(SvxVerJustifyItem(eJustify, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ if (m_xNfRotate->get_value_changed_from_saved())
+ {
+ const SdrAngleItem* pAngleItem = static_cast<const SdrAngleItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_DEGREES));
+ assert(pAngleItem);
+ std::unique_ptr<SdrAngleItem> pNewAngleItem(pAngleItem->Clone());
+ pNewAngleItem->SetValue(m_xCtrlDial->GetRotation());
+ rSet->Put(*pNewAngleItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LOCKPOS);
+ if (m_aVsRefEdge.IsValueChangedFromSaved())
+ {
+ switch (m_aVsRefEdge.GetSelectedItemId())
+ {
+ case IID_CELLLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_STANDARD, nWhich));
+ break;
+ case IID_TOPLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_TOP, nWhich));
+ break;
+ case IID_BOTTOMLOCK:
+ rSet->Put(SvxRotateModeItem(SvxRotateMode::SVX_ROTATE_MODE_BOTTOM, nWhich));
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_STACKED);
+ if (m_xCbStacked->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pStackItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_STACKED));
+ assert(pStackItem);
+ std::unique_ptr<SfxBoolItem> pNewStackItem(pStackItem->Clone());
+ pNewStackItem->SetValue(m_xCbStacked->get_active());
+ rSet->Put(*pNewStackItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL);
+ if (m_xCbAsianMode->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(nWhich, m_xCbAsianMode->get_active()));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LINEBREAK);
+ if (m_xBtnWrap->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pWrapItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_LINEBREAK));
+ assert(pWrapItem);
+ std::unique_ptr<SfxBoolItem> pNewWrapItem(pWrapItem->Clone());
+ pNewWrapItem->SetValue(m_xBtnWrap->get_active());
+ rSet->Put(*pNewWrapItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_HYPHENATION);
+ if (m_xBtnHyphen->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pHyphItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_HYPHENATION));
+ assert(pHyphItem);
+ std::unique_ptr<SfxBoolItem> pNewHyphItem(pHyphItem->Clone());
+ pNewHyphItem->SetValue(m_xBtnHyphen->get_active());
+ rSet->Put(*pNewHyphItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT);
+ if (m_xBtnShrink->get_state_changed_from_saved())
+ {
+ const SfxBoolItem* pShrinkItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rSet, SID_ATTR_ALIGN_SHRINKTOFIT));
+ assert(pShrinkItem);
+ std::unique_ptr<SfxBoolItem> pNewShrinkItem(pShrinkItem->Clone());
+ pNewShrinkItem->SetValue(m_xBtnShrink->get_active());
+ rSet->Put(*pNewShrinkItem);
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+
+ if (m_xLbFrameDir->get_visible())
+ {
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ if (m_xLbFrameDir->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xLbFrameDir->get_active_id();
+ rSet->Put(SvxFrameDirectionItem(eDir, nWhich));
+ bChanged = true;
+ }
+ else if (SfxItemState::DEFAULT == rOldSet.GetItemState(nWhich, false))
+ rSet->InvalidateItem(nWhich);
+ }
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+ sal_uInt16 nWhichHorJM = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD);
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichHorJM, *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichHorJM);
+
+ sal_uInt16 nWhichVerJM = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD);
+ lcl_SetJustifyMethodToItemSet(*rSet, rOldSet, nWhichVerJM, *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED);
+ if (!bChanged)
+ bChanged = HasAlignmentChanged(*rSet, nWhichVerJM);
+
+ return bChanged;
+}
+
+namespace
+{
+ void ResetBool(sal_uInt16 nWhich, const SfxItemSet* pSet, weld::CheckButton& rBtn, weld::TriStateEnabled& rTriState)
+ {
+ SfxItemState eState = pSet->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ rBtn.hide();
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ rBtn.set_sensitive(false);
+ rTriState.bTriStateEnabled = false;
+ break;
+ case SfxItemState::DONTCARE:
+ rBtn.set_state(TRISTATE_INDET);
+ rTriState.bTriStateEnabled = true;
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxBoolItem& rItem = static_cast<const SfxBoolItem&>(pSet->Get(nWhich));
+ rBtn.set_state(static_cast<TriState>(rItem.GetValue()));
+ rTriState.bTriStateEnabled = false;
+ break;
+ }
+ }
+ rBtn.save_state();
+ }
+}
+
+void AlignmentTabPage::Reset(const SfxItemSet* pCoreAttrs)
+{
+ SfxTabPage::Reset(pCoreAttrs);
+
+ ResetBool(GetWhich(SID_ATTR_ALIGN_STACKED), pCoreAttrs, *m_xCbStacked, m_aStackedState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_ASIANVERTICAL), pCoreAttrs, *m_xCbAsianMode, m_aAsianModeState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_LINEBREAK), pCoreAttrs, *m_xBtnWrap, m_aWrapState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_HYPHENATION), pCoreAttrs, *m_xBtnHyphen, m_aHyphenState);
+ ResetBool(GetWhich(SID_ATTR_ALIGN_SHRINKTOFIT), pCoreAttrs, *m_xBtnShrink, m_aShrinkState);
+
+ sal_uInt16 nWhich = GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY);
+ SfxItemState eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbHorAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xLbHorAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbHorAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxHorJustifyItem& rJustifyItem = static_cast<const SvxHorJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellHorJustify::Standard:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_STD));
+ break;
+ case SvxCellHorJustify::Left:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_LEFT));
+ break;
+ case SvxCellHorJustify::Center:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_CENTER));
+ break;
+ case SvxCellHorJustify::Right:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_RIGHT));
+ break;
+ case SvxCellHorJustify::Block:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_BLOCK));
+ break;
+ case SvxCellHorJustify::Repeat:
+ m_xLbHorAlign->set_active_id(OUString::number(ALIGNDLG_HORALIGN_FILL));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_INDENT);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEdIndent->hide();
+ m_xFtIndent->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xEdIndent->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xEdIndent->set_text("");
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SfxUInt16Item& rIndentItem = static_cast<const SfxUInt16Item&>(pCoreAttrs->Get(nWhich));
+ m_xEdIndent->set_value(rIndentItem.GetValue(), FieldUnit::TWIP);
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbVerAlign->hide();
+ m_xFtVerAlign->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xLbVerAlign->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbVerAlign->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxVerJustifyItem& rJustifyItem = static_cast<const SvxVerJustifyItem&>(pCoreAttrs->Get(nWhich));
+ switch (rJustifyItem.GetValue())
+ {
+ case SvxCellVerJustify::Standard:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_STD));
+ break;
+ case SvxCellVerJustify::Top:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_TOP));
+ break;
+ case SvxCellVerJustify::Center:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_MID));
+ break;
+ case SvxCellVerJustify::Bottom:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BOTTOM));
+ break;
+ case SvxCellVerJustify::Block:
+ m_xLbVerAlign->set_active_id(OUString::number(ALIGNDLG_VERALIGN_BLOCK));
+ break;
+ }
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_DEGREES);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xNfRotate->hide();
+ m_xCtrlDialWin->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xNfRotate->set_sensitive(false);
+ m_xCtrlDialWin->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xCtrlDial->SetNoRotation();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SdrAngleItem& rAlignItem = static_cast<const SdrAngleItem&>(pCoreAttrs->Get(nWhich));
+ m_xCtrlDial->SetRotation(rAlignItem.GetValue());
+ break;
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_ALIGN_LOCKPOS);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xVsRefEdge->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xVsRefEdge->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxRotateModeItem& rRotateModeItem = static_cast<const SvxRotateModeItem&>(pCoreAttrs->Get(nWhich));
+ switch (rRotateModeItem.GetValue())
+ {
+ case SvxRotateMode::SVX_ROTATE_MODE_STANDARD:
+ m_aVsRefEdge.SelectItem(IID_CELLLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_TOP:
+ m_aVsRefEdge.SelectItem(IID_TOPLOCK);
+ break;
+ case SvxRotateMode::SVX_ROTATE_MODE_BOTTOM:
+ m_aVsRefEdge.SelectItem(IID_BOTTOMLOCK);
+ break;
+ default:
+ m_aVsRefEdge.SetNoSelection();
+ break;
+ }
+ break;
+ }
+ }
+ m_aVsRefEdge.SaveValue();
+
+ //text direction
+ nWhich = GetWhich(SID_ATTR_FRAMEDIRECTION);
+ eState = pCoreAttrs->GetItemState(nWhich);
+ switch (eState)
+ {
+ case SfxItemState::UNKNOWN:
+ m_xLbFrameDir->hide();
+ break;
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xLbFrameDir->set_sensitive(false);
+ break;
+ case SfxItemState::DONTCARE:
+ m_xLbFrameDir->set_active(-1);
+ break;
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>(pCoreAttrs->Get(nWhich));
+ m_xLbFrameDir->set_active_id(rFrameDirItem.GetValue());
+ break;
+ }
+ }
+
+
+ // Special treatment for distributed alignment; we need to set the justify
+ // method to 'distribute' to distinguish from the normal justification.
+
+ lcl_MaybeResetAlignToDistro<SvxCellHorJustify, SvxCellHorJustify>(
+ *m_xLbHorAlign, ALIGNDLG_HORALIGN_DISTRIBUTED, *pCoreAttrs,
+ GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY), GetWhich(SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD),
+ SvxCellHorJustify::Block);
+
+ lcl_MaybeResetAlignToDistro<SvxCellVerJustify, SvxCellVerJustify>(
+ *m_xLbVerAlign, ALIGNDLG_VERALIGN_DISTRIBUTED, *pCoreAttrs,
+ GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY), GetWhich(SID_ATTR_ALIGN_VER_JUSTIFY_METHOD),
+ SvxCellVerJustify::Block);
+
+ m_xLbHorAlign->save_value();
+ m_xLbFrameDir->save_value();
+ m_xLbVerAlign->save_value();
+ m_xNfRotate->save_value();
+ m_xEdIndent->save_value();
+
+ UpdateEnableControls();
+}
+
+DeactivateRC AlignmentTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void AlignmentTabPage::InitVsRefEgde()
+{
+ // remember selection - is deleted in call to ValueSet::Clear()
+ sal_uInt16 nSel = m_aVsRefEdge.GetSelectedItemId();
+
+ Image aBottomLock(StockImage::Yes, RID_SVXBMP_BOTTOMLOCK);
+ Image aTopLock(StockImage::Yes, RID_SVXBMP_TOPLOCK);
+ Image aCellLock(StockImage::Yes, RID_SVXBMP_CELLLOCK);
+
+ m_aVsRefEdge.Clear();
+ m_aVsRefEdge.SetStyle(m_aVsRefEdge.GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER);
+
+ m_aVsRefEdge.SetColCount(3);
+ m_aVsRefEdge.InsertItem(IID_BOTTOMLOCK, aBottomLock, m_xFtBotLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_TOPLOCK, aTopLock, m_xFtTopLock->get_label());
+ m_aVsRefEdge.InsertItem(IID_CELLLOCK, aCellLock, m_xFtCelLock->get_label());
+ m_aVsRefEdge.SetOptimalSize();
+
+ m_aVsRefEdge.SelectItem( nSel );
+}
+
+void AlignmentTabPage::UpdateEnableControls()
+{
+ const sal_Int32 nHorAlign = m_xLbHorAlign->get_active();
+ bool bHorLeft = (nHorAlign == ALIGNDLG_HORALIGN_LEFT);
+ bool bHorBlock = (nHorAlign == ALIGNDLG_HORALIGN_BLOCK);
+ bool bHorFill = (nHorAlign == ALIGNDLG_HORALIGN_FILL);
+ bool bHorDist = (nHorAlign == ALIGNDLG_HORALIGN_DISTRIBUTED);
+
+ // indent edit field only for left alignment
+ m_xFtIndent->set_sensitive( bHorLeft );
+ m_xEdIndent->set_sensitive( bHorLeft );
+
+ // stacked disabled for fill alignment
+ m_xCbStacked->set_sensitive(!bHorFill);
+
+ // hyphenation only for automatic line breaks or for block alignment
+ m_xBtnHyphen->set_sensitive( m_xBtnWrap->get_active() || bHorBlock );
+
+ // shrink only without automatic line break, and not for block, fill or distribute.
+ m_xBtnShrink->set_sensitive( (m_xBtnWrap->get_state() == TRISTATE_FALSE) && !bHorBlock && !bHorFill && !bHorDist );
+
+ // visibility of frames
+ m_xAlignmentFrame->set_visible(m_xLbHorAlign->get_visible() || m_xEdIndent->get_visible() ||
+ m_xLbVerAlign->get_visible());
+ m_xOrientFrame->set_visible(m_xCtrlDialWin->get_visible() || m_xVsRefEdge->get_visible() ||
+ m_xCbStacked->get_visible() || m_xCbAsianMode->get_visible());
+ m_xPropertiesFrame->set_visible(m_xBtnWrap->get_visible() || m_xBtnHyphen->get_visible() ||
+ m_xBtnShrink->get_visible() || m_xLbFrameDir->get_visible());
+
+ bool bStackedText = m_xCbStacked->get_active();
+ // windows to be disabled, if stacked text is turned ON
+ m_xFtRotate->set_sensitive(!bStackedText);
+ m_xFtRefEdge->set_sensitive(!bStackedText);
+ m_xVsRefEdge->set_sensitive(!bStackedText);
+ // windows to be disabled, if stacked text is turned OFF
+ m_xCbAsianMode->set_sensitive(bStackedText);
+ // rotation/stacked disabled for fill alignment/stacked
+ m_xCtrlDialWin->set_sensitive(!bHorFill && !bStackedText);
+ m_xNfRotate->set_sensitive(!bHorFill && !bStackedText);
+}
+
+bool AlignmentTabPage::HasAlignmentChanged( const SfxItemSet& rNew, sal_uInt16 nWhich ) const
+{
+ const SfxItemSet& rOld = GetItemSet();
+ const SfxPoolItem* pItem;
+ SvxCellJustifyMethod eMethodOld = SvxCellJustifyMethod::Auto;
+ SvxCellJustifyMethod eMethodNew = SvxCellJustifyMethod::Auto;
+ if (rOld.GetItemState(nWhich, true, &pItem) == SfxItemState::SET)
+ {
+ const SfxEnumItemInterface* p = static_cast<const SfxEnumItemInterface*>(pItem);
+ eMethodOld = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ if (rNew.GetItemState(nWhich, true, &pItem) == SfxItemState::SET)
+ {
+ const SfxEnumItemInterface* p = static_cast<const SfxEnumItemInterface*>(pItem);
+ eMethodNew = static_cast<SvxCellJustifyMethod>(p->GetEnumValue());
+ }
+
+ return eMethodOld != eMethodNew;
+}
+
+IMPL_LINK(AlignmentTabPage, StackedClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aStackedState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, AsianModeClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aAsianModeState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, WrapClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aWrapState.ButtonToggled(rToggle);
+ UpdateEnableControls();
+}
+
+IMPL_LINK(AlignmentTabPage, HyphenClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aHyphenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(AlignmentTabPage, ShrinkClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aShrinkState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK_NOARG(AlignmentTabPage, UpdateEnableHdl, weld::ComboBox&, void)
+{
+ UpdateEnableControls();
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/autocdlg.cxx b/cui/source/tabpages/autocdlg.cxx
new file mode 100644
index 000000000..449e231d9
--- /dev/null
+++ b/cui/source/tabpages/autocdlg.cxx
@@ -0,0 +1,2355 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <i18nutil/unicode.hxx>
+#include <vcl/event.hxx>
+#include <vcl/keycodes.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/transfer.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <unotools/charclass.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <vcl/svapp.hxx>
+#include <sfx2/module.hxx>
+#include <svl/eitem.hxx>
+#include <svl/languageoptions.hxx>
+#include <svx/SmartTagMgr.hxx>
+#include <com/sun/star/smarttags/XSmartTagRecognizer.hpp>
+#include <rtl/strbuf.hxx>
+#include <osl/diagnose.h>
+#include <tools/debug.hxx>
+
+#include <autocdlg.hxx>
+#include <editeng/acorrcfg.hxx>
+#include <editeng/svxacorr.hxx>
+#include <cui/cuicharmap.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+#include <svx/svxids.hrc>
+
+static LanguageType eLastDialogLanguage = LANGUAGE_SYSTEM;
+
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star;
+
+OfaAutoCorrDlg::OfaAutoCorrDlg(weld::Window* pParent, const SfxItemSet* _pSet )
+ : SfxTabDialogController(pParent, "cui/ui/autocorrectdialog.ui", "AutoCorrectDialog", _pSet)
+ , m_xLanguageBox(m_xBuilder->weld_widget("langbox"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+{
+ bool bShowSWOptions = false;
+ bool bOpenSmartTagOptions = false;
+
+ if ( _pSet )
+ {
+ const SfxBoolItem* pItem = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ const SfxBoolItem* pItem2 = SfxItemSet::GetItem<SfxBoolItem>(_pSet, SID_OPEN_SMARTTAGOPTIONS, false);
+ if ( pItem2 && pItem2->GetValue() )
+ bOpenSmartTagOptions = true;
+ }
+
+ AddTabPage("options", OfaAutocorrOptionsPage::Create, nullptr);
+ AddTabPage("applypage", OfaSwAutoFmtOptionsPage::Create, nullptr);
+ AddTabPage("wordcompletion", OfaAutoCompleteTabPage::Create, nullptr);
+ AddTabPage("smarttags", OfaSmartTagOptionsTabPage::Create, nullptr);
+
+ if (!bShowSWOptions)
+ {
+ RemoveTabPage("applypage");
+ RemoveTabPage("wordcompletion");
+ RemoveTabPage("smarttags");
+ }
+ else
+ {
+ // remove smart tag tab page if no extensions are installed
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags& rOpt = pAutoCorrect->GetSwFlags();
+ if (!rOpt.pSmartTagMgr || 0 == rOpt.pSmartTagMgr->NumberOfRecognizers())
+ RemoveTabPage("smarttags");
+
+ RemoveTabPage("options");
+ }
+
+ AddTabPage("replace", OfaAutocorrReplacePage::Create, nullptr);
+ AddTabPage("exceptions", OfaAutocorrExceptPage::Create, nullptr);
+ AddTabPage("localized", OfaQuoteTabPage::Create, nullptr);
+
+ // initialize languages
+ //! LANGUAGE_NONE is displayed as '[All]' and the LanguageType
+ //! will be set to LANGUAGE_UNDETERMINED
+ SvxLanguageListFlags nLangList = SvxLanguageListFlags::WESTERN;
+
+ if( SvtLanguageOptions().IsCTLFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CTL;
+ if( SvtLanguageOptions().IsCJKFontEnabled() )
+ nLangList |= SvxLanguageListFlags::CJK;
+ m_xLanguageLB->SetLanguageList( nLangList, true, true );
+ m_xLanguageLB->set_active_id( LANGUAGE_NONE );
+ int nPos = m_xLanguageLB->get_active();
+ DBG_ASSERT(nPos != -1, "listbox entry missing" );
+ m_xLanguageLB->set_id(nPos, LANGUAGE_UNDETERMINED);
+
+ // Initializing doesn't work for static on linux - therefore here
+ if (LANGUAGE_SYSTEM == eLastDialogLanguage)
+ eLastDialogLanguage = Application::GetSettings().GetLanguageTag().getLanguageType();
+
+ LanguageType nSelectLang = LANGUAGE_UNDETERMINED;
+ nPos = m_xLanguageLB->find_id(eLastDialogLanguage);
+ if (nPos != -1)
+ nSelectLang = eLastDialogLanguage;
+ m_xLanguageLB->set_active_id(nSelectLang);
+
+ m_xLanguageLB->connect_changed(LINK(this, OfaAutoCorrDlg, SelectLanguageHdl));
+
+ if ( bOpenSmartTagOptions )
+ SetCurPageId("smarttags");
+}
+
+OfaAutoCorrDlg::~OfaAutoCorrDlg()
+{
+}
+
+void OfaAutoCorrDlg::EnableLanguage(bool bEnable)
+{
+ m_xLanguageBox->set_sensitive(bEnable);
+}
+
+static bool lcl_FindEntry(weld::TreeView& rLB, const OUString& rEntry,
+ CollatorWrapper const & rCmpClass)
+{
+ int nCount = rLB.n_children();
+ int nSelPos = rLB.get_selected_index();
+ for (int i = 0; i < nCount; i++)
+ {
+ if (0 == rCmpClass.compareString(rEntry, rLB.get_text(i)))
+ {
+ rLB.select(i);
+ return true;
+ }
+ }
+ if (nSelPos != -1)
+ rLB.unselect(nSelPos);
+ return false;
+}
+
+IMPL_LINK_NOARG(OfaAutoCorrDlg, SelectLanguageHdl, weld::ComboBox&, void)
+{
+ LanguageType eNewLang = m_xLanguageLB->get_active_id();
+ // save old settings and fill anew
+ if(eNewLang == eLastDialogLanguage)
+ return;
+
+ OString sPageId = GetCurPageId();
+ if (sPageId == "replace")
+ {
+ OfaAutocorrReplacePage* pPage = static_cast<OfaAutocorrReplacePage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+ else if (sPageId == "exceptions")
+ {
+ OfaAutocorrExceptPage* pPage = static_cast<OfaAutocorrExceptPage*>(GetTabPage(sPageId));
+ assert(pPage);
+ pPage->SetLanguage(eNewLang);
+ }
+}
+
+OfaAutocorrOptionsPage::OfaAutocorrOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acoroptionspage.ui", "AutocorrectOptionsPage", &rSet)
+ , m_sInput(CuiResId(RID_SVXSTR_USE_REPLACE))
+ , m_sDoubleCaps(CuiResId(RID_SVXSTR_CPTL_STT_WORD))
+ , m_sStartCap(CuiResId(RID_SVXSTR_CPTL_STT_SENT))
+ , m_sBoldUnderline(CuiResId(RID_SVXSTR_BOLD_UNDER))
+ , m_sURL(CuiResId(RID_SVXSTR_DETECT_URL))
+ , m_sNoDblSpaces(CuiResId(RID_SVXSTR_NO_DBL_SPACES))
+ , m_sDash(CuiResId(RID_SVXSTR_DASH))
+ , m_sAccidentalCaps(CuiResId(RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+{
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xCheckLB->get_checkbox_column_width());
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+ m_xCheckLB->set_size_request(-1, m_xCheckLB->get_height_rows(10));
+}
+
+OfaAutocorrOptionsPage::~OfaAutocorrOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrOptionsPage>(pPage, pController, *rSet);
+}
+
+#define CBCOL_FIRST 0
+#define CBCOL_SECOND 1
+#define CBCOL_BOTH 2
+
+bool OfaAutocorrOptionsPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaAutocorrOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaAutocorrOptionsPage::InsertEntry(const OUString& rTxt)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_text(nRow, rTxt, 1);
+}
+
+void OfaAutocorrOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ InsertEntry(m_sInput);
+ InsertEntry(m_sDoubleCaps);
+ InsertEntry(m_sStartCap);
+ InsertEntry(m_sBoldUnderline);
+ InsertEntry(m_sURL);
+ InsertEntry(m_sDash);
+ InsertEntry(m_sNoDblSpaces);
+ InsertEntry(m_sAccidentalCaps);
+
+ int nPos = 0;
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+ m_xCheckLB->set_toggle( nPos++, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST );
+
+ m_xCheckLB->thaw();
+}
+
+/*********************************************************************/
+/* */
+/* helping struct for dUserData of the Checklistbox */
+/* */
+/*********************************************************************/
+
+namespace {
+
+struct ImpUserData
+{
+ OUString *pString;
+ vcl::Font *pFont;
+
+ ImpUserData(OUString* pText, vcl::Font* pFnt)
+ { pString = pText; pFont = pFnt;}
+};
+
+
+/*********************************************************************/
+/* */
+/* dialog for per cent settings */
+/* */
+/*********************************************************************/
+
+class OfaAutoFmtPrcntSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::MetricSpinButton> m_xPrcntMF;
+public:
+ explicit OfaAutoFmtPrcntSet(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/percentdialog.ui", "PercentDialog")
+ , m_xPrcntMF(m_xBuilder->weld_metric_spin_button("margin", FieldUnit::PERCENT))
+ {
+ }
+
+ weld::MetricSpinButton& GetPrcntFld()
+ {
+ return *m_xPrcntMF;
+ }
+};
+
+/*********************************************************************/
+/* */
+/* use TabPage autoformat */
+/* */
+/*********************************************************************/
+
+enum OfaAutoFmtOptions
+{
+ USE_REPLACE_TABLE,
+ CORR_UPPER,
+ BEGIN_UPPER,
+ BOLD_UNDERLINE,
+ DETECT_URL,
+ REPLACE_DASHES,
+ DEL_SPACES_AT_STT_END,
+ DEL_SPACES_BETWEEN_LINES,
+ IGNORE_DBLSPACE,
+ CORRECT_CAPS_LOCK,
+ APPLY_NUMBERING,
+ INSERT_BORDER,
+ CREATE_TABLE,
+ REPLACE_STYLES,
+ DEL_EMPTY_NODE,
+ REPLACE_USER_COLL,
+ REPLACE_BULLETS,
+ MERGE_SINGLE_LINE_PARA
+};
+
+}
+
+OfaSwAutoFmtOptionsPage::OfaSwAutoFmtOptionsPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/applyautofmtpage.ui", "ApplyAutoFmtPage", &rSet)
+ , sDeleteEmptyPara(CuiResId(RID_SVXSTR_DEL_EMPTY_PARA))
+ , sUseReplaceTbl(CuiResId(RID_SVXSTR_USE_REPLACE))
+ , sCapitalStartWord(CuiResId(RID_SVXSTR_CPTL_STT_WORD))
+ , sCapitalStartSentence(CuiResId(RID_SVXSTR_CPTL_STT_SENT))
+ , sUserStyle(CuiResId(RID_SVXSTR_USER_STYLE))
+ , sBullet(CuiResId(RID_SVXSTR_BULLET))
+ , sBoldUnder(CuiResId(RID_SVXSTR_BOLD_UNDER))
+ , sNoDblSpaces(CuiResId(RID_SVXSTR_NO_DBL_SPACES))
+ , sCorrectCapsLock(CuiResId(RID_SVXSTR_CORRECT_ACCIDENTAL_CAPS_LOCK))
+ , sDetectURL(CuiResId(RID_SVXSTR_DETECT_URL))
+ , sDash(CuiResId(RID_SVXSTR_DASH))
+ , sRightMargin(CuiResId(RID_SVXSTR_RIGHT_MARGIN))
+ , sNum(CuiResId(RID_SVXSTR_NUM))
+ , sBorder(CuiResId(RID_SVXSTR_BORDER))
+ , sTable(CuiResId(RID_SVXSTR_CREATE_TABLE))
+ , sReplaceTemplates(CuiResId(RID_SVXSTR_REPLACE_TEMPLATES))
+ , sDelSpaceAtSttEnd(CuiResId(RID_SVXSTR_DEL_SPACES_AT_STT_END))
+ , sDelSpaceBetweenLines(CuiResId(RID_SVXSTR_DEL_SPACES_BETWEEN_LINES))
+ , nPercent(50)
+ , m_xCheckLB(m_xBuilder->weld_tree_view("list"))
+ , m_xEditPB(m_xBuilder->weld_button("edit"))
+{
+ m_xCheckLB->connect_changed(LINK(this, OfaSwAutoFmtOptionsPage, SelectHdl));
+ m_xCheckLB->connect_row_activated(LINK(this, OfaSwAutoFmtOptionsPage, DoubleClickEditHdl));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(0)).Width() * 2);
+ aWidths.push_back(m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(1)).Width() * 2);
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+
+ m_xEditPB->connect_clicked(LINK(this, OfaSwAutoFmtOptionsPage, EditHdl));
+}
+
+void OfaSwAutoFmtOptionsPage::CreateEntry(const OUString& rTxt, sal_uInt16 nCol)
+{
+ m_xCheckLB->append();
+ const int nRow = m_xCheckLB->n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ m_xCheckLB->set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_text(nRow, rTxt, 2);
+}
+
+OfaSwAutoFmtOptionsPage::~OfaSwAutoFmtOptionsPage()
+{
+ delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(REPLACE_BULLETS).toInt64());
+ delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(APPLY_NUMBERING).toInt64());
+ delete reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(MERGE_SINGLE_LINE_PARA).toInt64());
+}
+
+std::unique_ptr<SfxTabPage> OfaSwAutoFmtOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaSwAutoFmtOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaSwAutoFmtOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ bool bCheck = m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAutoCorrect != bCheck;
+ pOpt->bAutoCorrect = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::Autocorrect,
+ m_xCheckLB->get_toggle(USE_REPLACE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartWord != bCheck;
+ pOpt->bCapitalStartWord = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartWord,
+ m_xCheckLB->get_toggle(CORR_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bCapitalStartSentence != bCheck;
+ pOpt->bCapitalStartSentence = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CapitalStartSentence,
+ m_xCheckLB->get_toggle(BEGIN_UPPER, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgWeightUnderl != bCheck;
+ pOpt->bChgWeightUnderl = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgWeightUnderl,
+ m_xCheckLB->get_toggle(BOLD_UNDERLINE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::IgnoreDoubleSpace,
+ m_xCheckLB->get_toggle(IGNORE_DBLSPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::CorrectCapsLock,
+ m_xCheckLB->get_toggle(CORRECT_CAPS_LOCK, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DETECT_URL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetINetAttr != bCheck;
+ pOpt->bSetINetAttr = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::SetINetAttr,
+ m_xCheckLB->get_toggle(DETECT_URL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_EMPTY_NODE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bDelEmptyNode != bCheck;
+ pOpt->bDelEmptyNode = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_USER_COLL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgUserColl != bCheck;
+ pOpt->bChgUserColl = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_BULLETS, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgEnumNum != bCheck;
+ pOpt->bChgEnumNum = bCheck;
+ bModified |= aBulletFont != pOpt->aBulletFont;
+ pOpt->aBulletFont = aBulletFont;
+ bModified |= !comphelper::string::equals(sBulletChar, pOpt->cBullet);
+ pOpt->cBullet = sBulletChar[0];
+
+ bModified |= aByInputBulletFont != pOpt->aByInputBulletFont;
+ bModified |= !comphelper::string::equals(sByInputBulletChar, pOpt->cByInputBullet);
+ pOpt->aByInputBulletFont = aByInputBulletFont;
+ pOpt->cByInputBullet = sByInputBulletChar[0];
+
+ bCheck = m_xCheckLB->get_toggle(MERGE_SINGLE_LINE_PARA, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bRightMargin != bCheck;
+ pOpt->bRightMargin = bCheck;
+ bModified |= nPercent != pOpt->nRightMargin;
+ pOpt->nRightMargin = static_cast<sal_uInt8>(nPercent);
+
+ bCheck = m_xCheckLB->get_toggle(APPLY_NUMBERING, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetNumRule != bCheck;
+ pOpt->bSetNumRule = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(INSERT_BORDER, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bSetBorder != bCheck;
+ pOpt->bSetBorder = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(CREATE_TABLE, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bCreateTable != bCheck;
+ pOpt->bCreateTable = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_STYLES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bReplaceStyles != bCheck;
+ pOpt->bReplaceStyles = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgToEnEmDash != bCheck;
+ pOpt->bChgToEnEmDash = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgToEnEmDash,
+ m_xCheckLB->get_toggle(REPLACE_DASHES, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatDelSpacesAtSttEnd = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_AT_STT_END, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesAtSttEnd != bCheck;
+ pOpt->bAFormatByInpDelSpacesAtSttEnd = bCheck;
+
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatDelSpacesBetweenLines = bCheck;
+ bCheck = m_xCheckLB->get_toggle(DEL_SPACES_BETWEEN_LINES, CBCOL_SECOND) == TRISTATE_TRUE;
+ bModified |= pOpt->bAFormatByInpDelSpacesBetweenLines != bCheck;
+ pOpt->bAFormatByInpDelSpacesBetweenLines = bCheck;
+
+ if(bModified || nFlags != pAutoCorrect->GetFlags())
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+
+ return true;
+}
+
+void OfaSwAutoFmtOptionsPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaSwAutoFmtOptionsPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ aBulletFont = pOpt->aBulletFont;
+ sBulletChar = OUString(pOpt->cBullet);
+
+ aByInputBulletFont = pOpt->aByInputBulletFont;
+ sByInputBulletChar = OUString( pOpt->cByInputBullet );
+
+ nPercent = pOpt->nRightMargin;
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ // The following entries have to be inserted in the same order
+ // as in the OfaAutoFmtOptions-enum!
+ CreateEntry(sUseReplaceTbl, CBCOL_BOTH );
+ CreateEntry(sCapitalStartWord, CBCOL_BOTH );
+ CreateEntry(sCapitalStartSentence, CBCOL_BOTH );
+ CreateEntry(sBoldUnder, CBCOL_BOTH );
+ CreateEntry(sDetectURL, CBCOL_BOTH );
+ CreateEntry(sDash, CBCOL_BOTH );
+ CreateEntry(sDelSpaceAtSttEnd, CBCOL_BOTH );
+ CreateEntry(sDelSpaceBetweenLines, CBCOL_BOTH );
+
+ CreateEntry(sNoDblSpaces, CBCOL_SECOND);
+ CreateEntry(sCorrectCapsLock, CBCOL_SECOND);
+ CreateEntry(sNum.replaceFirst("%1", sBulletChar), CBCOL_SECOND);
+ CreateEntry(sBorder, CBCOL_SECOND);
+ CreateEntry(sTable, CBCOL_SECOND);
+ CreateEntry(sReplaceTemplates, CBCOL_SECOND);
+ CreateEntry(sDeleteEmptyPara, CBCOL_FIRST );
+ CreateEntry(sUserStyle, CBCOL_FIRST );
+ CreateEntry(sBullet.replaceFirst("%1", sByInputBulletChar), CBCOL_FIRST);
+ CreateEntry(sRightMargin.replaceFirst("%1", sMargin), CBCOL_FIRST);
+
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, pOpt->bAutoCorrect ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(USE_REPLACE_TABLE, bool(nFlags & ACFlags::Autocorrect) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORR_UPPER, pOpt->bCapitalStartWord ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(CORR_UPPER, bool(nFlags & ACFlags::CapitalStartWord) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, pOpt->bCapitalStartSentence ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BEGIN_UPPER, bool(nFlags & ACFlags::CapitalStartSentence) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, pOpt->bChgWeightUnderl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(BOLD_UNDERLINE, bool(nFlags & ACFlags::ChgWeightUnderl) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DETECT_URL, pOpt->bSetINetAttr ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DETECT_URL, bool(nFlags & ACFlags::SetINetAttr) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, pOpt->bChgToEnEmDash ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_DASHES, bool(nFlags & ACFlags::ChgToEnEmDash) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_AT_STT_END, pOpt->bAFormatByInpDelSpacesAtSttEnd ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(DEL_SPACES_BETWEEN_LINES, pOpt->bAFormatByInpDelSpacesBetweenLines ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(IGNORE_DBLSPACE, bool(nFlags & ACFlags::IgnoreDoubleSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CORRECT_CAPS_LOCK, bool(nFlags & ACFlags::CorrectCapsLock) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(APPLY_NUMBERING, pOpt->bSetNumRule ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(INSERT_BORDER, pOpt->bSetBorder ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(CREATE_TABLE, pOpt->bCreateTable ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(REPLACE_STYLES, pOpt->bReplaceStyles ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xCheckLB->set_toggle(DEL_EMPTY_NODE, pOpt->bDelEmptyNode ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_USER_COLL, pOpt->bChgUserColl ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(REPLACE_BULLETS, pOpt->bChgEnumNum ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(MERGE_SINGLE_LINE_PARA, pOpt->bRightMargin ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+
+ ImpUserData* pUserData = new ImpUserData(&sBulletChar, &aBulletFont);
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pUserData)));
+ m_xCheckLB->set_id(REPLACE_BULLETS, sId);
+
+ pUserData = new ImpUserData(&sMargin, nullptr);
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData));
+ m_xCheckLB->set_id(MERGE_SINGLE_LINE_PARA, sId);
+
+ ImpUserData* pUserData2 = new ImpUserData(&sByInputBulletChar, &aByInputBulletFont);
+ sId = OUString::number(reinterpret_cast<sal_Int64>(pUserData2));
+ m_xCheckLB->set_id(APPLY_NUMBERING, sId);
+
+ m_xCheckLB->thaw();
+}
+
+IMPL_LINK(OfaSwAutoFmtOptionsPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ m_xEditPB->set_sensitive(rBox.get_selected_id().toInt64() != 0);
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, DoubleClickEditHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEditPB);
+ return true;
+}
+
+IMPL_LINK_NOARG(OfaSwAutoFmtOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nSelEntryPos = m_xCheckLB->get_selected_index();
+ if (nSelEntryPos == REPLACE_BULLETS || nSelEntryPos == APPLY_NUMBERING)
+ {
+ SvxCharacterMap aMapDlg(GetFrameWeld(), nullptr, nullptr);
+ ImpUserData* pUserData = reinterpret_cast<ImpUserData*>(m_xCheckLB->get_id(nSelEntryPos).toInt64());
+ aMapDlg.SetCharFont(*pUserData->pFont);
+ aMapDlg.SetChar( (*pUserData->pString)[0] );
+ if (RET_OK == aMapDlg.run())
+ {
+ const vcl::Font& aFont(aMapDlg.GetCharFont());
+ *pUserData->pFont = aFont;
+ sal_UCS4 aChar = aMapDlg.GetChar();
+ // using the UCS4 constructor
+ OUString aOUStr( &aChar, 1 );
+ *pUserData->pString = aOUStr;
+ if (nSelEntryPos == REPLACE_BULLETS)
+ m_xCheckLB->set_text(nSelEntryPos, sNum.replaceFirst("%1", aOUStr), 2);
+ else
+ m_xCheckLB->set_text(nSelEntryPos, sBullet.replaceFirst("%1", aOUStr), 2);
+ }
+ }
+ else if( MERGE_SINGLE_LINE_PARA == nSelEntryPos )
+ {
+ // dialog for per cent settings
+ OfaAutoFmtPrcntSet aDlg(GetFrameWeld());
+ aDlg.GetPrcntFld().set_value(nPercent, FieldUnit::PERCENT);
+ if (aDlg.run() == RET_OK)
+ {
+ nPercent = static_cast<sal_uInt16>(aDlg.GetPrcntFld().get_value(FieldUnit::PERCENT));
+ sMargin = unicode::formatPercent(nPercent, Application::GetSettings().GetUILanguageTag());
+ m_xCheckLB->set_text(nSelEntryPos, sRightMargin.replaceFirst("%1", sMargin), 2);
+ }
+ }
+}
+
+
+OfaAutocorrReplacePage::OfaAutocorrReplacePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorreplacepage.ui", "AcorReplacePage", &rSet)
+ , eLang(eLastDialogLanguage)
+ , bHasSelectionText(false)
+ , bFirstSelect(true)
+ , bReplaceEditChanged(false)
+ , bSWriter(true)
+ , m_xTextOnlyCB(m_xBuilder->weld_check_button("textonly"))
+ , m_xShortED(m_xBuilder->weld_entry("origtext"))
+ , m_xReplaceED(m_xBuilder->weld_entry("newtext"))
+ , m_xReplaceTLB(m_xBuilder->weld_tree_view("tabview"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("new"))
+ , m_xReplacePB(m_xBuilder->weld_button("replace"))
+ , m_xDeleteReplacePB(m_xBuilder->weld_button("delete"))
+ , m_xButtonBox(m_xBuilder->weld_container("buttonbox"))
+{
+ sNew = m_xNewReplacePB->get_label();
+ sModify = m_xReplacePB->get_label();
+
+ // lock down the width of the button box to its max
+ // desired width
+ auto nMaxWidth = m_xButtonBox->get_preferred_size().Width();
+ m_xButtonBox->set_size_request(nMaxWidth, -1);
+ m_xReplacePB->hide();
+
+ // tdf#125348 set some small but fixed initial width size, final width will
+ // depend on the size of the entry boxes
+ m_xReplaceTLB->set_size_request(42, m_xReplaceTLB->get_height_rows(10));
+
+ SfxModule *pMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ bSWriter = pMod == SfxModule::GetActiveModule();
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( aLanguageTag ) );
+
+ auto nColWidth = m_xReplaceTLB->get_approximate_digit_width() * 32;
+ m_aReplaceFixedWidths.push_back(nColWidth);
+ m_aReplaceFixedWidths.push_back(nColWidth);
+
+ m_xReplaceTLB->connect_changed( LINK(this, OfaAutocorrReplacePage, SelectHdl) );
+ m_xNewReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xDeleteReplacePB->connect_clicked( LINK(this, OfaAutocorrReplacePage, NewDelButtonHdl) );
+ m_xShortED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xReplaceED->connect_changed( LINK(this, OfaAutocorrReplacePage, ModifyHdl) );
+ m_xShortED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xReplaceED->connect_activate( LINK(this, OfaAutocorrReplacePage, NewDelActionHdl) );
+ m_xShortED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, OfaAutocorrReplacePage, EntrySizeAllocHdl));
+}
+
+OfaAutocorrReplacePage::~OfaAutocorrReplacePage()
+{
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+
+ pCompareClass.reset();
+ pCharClass.reset();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrReplacePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrReplacePage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrReplacePage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrReplacePage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrReplacePage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ for (StringChangeTable::reverse_iterator it = aChangesTable.rbegin(); it != aChangesTable.rend(); ++it)
+ {
+ LanguageType eCurrentLang = it->first;
+ StringChangeList& rStringChangeList = it->second;
+ std::vector<SvxAutocorrWord> aDeleteWords;
+ std::vector<SvxAutocorrWord> aNewWords;
+
+ aDeleteWords.reserve( rStringChangeList.aDeletedEntries.size() );
+ for (const DoubleString & deleteEntry : rStringChangeList.aDeletedEntries)
+ {
+ SvxAutocorrWord aDeleteWord( deleteEntry.sShort, deleteEntry.sLong );
+ aDeleteWords.push_back( aDeleteWord );
+ }
+
+ aNewWords.reserve( rStringChangeList.aNewEntries.size() );
+ for (const DoubleString & newEntry : rStringChangeList.aNewEntries)
+ {
+ //fdo#67697 if the user data is set then we want to retain the
+ //source formatting of the entry, so don't use the optimized
+ //text-only MakeCombinedChanges for this entry
+ bool bKeepSourceFormatting = newEntry.pUserData == &bHasSelectionText;
+ if (bKeepSourceFormatting)
+ {
+ pAutoCorrect->PutText(newEntry.sShort, *SfxObjectShell::Current(), eCurrentLang);
+ continue;
+ }
+
+ SvxAutocorrWord aNewWord( newEntry.sShort, newEntry.sLong );
+ aNewWords.push_back( aNewWord );
+ }
+ pAutoCorrect->MakeCombinedChanges( aNewWords, aDeleteWords, eCurrentLang );
+ }
+ aChangesTable.clear();
+ return false;
+}
+
+void OfaAutocorrReplacePage::RefillReplaceBox(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aDoubleStringTable.clear();
+ aChangesTable.clear();
+ }
+ else
+ {
+ DoubleStringArray* pArray;
+ if(aDoubleStringTable.find(eOldLanguage) != aDoubleStringTable.end())
+ {
+ pArray = &aDoubleStringTable[eOldLanguage];
+ pArray->clear();
+ }
+ else
+ {
+ pArray = &aDoubleStringTable[eOldLanguage]; // create new array
+ }
+
+ m_xReplaceTLB->all_foreach([this, &pArray](weld::TreeIter& rIter) {
+ pArray->push_back(DoubleString());
+ DoubleString& rDouble = pArray->back();
+ rDouble.sShort = m_xReplaceTLB->get_text(rIter, 0);
+ rDouble.sLong = m_xReplaceTLB->get_text(rIter, 1);
+ rDouble.pUserData = reinterpret_cast<void*>(m_xReplaceTLB->get_id(rIter).toInt64());
+ return false;
+ });
+ }
+
+ if( !bSWriter )
+ aFormatText.clear();
+
+ if (aDoubleStringTable.find(eLang) != aDoubleStringTable.end())
+ {
+ DoubleStringArray& rArray = aDoubleStringTable[eNewLanguage];
+
+ m_xReplaceTLB->bulk_insert_for_each(rArray.size(), [this, &rArray](weld::TreeIter& rIter, int nIndex) {
+ DoubleString &rDouble = rArray[nIndex];
+ bool bTextOnly = nullptr == rDouble.pUserData;
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = OUString::number(reinterpret_cast<sal_Int64>(rDouble.pUserData));
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, rDouble.sShort, 0);
+ m_xReplaceTLB->set_text(rIter, rDouble.sLong, 1);
+ }
+ else
+ {
+ aFormatText.insert(rDouble.sShort);
+ }
+ }, &m_aReplaceFixedWidths);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxAutocorrWordList* pWordList = pAutoCorrect->LoadAutocorrWordList(eLang);
+ const SvxAutocorrWordList::AutocorrWordSetType & rContent = pWordList->getSortedContent();
+ m_xReplaceTLB->bulk_insert_for_each(rContent.size(), [this, rContent](weld::TreeIter& rIter, int nIndex) {
+ auto const& elem = rContent[nIndex];
+ bool bTextOnly = elem.IsTextOnly();
+ // formatted text is only in Writer
+ if (bSWriter || bTextOnly)
+ {
+ if (!bTextOnly)
+ {
+ // that means: with format info or even with selection text
+ OUString sId = OUString::number(reinterpret_cast<sal_Int64>(m_xTextOnlyCB.get()));
+ m_xReplaceTLB->set_id(rIter, sId);
+ }
+ m_xReplaceTLB->set_text(rIter, elem.GetShort(), 0);
+ m_xReplaceTLB->set_text(rIter, elem.GetLong(), 1);
+ }
+ else
+ {
+ aFormatText.insert(elem.GetShort());
+ }
+ }, &m_aReplaceFixedWidths);
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(false);
+ }
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if (pViewShell && pViewShell->HasSelection())
+ {
+ bHasSelectionText = true;
+ const OUString sSelection( pViewShell->GetSelectionText() );
+ m_xReplaceED->set_text(sSelection);
+ m_xTextOnlyCB->set_active(!bSWriter);
+ m_xTextOnlyCB->set_sensitive(bSWriter && !sSelection.isEmpty());
+ }
+ else
+ {
+ m_xTextOnlyCB->set_active(true);
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+}
+
+void OfaAutocorrReplacePage::Reset( const SfxItemSet* )
+{
+ RefillReplaceBox(true, eLang, eLang);
+ m_xShortED->grab_focus();
+}
+
+void OfaAutocorrReplacePage::SetLanguage(LanguageType eSet)
+{
+ //save old settings and refill
+ if(eSet != eLang)
+ {
+ RefillReplaceBox(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+
+ LanguageTag aLanguageTag( eLastDialogLanguage );
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLanguageTag.getLocale(), 0 );
+ pCharClass.reset( new CharClass( aLanguageTag ) );
+ ModifyHdl(*m_xShortED);
+ }
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if(!bFirstSelect || !bHasSelectionText)
+ {
+ int nEntry = rBox.get_selected_index();
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // if the text is set via ModifyHdl, the cursor is always at the beginning
+ // of a word, although you're editing here
+ bool bSameContent = 0 == pCompareClass->compareString(sTmpShort, m_xShortED->get_text());
+ int nStartPos, nEndPos;
+ m_xShortED->get_selection_bounds(nStartPos, nEndPos);
+ if (m_xShortED->get_text() != sTmpShort)
+ {
+ m_xShortED->set_text(sTmpShort);
+ // if it was only a different notation, the selection has to be set again
+ if (bSameContent)
+ {
+ m_xShortED->select_region(nStartPos, nEndPos);
+ }
+ }
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ // with UserData there is a Formatinfo
+ m_xTextOnlyCB->set_active(rBox.get_id(nEntry).isEmpty());
+ }
+ else
+ {
+ bFirstSelect = false;
+ }
+
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeleteReplacePB->set_sensitive(true);
+};
+
+void OfaAutocorrReplacePage::NewEntry(const OUString& sShort, const OUString& sLong, bool bKeepSourceFormatting)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aNewString;
+ aNewString.sShort = sShort;
+ aNewString.sLong = sLong;
+ rNewArray.push_back(aNewString);
+ if (bKeepSourceFormatting)
+ rNewArray.back().pUserData = &bHasSelectionText;
+}
+
+void OfaAutocorrReplacePage::DeleteEntry(const OUString& sShort, const OUString& sLong)
+{
+ DoubleStringArray& rNewArray = aChangesTable[eLang].aNewEntries;
+ for (size_t i = 0; i < rNewArray.size(); i++)
+ {
+ if (rNewArray[i].sShort == sShort)
+ {
+ rNewArray.erase(rNewArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleStringArray& rDeletedArray = aChangesTable[eLang].aDeletedEntries;
+ for (size_t i = 0; i < rDeletedArray.size(); i++)
+ {
+ if (rDeletedArray[i].sShort == sShort)
+ {
+ rDeletedArray.erase(rDeletedArray.begin() + i);
+ break;
+ }
+ }
+
+ DoubleString aDeletedString;
+ aDeletedString.sShort = sShort;
+ aDeletedString.sLong = sLong;
+ rDeletedArray.push_back(aDeletedString);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ return NewDelHdl(&rEdit);
+}
+
+IMPL_LINK_NOARG(OfaAutocorrReplacePage, EntrySizeAllocHdl, const Size&, void)
+{
+ m_aReplaceFixedWidths.clear();
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_xReplaceTLB, x, y, width, height))
+ {
+ m_aReplaceFixedWidths.push_back(x);
+ m_aReplaceFixedWidths.push_back(width - 1);
+ m_xReplaceTLB->set_column_fixed_widths(m_aReplaceFixedWidths);
+ }
+}
+
+bool OfaAutocorrReplacePage::NewDelHdl(const weld::Widget* pBtn)
+{
+ int nEntry = m_xReplaceTLB->get_selected_index();
+ if (pBtn == m_xDeleteReplacePB.get())
+ {
+ DBG_ASSERT( nEntry != -1, "no entry selected" );
+ if (nEntry != -1)
+ {
+ DeleteEntry(m_xReplaceTLB->get_text(nEntry, 0), m_xReplaceTLB->get_text(nEntry, 1));
+ m_xReplaceTLB->remove(nEntry);
+ ModifyHdl(*m_xShortED);
+ return false;
+ }
+ }
+
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ OUString sEntry(m_xShortED->get_text());
+ if (!sEntry.isEmpty() && (!m_xReplaceED->get_text().isEmpty() ||
+ ( bHasSelectionText && bSWriter ) ))
+ {
+ bool bKeepSourceFormatting = !bReplaceEditChanged && !m_xTextOnlyCB->get_active();
+
+ NewEntry(m_xShortED->get_text(), m_xReplaceED->get_text(), bKeepSourceFormatting);
+ m_xReplaceTLB->freeze();
+ int nPos = -1;
+ if (nEntry != -1)
+ {
+ nPos = nEntry;
+ m_xReplaceTLB->remove(nEntry);
+ }
+ else
+ {
+ int j;
+ int nCount = m_xReplaceTLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ if (0 >= pCompareClass->compareString(sEntry, m_xReplaceTLB->get_text(j, 0)))
+ break;
+ }
+ nPos = j;
+ }
+
+ OUString sId;
+ if (bKeepSourceFormatting)
+ {
+ sId = OUString::number(reinterpret_cast<sal_Int64>(&bHasSelectionText)); // new formatted text
+ }
+
+ m_xReplaceTLB->insert(nPos, sEntry, &sId, nullptr, nullptr);
+ m_xReplaceTLB->set_text(nPos, m_xReplaceED->get_text(), 1);
+ m_xReplaceTLB->thaw();
+ m_xReplaceTLB->scroll_to_row(nPos);
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ {
+ m_xShortED->grab_focus();
+ }
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xShortED);
+ return true;
+}
+
+IMPL_LINK(OfaAutocorrReplacePage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ std::unique_ptr<weld::TreeIter> xFirstSel(m_xReplaceTLB->make_iterator());
+ bool bFirstSelIterSet = m_xReplaceTLB->get_selected(xFirstSel.get());
+ bool bShort = &rEdt == m_xShortED.get();
+ const OUString rEntry = rEdt.get_text();
+ const OUString rRepString = m_xReplaceED->get_text();
+ OUString aWordStr(pCharClass->lowercase(rEntry));
+
+ if(bShort)
+ {
+ if(!rEntry.isEmpty())
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+
+ m_xReplaceTLB->all_foreach([this, &rEntry, &rRepString, &bFound,
+ &bTmpSelEntry, &bFirstSelIterSet,
+ &xFirstSel, &aWordStr](weld::TreeIter& rIter){
+ OUString aTestStr = m_xReplaceTLB->get_text(rIter, 0);
+ if( pCompareClass->compareString(rEntry, aTestStr ) == 0 )
+ {
+ if (!rRepString.isEmpty())
+ bFirstSelect = true;
+ m_xReplaceTLB->set_cursor(rIter);
+ m_xReplaceTLB->copy_iterator(rIter, *xFirstSel);
+ bFirstSelIterSet = true;
+ m_xNewReplacePB->set_label(sModify);
+ bFound = true;
+ return true;
+ }
+ else
+ {
+ aTestStr = pCharClass->lowercase( aTestStr );
+ if( aTestStr.startsWith(aWordStr) && !bTmpSelEntry )
+ {
+ m_xReplaceTLB->scroll_to_row(rIter);
+ bTmpSelEntry = true;
+ }
+ }
+ return false;
+ });
+ if( !bFound )
+ {
+ m_xReplaceTLB->select(-1);
+ bFirstSelIterSet = false;
+ m_xNewReplacePB->set_label(sNew);
+ if( bReplaceEditChanged )
+ m_xTextOnlyCB->set_sensitive(false);
+ }
+ m_xDeleteReplacePB->set_sensitive(bFound);
+ }
+ else if (m_xReplaceTLB->n_children() > 0)
+ {
+ m_xReplaceTLB->scroll_to_row(0);
+ }
+
+ }
+ else if( !bShort )
+ {
+ bReplaceEditChanged = true;
+ if (bFirstSelIterSet)
+ {
+ m_xNewReplacePB->set_label(sModify);
+ }
+ }
+
+ const OUString& rShortTxt = m_xShortED->get_text();
+ bool bEnableNew = !rShortTxt.isEmpty() &&
+ ( !rRepString.isEmpty() ||
+ ( bHasSelectionText && bSWriter )) &&
+ ( !bFirstSelIterSet || rRepString !=
+ m_xReplaceTLB->get_text(*xFirstSel, 1) );
+ if( bEnableNew )
+ {
+ for (auto const& elem : aFormatText)
+ {
+ if(elem == rShortTxt)
+ {
+ bEnableNew = false;
+ break;
+ }
+ }
+ }
+ m_xNewReplacePB->set_sensitive(bEnableNew);
+}
+
+static bool lcl_FindInArray(std::vector<OUString>& rStrings, const OUString& rString)
+{
+ for (auto const& elem : rStrings)
+ {
+ if(elem == rString)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+OfaAutocorrExceptPage::OfaAutocorrExceptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/acorexceptpage.ui", "AcorExceptPage", &rSet)
+ , eLang(eLastDialogLanguage)
+ , m_xAbbrevED(m_xBuilder->weld_entry("abbrev"))
+ , m_xAbbrevLB(m_xBuilder->weld_tree_view("abbrevlist"))
+ , m_xNewAbbrevPB(m_xBuilder->weld_button("newabbrev"))
+ , m_xDelAbbrevPB(m_xBuilder->weld_button("delabbrev"))
+ , m_xAutoAbbrevCB(m_xBuilder->weld_check_button("autoabbrev"))
+ , m_xDoubleCapsED(m_xBuilder->weld_entry("double"))
+ , m_xDoubleCapsLB(m_xBuilder->weld_tree_view("doublelist"))
+ , m_xNewDoublePB(m_xBuilder->weld_button("newdouble"))
+ , m_xDelDoublePB(m_xBuilder->weld_button("deldouble"))
+ , m_xAutoCapsCB(m_xBuilder->weld_check_button("autodouble"))
+{
+ m_xAbbrevLB->make_sorted();
+ m_xAbbrevLB->set_size_request(-1, m_xAbbrevLB->get_height_rows(6));
+
+ m_xDoubleCapsLB->make_sorted();
+ m_xDoubleCapsLB->set_size_request(-1, m_xDoubleCapsLB->get_height_rows(6));
+
+ css::lang::Locale aLcl( LanguageTag::convertToLocale(eLastDialogLanguage ));
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( aLcl, 0 );
+
+ m_xNewAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelAbbrevPB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xNewDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+ m_xDelDoublePB->connect_clicked(LINK(this, OfaAutocorrExceptPage, NewDelButtonHdl));
+
+ m_xAbbrevLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xDoubleCapsLB->connect_changed(LINK(this, OfaAutocorrExceptPage, SelectHdl));
+ m_xAbbrevED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+ m_xDoubleCapsED->connect_changed(LINK(this, OfaAutocorrExceptPage, ModifyHdl));
+
+ m_xAbbrevED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+ m_xDoubleCapsED->connect_activate(LINK(this, OfaAutocorrExceptPage, NewDelActionHdl));
+}
+
+OfaAutocorrExceptPage::~OfaAutocorrExceptPage()
+{
+ aStringsTable.clear();
+ pCompareClass.reset();
+}
+
+std::unique_ptr<SfxTabPage> OfaAutocorrExceptPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutocorrExceptPage>(pPage, pController, *rSet);
+}
+
+void OfaAutocorrExceptPage::ActivatePage( const SfxItemSet& )
+{
+ if(eLang != eLastDialogLanguage)
+ SetLanguage(eLastDialogLanguage);
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(true);
+}
+
+DeactivateRC OfaAutocorrExceptPage::DeactivatePage( SfxItemSet* )
+{
+ return DeactivateRC::LeavePage;
+}
+
+bool OfaAutocorrExceptPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ for(StringsTable::reverse_iterator it1 = aStringsTable.rbegin(); it1 != aStringsTable.rend(); ++it1)
+ {
+ LanguageType eCurLang = it1->first;
+ StringsArrays& rArrays = it1->second;
+ if(eCurLang != eLang) // current language is treated later
+ {
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWrdSttExceptList(eCurLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+
+ if( !lcl_FindInArray(rArrays.aDoubleCapsStrings, aString))
+ {
+ pWrdList->erase(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ {
+ pWrdList->insert(elem);
+ }
+ pAutoCorrect->SaveWrdSttExceptList(eCurLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eCurLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if( !lcl_FindInArray(rArrays.aAbbrevStrings, aString))
+ {
+ pCplList->erase(i);
+ }
+ }
+
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ {
+ pCplList->insert(elem);
+ }
+
+ pAutoCorrect->SaveCplSttExceptList(eCurLang);
+ }
+ }
+ }
+ aStringsTable.clear();
+
+ SvStringsISortDtor* pWrdList = pAutoCorrect->LoadWrdSttExceptList(eLang);
+
+ if(pWrdList)
+ {
+ size_t nCount = pWrdList->size();
+ size_t i;
+ for( i = nCount; i; )
+ {
+ OUString aString = (*pWrdList)[ --i ];
+ if (m_xDoubleCapsLB->find_text(aString) == -1)
+ {
+ pWrdList->erase(i);
+ }
+ }
+ nCount = m_xDoubleCapsLB->n_children();
+ for( i = 0; i < nCount; ++i )
+ {
+ pWrdList->insert(m_xDoubleCapsLB->get_text(i));
+ }
+ pAutoCorrect->SaveWrdSttExceptList(eLang);
+ }
+
+ SvStringsISortDtor* pCplList = pAutoCorrect->LoadCplSttExceptList(eLang);
+
+ if(pCplList)
+ {
+ size_t nCount = pCplList->size();
+ for( size_t i = nCount; i; )
+ {
+ OUString aString = (*pCplList)[ --i ];
+ if (m_xAbbrevLB->find_text(aString) == -1)
+ {
+ pCplList->erase(i);
+ }
+ }
+ sal_Int32 nAbbrevCount = m_xAbbrevLB->n_children();
+ for( sal_Int32 ia = 0; ia < nAbbrevCount; ++ia )
+ {
+ pCplList->insert(m_xAbbrevLB->get_text(ia));
+ }
+ pAutoCorrect->SaveCplSttExceptList(eLang);
+ }
+ if (m_xAutoAbbrevCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordCplSttLst, m_xAutoAbbrevCB->get_active());
+ if (m_xAutoCapsCB->get_state_changed_from_saved())
+ pAutoCorrect->SetAutoCorrFlag( ACFlags::SaveWordWrdSttLst, m_xAutoCapsCB->get_active());
+ return false;
+}
+
+void OfaAutocorrExceptPage::SetLanguage(LanguageType eSet)
+{
+ if(eLang != eSet)
+ {
+ // save old settings and fill anew
+ RefillReplaceBoxes(false, eLang, eSet);
+ eLastDialogLanguage = eSet;
+ pCompareClass.reset( new CollatorWrapper( comphelper::getProcessComponentContext() ) );
+ pCompareClass->loadDefaultCollator( LanguageTag::convertToLocale( eLastDialogLanguage ), 0 );
+ ModifyHdl(*m_xAbbrevED);
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+}
+
+void OfaAutocorrExceptPage::RefillReplaceBoxes(bool bFromReset,
+ LanguageType eOldLanguage,
+ LanguageType eNewLanguage)
+{
+ eLang = eNewLanguage;
+ if(bFromReset)
+ {
+ aStringsTable.clear();
+ }
+ else
+ {
+ StringsArrays* pArrays;
+ if(aStringsTable.find(eOldLanguage) != aStringsTable.end())
+ {
+ pArrays = &aStringsTable[eOldLanguage];
+ pArrays->aAbbrevStrings.clear();
+ pArrays->aDoubleCapsStrings.clear();
+ }
+ else
+ {
+ pArrays = &aStringsTable[eOldLanguage]; // create new array
+ }
+
+ sal_Int32 i, nCount;
+ nCount = m_xAbbrevLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aAbbrevStrings.push_back(m_xAbbrevLB->get_text(i));
+
+ nCount = m_xDoubleCapsLB->n_children();
+ for(i = 0; i < nCount; i++)
+ pArrays->aDoubleCapsStrings.push_back(m_xDoubleCapsLB->get_text(i));
+ }
+ m_xDoubleCapsLB->clear();
+ m_xAbbrevLB->clear();
+ OUString sTemp;
+ m_xAbbrevED->set_text(sTemp);
+ m_xDoubleCapsED->set_text(sTemp);
+
+ if(aStringsTable.find(eLang) != aStringsTable.end())
+ {
+ StringsArrays& rArrays = aStringsTable[eLang];
+ for (auto const& elem : rArrays.aAbbrevStrings)
+ m_xAbbrevLB->append_text(elem);
+
+ for (auto const& elem : rArrays.aDoubleCapsStrings)
+ m_xDoubleCapsLB->append_text(elem);
+ }
+ else
+ {
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const SvStringsISortDtor* pCplList = pAutoCorrect->GetCplSttExceptList(eLang);
+ const SvStringsISortDtor* pWrdList = pAutoCorrect->GetWrdSttExceptList(eLang);
+ size_t i;
+ for( i = 0; i < pCplList->size(); i++ )
+ {
+ m_xAbbrevLB->append_text((*pCplList)[i]);
+ }
+ for( i = 0; i < pWrdList->size(); i++ )
+ {
+ m_xDoubleCapsLB->append_text((*pWrdList)[i]);
+ }
+ }
+}
+
+void OfaAutocorrExceptPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ RefillReplaceBoxes(true, eLang, eLang);
+ m_xAutoAbbrevCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordCplSttLst));
+ m_xAutoCapsCB->set_active(pAutoCorrect->IsAutoCorrFlag( ACFlags::SaveWordWrdSttLst));
+ m_xAutoAbbrevCB->save_state();
+ m_xAutoCapsCB->save_state();
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, NewDelActionHdl, weld::Entry&, rEdit, bool)
+{
+ NewDelHdl(&rEdit);
+ return false;
+}
+
+void OfaAutocorrExceptPage::NewDelHdl(const weld::Widget* pBtn)
+{
+ if ((pBtn == m_xNewAbbrevPB.get() || pBtn == m_xAbbrevED.get())
+ && !m_xAbbrevED->get_text().isEmpty())
+ {
+ m_xAbbrevLB->append_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if(pBtn == m_xDelAbbrevPB.get())
+ {
+ m_xAbbrevLB->remove_text(m_xAbbrevED->get_text());
+ ModifyHdl(*m_xAbbrevED);
+ }
+ else if((pBtn == m_xNewDoublePB.get() || pBtn == m_xDoubleCapsED.get() )
+ && !m_xDoubleCapsED->get_text().isEmpty())
+ {
+ m_xDoubleCapsLB->append_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+ else if (pBtn == m_xDelDoublePB.get())
+ {
+ m_xDoubleCapsLB->remove_text(m_xDoubleCapsED->get_text());
+ ModifyHdl(*m_xDoubleCapsED);
+ }
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (&rBox == m_xAbbrevLB.get())
+ {
+ m_xAbbrevED->set_text(rBox.get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(false);
+ m_xDelAbbrevPB->set_sensitive(true);
+ }
+ else
+ {
+ m_xDoubleCapsED->set_text(rBox.get_selected_text());
+ m_xNewDoublePB->set_sensitive(false);
+ m_xDelDoublePB->set_sensitive(true);
+ }
+}
+
+IMPL_LINK(OfaAutocorrExceptPage, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ const OUString& sEntry = rEdt.get_text();
+ bool bEntryLen = !sEntry.isEmpty();
+ if (&rEdt == m_xAbbrevED.get())
+ {
+ bool bSame = lcl_FindEntry(*m_xAbbrevLB, sEntry, *pCompareClass);
+ if(bSame && sEntry != m_xAbbrevLB->get_selected_text())
+ rEdt.set_text(m_xAbbrevLB->get_selected_text());
+ m_xNewAbbrevPB->set_sensitive(!bSame && bEntryLen);
+ m_xDelAbbrevPB->set_sensitive(bSame && bEntryLen);
+ }
+ else
+ {
+ bool bSame = lcl_FindEntry(*m_xDoubleCapsLB, sEntry, *pCompareClass);
+ if(bSame && sEntry != m_xDoubleCapsLB->get_selected_text())
+ rEdt.set_text(m_xDoubleCapsLB->get_selected_text());
+ m_xNewDoublePB->set_sensitive(!bSame && bEntryLen);
+ m_xDelDoublePB->set_sensitive(bSame && bEntryLen);
+ }
+}
+
+namespace {
+
+enum OfaQuoteOptions
+{
+ ADD_NONBRK_SPACE,
+ REPLACE_1ST,
+ TRANSLITERATE_RTL,
+ REPLACE_ANGLE_QUOTES
+};
+
+}
+
+void OfaQuoteTabPage::CreateEntry(weld::TreeView& rCheckLB, const OUString& rTxt, sal_uInt16 nCol, sal_uInt16 nTextCol)
+{
+ rCheckLB.append();
+ const int nRow = rCheckLB.n_children() - 1;
+ if (nCol == CBCOL_FIRST || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_FIRST);
+ if (nCol == CBCOL_SECOND || nCol == CBCOL_BOTH)
+ rCheckLB.set_toggle(nRow, TRISTATE_FALSE, CBCOL_SECOND);
+ rCheckLB.set_text(nRow, rTxt, nTextCol);
+}
+
+OfaQuoteTabPage::OfaQuoteTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/applylocalizedpage.ui", "ApplyLocalizedPage", &rSet)
+ , sNonBrkSpace(CuiResId(RID_SVXSTR_NON_BREAK_SPACE))
+ , sOrdinal(CuiResId(RID_SVXSTR_ORDINAL))
+ , sTransliterateRTL(CuiResId(RID_SVXSTR_OLD_HUNGARIAN))
+ , sAngleQuotes(CuiResId(RID_SVXSTR_ANGLE_QUOTES))
+ , cSglStartQuote(0)
+ , cSglEndQuote(0)
+ , cStartQuote(0)
+ , cEndQuote(0)
+ , m_xSingleTypoCB(m_xBuilder->weld_check_button("singlereplace"))
+ , m_xSglStartQuotePB(m_xBuilder->weld_button("startsingle"))
+ , m_xSglStartExFT(m_xBuilder->weld_label("singlestartex"))
+ , m_xSglEndQuotePB(m_xBuilder->weld_button("endsingle"))
+ , m_xSglEndExFT(m_xBuilder->weld_label("singleendex"))
+ , m_xSglStandardPB(m_xBuilder->weld_button("defaultsingle"))
+ , m_xDoubleTypoCB(m_xBuilder->weld_check_button("doublereplace"))
+ , m_xDblStartQuotePB(m_xBuilder->weld_button("startdouble"))
+ , m_xDblStartExFT(m_xBuilder->weld_label("doublestartex"))
+ , m_xDblEndQuotePB(m_xBuilder->weld_button("enddouble"))
+ , m_xDblEndExFT(m_xBuilder->weld_label("doubleendex"))
+ , m_xDblStandardPB(m_xBuilder->weld_button("defaultdouble"))
+ , m_sStandard(m_xSglStartExFT->get_label())
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklist"))
+ , m_xSwCheckLB(m_xBuilder->weld_tree_view("list"))
+{
+ m_xSwCheckLB->set_size_request(m_xSwCheckLB->get_approximate_digit_width() * 50,
+ m_xSwCheckLB->get_height_rows(6));
+
+ bool bShowSWOptions = false;
+
+ const SfxBoolItem* pItem = rSet.GetItem<SfxBoolItem>(SID_AUTO_CORRECT_DLG, false);
+ if ( pItem && pItem->GetValue() )
+ bShowSWOptions = true;
+
+ if ( bShowSWOptions )
+ {
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(0)).Width() * 2);
+ aWidths.push_back(m_xSwCheckLB->get_pixel_size(m_xSwCheckLB->get_column_title(1)).Width() * 2);
+ m_xSwCheckLB->set_column_fixed_widths(aWidths);
+ m_xCheckLB->hide();
+ }
+ else
+ {
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xSwCheckLB->get_checkbox_column_width());
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+ m_xSwCheckLB->hide();
+ }
+
+ m_xDblStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglStartQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xSglEndQuotePB->connect_clicked(LINK(this, OfaQuoteTabPage, QuoteHdl));
+ m_xDblStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+ m_xSglStandardPB->connect_clicked(LINK(this, OfaQuoteTabPage, StdQuoteHdl));
+}
+
+OfaQuoteTabPage::~OfaQuoteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaQuoteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OfaQuoteTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaQuoteTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+
+ ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ if (m_xCheckLB->get_visible())
+ {
+ int nPos = 0;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes, m_xCheckLB->get_toggle(nPos++, CBCOL_FIRST) == TRISTATE_TRUE);
+ }
+
+ bool bModified = false;
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ bool bCheck = m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bAddNonBrkSpace != bCheck;
+ pOpt->bAddNonBrkSpace = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::AddNonBrkSpace,
+ m_xSwCheckLB->get_toggle(ADD_NONBRK_SPACE, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgOrdinalNumber != bCheck;
+ pOpt->bChgOrdinalNumber = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgOrdinalNumber,
+ m_xSwCheckLB->get_toggle(REPLACE_1ST, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bTransliterateRTL != bCheck;
+ pOpt->bTransliterateRTL = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::TransliterateRTL,
+ m_xSwCheckLB->get_toggle(TRANSLITERATE_RTL, CBCOL_SECOND) == TRISTATE_TRUE);
+
+ bCheck = m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_FIRST) == TRISTATE_TRUE;
+ bModified |= pOpt->bChgAngleQuotes != bCheck;
+ pOpt->bChgAngleQuotes = bCheck;
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgAngleQuotes,
+ m_xSwCheckLB->get_toggle(REPLACE_ANGLE_QUOTES, CBCOL_SECOND) == TRISTATE_TRUE);
+ }
+
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgQuotes, m_xDoubleTypoCB->get_active());
+ pAutoCorrect->SetAutoCorrFlag(ACFlags::ChgSglQuotes, m_xSingleTypoCB->get_active());
+ bool bReturn = nFlags != pAutoCorrect->GetFlags();
+ if(cStartQuote != pAutoCorrect->GetStartDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cStartQuote); //TODO
+ pAutoCorrect->SetStartDoubleQuote(cUCS2);
+ }
+ if(cEndQuote != pAutoCorrect->GetEndDoubleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cEndQuote); //TODO
+ pAutoCorrect->SetEndDoubleQuote(cUCS2);
+ }
+ if(cSglStartQuote != pAutoCorrect->GetStartSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglStartQuote); //TODO
+ pAutoCorrect->SetStartSingleQuote(cUCS2);
+ }
+ if(cSglEndQuote != pAutoCorrect->GetEndSingleQuote())
+ {
+ bReturn = true;
+ sal_Unicode cUCS2 = static_cast<sal_Unicode>(cSglEndQuote); //TODO
+ pAutoCorrect->SetEndSingleQuote(cUCS2);
+ }
+
+ if( bModified || bReturn )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return bReturn;
+}
+
+void OfaQuoteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage(false);
+}
+
+void OfaQuoteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ const ACFlags nFlags = pAutoCorrect->GetFlags();
+
+ // Initialize the Sw options
+ if (m_xSwCheckLB->get_visible())
+ {
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xSwCheckLB->freeze();
+ m_xSwCheckLB->clear();
+
+ CreateEntry(*m_xSwCheckLB, sNonBrkSpace, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sOrdinal, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sTransliterateRTL, CBCOL_BOTH, 2);
+ CreateEntry(*m_xSwCheckLB, sAngleQuotes, CBCOL_BOTH, 2);
+
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, pOpt->bAddNonBrkSpace ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(ADD_NONBRK_SPACE, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, pOpt->bChgOrdinalNumber ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_1ST, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, pOpt->bTransliterateRTL ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(TRANSLITERATE_RTL, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, pOpt->bChgAngleQuotes ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSwCheckLB->set_toggle(REPLACE_ANGLE_QUOTES, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_SECOND);
+
+ m_xSwCheckLB->thaw();
+ }
+
+ // Initialize the non Sw options
+ if (m_xCheckLB->get_visible())
+ {
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ CreateEntry(*m_xCheckLB, sNonBrkSpace, CBCOL_FIRST, 1);
+ CreateEntry(*m_xCheckLB, sOrdinal, CBCOL_FIRST, 1);
+ CreateEntry(*m_xCheckLB, sTransliterateRTL, CBCOL_FIRST, 1);
+ CreateEntry(*m_xCheckLB, sAngleQuotes, CBCOL_FIRST, 1);
+
+ int nPos = 0;
+ m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::AddNonBrkSpace) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::ChgOrdinalNumber) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::TransliterateRTL) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xCheckLB->set_toggle(nPos++, bool(nFlags & ACFlags::ChgAngleQuotes) ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+
+ m_xCheckLB->thaw();
+ }
+
+ // Initialize the quote stuffs
+ m_xDoubleTypoCB->set_active(bool(nFlags & ACFlags::ChgQuotes));
+ m_xSingleTypoCB->set_active(bool(nFlags & ACFlags::ChgSglQuotes));
+ m_xDoubleTypoCB->save_state();
+ m_xSingleTypoCB->save_state();
+
+ cStartQuote = pAutoCorrect->GetStartDoubleQuote();
+ cEndQuote = pAutoCorrect->GetEndDoubleQuote();
+ cSglStartQuote = pAutoCorrect->GetStartSingleQuote();
+ cSglEndQuote = pAutoCorrect->GetEndSingleQuote();
+
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cSglStartQuote));
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cSglEndQuote));
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cStartQuote));
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cEndQuote));
+}
+
+#define SGL_START 0
+#define DBL_START 1
+#define SGL_END 2
+#define DBL_END 3
+
+
+IMPL_LINK(OfaQuoteTabPage, QuoteHdl, weld::Button&, rBtn, void)
+{
+ sal_uInt16 nMode = SGL_START;
+ if (&rBtn == m_xSglEndQuotePB.get())
+ nMode = SGL_END;
+ else if (&rBtn == m_xDblStartQuotePB.get())
+ nMode = DBL_START;
+ else if (&rBtn == m_xDblEndQuotePB.get())
+ nMode = DBL_END;
+ // start character selection dialog
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+ aMap.SetCharFont( OutputDevice::GetDefaultFont(DefaultFontType::LATIN_TEXT,
+ LANGUAGE_ENGLISH_US, GetDefaultFontFlags::OnlyOne ));
+ aMap.set_title(nMode < SGL_END ? CuiResId(RID_SVXSTR_STARTQUOTE) : CuiResId(RID_SVXSTR_ENDQUOTE));
+ sal_UCS4 cDlg;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ LanguageType eLang = Application::GetSettings().GetLanguageTag().getLanguageType();
+ switch( nMode )
+ {
+ case SGL_START:
+ cDlg = cSglStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', true, eLang);
+ break;
+ case SGL_END:
+ cDlg = cSglEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\'', false, eLang);
+ break;
+ case DBL_START:
+ cDlg = cStartQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', true, eLang);
+ break;
+ case DBL_END:
+ cDlg = cEndQuote;
+ if(cDlg == 0)
+ cDlg = pAutoCorrect->GetQuote('\"', false, eLang);
+ break;
+ default:
+ OSL_FAIL("svx::OfaQuoteTabPage::QuoteHdl(), how to initialize cDlg?" );
+ cDlg = 0;
+ break;
+
+ }
+ aMap.SetChar( cDlg );
+ aMap.DisableFontSelection();
+ if (aMap.run() != RET_OK)
+ return;
+
+ sal_UCS4 cNewChar = aMap.GetChar();
+ switch( nMode )
+ {
+ case SGL_START:
+ cSglStartQuote = cNewChar;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case SGL_END:
+ cSglEndQuote = cNewChar;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_START:
+ cStartQuote = cNewChar;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ case DBL_END:
+ cEndQuote = cNewChar;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(cNewChar));
+ break;
+ }
+}
+
+IMPL_LINK(OfaQuoteTabPage, StdQuoteHdl, weld::Button&, rBtn, void)
+{
+ if (&rBtn == m_xDblStandardPB.get())
+ {
+ cStartQuote = 0;
+ m_xDblStartExFT->set_label(ChangeStringExt_Impl(0));
+ cEndQuote = 0;
+ m_xDblEndExFT->set_label(ChangeStringExt_Impl(0));
+
+ }
+ else
+ {
+ cSglStartQuote = 0;
+ m_xSglStartExFT->set_label(ChangeStringExt_Impl(0));
+ cSglEndQuote = 0;
+ m_xSglEndExFT->set_label(ChangeStringExt_Impl(0));
+ }
+}
+
+OUString OfaQuoteTabPage::ChangeStringExt_Impl( sal_UCS4 cChar )
+{
+ if (!cChar)
+ return m_sStandard;
+
+ // convert codepoint value to unicode-hex string
+ sal_UCS4 aStrCodes[32] = { 0, ' ', '(', 'U', '+', '0' };
+ aStrCodes[0] = cChar;
+ int nFullLen = 5;
+ int nHexLen = 4;
+ while( (cChar >> (4*nHexLen)) != 0 )
+ ++nHexLen;
+ for( int i = nHexLen; --i >= 0;)
+ {
+ sal_UCS4 cHexDigit = ((cChar >> (4*i)) & 0x0f) + '0';
+ if( cHexDigit > '9' )
+ cHexDigit += 'A' - ('9' + 1);
+ aStrCodes[ nFullLen++ ] = cHexDigit;
+ }
+ aStrCodes[ nFullLen++ ] = ')';
+ // using the new UCS4 constructor
+ OUString aOUStr( aStrCodes, nFullLen );
+ return aOUStr;
+}
+
+OfaAutoCompleteTabPage::OfaAutoCompleteTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/wordcompletionpage.ui",
+ "WordCompletionPage", &rSet)
+ , m_pAutoCompleteList(nullptr)
+ , m_nAutoCmpltListCnt(0)
+ , m_xCBActiv(m_xBuilder->weld_check_button("enablewordcomplete"))
+ , m_xCBAppendSpace(m_xBuilder->weld_check_button("appendspace"))
+ , m_xCBAsTip(m_xBuilder->weld_check_button("showastip"))
+ , m_xCBCollect(m_xBuilder->weld_check_button("collectwords"))
+ , m_xCBRemoveList(m_xBuilder->weld_check_button("whenclosing"))
+ , m_xDCBExpandKey(m_xBuilder->weld_combo_box("acceptwith"))
+ , m_xNFMinWordlen(m_xBuilder->weld_spin_button("minwordlen"))
+ , m_xNFMaxEntries(m_xBuilder->weld_spin_button("maxentries"))
+ , m_xLBEntries(m_xBuilder->weld_tree_view("entries"))
+ , m_xPBEntries(m_xBuilder->weld_button("delete"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xCBRemoveList->get_preferred_size());
+ int nMaxWidth = m_xCBRemoveList->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xCBRemoveList->set_label_line_wrap(true);
+ m_xCBRemoveList->set_size_request(nMaxWidth, -1);
+ }
+
+ m_xLBEntries->set_size_request(m_xLBEntries->get_approximate_digit_width() * 30,
+ m_xLBEntries->get_height_rows(10));
+
+ // the defined KEYs
+ static const sal_uInt16 aKeyCodes[] = {
+ KEY_END,
+ KEY_RETURN,
+ KEY_SPACE,
+ KEY_RIGHT,
+ KEY_TAB,
+ 0
+ };
+
+ for( const sal_uInt16* pKeys = aKeyCodes; *pKeys; ++pKeys )
+ {
+ vcl::KeyCode aKCode(*pKeys);
+ m_xDCBExpandKey->append(OUString::number(static_cast<sal_Int32>(*pKeys)), aKCode.GetName());
+ if (KEY_RETURN == *pKeys) // default to RETURN
+ m_xDCBExpandKey->set_active(std::distance(aKeyCodes, pKeys));
+ }
+
+ m_xPBEntries->connect_clicked(LINK(this, OfaAutoCompleteTabPage, DeleteHdl));
+ m_xCBActiv->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xCBCollect->connect_toggled(LINK(this, OfaAutoCompleteTabPage, CheckHdl));
+ m_xLBEntries->connect_key_release(LINK(this, OfaAutoCompleteTabPage, KeyReleaseHdl));
+}
+
+OfaAutoCompleteTabPage::~OfaAutoCompleteTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaAutoCompleteTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaAutoCompleteTabPage>(pPage, pController, *rSet);
+}
+
+bool OfaAutoCompleteTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false, bCheck;
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ sal_uInt16 nVal;
+
+ bCheck = m_xCBActiv->get_active();
+ bModified |= pOpt->bAutoCompleteWords != bCheck;
+ pOpt->bAutoCompleteWords = bCheck;
+ bCheck = m_xCBCollect->get_active();
+ bModified |= pOpt->bAutoCmpltCollectWords != bCheck;
+ pOpt->bAutoCmpltCollectWords = bCheck;
+ bCheck = !m_xCBRemoveList->get_active(); // inverted value!
+ bModified |= pOpt->bAutoCmpltKeepList != bCheck;
+ pOpt->bAutoCmpltKeepList = bCheck;
+ bCheck = m_xCBAppendSpace->get_active();
+ bModified |= pOpt->bAutoCmpltAppendBlanc != bCheck;
+ pOpt->bAutoCmpltAppendBlanc = bCheck;
+ bCheck = m_xCBAsTip->get_active();
+ bModified |= pOpt->bAutoCmpltShowAsTip != bCheck;
+ pOpt->bAutoCmpltShowAsTip = bCheck;
+
+ nVal = static_cast<sal_uInt16>(m_xNFMinWordlen->get_value());
+ bModified |= nVal != pOpt->nAutoCmpltWordLen;
+ pOpt->nAutoCmpltWordLen = nVal;
+
+ nVal = static_cast<sal_uInt16>(m_xNFMaxEntries->get_value());
+ bModified |= nVal != pOpt->nAutoCmpltListLen;
+ pOpt->nAutoCmpltListLen = nVal;
+
+ const int nPos = m_xDCBExpandKey->get_active();
+ if (nPos != -1)
+ {
+ sal_Int32 nKey = m_xDCBExpandKey->get_id(nPos).toInt32();
+ bModified |= nKey != pOpt->nAutoCmpltExpandKey;
+ pOpt->nAutoCmpltExpandKey = static_cast<sal_uInt16>(nKey);
+ }
+
+ if (m_pAutoCompleteList && m_nAutoCmpltListCnt != m_xLBEntries->n_children())
+ {
+ bModified = true;
+ pOpt->m_pAutoCompleteList = m_pAutoCompleteList;
+ }
+ if( bModified )
+ {
+ SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
+ rCfg.SetModified();
+ rCfg.Commit();
+ }
+ return true;
+}
+
+void OfaAutoCompleteTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+
+ m_xCBActiv->set_active( pOpt->bAutoCompleteWords );
+ m_xCBCollect->set_active( pOpt->bAutoCmpltCollectWords );
+ m_xCBRemoveList->set_active( !pOpt->bAutoCmpltKeepList ); //inverted value!
+ m_xCBAppendSpace->set_active( pOpt->bAutoCmpltAppendBlanc );
+ m_xCBAsTip->set_active( pOpt->bAutoCmpltShowAsTip );
+
+ m_xNFMinWordlen->set_value( pOpt->nAutoCmpltWordLen );
+ m_xNFMaxEntries->set_value( pOpt->nAutoCmpltListLen );
+
+ // select the specific KeyCode:
+ {
+ sal_Int32 nKey = pOpt->nAutoCmpltExpandKey;
+ for (int n = 0, nCnt = m_xDCBExpandKey->get_count(); n < nCnt; ++n)
+ {
+ if (nKey == m_xDCBExpandKey->get_id(n).toInt32())
+ {
+ m_xDCBExpandKey->set_active(n);
+ break;
+ }
+ }
+ }
+
+ if (pOpt->m_pAutoCompleteList && !pOpt->m_pAutoCompleteList->empty())
+ {
+ m_pAutoCompleteList = const_cast<editeng::SortedAutoCompleteStrings*>(
+ pOpt->m_pAutoCompleteList);
+ pOpt->m_pAutoCompleteList = nullptr;
+ m_nAutoCmpltListCnt = m_pAutoCompleteList->size();
+ for (size_t n = 0; n < m_nAutoCmpltListCnt; ++n)
+ {
+ const OUString* pStr =
+ &(*m_pAutoCompleteList)[n]->GetAutoCompleteString();
+ OUString sId(OUString::number(reinterpret_cast<sal_Int64>(pStr)));
+ m_xLBEntries->append(sId, *pStr);
+ }
+ }
+ else
+ {
+ m_xLBEntries->set_sensitive(false);
+ m_xPBEntries->set_sensitive(false);
+ }
+
+ CheckHdl(*m_xCBActiv);
+ CheckHdl(*m_xCBCollect);
+}
+
+void OfaAutoCompleteTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+IMPL_LINK_NOARG(OfaAutoCompleteTabPage, DeleteHdl, weld::Button&, void)
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ std::sort(rows.begin(), rows.end());
+ while (!rows.empty())
+ {
+ sal_Int32 nPos = rows.back();
+ OUString* pStr = reinterpret_cast<OUString*>(m_xLBEntries->get_id(nPos).toInt64());
+ m_xLBEntries->remove(nPos);
+ editeng::IAutoCompleteString hack(*pStr); // UGLY
+ m_pAutoCompleteList->erase(&hack);
+ rows.pop_back();
+ }
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, CheckHdl, weld::ToggleButton&, rBox, void)
+{
+ bool bEnable = rBox.get_active();
+ if (&rBox == m_xCBActiv.get())
+ {
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAppendSpace->set_sensitive(bEnable);
+ m_xCBAsTip->set_sensitive(bEnable);
+ m_xDCBExpandKey->set_sensitive(bEnable);
+ }
+ else if (&rBox == m_xCBCollect.get())
+ m_xCBRemoveList->set_sensitive(bEnable);
+}
+
+void OfaAutoCompleteTabPage::CopyToClipboard() const
+{
+ auto rows = m_xLBEntries->get_selected_rows();
+ if (!(m_pAutoCompleteList && !rows.empty()))
+ return;
+
+ rtl::Reference<TransferDataContainer> pCntnr = new TransferDataContainer;
+
+ OStringBuffer sData;
+
+ rtl_TextEncoding nEncode = osl_getThreadTextEncoding();
+
+ for (auto a : rows)
+ {
+ sData.append(OUStringToOString(m_xLBEntries->get_text(a), nEncode));
+#if defined(_WIN32)
+ sData.append("\015\012");
+#else
+ sData.append("\012");
+#endif
+ }
+ pCntnr->CopyByteString( SotClipboardFormatId::STRING, sData.makeStringAndClear() );
+ pCntnr->CopyToClipboard(GetSystemClipboard());
+}
+
+IMPL_LINK(OfaAutoCompleteTabPage, KeyReleaseHdl, const KeyEvent&, rEvent, bool)
+{
+ bool bHandled = false;
+ const vcl::KeyCode& rKeyCode = rEvent.GetKeyCode();
+ switch (rKeyCode.GetModifier() | rKeyCode.GetCode())
+ {
+ case KEY_DELETE:
+ DeleteHdl(*m_xPBEntries);
+ bHandled = true;
+ break;
+ default:
+ if (KeyFuncType::COPY == rKeyCode.GetFunction())
+ {
+ CopyToClipboard();
+ bHandled = true;
+ }
+ break;
+ }
+ return bHandled;
+}
+
+// class OfaSmartTagOptionsTabPage ---------------------------------------------
+
+OfaSmartTagOptionsTabPage::OfaSmartTagOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet )
+ : SfxTabPage(pPage, pController, "cui/ui/smarttagoptionspage.ui", "SmartTagOptionsPage", &rSet)
+ , m_xMainCB(m_xBuilder->weld_check_button("main"))
+ , m_xSmartTagTypesLB(m_xBuilder->weld_tree_view("list"))
+ , m_xPropertiesPB(m_xBuilder->weld_button("properties"))
+{
+ m_xSmartTagTypesLB->set_size_request(m_xSmartTagTypesLB->get_approximate_digit_width() * 50,
+ m_xSmartTagTypesLB->get_height_rows(6));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(m_xSmartTagTypesLB->get_checkbox_column_width());
+ m_xSmartTagTypesLB->set_column_fixed_widths(aWidths);
+
+ // set the handlers:
+ m_xMainCB->connect_toggled(LINK(this, OfaSmartTagOptionsTabPage, CheckHdl));
+ m_xPropertiesPB->connect_clicked(LINK(this, OfaSmartTagOptionsTabPage, ClickHdl));
+ m_xSmartTagTypesLB->connect_changed(LINK(this, OfaSmartTagOptionsTabPage, SelectHdl));
+}
+
+OfaSmartTagOptionsTabPage::~OfaSmartTagOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaSmartTagOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<OfaSmartTagOptionsTabPage>(pPage, pController, *rSet);
+}
+
+namespace {
+
+/** This struct is used to associate list box entries with smart tag data
+*/
+struct ImplSmartTagLBUserData
+{
+ OUString maSmartTagType;
+ uno::Reference< smarttags::XSmartTagRecognizer > mxRec;
+ sal_Int32 mnSmartTagIdx;
+
+ ImplSmartTagLBUserData( const OUString& rSmartTagType,
+ uno::Reference< smarttags::XSmartTagRecognizer > const & xRec,
+ sal_Int32 nSmartTagIdx ) :
+ maSmartTagType( rSmartTagType ),
+ mxRec( xRec ),
+ mnSmartTagIdx( nSmartTagIdx ) {}
+};
+
+}
+
+/** Clears m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::ClearListBox()
+{
+ const int nCount = m_xSmartTagTypesLB->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i).toInt64());
+ delete pUserData;
+ }
+
+ m_xSmartTagTypesLB->clear();
+}
+
+/** Inserts items into m_xSmartTagTypesLB
+*/
+void OfaSmartTagOptionsTabPage::FillListBox( const SmartTagMgr& rSmartTagMgr )
+{
+ // first we have to clear the list box:
+ ClearListBox();
+
+ // fill list box:
+ const sal_uInt32 nNumberOfRecognizers = rSmartTagMgr.NumberOfRecognizers();
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+
+ for ( sal_uInt32 i = 0; i < nNumberOfRecognizers; ++i )
+ {
+ const uno::Reference< smarttags::XSmartTagRecognizer >& xRec = rSmartTagMgr.GetRecognizer(i);
+
+ const OUString aName = xRec->getName( aLocale );
+ const sal_Int32 nNumberOfSupportedSmartTags = xRec->getSmartTagCount();
+
+ for ( sal_Int32 j = 0; j < nNumberOfSupportedSmartTags; ++j )
+ {
+ const OUString aSmartTagType = xRec->getSmartTagName(j);
+ OUString aSmartTagCaption = rSmartTagMgr.GetSmartTagCaption( aSmartTagType, aLocale );
+
+ if ( aSmartTagCaption.isEmpty() )
+ aSmartTagCaption = aSmartTagType;
+
+ const OUString aLBEntry = aSmartTagCaption + " (" + aName + ")";
+
+ m_xSmartTagTypesLB->append();
+ const int nRow = m_xSmartTagTypesLB->n_children() - 1;
+ const bool bCheck = rSmartTagMgr.IsSmartTagTypeEnabled( aSmartTagType );
+ m_xSmartTagTypesLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, CBCOL_FIRST);
+ m_xSmartTagTypesLB->set_text(nRow, aLBEntry, 1);
+ m_xSmartTagTypesLB->set_id(nRow, OUString::number(reinterpret_cast<sal_Int64>(new ImplSmartTagLBUserData(aSmartTagType, xRec, j))));
+ }
+ }
+}
+
+/** Handler for the push button
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, ClickHdl, weld::Button&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos).toInt64());
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ xRec->displayPropertyPage( nSmartTagIdx, aLocale );
+}
+
+/** Handler for the check box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, CheckHdl, weld::ToggleButton&, void)
+{
+ const bool bEnable = m_xMainCB->get_active();
+ m_xSmartTagTypesLB->set_sensitive(bEnable);
+ m_xPropertiesPB->set_sensitive(false);
+
+ // if the controls are currently enabled, we still have to check
+ // if the properties button should be disabled because the currently
+ // selected smart tag type does not have a properties dialog.
+ // We do this by calling SelectHdl:
+ if (bEnable)
+ SelectHdl(*m_xSmartTagTypesLB);
+}
+
+/** Handler for the list box
+*/
+IMPL_LINK_NOARG(OfaSmartTagOptionsTabPage, SelectHdl, weld::TreeView&, void)
+{
+ const int nPos = m_xSmartTagTypesLB->get_selected_index();
+ if (nPos == -1)
+ return;
+ const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(nPos).toInt64());
+ uno::Reference< smarttags::XSmartTagRecognizer > xRec = pUserData->mxRec;
+ const sal_Int32 nSmartTagIdx = pUserData->mnSmartTagIdx;
+
+ const lang::Locale aLocale( LanguageTag::convertToLocale( eLastDialogLanguage ) );
+ if ( xRec->hasPropertyPage( nSmartTagIdx, aLocale ) )
+ m_xPropertiesPB->set_sensitive(true);
+ else
+ m_xPropertiesPB->set_sensitive(false);
+}
+
+/** Propagates the current settings to the smart tag manager.
+*/
+bool OfaSmartTagOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust!
+ if ( !pSmartTagMgr )
+ return false;
+
+ bool bModifiedSmartTagTypes = false;
+ std::vector< OUString > aDisabledSmartTagTypes;
+
+ const int nCount = m_xSmartTagTypesLB->n_children();
+
+ for (int i = 0; i < nCount; ++i)
+ {
+ const ImplSmartTagLBUserData* pUserData = reinterpret_cast<ImplSmartTagLBUserData*>(m_xSmartTagTypesLB->get_id(i).toInt64());
+ const bool bChecked = m_xSmartTagTypesLB->get_toggle(i, CBCOL_FIRST) == TRISTATE_TRUE;
+ const bool bIsCurrentlyEnabled = pSmartTagMgr->IsSmartTagTypeEnabled( pUserData->maSmartTagType );
+
+ bModifiedSmartTagTypes = bModifiedSmartTagTypes || ( !bChecked != !bIsCurrentlyEnabled );
+
+ if ( !bChecked )
+ aDisabledSmartTagTypes.push_back( pUserData->maSmartTagType );
+
+ delete pUserData;
+ }
+
+ const bool bModifiedRecognize = ( !m_xMainCB->get_active() != !pSmartTagMgr->IsLabelTextWithSmartTags() );
+ if ( bModifiedSmartTagTypes || bModifiedRecognize )
+ {
+ bool bLabelTextWithSmartTags = m_xMainCB->get_active();
+ pSmartTagMgr->WriteConfiguration( bModifiedRecognize ? &bLabelTextWithSmartTags : nullptr,
+ bModifiedSmartTagTypes ? &aDisabledSmartTagTypes : nullptr );
+ }
+
+ return true;
+}
+
+/** Sets the controls based on the current settings at SmartTagMgr.
+*/
+void OfaSmartTagOptionsTabPage::Reset( const SfxItemSet* )
+{
+ SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get().GetAutoCorrect();
+ SvxSwAutoFormatFlags *pOpt = &pAutoCorrect->GetSwFlags();
+ const SmartTagMgr* pSmartTagMgr = pOpt->pSmartTagMgr;
+
+ // robust, should not happen!
+ if ( !pSmartTagMgr )
+ return;
+
+ FillListBox(*pSmartTagMgr);
+ m_xSmartTagTypesLB->select(0);
+ m_xMainCB->set_active(pSmartTagMgr->IsLabelTextWithSmartTags());
+ CheckHdl(*m_xMainCB);
+}
+
+void OfaSmartTagOptionsTabPage::ActivatePage( const SfxItemSet& )
+{
+ static_cast<OfaAutoCorrDlg*>(GetDialogController())->EnableLanguage( false );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/backgrnd.cxx b/cui/source/tabpages/backgrnd.cxx
new file mode 100644
index 000000000..38190271d
--- /dev/null
+++ b/cui/source/tabpages/backgrnd.cxx
@@ -0,0 +1,343 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <editeng/colritem.hxx>
+#include <backgrnd.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/intitem.hxx>
+#include <svx/unobrushitemhelper.hxx>
+
+using namespace css;
+
+// table background
+#define TBL_DEST_CELL 0
+#define TBL_DEST_ROW 1
+#define TBL_DEST_TBL 2
+
+const sal_uInt16 SvxBkgTabPage::pPageRanges[] =
+{
+ SID_ATTR_BRUSH, SID_ATTR_BRUSH,
+ SID_ATTR_BRUSH_CHAR, SID_ATTR_BRUSH_CHAR,
+ 0
+};
+
+static sal_uInt16 lcl_GetTableDestSlot(sal_Int32 nTblDest)
+{
+ switch (nTblDest)
+ {
+ default:
+ case TBL_DEST_CELL:
+ {
+ return SID_ATTR_BRUSH;
+ }
+ case TBL_DEST_ROW:
+ {
+ return SID_ATTR_BRUSH_ROW;
+ }
+ case TBL_DEST_TBL:
+ {
+ return SID_ATTR_BRUSH_TABLE;
+ }
+ }
+}
+
+SvxBkgTabPage::SvxBkgTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxAreaTabPage(pPage, pController, rInAttrs),
+ bHighlighting(false),
+ bCharBackColor(false),
+ maSet(rInAttrs)
+{
+ m_xBtnGradient->hide();
+ m_xBtnHatch->hide();
+ m_xBtnBitmap->hide();
+ m_xBtnPattern->hide();
+
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ XColorListRef pColorTable;
+ if ( pDocSh )
+ if (auto pItem = pDocSh->GetItem( SID_COLOR_TABLE ))
+ pColorTable = pItem->GetColorList();
+
+ if ( !pColorTable.is() )
+ pColorTable = XColorList::CreateStdColorList();
+
+ XBitmapListRef pBitmapList;
+ if ( pDocSh )
+ if (auto pItem = pDocSh->GetItem( SID_BITMAP_LIST ) )
+ pBitmapList = pItem->GetBitmapList();
+
+ SetColorList(pColorTable);
+ SetBitmapList(pBitmapList);
+}
+
+SvxBkgTabPage::~SvxBkgTabPage()
+{
+ m_xTblLBox.reset();
+}
+
+void SvxBkgTabPage::ActivatePage( const SfxItemSet& )
+{
+ SvxAreaTabPage::ActivatePage( maSet );
+}
+
+DeactivateRC SvxBkgTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( DeactivateRC::KeepPage == SvxAreaTabPage::DeactivatePage( &maSet ) )
+ return DeactivateRC::KeepPage;
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBkgTabPage::Reset( const SfxItemSet* )
+{
+ maSet.Set( *m_pResetSet );
+ if ( m_xTblLBox && m_xTblLBox->get_visible() )
+ {
+ m_nActPos = -1;
+ const SfxPoolItem* pItem;
+ if ( SfxItemState::SET == m_pResetSet->GetItemState( SID_BACKGRND_DESTINATION, false, &pItem ) )
+ {
+ sal_uInt16 nDestValue = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ m_xTblLBox->set_active( nDestValue );
+ TblDestinationHdl_Impl( *m_xTblLBox );
+ }
+ m_xTblLBox->save_value();
+ }
+ SvxAreaTabPage::Reset( &maSet );
+}
+
+bool SvxBkgTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ sal_uInt16 nSlot = SID_ATTR_BRUSH;
+ if (m_xTblLBox && m_xTblLBox->get_visible())
+ nSlot = lcl_GetTableDestSlot(m_xTblLBox->get_active());
+ else if ( bHighlighting )
+ nSlot = SID_ATTR_BRUSH_CHAR;
+ else if( bCharBackColor )
+ nSlot = SID_ATTR_CHAR_BACK_COLOR;
+
+ sal_uInt16 nWhich = GetWhich(nSlot);
+
+ drawing::FillStyle eFillType = maSet.Get( XATTR_FILLSTYLE ).GetValue();
+ switch( eFillType )
+ {
+ case drawing::FillStyle_NONE:
+ {
+ if ( IsBtnClicked() )
+ {
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ maSet.Put( SvxBackgroundColorItem( COL_TRANSPARENT, nWhich ) );
+ rCoreSet->Put( SvxBackgroundColorItem( COL_TRANSPARENT, nWhich ) );
+ }
+ else
+ {
+ maSet.Put( SvxBrushItem( COL_TRANSPARENT, nWhich ) );
+ rCoreSet->Put( SvxBrushItem( COL_TRANSPARENT, nWhich ) );
+ }
+ }
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ XFillColorItem aColorItem( maSet.Get( XATTR_FILLCOLOR ) );
+ if ( SID_ATTR_CHAR_BACK_COLOR == nSlot )
+ {
+ maSet.Put( SvxBackgroundColorItem( aColorItem.GetColorValue(), nWhich ) );
+ rCoreSet->Put( SvxBackgroundColorItem( aColorItem.GetColorValue(), nWhich ) );
+ }
+ else
+ {
+ maSet.Put( SvxBrushItem( aColorItem.GetColorValue(), nWhich ) );
+ rCoreSet->Put( SvxBrushItem( aColorItem.GetColorValue(), nWhich ) );
+ }
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ std::unique_ptr<SvxBrushItem> aBrushItem( getSvxBrushItemFromSourceSet( maSet, nWhich ) );
+ if ( GraphicType::NONE != aBrushItem->GetGraphicObject()->GetType() )
+ rCoreSet->Put( *aBrushItem );
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (m_xTblLBox && m_xTblLBox->get_visible())
+ {
+ if (nSlot != SID_ATTR_BRUSH)
+ {
+ nWhich = maSet.GetPool()->GetWhich(SID_ATTR_BRUSH);
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_ROW)
+ {
+ nWhich = maSet.GetPool()->GetWhich(SID_ATTR_BRUSH_ROW);
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+ if (nSlot != SID_ATTR_BRUSH_TABLE)
+ {
+ nWhich = maSet.GetPool()->GetWhich(SID_ATTR_BRUSH_TABLE);
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ rCoreSet->Put(aBrushItem);
+ }
+ }
+
+ if (m_xTblLBox->get_value_changed_from_saved())
+ {
+ rCoreSet->Put(SfxUInt16Item(SID_BACKGRND_DESTINATION, m_xTblLBox->get_active()));
+ }
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxTabPage> SvxBkgTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxBkgTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+void SvxBkgTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ SvxBackgroundTabFlags nFlags = static_cast<SvxBackgroundTabFlags>(pFlagItem->GetValue());
+ if ( nFlags & SvxBackgroundTabFlags::SHOW_TBLCTL )
+ {
+ m_xBtnBitmap->show();
+ m_xTblLBox = m_xBuilder->weld_combo_box("tablelb");
+ m_xTblLBox->connect_changed(LINK(this, SvxBkgTabPage, TblDestinationHdl_Impl));
+ m_xTblLBox->show();
+ }
+ if ((nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING) ||
+ (nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR))
+ {
+ bHighlighting = bool(nFlags & SvxBackgroundTabFlags::SHOW_HIGHLIGHTING);
+ bCharBackColor = bool(nFlags & SvxBackgroundTabFlags::SHOW_CHAR_BKGCOLOR);
+ }
+ if (nFlags & SvxBackgroundTabFlags::SHOW_SELECTOR)
+ m_xBtnBitmap->show();
+ SetOptimalSize(GetDialogController());
+ }
+
+ if ( bCharBackColor )
+ {
+ sal_uInt16 nWhich(maSet.GetPool()->GetWhich(SID_ATTR_CHAR_BACK_COLOR));
+ Color aBackColor(static_cast<const SvxBackgroundColorItem&>(maSet.Get(nWhich)).GetValue());
+ SvxBrushItem aBrushItem(SvxBrushItem(aBackColor, SID_ATTR_BRUSH_CHAR));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+ else
+ {
+ sal_uInt16 nWhich(maSet.GetPool()->GetWhich(bHighlighting ? SID_ATTR_BRUSH_CHAR : SID_ATTR_BRUSH));
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+
+ m_pResetSet = maSet.Clone();
+
+ SvxAreaTabPage::PageCreated(aSet);
+}
+
+IMPL_LINK(SvxBkgTabPage, TblDestinationHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ if (m_nActPos > -1)
+ {
+ // fill local item set with XATTR_FILL settings gathered from tab page
+ // and convert to SvxBrushItem and store in table destination slot Which
+ SvxAreaTabPage::FillItemSet(&maSet);
+ maSet.Put(*getSvxBrushItemFromSourceSet(maSet, maSet.GetPool()->GetWhich(lcl_GetTableDestSlot(m_nActPos))));
+ }
+
+ sal_Int32 nSelPos = rBox.get_active();
+ if (m_nActPos == nSelPos)
+ return;
+
+ m_nActPos = nSelPos;
+
+ // fill local item set with XATTR_FILL created from SvxBushItem for table destination slot Which
+ sal_uInt16 nWhich = maSet.GetPool()->GetWhich(lcl_GetTableDestSlot(nSelPos));
+ if (SfxItemState::SET == maSet.GetItemState(nWhich))
+ {
+ SvxBrushItem aBrushItem(static_cast<const SvxBrushItem&>(maSet.Get(nWhich)));
+ setSvxBrushItemAsFillAttributesToTargetSet(aBrushItem, maSet);
+ }
+ else
+ {
+ SelectFillType(*m_xBtnNone, &maSet);
+ return;
+ }
+
+ // show tab page
+ drawing::FillStyle eXFS = drawing::FillStyle_NONE;
+ if (maSet.GetItemState(XATTR_FILLSTYLE) != SfxItemState::DONTCARE)
+ {
+ XFillStyleItem aFillStyleItem(static_cast<const XFillStyleItem&>(maSet.Get(GetWhich( XATTR_FILLSTYLE))));
+ eXFS = aFillStyleItem.GetValue();
+ }
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ SelectFillType(*m_xBtnNone, &maSet);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ SelectFillType(*m_xBtnColor, &maSet);
+ // color tab page Active and New preview controls are same after SelectFillType
+ // hack to restore color tab page Active preview
+ setSvxBrushItemAsFillAttributesToTargetSet(static_cast<const SvxBrushItem&>(m_pResetSet->Get(nWhich)), *m_pResetSet);
+ static_cast<SvxColorTabPage*>(GetFillTabPage())->SetCtlPreviewOld(*m_pResetSet);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ SelectFillType(*m_xBtnBitmap, &maSet);
+ break;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/bbdlg.cxx b/cui/source/tabpages/bbdlg.cxx
new file mode 100644
index 000000000..d21d046da
--- /dev/null
+++ b/cui/source/tabpages/bbdlg.cxx
@@ -0,0 +1,90 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <bbdlg.hxx>
+#include <border.hxx>
+#include <backgrnd.hxx>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxBorderBackgroundDlg::SvxBorderBackgroundDlg(weld::Window *pParent,
+ const SfxItemSet& rCoreSet,
+ bool bEnableSelector,
+ bool bEnableDrawingLayerFillStyles)
+ : SfxTabDialogController(pParent,
+ bEnableDrawingLayerFillStyles
+ ? OUString("cui/ui/borderareatransparencydialog.ui")
+ : OUString("cui/ui/borderbackgrounddialog.ui"),
+ bEnableDrawingLayerFillStyles
+ ? OString("BorderAreaTransparencyDialog")
+ : OString("BorderBackgroundDialog"),
+ &rCoreSet)
+ , mbEnableBackgroundSelector(bEnableSelector)
+{
+ AddTabPage("borders", SvxBorderTabPage::Create, nullptr );
+ if (bEnableDrawingLayerFillStyles)
+ {
+ // Here we want full DrawingLayer FillStyle access, so add Area and Transparency TabPages
+ AddTabPage("area", SvxAreaTabPage::Create, nullptr);
+ AddTabPage("transparence", SvxTransparenceTabPage::Create, nullptr);
+ }
+ else
+ {
+ AddTabPage("background", SvxBkgTabPage::Create, nullptr );
+ }
+}
+
+void SvxBorderBackgroundDlg::PageCreated(const OString& rPageId, SfxTabPage& rTabPage)
+{
+ if (rPageId == "background")
+ {
+ SfxAllItemSet aSet(*(GetInputSetImpl()->GetPool()));
+ // allow switching between Color/graphic
+ if (mbEnableBackgroundSelector)
+ aSet.Put(SfxUInt32Item(SID_FLAG_TYPE, static_cast<sal_uInt32>(SvxBackgroundTabFlags::SHOW_SELECTOR)));
+ rTabPage.PageCreated(aSet);
+ }
+ // inits for Area and Transparency TabPages
+ // The selection attribute lists (XPropertyList derivates, e.g. XColorList for
+ // the color table) need to be added as items (e.g. SvxColorTableItem) to make
+ // these pages find the needed attributes for fill style suggestions.
+ // These are added in SwDocStyleSheet::GetItemSet() for the SfxStyleFamily::Para on
+ // demand, but could also be directly added from the DrawModel.
+ else if (rPageId == "area")
+ {
+ SfxItemSet aNew(
+ *GetInputSetImpl()->GetPool(),
+ svl::Items<SID_COLOR_TABLE, SID_PATTERN_LIST,
+ SID_OFFER_IMPORT, SID_OFFER_IMPORT>{});
+
+ aNew.Put(*GetInputSetImpl());
+
+ // add flag for direct graphic content selection
+ aNew.Put(SfxBoolItem(SID_OFFER_IMPORT, true));
+
+ rTabPage.PageCreated(aNew);
+ }
+ else if (rPageId == "transparence")
+ {
+ rTabPage.PageCreated(*GetInputSetImpl());
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/border.cxx b/cui/source/tabpages/border.cxx
new file mode 100644
index 000000000..ed6c1add9
--- /dev/null
+++ b/cui/source/tabpages/border.cxx
@@ -0,0 +1,1522 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+
+#include <strings.hrc>
+#include <bitmaps.hlst>
+
+#include <editeng/boxitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <border.hxx>
+#include <svx/dlgutil.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/flagsdef.hxx>
+#include <svl/grabbagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/ilstitem.hxx>
+#include <svl/int64item.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace ::editeng;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+
+/*
+ * [Description:]
+ * TabPage for setting the border attributes.
+ * Needs
+ * a SvxShadowItem: shadow
+ * a SvxBoxItem: lines left, right, top, bottom,
+ * a SvxBoxInfo: lines vertical, horizontal, distance, flags
+ *
+ * Lines can have three conditions:
+ * 1. Show ( -> valid values )
+ * 2. Hide ( -> NULL-Pointer )
+ * 3. DontCare ( -> special Valid-Flags in the InfoItem )
+ */
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxBorderTabPage::pRanges[] =
+{
+ SID_ATTR_BORDER_INNER, SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_ALIGN_MARGIN, SID_ATTR_ALIGN_MARGIN,
+ SID_ATTR_BORDER_CONNECT, SID_ATTR_BORDER_CONNECT,
+ SID_SW_COLLAPSING_BORDERS, SID_SW_COLLAPSING_BORDERS,
+ SID_ATTR_BORDER_DIAG_TLBR, SID_ATTR_BORDER_DIAG_BLTR,
+ 0
+};
+
+static void lcl_SetDecimalDigitsTo1(weld::MetricSpinButton& rField)
+{
+ auto nMin = rField.denormalize(rField.get_min(FieldUnit::TWIP));
+ rField.set_digits(1);
+ rField.set_min(rField.normalize(nMin), FieldUnit::TWIP);
+}
+
+// number of preset images to show
+const sal_uInt16 SVX_BORDER_PRESET_COUNT = 5;
+
+// number of shadow images to show
+const sal_uInt16 SVX_BORDER_SHADOW_COUNT = 5;
+
+ShadowControlsWrapper::ShadowControlsWrapper(ValueSet& rVsPos, weld::MetricSpinButton& rMfSize, ColorListBox& rLbColor)
+ : mrVsPos(rVsPos)
+ , mrMfSize(rMfSize)
+ , mrLbColor(rLbColor)
+{
+}
+
+SvxShadowItem ShadowControlsWrapper::GetControlValue(const SvxShadowItem& rItem) const
+{
+ SvxShadowItem aItem(rItem);
+ if (!mrVsPos.IsNoSelection())
+ {
+ switch (mrVsPos.GetSelectedItemId())
+ {
+ case 1:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ case 2:
+ aItem.SetLocation(SvxShadowLocation::BottomRight);
+ break;
+ case 3:
+ aItem.SetLocation(SvxShadowLocation::TopRight);
+ break;
+ case 4:
+ aItem.SetLocation(SvxShadowLocation::BottomLeft);
+ break;
+ case 5:
+ aItem.SetLocation(SvxShadowLocation::TopLeft);
+ break;
+ default:
+ aItem.SetLocation(SvxShadowLocation::NONE);
+ break;
+ }
+ }
+ // Default value was saved; so don't change the aItem's width if the control
+ // has not changed its value, to avoid round-trip errors (like twip->cm->twip)
+ // E.g., initial 100 twip will become 0.18 cm, which will return as 102 twip
+ if (mrMfSize.get_value_changed_from_saved())
+ aItem.SetWidth(mrMfSize.denormalize(mrMfSize.get_value(FieldUnit::TWIP)));
+ if (!mrLbColor.IsNoSelection())
+ aItem.SetColor(mrLbColor.GetSelectEntryColor());
+ return aItem;
+}
+
+void ShadowControlsWrapper::SetControlValue(const SvxShadowItem& rItem)
+{
+ switch (rItem.GetLocation())
+ {
+ case SvxShadowLocation::NONE:
+ mrVsPos.SelectItem(1);
+ break;
+ case SvxShadowLocation::BottomRight:
+ mrVsPos.SelectItem(2);
+ break;
+ case SvxShadowLocation::TopRight:
+ mrVsPos.SelectItem(3);
+ break;
+ case SvxShadowLocation::BottomLeft:
+ mrVsPos.SelectItem(4);
+ break;
+ case SvxShadowLocation::TopLeft:
+ mrVsPos.SelectItem(5);
+ break;
+ default:
+ mrVsPos.SetNoSelection();
+ break;
+ }
+ mrVsPos.SaveValue();
+ mrMfSize.set_value(mrMfSize.normalize(rItem.GetWidth()), FieldUnit::TWIP);
+ mrMfSize.save_value();
+ mrLbColor.SelectEntry(rItem.GetColor());
+ mrLbColor.SaveValue();
+}
+
+bool ShadowControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrVsPos.IsValueChangedFromSaved() ||
+ mrMfSize.get_value_changed_from_saved() ||
+ mrLbColor.IsValueChangedFromSaved();
+}
+
+void ShadowControlsWrapper::SetControlDontKnow()
+{
+ mrVsPos.SetNoSelection();
+ mrMfSize.set_text("");
+ mrLbColor.SetNoSelection();
+}
+
+MarginControlsWrapper::MarginControlsWrapper(weld::MetricSpinButton& rMfLeft, weld::MetricSpinButton& rMfRight,
+ weld::MetricSpinButton& rMfTop, weld::MetricSpinButton& rMfBottom)
+ : mrLeftWrp(rMfLeft)
+ , mrRightWrp(rMfRight)
+ , mrTopWrp(rMfTop)
+ , mrBottomWrp(rMfBottom)
+{
+}
+
+SvxMarginItem MarginControlsWrapper::GetControlValue(const SvxMarginItem &rItem) const
+{
+ SvxMarginItem aItem(rItem);
+ if (mrLeftWrp.get_sensitive())
+ aItem.SetLeftMargin(mrLeftWrp.denormalize(mrLeftWrp.get_value(FieldUnit::TWIP)));
+ if (mrRightWrp.get_sensitive())
+ aItem.SetRightMargin(mrRightWrp.denormalize(mrRightWrp.get_value(FieldUnit::TWIP)));
+ if (mrTopWrp.get_sensitive())
+ aItem.SetTopMargin(mrTopWrp.denormalize(mrTopWrp.get_value(FieldUnit::TWIP)));
+ if (mrBottomWrp.get_sensitive())
+ aItem.SetBottomMargin(mrBottomWrp.denormalize(mrBottomWrp.get_value(FieldUnit::TWIP)));
+ return aItem;
+}
+
+bool MarginControlsWrapper::get_value_changed_from_saved() const
+{
+ return mrLeftWrp.get_value_changed_from_saved() ||
+ mrRightWrp.get_value_changed_from_saved() ||
+ mrTopWrp.get_value_changed_from_saved() ||
+ mrBottomWrp.get_value_changed_from_saved();
+}
+
+void MarginControlsWrapper::SetControlValue(const SvxMarginItem& rItem)
+{
+ mrLeftWrp.set_value(mrLeftWrp.normalize(rItem.GetLeftMargin()), FieldUnit::TWIP);
+ mrRightWrp.set_value(mrRightWrp.normalize(rItem.GetRightMargin()), FieldUnit::TWIP);
+ mrTopWrp.set_value(mrTopWrp.normalize(rItem.GetTopMargin()), FieldUnit::TWIP);
+ mrBottomWrp.set_value(mrBottomWrp.normalize(rItem.GetBottomMargin()), FieldUnit::TWIP);
+ mrLeftWrp.save_value();
+ mrRightWrp.save_value();
+ mrTopWrp.save_value();
+ mrBottomWrp.save_value();
+}
+
+void MarginControlsWrapper::SetControlDontKnow()
+{
+ const OUString sEmpty;
+ mrLeftWrp.set_text(sEmpty);
+ mrRightWrp.set_text(sEmpty);
+ mrTopWrp.set_text(sEmpty);
+ mrBottomWrp.set_text(sEmpty);
+}
+
+SvxBorderTabPage::SvxBorderTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/borderpage.ui", "BorderPage", &rCoreAttrs)
+ , nMinValue(0)
+ , nSWMode(SwBorderModes::NONE)
+ , mnBoxSlot(SID_ATTR_BORDER_OUTER)
+ , mnShadowSlot(SID_ATTR_BORDER_SHADOW)
+ , mbHorEnabled(false)
+ , mbVerEnabled(false)
+ , mbTLBREnabled(false)
+ , mbBLTREnabled(false)
+ , mbUseMarginItem(false)
+ , mbLeftModified(false)
+ , mbRightModified(false)
+ , mbTopModified(false)
+ , mbBottomModified(false)
+ , mbSync(true)
+ , mbRemoveAdjacentCellBorders(false)
+ , bIsCalcDoc(false)
+ , m_xWndPresets(new ValueSet(nullptr))
+ , m_xWndPresetsWin(new weld::CustomWeld(*m_xBuilder, "presets", *m_xWndPresets))
+ , m_xUserDefFT(m_xBuilder->weld_label("userdefft"))
+ , m_xFrameSelWin(new weld::CustomWeld(*m_xBuilder, "framesel", m_aFrameSel))
+ , m_xLbLineStyle(new SvtLineListBox(m_xBuilder->weld_menu_button("linestylelb")))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"), pController->getDialog()))
+ , m_xLineWidthMF(m_xBuilder->weld_metric_spin_button("linewidthmf", FieldUnit::POINT))
+ , m_xSpacingFrame(m_xBuilder->weld_container("spacing"))
+ , m_xLeftFT(m_xBuilder->weld_label("leftft"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("leftmf", FieldUnit::MM))
+ , m_xRightFT(m_xBuilder->weld_label("rightft"))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("rightmf", FieldUnit::MM))
+ , m_xTopFT(m_xBuilder->weld_label("topft"))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("topmf", FieldUnit::MM))
+ , m_xBottomFT(m_xBuilder->weld_label("bottomft"))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottommf", FieldUnit::MM))
+ , m_xSynchronizeCB(m_xBuilder->weld_check_button("sync"))
+ , m_xShadowFrame(m_xBuilder->weld_container("shadow"))
+ , m_xWndShadows(new ValueSet(nullptr))
+ , m_xWndShadowsWin(new weld::CustomWeld(*m_xBuilder, "shadows", *m_xWndShadows))
+ , m_xFtShadowSize(m_xBuilder->weld_label("distanceft"))
+ , m_xEdShadowSize(m_xBuilder->weld_metric_spin_button("distancemf", FieldUnit::MM))
+ , m_xFtShadowColor(m_xBuilder->weld_label("shadowcolorft"))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("shadowcolorlb"), pController->getDialog()))
+ , m_xPropertiesFrame(m_xBuilder->weld_container("properties"))
+ , m_xMergeWithNextCB(m_xBuilder->weld_check_button("mergewithnext"))
+ , m_xMergeAdjacentBordersCB(m_xBuilder->weld_check_button("mergeadjacent"))
+ , m_xRemoveAdjcentCellBordersCB(m_xBuilder->weld_check_button("rmadjcellborders"))
+ , m_xRemoveAdjcentCellBordersFT(m_xBuilder->weld_label("rmadjcellbordersft"))
+{
+ static std::vector<OUStringLiteral> aBorderImageIds;
+
+ if (aBorderImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE_32,
+ RID_SVXBMP_CELL_ALL_32,
+ RID_SVXBMP_CELL_LR_32,
+ RID_SVXBMP_CELL_TB_32,
+ RID_SVXBMP_CELL_L_32,
+ RID_SVXBMP_CELL_DIAG_32
+ });
+ }
+ else
+ {
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_CELL_NONE,
+ RID_SVXBMP_CELL_ALL,
+ RID_SVXBMP_CELL_LR,
+ RID_SVXBMP_CELL_TB,
+ RID_SVXBMP_CELL_L,
+ RID_SVXBMP_CELL_DIAG
+ });
+ }
+ aBorderImageIds.insert(aBorderImageIds.end(), {
+ RID_SVXBMP_HOR_NONE,
+ RID_SVXBMP_HOR_OUTER,
+ RID_SVXBMP_HOR_HOR,
+ RID_SVXBMP_HOR_ALL,
+ RID_SVXBMP_HOR_OUTER2,
+ RID_SVXBMP_VER_NONE,
+ RID_SVXBMP_VER_OUTER,
+ RID_SVXBMP_VER_VER,
+ RID_SVXBMP_VER_ALL,
+ RID_SVXBMP_VER_OUTER2,
+ RID_SVXBMP_TABLE_NONE,
+ RID_SVXBMP_TABLE_OUTER,
+ RID_SVXBMP_TABLE_OUTERH,
+ RID_SVXBMP_TABLE_ALL,
+ RID_SVXBMP_TABLE_OUTER2
+ });
+ }
+
+ for (auto const & rImageId : aBorderImageIds)
+ m_aBorderImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ static std::vector<OUStringLiteral> aShadowImageIds;
+ if (aShadowImageIds.empty())
+ {
+ if (comphelper::LibreOfficeKit::isActive())
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE_32,
+ RID_SVXBMP_SHADOW_BOT_RIGHT_32,
+ RID_SVXBMP_SHADOW_TOP_RIGHT_32,
+ RID_SVXBMP_SHADOW_BOT_LEFT_32,
+ RID_SVXBMP_SHADOW_TOP_LEFT_32
+ });
+ }
+ else
+ {
+ aShadowImageIds.insert(aShadowImageIds.end(), {
+ RID_SVXBMP_SHADOWNONE,
+ RID_SVXBMP_SHADOW_BOT_RIGHT,
+ RID_SVXBMP_SHADOW_TOP_RIGHT,
+ RID_SVXBMP_SHADOW_BOT_LEFT,
+ RID_SVXBMP_SHADOW_TOP_LEFT
+ });
+ }
+ }
+
+ for (auto const & rImageId : aShadowImageIds)
+ m_aShadowImgVec.emplace_back(StockImage::Yes, rImageId);
+
+ assert(m_aShadowImgVec.size() == SVX_BORDER_SHADOW_COUNT);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ /* Use SvxMarginItem instead of margins from SvxBoxItem, if present.
+ -> Remember this state in mbUseMarginItem, because other special handling
+ is needed across various functions... */
+ mbUseMarginItem = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_ALIGN_MARGIN)) != SfxItemState::UNKNOWN;
+
+ const SfxPoolItem* pItem = nullptr;
+ if (rCoreAttrs.HasItem(SID_ATTR_BORDER_STYLES, &pItem))
+ {
+ const SfxIntegerListItem* p = static_cast<const SfxIntegerListItem*>(pItem);
+ std::vector<sal_Int32> aUsedStyles = p->GetList();
+ for (int aUsedStyle : aUsedStyles)
+ maUsedBorderStyles.insert(static_cast<SvxBorderLineStyle>(aUsedStyle));
+ }
+
+ if (rCoreAttrs.HasItem(SID_ATTR_BORDER_DEFAULT_WIDTH, &pItem))
+ {
+ // The caller specifies default line width. Honor it.
+ const SfxInt64Item* p = static_cast<const SfxInt64Item*>(pItem);
+ m_xLineWidthMF->set_value(p->GetValue(), FieldUnit::POINT);
+ }
+
+ // set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rCoreAttrs );
+
+ if( mbUseMarginItem )
+ {
+ // copied from SvxAlignmentTabPage
+ switch ( eFUnit )
+ {
+ // #103396# the default value (1pt) can't be accurately represented in
+ // inches or pica with two decimals, so point is used instead.
+ case FieldUnit::PICA:
+ case FieldUnit::INCH:
+ case FieldUnit::FOOT:
+ case FieldUnit::MILE:
+ eFUnit = FieldUnit::POINT;
+ break;
+
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ }
+
+ SetFieldUnit(*m_xEdShadowSize, eFUnit);
+
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_BORDER_INNER, false );
+ bool bIsDontCare = true;
+
+ if ( rCoreAttrs.GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ // paragraph or table
+ const SvxBoxInfoItem* pBoxInfo =
+ static_cast<const SvxBoxInfoItem*>(&( rCoreAttrs.Get( nWhich ) ));
+
+ mbHorEnabled = pBoxInfo->IsHorEnabled();
+ mbVerEnabled = pBoxInfo->IsVerEnabled();
+ mbTLBREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_TLBR)) != SfxItemState::UNKNOWN;
+ mbBLTREnabled = rCoreAttrs.GetItemState(GetWhich(SID_ATTR_BORDER_DIAG_BLTR)) != SfxItemState::UNKNOWN;
+
+ if(pBoxInfo->IsDist())
+ {
+ SetFieldUnit(*m_xLeftMF, eFUnit);
+ SetFieldUnit(*m_xRightMF, eFUnit);
+ SetFieldUnit(*m_xTopMF, eFUnit);
+ SetFieldUnit(*m_xBottomMF, eFUnit);
+ m_xSynchronizeCB->connect_toggled(LINK(this, SvxBorderTabPage, SyncHdl_Impl));
+ m_xLeftMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xRightMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xTopMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ m_xBottomMF->connect_value_changed(LINK(this, SvxBorderTabPage, ModifyDistanceHdl_Impl));
+ }
+ else
+ {
+ m_xSpacingFrame->hide();
+ }
+ bIsDontCare = !pBoxInfo->IsValid( SvxBoxInfoItemValidFlags::DISABLE );
+ }
+ if(!mbUseMarginItem && eFUnit == FieldUnit::MM && MapUnit::MapTwip == rCoreAttrs.GetPool()->GetMetric( GetWhich( SID_ATTR_BORDER_INNER ) ))
+ {
+ //#i91548# changing the number of decimal digits changes the minimum values, too
+ lcl_SetDecimalDigitsTo1(*m_xLeftMF);
+ lcl_SetDecimalDigitsTo1(*m_xRightMF);
+ lcl_SetDecimalDigitsTo1(*m_xTopMF);
+ lcl_SetDecimalDigitsTo1(*m_xBottomMF);
+ lcl_SetDecimalDigitsTo1(*m_xEdShadowSize);
+ }
+
+ FrameSelFlags nFlags = FrameSelFlags::Outer;
+ if( mbHorEnabled )
+ nFlags |= FrameSelFlags::InnerHorizontal;
+ if( mbVerEnabled )
+ nFlags |= FrameSelFlags::InnerVertical;
+ if( mbTLBREnabled )
+ nFlags |= FrameSelFlags::DiagonalTLBR;
+ if( mbBLTREnabled )
+ nFlags |= FrameSelFlags::DiagonalBLTR;
+ if( bIsDontCare )
+ nFlags |= FrameSelFlags::DontCare;
+ m_aFrameSel.Initialize( nFlags );
+
+ m_aFrameSel.SetSelectHdl(LINK(this, SvxBorderTabPage, LinesChanged_Impl));
+ m_xLbLineStyle->SetSelectHdl( LINK( this, SvxBorderTabPage, SelStyleHdl_Impl ) );
+ m_xLbLineColor->SetSelectHdl( LINK( this, SvxBorderTabPage, SelColHdl_Impl ) );
+ m_xLineWidthMF->connect_value_changed( LINK( this, SvxBorderTabPage, ModifyWidthHdl_Impl ) );
+ m_xWndPresets->SetSelectHdl( LINK( this, SvxBorderTabPage, SelPreHdl_Impl ) );
+ m_xWndShadows->SetSelectHdl( LINK( this, SvxBorderTabPage, SelSdwHdl_Impl ) );
+
+ FillValueSets();
+ FillLineListBox_Impl();
+
+ // connections
+ if (rCoreAttrs.HasItem(GetWhich(SID_ATTR_PARA_GRABBAG), &pItem))
+ {
+ const SfxGrabBagItem* pGrabBag = static_cast<const SfxGrabBagItem*>(pItem);
+ auto it = pGrabBag->GetGrabBag().find("DialogUseCharAttr");
+ if (it != pGrabBag->GetGrabBag().end())
+ {
+ bool bDialogUseCharAttr = false;
+ it->second >>= bDialogUseCharAttr;
+ if (bDialogUseCharAttr)
+ {
+ mnShadowSlot = SID_ATTR_CHAR_SHADOW;
+ mnBoxSlot = SID_ATTR_CHAR_BOX;
+ }
+ }
+ }
+
+ bool bSupportsShadow = !SfxItemPool::IsSlot(GetWhich(mnShadowSlot));
+ if( bSupportsShadow )
+ m_xShadowControls.reset(new ShadowControlsWrapper(*m_xWndShadows, *m_xEdShadowSize, *m_xLbShadowColor));
+ else
+ HideShadowControls();
+
+ if (mbUseMarginItem)
+ m_xMarginControls.reset(new MarginControlsWrapper(*m_xLeftMF, *m_xRightMF, *m_xTopMF, *m_xBottomMF));
+
+ // checkbox "Merge with next paragraph" only visible for Writer dialog format.paragraph
+ m_xMergeWithNextCB->hide();
+ // checkbox "Merge adjacent line styles" only visible for Writer dialog format.table
+ m_xMergeAdjacentBordersCB->hide();
+
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ if (pDocSh)
+ {
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bIsCalcDoc = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ if( bIsCalcDoc )
+ {
+ m_xRemoveAdjcentCellBordersCB->connect_toggled(LINK(this, SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl));
+ m_xRemoveAdjcentCellBordersCB->show();
+ m_xRemoveAdjcentCellBordersCB->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveAdjcentCellBordersCB->hide();
+ m_xRemoveAdjcentCellBordersFT->hide();
+ }
+}
+
+SvxBorderTabPage::~SvxBorderTabPage()
+{
+ m_xLbShadowColor.reset();
+ m_xWndShadowsWin.reset();
+ m_xWndShadows.reset();
+ m_xLbLineColor.reset();
+ m_xLbLineStyle.reset();
+ m_xFrameSelWin.reset();
+ m_xWndPresetsWin.reset();
+ m_xWndPresets.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBorderTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBorderTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBorderTabPage::ResetFrameLine_Impl( svx::FrameBorderType eBorder, const SvxBorderLine* pCoreLine, bool bValid )
+{
+ if( m_aFrameSel.IsBorderEnabled( eBorder ) )
+ {
+ if( bValid )
+ m_aFrameSel.ShowBorder( eBorder, pCoreLine );
+ else
+ m_aFrameSel.SetBorderDontCare( eBorder );
+ }
+}
+
+bool SvxBorderTabPage::IsBorderLineStyleAllowed( SvxBorderLineStyle nStyle ) const
+{
+ if (maUsedBorderStyles.empty())
+ // All border styles are allowed.
+ return true;
+
+ return maUsedBorderStyles.count(nStyle) > 0;
+}
+
+void SvxBorderTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_TLBR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::TLBR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::TLBR);
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR))
+ {
+ sal_uInt16 nBorderDiagId = pPool->GetWhich(SID_ATTR_BORDER_DIAG_BLTR);
+ if (const SvxLineItem* pLineItem = static_cast<const SvxLineItem*>(rSet->GetItem(nBorderDiagId)))
+ m_aFrameSel.ShowBorder(svx::FrameBorderType::BLTR, pLineItem->GetLine());
+ else
+ m_aFrameSel.SetBorderDontCare(svx::FrameBorderType::BLTR);
+ }
+
+ if (m_xShadowControls)
+ {
+ sal_uInt16 nShadowId = pPool->GetWhich(mnShadowSlot);
+ const SfxPoolItem* pItem = rSet->GetItem(nShadowId);
+ if (pItem)
+ m_xShadowControls->SetControlValue(*static_cast<const SvxShadowItem*>(pItem));
+ else
+ m_xShadowControls->SetControlDontKnow();
+ }
+
+ if (m_xMarginControls)
+ {
+ sal_uInt16 nAlignMarginId = pPool->GetWhich(SID_ATTR_ALIGN_MARGIN);
+ const SfxPoolItem* pItem = rSet->GetItem(nAlignMarginId);
+ if (pItem)
+ m_xMarginControls->SetControlValue(*static_cast<const SvxMarginItem*>(pItem));
+ else
+ m_xMarginControls->SetControlDontKnow();
+ }
+
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ const SfxBoolItem *pMergeAdjacentBorders = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeAdjacentBordersId));
+ if (!pMergeAdjacentBorders)
+ m_xMergeAdjacentBordersCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeAdjacentBordersCB->set_active(pMergeAdjacentBorders->GetValue());
+ m_xMergeAdjacentBordersCB->save_state();
+
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ const SfxBoolItem *pMergeWithNext = static_cast<const SfxBoolItem*>(rSet->GetItem(nMergeWithNextId));
+ if (!pMergeWithNext)
+ m_xMergeWithNextCB->set_state(TRISTATE_INDET);
+ else
+ m_xMergeWithNextCB->set_active(pMergeWithNext->GetValue());
+ m_xMergeWithNextCB->save_state();
+
+ const SvxBoxItem* pBoxItem;
+ const SvxBoxInfoItem* pBoxInfoItem;
+ sal_uInt16 nWhichBox = GetWhich(mnBoxSlot);
+ MapUnit eCoreUnit;
+
+ pBoxItem = static_cast<const SvxBoxItem*>(GetItem( *rSet, mnBoxSlot ));
+
+ pBoxInfoItem = GetItem( *rSet, SID_ATTR_BORDER_INNER, false );
+
+ eCoreUnit = pPool->GetMetric( nWhichBox );
+
+ if ( pBoxItem && pBoxInfoItem ) // -> Don't Care
+ {
+ ResetFrameLine_Impl( svx::FrameBorderType::Left, pBoxItem->GetLeft(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::LEFT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Right, pBoxItem->GetRight(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::RIGHT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Top, pBoxItem->GetTop(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::TOP ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Bottom, pBoxItem->GetBottom(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::BOTTOM ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Vertical, pBoxInfoItem->GetVert(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::VERT ) );
+ ResetFrameLine_Impl( svx::FrameBorderType::Horizontal, pBoxInfoItem->GetHori(), pBoxInfoItem->IsValid( SvxBoxInfoItemValidFlags::HORI ) );
+
+
+ // distance inside
+
+ if( !mbUseMarginItem )
+ {
+ if (m_xLeftMF->get_visible())
+ {
+ SetMetricValue(*m_xLeftMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xRightMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xTopMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+ SetMetricValue(*m_xBottomMF, pBoxInfoItem->GetDefDist(), eCoreUnit);
+
+ nMinValue = m_xLeftMF->get_value(FieldUnit::NONE);
+
+ if ( pBoxInfoItem->IsDist() )
+ {
+ if( rSet->GetItemState( nWhichBox ) >= SfxItemState::DEFAULT )
+ {
+ bool bIsAnyBorderVisible = m_aFrameSel.IsAnyBorderVisible();
+ if( !bIsAnyBorderVisible || !pBoxInfoItem->IsMinDist() )
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ long nLeftDist = pBoxItem->GetDistance( SvxBoxItemLine::LEFT);
+ SetMetricValue(*m_xLeftMF, nLeftDist, eCoreUnit);
+ long nRightDist = pBoxItem->GetDistance( SvxBoxItemLine::RIGHT);
+ SetMetricValue(*m_xRightMF, nRightDist, eCoreUnit);
+ long nTopDist = pBoxItem->GetDistance( SvxBoxItemLine::TOP);
+ SetMetricValue( *m_xTopMF, nTopDist, eCoreUnit );
+ long nBottomDist = pBoxItem->GetDistance( SvxBoxItemLine::BOTTOM);
+ SetMetricValue( *m_xBottomMF, nBottomDist, eCoreUnit );
+
+ // if the distance is set with no active border line
+ // or it is null with an active border line
+ // no automatic changes should be made
+ const long nDefDist = bIsAnyBorderVisible ? pBoxInfoItem->GetDefDist() : 0;
+ bool bDiffDist = (nDefDist != nLeftDist ||
+ nDefDist != nRightDist ||
+ nDefDist != nTopDist ||
+ nDefDist != nBottomDist);
+ if ((pBoxItem->GetSmallestDistance() || bIsAnyBorderVisible) && bDiffDist )
+ {
+ mbLeftModified = true;
+ mbRightModified = true;
+ mbTopModified = true;
+ mbBottomModified = true;
+ }
+ }
+ else
+ {
+ // #106224# different margins -> do not fill the edits
+ m_xLeftMF->set_text( OUString() );
+ m_xRightMF->set_text( OUString() );
+ m_xTopMF->set_text( OUString() );
+ m_xBottomMF->set_text( OUString() );
+ }
+ }
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ }
+ }
+ }
+ else
+ {
+ // avoid ResetFrameLine-calls:
+ m_aFrameSel.HideAllBorders();
+ }
+
+ if( !m_aFrameSel.IsAnyBorderVisible() )
+ m_aFrameSel.DeselectAllBorders();
+
+ // depict line (color) in controllers if unambiguous:
+
+ {
+ // Do all visible lines show the same line widths?
+ long nWidth;
+ SvxBorderLineStyle nStyle;
+ bool bWidthEq = m_aFrameSel.GetVisibleWidth( nWidth, nStyle );
+ if( bWidthEq )
+ {
+ // Determine the width first as some styles can be missing depending on it
+ sal_Int64 nWidthPt = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ sal_Int64( nWidth ), m_xLineWidthMF->get_digits(),
+ MapUnit::MapTwip, FieldUnit::POINT ));
+ m_xLineWidthMF->set_value(nWidthPt, FieldUnit::POINT);
+ m_xLbLineStyle->SetWidth(nWidth);
+
+ // then set the style
+ m_xLbLineStyle->SelectEntry( nStyle );
+ }
+ else
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // Do all visible lines show the same line color?
+ Color aColor;
+ bool bColorEq = m_aFrameSel.GetVisibleColor( aColor );
+ if( !bColorEq )
+ aColor = COL_BLACK;
+
+ m_xLbLineColor->SelectEntry(aColor);
+ auto nTextColor = Application::GetSettings().GetStyleSettings().GetWindowTextColor();
+ m_xLbLineStyle->SetColor(nTextColor);
+
+ // Select all visible lines, if they are all equal.
+ if( bWidthEq && bColorEq )
+ m_aFrameSel.SelectAllVisibleBorders();
+
+ // set the current style and color (caches style in control even if nothing is selected)
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1 ;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+
+ m_xWndPresets->SetNoSelection();
+
+ // - no line - should not be selected
+
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ {
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ }
+
+ const SfxPoolItem* pItem;
+ SfxObjectShell* pShell;
+ if(SfxItemState::SET == rSet->GetItemState(SID_HTML_MODE, false, &pItem) ||
+ ( nullptr != (pShell = SfxObjectShell::Current()) &&
+ nullptr != (pItem = pShell->GetItem(SID_HTML_MODE))))
+ {
+ sal_uInt16 nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ // there are no shadows in Html-mode and only complete borders
+ m_xShadowFrame->set_sensitive(false);
+
+ if( !(nSWMode & SwBorderModes::TABLE) )
+ {
+ m_xUserDefFT->set_sensitive(false);
+ m_xFrameSelWin->set_sensitive(false);
+ m_xWndPresets->RemoveItem(3);
+ m_xWndPresets->RemoveItem(4);
+ m_xWndPresets->RemoveItem(5);
+ }
+ }
+ }
+
+ LinesChanged_Impl( nullptr );
+ if (m_xLeftMF->get_value(FieldUnit::NONE) == m_xRightMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xBottomMF->get_value(FieldUnit::NONE) &&
+ m_xTopMF->get_value(FieldUnit::NONE) == m_xLeftMF->get_value(FieldUnit::NONE))
+ {
+ mbSync = true;
+ }
+ else
+ mbSync = false;
+ m_xSynchronizeCB->set_active(mbSync);
+
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjcentCellBordersCB->set_active(false);
+ m_xRemoveAdjcentCellBordersCB->set_sensitive(false);
+}
+
+void SvxBorderTabPage::ChangesApplied()
+{
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+ m_xMergeWithNextCB->save_state();
+ m_xMergeAdjacentBordersCB->save_state();
+}
+
+DeactivateRC SvxBorderTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBorderTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bAttrsChanged = false;
+
+ SfxItemPool* pPool = rCoreAttrs->GetPool();
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::TLBR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::TLBR) != svx::FrameBorderState::DontCare)
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_TLBR)));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::TLBR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+
+ if (m_aFrameSel.IsBorderEnabled(svx::FrameBorderType::BLTR) &&
+ m_aFrameSel.GetFrameBorderState(svx::FrameBorderType::BLTR) != svx::FrameBorderState::DontCare)
+ {
+ SvxLineItem aLineItem(*static_cast<const SvxLineItem*>(GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_DIAG_BLTR)));
+ aLineItem.SetLine(m_aFrameSel.GetFrameBorderStyle(svx::FrameBorderType::BLTR));
+ rCoreAttrs->Put(aLineItem);
+ bAttrsChanged = true;
+ }
+
+ if (m_xShadowControls && m_xShadowControls->get_value_changed_from_saved())
+ {
+ const SvxShadowItem& rOldShadowItem = *static_cast<const SvxShadowItem*>(GetOldItem(*rCoreAttrs, mnShadowSlot));
+ rCoreAttrs->Put(m_xShadowControls->GetControlValue(rOldShadowItem));
+ bAttrsChanged = true;
+ }
+
+ if (m_xMarginControls && m_xMarginControls->get_value_changed_from_saved())
+ {
+ const SvxMarginItem& rOldMarginItem = *static_cast<const SvxMarginItem*>(GetOldItem(*rCoreAttrs, SID_ATTR_ALIGN_MARGIN));
+ rCoreAttrs->Put(m_xMarginControls->GetControlValue(rOldMarginItem));
+ bAttrsChanged = true;
+ }
+
+ if (m_xMergeAdjacentBordersCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeAdjacentBordersCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeAdjacentBordersId = pPool->GetWhich(SID_SW_COLLAPSING_BORDERS);
+ rCoreAttrs->ClearItem(nMergeAdjacentBordersId);
+ }
+ else
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(GetOldItem(*rCoreAttrs, SID_SW_COLLAPSING_BORDERS)->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ bAttrsChanged = true;
+ }
+
+ if (m_xMergeWithNextCB->get_state_changed_from_saved())
+ {
+ auto nState = m_xMergeWithNextCB->get_state();
+ if (nState == TRISTATE_INDET)
+ {
+ sal_uInt16 nMergeWithNextId = pPool->GetWhich(SID_ATTR_BORDER_CONNECT);
+ rCoreAttrs->ClearItem(nMergeWithNextId);
+ }
+ else
+ {
+ std::unique_ptr<SfxBoolItem> xNewItem(static_cast<SfxBoolItem*>(GetOldItem(*rCoreAttrs, SID_ATTR_BORDER_CONNECT)->Clone()));
+ xNewItem->SetValue(static_cast<bool>(nState));
+ rCoreAttrs->Put(std::move(xNewItem));
+ }
+ bAttrsChanged = true;
+ }
+
+ bool bPut = true;
+ sal_uInt16 nBoxWhich = GetWhich( mnBoxSlot );
+ sal_uInt16 nBoxInfoWhich = pPool->GetWhich( SID_ATTR_BORDER_INNER, false );
+ const SfxItemSet& rOldSet = GetItemSet();
+ SvxBoxItem aBoxItem ( nBoxWhich );
+ SvxBoxInfoItem aBoxInfoItem ( nBoxInfoWhich );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( *rCoreAttrs, mnBoxSlot ));
+
+ MapUnit eCoreUnit = rOldSet.GetPool()->GetMetric( nBoxWhich );
+
+
+ // outer border:
+
+ std::pair<svx::FrameBorderType,SvxBoxItemLine> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxItemLine::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxItemLine::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxItemLine::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxItemLine::RIGHT },
+ };
+
+ for (std::pair<svx::FrameBorderType,SvxBoxItemLine> const & i : eTypes1)
+ aBoxItem.SetLine( m_aFrameSel.GetFrameBorderStyle( i.first ), i.second );
+
+
+ aBoxItem.SetRemoveAdjacentCellBorder( mbRemoveAdjacentCellBorders );
+ // border hor/ver and TableFlag
+
+ std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> eTypes2[] = {
+ { svx::FrameBorderType::Horizontal,SvxBoxInfoItemLine::HORI },
+ { svx::FrameBorderType::Vertical,SvxBoxInfoItemLine::VERT }
+ };
+ for (std::pair<svx::FrameBorderType,SvxBoxInfoItemLine> const & j : eTypes2)
+ aBoxInfoItem.SetLine( m_aFrameSel.GetFrameBorderStyle( j.first ), j.second );
+
+ aBoxInfoItem.EnableHor( mbHorEnabled );
+ aBoxInfoItem.EnableVer( mbVerEnabled );
+
+
+ // inner distance
+
+ if (m_xLeftMF->get_visible())
+ {
+ // #i40405# enable distance controls for next dialog call
+ aBoxInfoItem.SetDist( true );
+
+ if( !mbUseMarginItem )
+ {
+ // #106224# all edits empty: do nothing
+ if( !m_xLeftMF->get_text().isEmpty() || !m_xRightMF->get_text().isEmpty() ||
+ !m_xTopMF->get_text().isEmpty() || !m_xBottomMF->get_text().isEmpty() )
+ {
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER );
+ if (
+ !pOldBoxItem ||
+ m_xLeftMF->get_value_changed_from_saved() ||
+ m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() ||
+ m_xBottomMF->get_value_changed_from_saved() ||
+ nMinValue == m_xLeftMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xRightMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xTopMF->get_value(FieldUnit::NONE) ||
+ nMinValue == m_xBottomMF->get_value(FieldUnit::NONE) ||
+ (pOldBoxInfoItem && !pOldBoxInfoItem->IsValid(SvxBoxInfoItemValidFlags::DISTANCE))
+ )
+ {
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xLeftMF, eCoreUnit )), SvxBoxItemLine::LEFT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xRightMF, eCoreUnit )), SvxBoxItemLine::RIGHT );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xTopMF, eCoreUnit )), SvxBoxItemLine::TOP );
+ aBoxItem.SetDistance( static_cast<sal_uInt16>(GetCoreValue(*m_xBottomMF, eCoreUnit )), SvxBoxItemLine::BOTTOM);
+ }
+ else
+ {
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::LEFT ), SvxBoxItemLine::LEFT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::RIGHT), SvxBoxItemLine::RIGHT);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::TOP ), SvxBoxItemLine::TOP);
+ aBoxItem.SetDistance(pOldBoxItem->GetDistance(SvxBoxItemLine::BOTTOM), SvxBoxItemLine::BOTTOM);
+ }
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::DISTANCE );
+ }
+ }
+ }
+
+
+ // note Don't Care Status in the Info-Item:
+
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::TOP, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Top ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::BOTTOM, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Bottom ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::LEFT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Left ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::RIGHT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Right ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::HORI, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Horizontal ) != svx::FrameBorderState::DontCare );
+ aBoxInfoItem.SetValid( SvxBoxInfoItemValidFlags::VERT, m_aFrameSel.GetFrameBorderState( svx::FrameBorderType::Vertical ) != svx::FrameBorderState::DontCare );
+
+
+ // Put or Clear of the border?
+
+ bPut = true;
+
+ if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxWhich, false ))
+ {
+ bPut = aBoxItem != static_cast<const SvxBoxItem&>(rOldSet.Get(nBoxWhich));
+ }
+ if( SfxItemState::DEFAULT == rOldSet.GetItemState( nBoxInfoWhich, false ) )
+ {
+ const SvxBoxInfoItem& rOldBoxInfo = static_cast<const SvxBoxInfoItem&>(
+ rOldSet.Get(nBoxInfoWhich));
+
+ aBoxInfoItem.SetMinDist( rOldBoxInfo.IsMinDist() );
+ aBoxInfoItem.SetDefDist( rOldBoxInfo.GetDefDist() );
+ bPut |= (aBoxInfoItem != rOldBoxInfo );
+ }
+
+ if ( bPut )
+ {
+ if ( !pOldBoxItem || *pOldBoxItem != aBoxItem )
+ {
+ rCoreAttrs->Put( aBoxItem );
+ bAttrsChanged = true;
+ }
+ const SfxPoolItem* pOld = GetOldItem( *rCoreAttrs, SID_ATTR_BORDER_INNER, false );
+
+ if ( !pOld || *static_cast<const SvxBoxInfoItem*>(pOld) != aBoxInfoItem )
+ {
+ rCoreAttrs->Put( aBoxInfoItem );
+ bAttrsChanged = true;
+ }
+ }
+ else
+ {
+ rCoreAttrs->ClearItem( nBoxWhich );
+ rCoreAttrs->ClearItem( nBoxInfoWhich );
+ }
+
+ return bAttrsChanged;
+}
+
+void SvxBorderTabPage::HideShadowControls()
+{
+ m_xShadowFrame->hide();
+}
+
+#define IID_PRE_CELL_NONE 1
+#define IID_PRE_CELL_ALL 2
+#define IID_PRE_CELL_LR 3
+#define IID_PRE_CELL_TB 4
+#define IID_PRE_CELL_L 5
+#define IID_PRE_CELL_DIAG 6
+#define IID_PRE_HOR_NONE 7
+#define IID_PRE_HOR_OUTER 8
+#define IID_PRE_HOR_HOR 9
+#define IID_PRE_HOR_ALL 10
+#define IID_PRE_HOR_OUTER2 11
+#define IID_PRE_VER_NONE 12
+#define IID_PRE_VER_OUTER 13
+#define IID_PRE_VER_VER 14
+#define IID_PRE_VER_ALL 15
+#define IID_PRE_VER_OUTER2 16
+#define IID_PRE_TABLE_NONE 17
+#define IID_PRE_TABLE_OUTER 18
+#define IID_PRE_TABLE_OUTERH 19
+#define IID_PRE_TABLE_ALL 20
+#define IID_PRE_TABLE_OUTER2 21
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelPreHdl_Impl, ValueSet*, void)
+{
+ const svx::FrameBorderState SHOW = svx::FrameBorderState::Show;
+ const svx::FrameBorderState HIDE = svx::FrameBorderState::Hide;
+ const svx::FrameBorderState DONT = svx::FrameBorderState::DontCare;
+
+ static const svx::FrameBorderState ppeStates[][ svx::FRAMEBORDERTYPE_COUNT ] =
+ { /* Left Right Top Bot Hor Ver TLBR BLTR */
+/* ---------------------+--------------------------------------------------- */
+/* IID_PRE_CELL_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_LR */ { SHOW, SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_TB */ { HIDE, HIDE, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_L */ { SHOW, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_CELL_DIAG */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, SHOW, SHOW },
+/* IID_PRE_HOR_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_HOR */ { HIDE, HIDE, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_HOR_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_VER_VER */ { SHOW, SHOW, HIDE, HIDE, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_ALL */ { SHOW, SHOW, SHOW, SHOW, HIDE, SHOW, HIDE, HIDE },
+/* IID_PRE_VER_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, HIDE, DONT, HIDE, HIDE },
+/* IID_PRE_TABLE_NONE */ { HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER */ { SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTERH */ { SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE, HIDE },
+/* IID_PRE_TABLE_ALL */ { SHOW, SHOW, SHOW, SHOW, SHOW, SHOW, HIDE, HIDE },
+/* IID_PRE_TABLE_OUTER2 */ { SHOW, SHOW, SHOW, SHOW, DONT, DONT, HIDE, HIDE }
+ };
+
+ // first hide and deselect all frame borders
+ m_aFrameSel.HideAllBorders();
+ m_aFrameSel.DeselectAllBorders();
+
+ // Using image ID to find correct line in table above.
+ sal_uInt16 nLine = GetPresetImageId( m_xWndPresets->GetSelectedItemId() ) - 1;
+
+ // Apply all styles from the table
+ for( int nBorder = 0; nBorder < svx::FRAMEBORDERTYPE_COUNT; ++nBorder )
+ {
+ svx::FrameBorderType eBorder = svx::GetFrameBorderTypeFromIndex( nBorder );
+ switch( ppeStates[ nLine ][ nBorder ] )
+ {
+ case SHOW: m_aFrameSel.SelectBorder( eBorder ); break;
+ case HIDE: /* nothing to do */ break;
+ case DONT: m_aFrameSel.SetBorderDontCare( eBorder ); break;
+ }
+ }
+
+ // Show all lines that have been selected above
+ if( m_aFrameSel.IsAnyBorderSelected() )
+ {
+ // any visible style, but "no-line" in line list box? -> use hair-line
+ if (m_xLbLineStyle->GetSelectEntryStyle() == SvxBorderLineStyle::NONE)
+ m_xLbLineStyle->SelectEntry(SvxBorderLineStyle::SOLID);
+
+ // set current style to all previously selected lines
+ SelStyleHdl_Impl(*m_xLbLineStyle);
+ SelColHdl_Impl(*m_xLbLineColor);
+ }
+
+ // Presets ValueSet does not show a selection (used as push buttons).
+ m_xWndPresets->SetNoSelection();
+
+ LinesChanged_Impl( nullptr );
+ UpdateRemoveAdjCellBorderCB( nLine + 1 );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelSdwHdl_Impl, ValueSet*, void)
+{
+ bool bEnable = m_xWndShadows->GetSelectedItemId() > 1;
+ m_xFtShadowSize->set_sensitive(bEnable);
+ m_xEdShadowSize->set_sensitive(bEnable);
+ m_xFtShadowColor->set_sensitive(bEnable);
+ m_xLbShadowColor->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxBorderTabPage, SelColHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color aColor = rColorBox.GetSelectEntryColor();
+ m_aFrameSel.SetColorToSelection(aColor);
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, ModifyWidthHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nVal,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT, MapUnit::MapTwip ));
+ m_xLbLineStyle->SetWidth( nVal );
+
+ m_aFrameSel.SetStyleToSelection( nVal,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+IMPL_LINK_NOARG(SvxBorderTabPage, SelStyleHdl_Impl, SvtLineListBox&, void)
+{
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(
+ nVal,
+ m_xLineWidthMF->get_digits(),
+ FieldUnit::POINT, MapUnit::MapTwip ));
+ m_aFrameSel.SetStyleToSelection ( nVal,
+ m_xLbLineStyle->GetSelectEntryStyle() );
+}
+
+// ValueSet handling
+sal_uInt16 SvxBorderTabPage::GetPresetImageId( sal_uInt16 nValueSetIdx ) const
+{
+ // table with all sets of predefined border styles
+ static const sal_uInt16 ppnImgIds[][ SVX_BORDER_PRESET_COUNT ] =
+ {
+ // simple cell without diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_L },
+ // simple cell with diagonal frame borders
+ { IID_PRE_CELL_NONE, IID_PRE_CELL_ALL, IID_PRE_CELL_LR, IID_PRE_CELL_TB, IID_PRE_CELL_DIAG },
+ // with horizontal inner frame border
+ { IID_PRE_HOR_NONE, IID_PRE_HOR_OUTER, IID_PRE_HOR_HOR, IID_PRE_HOR_ALL, IID_PRE_HOR_OUTER2 },
+ // with vertical inner frame border
+ { IID_PRE_VER_NONE, IID_PRE_VER_OUTER, IID_PRE_VER_VER, IID_PRE_VER_ALL, IID_PRE_VER_OUTER2 },
+ // with horizontal and vertical inner frame borders
+ { IID_PRE_TABLE_NONE, IID_PRE_TABLE_OUTER, IID_PRE_TABLE_OUTERH, IID_PRE_TABLE_ALL, IID_PRE_TABLE_OUTER2 }
+ };
+
+ // find correct set of presets
+ int nLine = 0;
+ if( !mbHorEnabled && !mbVerEnabled )
+ nLine = (mbTLBREnabled || mbBLTREnabled) ? 1 : 0;
+ else if( mbHorEnabled && !mbVerEnabled )
+ nLine = 2;
+ else if( !mbHorEnabled && mbVerEnabled )
+ nLine = 3;
+ else
+ nLine = 4;
+
+ DBG_ASSERT( (1 <= nValueSetIdx) && (nValueSetIdx <= SVX_BORDER_PRESET_COUNT),
+ "SvxBorderTabPage::GetPresetImageId - wrong index" );
+ return ppnImgIds[ nLine ][ nValueSetIdx - 1 ];
+}
+
+const char* SvxBorderTabPage::GetPresetStringId( sal_uInt16 nValueSetIdx ) const
+{
+ // string resource IDs for each image (in order of the IID_PRE_* image IDs)
+ static const char* pnStrIds[] =
+ {
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_PARA_PRESET_ALL,
+ RID_SVXSTR_PARA_PRESET_LEFTRIGHT,
+ RID_SVXSTR_PARA_PRESET_TOPBOTTOM,
+ RID_SVXSTR_PARA_PRESET_ONLYLEFT,
+ RID_SVXSTR_PARA_PRESET_DIAGONAL,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_HOR_PRESET_ONLYHOR,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_VER_PRESET_ONLYVER,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER,
+
+ RID_SVXSTR_TABLE_PRESET_NONE,
+ RID_SVXSTR_TABLE_PRESET_ONLYOUTER,
+ RID_SVXSTR_TABLE_PRESET_OUTERHORI,
+ RID_SVXSTR_TABLE_PRESET_OUTERALL,
+ RID_SVXSTR_TABLE_PRESET_OUTERINNER
+ };
+ return pnStrIds[ GetPresetImageId( nValueSetIdx ) - 1 ];
+}
+
+void SvxBorderTabPage::FillPresetVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndPresets->SetStyle( m_xWndPresets->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndPresets->SetColCount( SVX_BORDER_PRESET_COUNT );
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= SVX_BORDER_PRESET_COUNT; ++nVSIdx )
+ {
+ m_xWndPresets->InsertItem( nVSIdx );
+ m_xWndPresets->SetItemImage(nVSIdx, m_aBorderImgVec[GetPresetImageId(nVSIdx) - 1]);
+ m_xWndPresets->SetItemText( nVSIdx, CuiResId( GetPresetStringId( nVSIdx ) ) );
+ }
+
+ // show the control
+ m_xWndPresets->SetNoSelection();
+ m_xWndPresets->SetOptimalSize();
+ m_xWndPresets->Show();
+}
+
+void SvxBorderTabPage::FillShadowVS()
+{
+ // basic initialization of the ValueSet
+ m_xWndShadows->SetStyle( m_xWndShadows->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER );
+ m_xWndShadows->SetColCount( SVX_BORDER_SHADOW_COUNT );
+
+ // string resource IDs for each image
+ static const char* pnStrIds[ SVX_BORDER_SHADOW_COUNT ] =
+ { RID_SVXSTR_SHADOW_STYLE_NONE, RID_SVXSTR_SHADOW_STYLE_BOTTOMRIGHT, RID_SVXSTR_SHADOW_STYLE_TOPRIGHT, RID_SVXSTR_SHADOW_STYLE_BOTTOMLEFT, RID_SVXSTR_SHADOW_STYLE_TOPLEFT };
+
+ // insert images and help texts
+ for( sal_uInt16 nVSIdx = 1; nVSIdx <= SVX_BORDER_SHADOW_COUNT; ++nVSIdx )
+ {
+ m_xWndShadows->InsertItem( nVSIdx );
+ m_xWndShadows->SetItemImage(nVSIdx, m_aShadowImgVec[nVSIdx-1]);
+ m_xWndShadows->SetItemText( nVSIdx, CuiResId( pnStrIds[ nVSIdx - 1 ] ) );
+ }
+
+ // show the control
+ m_xWndShadows->SelectItem( 1 );
+ m_xWndShadows->SetOptimalSize();
+ m_xWndShadows->Show();
+}
+
+
+void SvxBorderTabPage::FillValueSets()
+{
+ FillPresetVS();
+ FillShadowVS();
+}
+
+
+static Color lcl_mediumColor( Color aMain, Color /*aDefault*/ )
+{
+ return SvxBorderLine::threeDMediumColor( aMain );
+}
+
+void SvxBorderTabPage::FillLineListBox_Impl()
+{
+ using namespace ::com::sun::star::table::BorderLineStyle;
+
+ static struct {
+ SvxBorderLineStyle mnStyle;
+ long mnMinWidth;
+ SvtLineListBox::ColorFunc mpColor1Fn;
+ SvtLineListBox::ColorFunc mpColor2Fn;
+ SvtLineListBox::ColorDistFunc mpColorDistFn;
+ } const aLines[] = {
+ // Simple lines
+ { SvxBorderLineStyle::SOLID, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOTTED, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASHED, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::FINE_DASHED, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DASH_DOT_DOT, 0, &sameColor, &sameColor, &sameDistColor },
+
+ // Double lines
+ { SvxBorderLineStyle::DOUBLE, 10, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::DOUBLE_THIN, 10, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_SMALLGAP, 20, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_MEDIUMGAP, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THINTHICK_LARGEGAP, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_SMALLGAP, 20, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_MEDIUMGAP, 0, &sameColor, &sameColor, &sameDistColor },
+ { SvxBorderLineStyle::THICKTHIN_LARGEGAP, 0, &sameColor, &sameColor, &sameDistColor },
+
+ { SvxBorderLineStyle::EMBOSSED, 15, &SvxBorderLine::threeDLightColor, &SvxBorderLine::threeDDarkColor, &lcl_mediumColor },
+ { SvxBorderLineStyle::ENGRAVED, 15, &SvxBorderLine::threeDDarkColor, &SvxBorderLine::threeDLightColor, &lcl_mediumColor },
+
+ { SvxBorderLineStyle::OUTSET, 10, &SvxBorderLine::lightColor, &SvxBorderLine::darkColor, &sameDistColor },
+ { SvxBorderLineStyle::INSET, 10, &SvxBorderLine::darkColor, &SvxBorderLine::lightColor, &sameDistColor }
+ };
+
+ m_xLbLineStyle->SetSourceUnit( FieldUnit::TWIP );
+
+ for (size_t i = 0; i < SAL_N_ELEMENTS(aLines); ++i)
+ {
+ if (!IsBorderLineStyleAllowed(aLines[i].mnStyle))
+ continue;
+
+ m_xLbLineStyle->InsertEntry(
+ SvxBorderLine::getWidthImpl(aLines[i].mnStyle), aLines[i].mnStyle,
+ aLines[i].mnMinWidth, aLines[i].mpColor1Fn, aLines[i].mpColor2Fn, aLines[i].mpColorDistFn);
+ }
+
+ sal_Int64 nVal = m_xLineWidthMF->get_value(FieldUnit::NONE);
+ nVal = static_cast<sal_Int64>(vcl::ConvertDoubleValue(nVal, m_xLineWidthMF->get_digits(),
+ m_xLineWidthMF->get_unit(), MapUnit::MapTwip));
+ m_xLbLineStyle->SetWidth( nVal );
+}
+
+
+IMPL_LINK_NOARG(SvxBorderTabPage, LinesChanged_Impl, LinkParamNone*, void)
+{
+ if (!mbUseMarginItem && m_xLeftMF->get_visible())
+ {
+ bool bLineSet = m_aFrameSel.IsAnyBorderVisible();
+ bool bSpaceModified = mbLeftModified ||
+ mbRightModified ||
+ mbTopModified ||
+ mbBottomModified;
+
+ if(bLineSet)
+ {
+ if(!bSpaceModified)
+ {
+ m_xLeftMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xRightMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xTopMF->set_value(nMinValue, FieldUnit::NONE);
+ m_xBottomMF->set_value(nMinValue, FieldUnit::NONE);
+ }
+ }
+ else
+ {
+ m_xLeftMF->set_min(0, FieldUnit::NONE);
+ m_xRightMF->set_min(0, FieldUnit::NONE);
+ m_xTopMF->set_min(0, FieldUnit::NONE);
+ m_xBottomMF->set_min(0, FieldUnit::NONE);
+ }
+ // for tables everything is allowed
+ SvxBoxInfoItemValidFlags nValid = SvxBoxInfoItemValidFlags::TOP|SvxBoxInfoItemValidFlags::BOTTOM|SvxBoxInfoItemValidFlags::LEFT|SvxBoxInfoItemValidFlags::RIGHT;
+
+ m_xLeftFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomFT->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xLeftMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::LEFT) );
+ m_xRightMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::RIGHT) );
+ m_xTopMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::TOP) );
+ m_xBottomMF->set_sensitive( bool(nValid & SvxBoxInfoItemValidFlags::BOTTOM) );
+ m_xSynchronizeCB->set_sensitive(m_xRightMF->get_sensitive() || m_xTopMF->get_sensitive() ||
+ m_xBottomMF->get_sensitive() || m_xLeftMF->get_sensitive());
+ }
+ UpdateRemoveAdjCellBorderCB( SAL_MAX_UINT16 );
+}
+
+
+IMPL_LINK( SvxBorderTabPage, ModifyDistanceHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ if (&rField == m_xLeftMF.get())
+ mbLeftModified = true;
+ else if (&rField == m_xRightMF.get())
+ mbRightModified = true;
+ else if (&rField == m_xTopMF.get())
+ mbTopModified = true;
+ else if (&rField == m_xBottomMF.get())
+ mbBottomModified = true;
+
+ if (mbSync)
+ {
+ const auto nVal = rField.get_value(FieldUnit::NONE);
+ if (&rField != m_xLeftMF.get())
+ m_xLeftMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xRightMF.get())
+ m_xRightMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xTopMF.get())
+ m_xTopMF->set_value(nVal, FieldUnit::NONE);
+ if (&rField != m_xBottomMF.get())
+ m_xBottomMF->set_value(nVal, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK( SvxBorderTabPage, SyncHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ mbSync = rBox.get_active();
+}
+
+IMPL_LINK( SvxBorderTabPage, RemoveAdjacentCellBorderHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ mbRemoveAdjacentCellBorders = rBox.get_active();
+}
+
+void SvxBorderTabPage::UpdateRemoveAdjCellBorderCB( sal_uInt16 nPreset )
+{
+ if( !bIsCalcDoc )
+ return;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SvxBoxInfoItem* pOldBoxInfoItem = GetOldItem( rOldSet, SID_ATTR_BORDER_INNER );
+ const SvxBoxItem* pOldBoxItem = static_cast<const SvxBoxItem*>(GetOldItem( rOldSet, mnBoxSlot ));
+ if( !pOldBoxInfoItem || !pOldBoxItem )
+ return;
+ std::pair<svx::FrameBorderType, SvxBoxInfoItemValidFlags> eTypes1[] = {
+ { svx::FrameBorderType::Top,SvxBoxInfoItemValidFlags::TOP },
+ { svx::FrameBorderType::Bottom,SvxBoxInfoItemValidFlags::BOTTOM },
+ { svx::FrameBorderType::Left,SvxBoxInfoItemValidFlags::LEFT },
+ { svx::FrameBorderType::Right,SvxBoxInfoItemValidFlags::RIGHT },
+ };
+ SvxBoxItemLine const eTypes2[] = {
+ SvxBoxItemLine::TOP,
+ SvxBoxItemLine::BOTTOM,
+ SvxBoxItemLine::LEFT,
+ SvxBoxItemLine::RIGHT,
+ };
+
+ // Check if current selection involves deletion of at least one border
+ bool bBorderDeletionReq = false;
+ for ( size_t i=0; i < SAL_N_ELEMENTS( eTypes1 ); ++i )
+ {
+ if( pOldBoxItem->GetLine( eTypes2[i] ) || !( pOldBoxInfoItem->IsValid( eTypes1[i].second ) ) )
+ {
+ if( m_aFrameSel.GetFrameBorderState( eTypes1[i].first ) == svx::FrameBorderState::Hide )
+ {
+ bBorderDeletionReq = true;
+ break;
+ }
+ }
+ }
+
+ if( !bBorderDeletionReq && ( nPreset == IID_PRE_CELL_NONE || nPreset == IID_PRE_TABLE_NONE ) )
+ bBorderDeletionReq = true;
+
+ m_xRemoveAdjcentCellBordersCB->set_sensitive(bBorderDeletionReq);
+
+ if( !bBorderDeletionReq )
+ {
+ mbRemoveAdjacentCellBorders = false;
+ m_xRemoveAdjcentCellBordersCB->set_active(false);
+ }
+}
+
+void SvxBorderTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pSWModeItem = aSet.GetItem<SfxUInt16Item>(SID_SWMODE_TYPE, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pSWModeItem)
+ {
+ nSWMode = static_cast<SwBorderModes>(pSWModeItem->GetValue());
+ // #i43593#
+ // show checkbox <m_xMergeWithNextCB> for format.paragraph
+ if ( nSWMode == SwBorderModes::PARA )
+ {
+ m_xMergeWithNextCB->show();
+ m_xPropertiesFrame->show();
+ }
+ // show checkbox <m_xMergeAdjacentBordersCB> for format.paragraph
+ else if ( nSWMode == SwBorderModes::TABLE )
+ {
+ m_xMergeAdjacentBordersCB->show();
+ m_xPropertiesFrame->show();
+ }
+ }
+ if (pFlagItem)
+ if ( ( pFlagItem->GetValue() & SVX_HIDESHADOWCTL ) == SVX_HIDESHADOWCTL )
+ HideShadowControls();
+}
+
+void SvxBorderTabPage::SetTableMode()
+{
+ nSWMode = SwBorderModes::TABLE;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.cxx b/cui/source/tabpages/chardlg.cxx
new file mode 100644
index 000000000..077a62aec
--- /dev/null
+++ b/cui/source/tabpages/chardlg.cxx
@@ -0,0 +1,3261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/idle.hxx>
+#include <svtools/ctrltool.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+#include <svl/languageoptions.hxx>
+#include <chardlg.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/escapementitem.hxx>
+#include <editeng/wrlmitem.hxx>
+#include <editeng/cmapitem.hxx>
+#include <editeng/kernitem.hxx>
+#include <editeng/blinkitem.hxx>
+#include <editeng/flstitem.hxx>
+#include <editeng/autokernitem.hxx>
+#include <editeng/colritem.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <cui/cuicharmap.hxx>
+#include "chardlg.h"
+#include <editeng/emphasismarkitem.hxx>
+#include <editeng/charreliefitem.hxx>
+#include <editeng/twolinesitem.hxx>
+#include <editeng/charhiddenitem.hxx>
+#include <editeng/charscaleitem.hxx>
+#include <editeng/charrotateitem.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <strings.hrc>
+#include <twolines.hrc>
+#include <svl/intitem.hxx>
+#include <svx/flagsdef.hxx>
+#include <FontFeaturesDialog.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+using namespace ::com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxCharNamePage::pNameRanges[] =
+{
+ SID_ATTR_CHAR_FONT,
+ SID_ATTR_CHAR_WEIGHT,
+ SID_ATTR_CHAR_FONTHEIGHT,
+ SID_ATTR_CHAR_FONTHEIGHT,
+ SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_LANGUAGE,
+ SID_ATTR_CHAR_LANGUAGE,
+ SID_ATTR_CHAR_CJK_FONT,
+ SID_ATTR_CHAR_CJK_WEIGHT,
+ SID_ATTR_CHAR_CTL_FONT,
+ SID_ATTR_CHAR_CTL_WEIGHT,
+ 0
+};
+
+const sal_uInt16 SvxCharEffectsPage::pEffectsRanges[] =
+{
+ SID_ATTR_CHAR_SHADOWED,
+ SID_ATTR_CHAR_UNDERLINE,
+ SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_COLOR,
+ SID_ATTR_CHAR_CASEMAP,
+ SID_ATTR_CHAR_CASEMAP,
+ SID_ATTR_FLASH,
+ SID_ATTR_FLASH,
+ SID_ATTR_CHAR_EMPHASISMARK,
+ SID_ATTR_CHAR_EMPHASISMARK,
+ SID_ATTR_CHAR_RELIEF,
+ SID_ATTR_CHAR_RELIEF,
+ SID_ATTR_CHAR_HIDDEN,
+ SID_ATTR_CHAR_HIDDEN,
+ SID_ATTR_CHAR_OVERLINE,
+ SID_ATTR_CHAR_OVERLINE,
+ 0
+};
+
+const sal_uInt16 SvxCharPositionPage::pPositionRanges[] =
+{
+ SID_ATTR_CHAR_KERNING,
+ SID_ATTR_CHAR_KERNING,
+ SID_ATTR_CHAR_ESCAPEMENT,
+ SID_ATTR_CHAR_ESCAPEMENT,
+ SID_ATTR_CHAR_AUTOKERN,
+ SID_ATTR_CHAR_AUTOKERN,
+ SID_ATTR_CHAR_ROTATED,
+ SID_ATTR_CHAR_SCALEWIDTH,
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE,
+ 0
+};
+
+const sal_uInt16 SvxCharTwoLinesPage::pTwoLinesRanges[] =
+{
+ SID_ATTR_CHAR_TWO_LINES,
+ SID_ATTR_CHAR_TWO_LINES,
+ 0
+};
+
+// C-Function ------------------------------------------------------------
+
+static bool StateToAttr( TriState aState )
+{
+ return ( TRISTATE_TRUE == aState );
+}
+
+namespace
+{
+ void setPrevFontEscapement(SvxFont& _rFont,sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+ {
+ _rFont.SetPropr( nProp );
+ _rFont.SetProprRel( nEscProp );
+ _rFont.SetEscapement( nEsc );
+ }
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewFont()
+{
+ return m_aPreviewWin.GetFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCJKFont()
+{
+ return m_aPreviewWin.GetCJKFont();
+}
+
+inline SvxFont& SvxCharBasePage::GetPreviewCTLFont()
+{
+ return m_aPreviewWin.GetCTLFont();
+}
+
+SvxCharBasePage::SvxCharBasePage(weld::Container* pPage, weld::DialogController* pController, const OUString& rUIXMLDescription, const OString& rID, const SfxItemSet& rItemset)
+ : SfxTabPage(pPage, pController, rUIXMLDescription, rID, &rItemset)
+ , m_bPreviewBackgroundToCharacter( false )
+{
+}
+
+SvxCharBasePage::~SvxCharBasePage()
+{
+}
+
+void SvxCharBasePage::ActivatePage(const SfxItemSet& rSet)
+{
+ m_aPreviewWin.SetFromItemSet(rSet, m_bPreviewBackgroundToCharacter);
+}
+
+void SvxCharBasePage::SetPrevFontWidthScale( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (rSet.GetItemState(nWhich)>=SfxItemState::DEFAULT)
+ {
+ const SvxCharScaleWidthItem &rItem = static_cast<const SvxCharScaleWidthItem&>( rSet.Get( nWhich ) );
+ m_aPreviewWin.SetFontWidthScale(rItem.GetValue());
+ }
+}
+
+void SvxCharBasePage::SetPrevFontEscapement( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ setPrevFontEscapement(GetPreviewFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCJKFont(),nProp,nEscProp,nEsc);
+ setPrevFontEscapement(GetPreviewCTLFont(),nProp,nEscProp,nEsc);
+ m_aPreviewWin.Invalidate();
+}
+
+
+// SvxCharNamePage_Impl --------------------------------------------------
+
+struct SvxCharNamePage_Impl
+{
+ Idle m_aUpdateIdle;
+ OUString m_aNoStyleText;
+ std::unique_ptr<FontList> m_pFontList;
+ int m_nExtraEntryPos;
+ bool m_bInSearchMode;
+
+ SvxCharNamePage_Impl()
+ : m_nExtraEntryPos(std::numeric_limits<int>::max())
+ , m_bInSearchMode(false)
+
+ {
+ m_aUpdateIdle.SetPriority( TaskPriority::LOWEST );
+ }
+};
+
+// class SvxCharNamePage -------------------------------------------------
+
+SvxCharNamePage::SvxCharNamePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/charnamepage.ui", "CharNamePage", rInSet)
+ , m_pImpl(new SvxCharNamePage_Impl)
+ , m_xEastFrame(m_xBuilder->weld_widget("asian"))
+ , m_xEastFontNameFT(m_xBuilder->weld_label("eastfontnameft"))
+ , m_xEastFontNameLB(m_xBuilder->weld_combo_box("eastfontnamelb"))
+ , m_xEastFontStyleFT(m_xBuilder->weld_label("eaststyleft"))
+ , m_xEastFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("eaststylelb")))
+ , m_xEastFontSizeFT(m_xBuilder->weld_label("eastsizeft"))
+ , m_xEastFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("eastsizelb")))
+ , m_xEastFontLanguageFT(m_xBuilder->weld_label("eastlangft"))
+ , m_xEastFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("eastlanglb")))
+ , m_xEastFontTypeFT(m_xBuilder->weld_label("eastfontinfo"))
+ , m_xEastFontFeaturesButton(m_xBuilder->weld_button("east_features_button"))
+ , m_xCTLFrame(m_xBuilder->weld_widget("ctl"))
+ , m_xCTLFontNameFT(m_xBuilder->weld_label("ctlfontnameft"))
+ , m_xCTLFontNameLB(m_xBuilder->weld_combo_box("ctlfontnamelb"))
+ , m_xCTLFontStyleFT(m_xBuilder->weld_label("ctlstyleft"))
+ , m_xCTLFontStyleLB(new FontStyleBox(m_xBuilder->weld_combo_box("ctlstylelb")))
+ , m_xCTLFontSizeFT(m_xBuilder->weld_label("ctlsizeft"))
+ , m_xCTLFontSizeLB(new FontSizeBox(m_xBuilder->weld_combo_box("ctlsizelb")))
+ , m_xCTLFontLanguageFT(m_xBuilder->weld_label("ctllangft"))
+ , m_xCTLFontLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("ctllanglb")))
+ , m_xCTLFontTypeFT(m_xBuilder->weld_label("ctlfontinfo"))
+ , m_xCTLFontFeaturesButton(m_xBuilder->weld_button("ctl_features_button"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_pImpl->m_aNoStyleText = CuiResId( RID_SVXSTR_CHARNAME_NOSTYLE );
+
+ SvtLanguageOptions aLanguageOptions;
+ bool bShowCJK = aLanguageOptions.IsCJKFontEnabled();
+ bool bShowCTL = aLanguageOptions.IsCTLFontEnabled();
+ bool bShowNonWestern = bShowCJK || bShowCTL;
+
+ if (bShowNonWestern)
+ {
+ m_xWestFrame = m_xBuilder->weld_widget("western");
+ m_xWestFontNameFT = m_xBuilder->weld_label("westfontnameft-cjk");
+ m_xWestFontNameLB = m_xBuilder->weld_combo_box("westfontnamelb-cjk");
+ m_xWestFontStyleFT = m_xBuilder->weld_label("weststyleft-cjk");
+ m_xWestFontSizeFT = m_xBuilder->weld_label("westsizeft-cjk");
+
+ m_xWestFontStyleLB.reset(new FontStyleBox(m_xBuilder->weld_combo_box("weststylelb-cjk")));
+ m_xWestFontSizeLB.reset(new FontSizeBox(m_xBuilder->weld_combo_box("westsizelb-cjk")));
+
+ m_xWestFontLanguageFT = m_xBuilder->weld_label("westlangft-cjk");
+ m_xWestFontLanguageLB.reset(new SvxLanguageBox(m_xBuilder->weld_combo_box("westlanglb-cjk")));
+ m_xWestFontTypeFT = m_xBuilder->weld_label("westfontinfo-cjk");
+
+ m_xWestFontFeaturesButton = m_xBuilder->weld_button("west_features_button-cjk");
+ }
+ else
+ {
+ m_xWestFrame = m_xBuilder->weld_widget("simple");
+ m_xWestFontNameFT = m_xBuilder->weld_label("westfontnameft-nocjk");
+ m_xWestFontStyleFT = m_xBuilder->weld_label("weststyleft-nocjk");
+ m_xWestFontSizeFT = m_xBuilder->weld_label("westsizeft-nocjk");
+
+ m_xWestFontLanguageFT = m_xBuilder->weld_label("westlangft-nocjk");
+ m_xWestFontLanguageLB.reset(new SvxLanguageBox(m_xBuilder->weld_combo_box("westlanglb-nocjk")));
+ m_xWestFontTypeFT = m_xBuilder->weld_label("westfontinfo-nocjk");
+
+ m_xWestFontFeaturesButton = m_xBuilder->weld_button("west_features_button-nocjk");
+
+ std::unique_ptr<weld::EntryTreeView> xWestFontNameLB = m_xBuilder->weld_entry_tree_view("namegrid", "westfontname-nocjk", "westfontnamelb-nocjk");
+ std::unique_ptr<weld::EntryTreeView> xWestFontStyleLB = m_xBuilder->weld_entry_tree_view("stylegrid", "weststyle-nocjk", "weststylelb-nocjk");
+ std::unique_ptr<weld::EntryTreeView> xWestFontSizeLB = m_xBuilder->weld_entry_tree_view("sizegrid", "westsize-nocjk", "westsizelb-nocjk");
+
+ // 7 lines in the treeview
+ xWestFontNameLB->set_height_request_by_rows(7);
+ xWestFontStyleLB->set_height_request_by_rows(7);
+ xWestFontSizeLB->set_height_request_by_rows(7);
+
+ m_xWestFontNameLB = std::move(xWestFontNameLB);
+ m_xWestFontStyleLB.reset(new FontStyleBox(std::move(xWestFontStyleLB)));
+ m_xWestFontSizeLB.reset(new FontSizeBox(std::move(xWestFontSizeLB)));
+ }
+
+ //In MacOSX the standard dialogs name font-name, font-style as
+ //Family, Typeface
+ //In GNOME the standard dialogs name font-name, font-style as
+ //Family, Style
+ //In Windows the standard dialogs name font-name, font-style as
+ //Font, Style
+#ifdef _WIN32
+ OUString sFontFamilyString(CuiResId(RID_SVXSTR_CHARNAME_FONT));
+#else
+ OUString sFontFamilyString(CuiResId(RID_SVXSTR_CHARNAME_FAMILY));
+#endif
+ m_xWestFontNameFT->set_label(sFontFamilyString);
+ m_xEastFontNameFT->set_label(sFontFamilyString);
+ m_xCTLFontNameFT->set_label(sFontFamilyString);
+
+#ifdef MACOSX
+ OUString sFontStyleString(CuiResId(RID_SVXSTR_CHARNAME_TYPEFACE));
+#else
+ OUString sFontStyleString(CuiResId(RID_SVXSTR_CHARNAME_STYLE));
+#endif
+ m_xWestFontStyleFT->set_label(sFontStyleString);
+ m_xEastFontStyleFT->set_label(sFontStyleString);
+ m_xCTLFontStyleFT->set_label(sFontStyleString);
+
+ m_xWestFrame->show();
+ m_xEastFrame->set_visible(bShowCJK);
+ m_xCTLFrame->set_visible(bShowCTL);
+
+ m_xWestFontLanguageLB->SetLanguageList(SvxLanguageListFlags::WESTERN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+ m_xEastFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CJK, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+ m_xCTLFontLanguageLB->SetLanguageList(SvxLanguageListFlags::CTL, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+
+ Initialize();
+}
+
+SvxCharNamePage::~SvxCharNamePage()
+{
+ m_pImpl.reset();
+ m_xCTLFontStyleLB.reset();
+ m_xEastFontLanguageLB.reset();
+ m_xWestFontStyleLB.reset();
+ m_xCTLFontSizeLB.reset();
+ m_xEastFontSizeLB.reset();
+ m_xWestFontSizeLB.reset();
+ m_xWestFontLanguageLB.reset();
+ m_xPreviewWin.reset();
+ m_xCTLFontLanguageLB.reset();
+ m_xEastFontLanguageLB.reset();
+}
+
+void SvxCharNamePage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ Link<weld::ComboBox&,void> aLink = LINK(this, SvxCharNamePage, FontModifyComboBoxHdl_Impl);
+ m_xWestFontNameLB->connect_changed(aLink);
+ m_xWestFontStyleLB->connect_changed(aLink);
+ m_xWestFontSizeLB->connect_changed(aLink);
+ m_xWestFontLanguageLB->connect_changed(aLink);
+
+ m_xWestFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xEastFontNameLB->connect_changed(aLink);
+ m_xEastFontStyleLB->connect_changed(aLink);
+ m_xEastFontSizeLB->connect_changed(aLink);
+ m_xEastFontLanguageLB->connect_changed(aLink);
+ m_xEastFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_xCTLFontNameLB->connect_changed(aLink);
+ m_xCTLFontStyleLB->connect_changed(aLink);
+ m_xCTLFontSizeLB->connect_changed(aLink);
+ m_xCTLFontLanguageLB->connect_changed(aLink);
+ m_xCTLFontFeaturesButton->connect_clicked(LINK(this, SvxCharNamePage, FontFeatureButtonClicked));
+
+ m_pImpl->m_aUpdateIdle.SetInvokeHandler( LINK( this, SvxCharNamePage, UpdateHdl_Impl ) );
+}
+
+const FontList* SvxCharNamePage::GetFontList() const
+{
+ if ( !m_pImpl->m_pFontList )
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ /* #110771# SvxFontListItem::GetFontList can return NULL */
+ if ( pDocSh )
+ {
+ const SfxPoolItem* pItem = pDocSh->GetItem( SID_ATTR_CHAR_FONTLIST );
+ if ( pItem != nullptr )
+ {
+ DBG_ASSERT(nullptr != static_cast<const SvxFontListItem*>(pItem)->GetFontList(),
+ "Where is the font list?");
+ m_pImpl->m_pFontList = static_cast<const SvxFontListItem*>(pItem )->GetFontList()->Clone();
+ }
+ }
+ if(!m_pImpl->m_pFontList)
+ {
+ m_pImpl->m_pFontList.reset(new FontList( Application::GetDefaultDevice() ));
+ }
+ }
+
+ return m_pImpl->m_pFontList.get();
+}
+
+
+namespace
+{
+ FontMetric calcFontMetrics( SvxFont& _rFont,
+ SvxCharNamePage const * _pPage,
+ const weld::ComboBox* _pFontNameLB,
+ const FontStyleBox* _pFontStyleLB,
+ const FontSizeBox* _pFontSizeLB,
+ const SvxLanguageBox* _pLanguageLB,
+ const FontList* _pFontList,
+ sal_uInt16 _nFontWhich,
+ sal_uInt16 _nFontHeightWhich)
+ {
+ Size aSize = _rFont.GetFontSize();
+ aSize.setWidth( 0 );
+ FontMetric aFontMetrics;
+ OUString sFontName(_pFontNameLB->get_active_text());
+ bool bFontAvailable = _pFontList->IsAvailable( sFontName );
+ if (bFontAvailable || _pFontNameLB->get_value_changed_from_saved())
+ aFontMetrics = _pFontList->Get(sFontName, _pFontStyleLB->get_active_text());
+ else
+ {
+ //get the font from itemset
+ SfxItemState eState = _pPage->GetItemSet().GetItemState( _nFontWhich );
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxFontItem* pFontItem = static_cast<const SvxFontItem*>(&( _pPage->GetItemSet().Get( _nFontWhich ) ));
+ aFontMetrics.SetFamilyName(pFontItem->GetFamilyName());
+ aFontMetrics.SetStyleName(pFontItem->GetStyleName());
+ aFontMetrics.SetFamily(pFontItem->GetFamily());
+ aFontMetrics.SetPitch(pFontItem->GetPitch());
+ aFontMetrics.SetCharSet(pFontItem->GetCharSet());
+ }
+ }
+ if ( _pFontSizeLB->IsRelative() )
+ {
+ DBG_ASSERT( _pPage->GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem = static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nFontHeightWhich ));
+
+ // old value, scaled
+ long nHeight;
+ if ( _pFontSizeLB->IsPtRelative() )
+ nHeight = rOldItem.GetHeight() + PointToTwips( static_cast<long>(_pFontSizeLB->get_value() / 10) );
+ else
+ nHeight = static_cast<long>(rOldItem.GetHeight() * _pFontSizeLB->get_value() / 100);
+
+ // conversion twips for the example-window
+ aSize.setHeight(
+ ItemToControl( nHeight, _pPage->GetItemSet().GetPool()->GetMetric( _nFontHeightWhich ), FieldUnit::TWIP ) );
+ }
+ else if ( !_pFontSizeLB->get_active_text().isEmpty() )
+ aSize.setHeight( PointToTwips( static_cast<long>(_pFontSizeLB->get_value() / 10) ) );
+ else
+ aSize.setHeight( 200 ); // default 10pt
+ aFontMetrics.SetFontSize( aSize );
+
+ _rFont.SetLanguage(_pLanguageLB->get_active_id());
+
+ _rFont.SetFamily( aFontMetrics.GetFamilyType() );
+ _rFont.SetFamilyName( aFontMetrics.GetFamilyName() );
+ _rFont.SetStyleName( aFontMetrics.GetStyleName() );
+ _rFont.SetPitch( aFontMetrics.GetPitch() );
+ _rFont.SetCharSet( aFontMetrics.GetCharSet() );
+ _rFont.SetWeight( aFontMetrics.GetWeight() );
+ _rFont.SetItalic( aFontMetrics.GetItalic() );
+ _rFont.SetFontSize( aFontMetrics.GetFontSize() );
+
+ return aFontMetrics;
+ }
+}
+
+
+void SvxCharNamePage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ // Font
+ const FontList* pFontList = GetFontList();
+
+ FontMetric aWestFontMetric = calcFontMetrics(rFont, this, m_xWestFontNameLB.get(),
+ m_xWestFontStyleLB.get(), m_xWestFontSizeLB.get(), m_xWestFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_FONT),
+ GetWhich(SID_ATTR_CHAR_FONTHEIGHT));
+
+ m_xWestFontTypeFT->set_label(pFontList->GetFontMapText(aWestFontMetric));
+
+ FontMetric aEastFontMetric = calcFontMetrics(rCJKFont, this, m_xEastFontNameLB.get(),
+ m_xEastFontStyleLB.get(), m_xEastFontSizeLB.get(), m_xEastFontLanguageLB.get(),
+ pFontList, GetWhich(SID_ATTR_CHAR_CJK_FONT),
+ GetWhich(SID_ATTR_CHAR_CJK_FONTHEIGHT));
+
+ m_xEastFontTypeFT->set_label(pFontList->GetFontMapText(aEastFontMetric));
+
+ FontMetric aCTLFontMetric = calcFontMetrics(rCTLFont,
+ this, m_xCTLFontNameLB.get(), m_xCTLFontStyleLB.get(), m_xCTLFontSizeLB.get(),
+ m_xCTLFontLanguageLB.get(), pFontList, GetWhich(SID_ATTR_CHAR_CTL_FONT),
+ GetWhich(SID_ATTR_CHAR_CTL_FONTHEIGHT));
+
+ m_xCTLFontTypeFT->set_label(pFontList->GetFontMapText(aCTLFontMetric));
+
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharNamePage::FillStyleBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontStyleBox* pStyleBox = nullptr;
+ OUString sFontName;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xWestFontStyleLB.get();
+ sFontName = m_xWestFontNameLB->get_active_text();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xEastFontStyleLB.get();
+ sFontName = m_xEastFontStyleLB->get_active_text();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xCTLFontStyleLB.get();
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ pStyleBox->Fill(sFontName, pFontList);
+
+ if ( !m_pImpl->m_bInSearchMode )
+ return;
+
+ // additional entries for the search:
+ // "not bold" and "not italic"
+ OUString aEntry = m_pImpl->m_aNoStyleText;
+ const char sS[] = "%1";
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetBoldStr() );
+ m_pImpl->m_nExtraEntryPos = pStyleBox->get_count();
+ pStyleBox->append_text( aEntry );
+ aEntry = m_pImpl->m_aNoStyleText;
+ aEntry = aEntry.replaceFirst( sS, pFontList->GetItalicStr() );
+ pStyleBox->append_text(aEntry);
+}
+
+void SvxCharNamePage::FillSizeBox_Impl(const weld::Widget& rNameBox)
+{
+ const FontList* pFontList = GetFontList();
+ DBG_ASSERT( pFontList, "no fontlist" );
+
+ FontStyleBox* pStyleBox = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ OUString sFontName;
+
+ if (m_xWestFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ sFontName = m_xWestFontNameLB->get_active_text();
+ }
+ else if (m_xEastFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ sFontName = m_xEastFontNameLB->get_active_text();
+ }
+ else if (m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ sFontName = m_xCTLFontNameLB->get_active_text();
+ }
+ else
+ {
+ SAL_WARN( "cui.tabpages", "invalid font name box" );
+ return;
+ }
+
+ FontMetric _aFontMetric(pFontList->Get(sFontName, pStyleBox->get_active_text()));
+ pSizeBox->Fill( &_aFontMetric, pFontList );
+}
+
+namespace
+{
+ void FillFontNames(weld::ComboBox& rBox, const FontList& rList)
+ {
+ // insert fonts
+ sal_uInt16 nFontCount = rList.GetFontNameCount();
+ std::vector<weld::ComboBoxEntry> aVector;
+ aVector.reserve(nFontCount);
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = rList.GetFontName(i);
+ aVector.emplace_back(rFontMetric.GetFamilyName());
+ }
+ rBox.insert_vector(aVector, false);
+ }
+}
+
+void SvxCharNamePage::Reset_Impl( const SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ weld::ComboBox* pNameBox = nullptr;
+ weld::Label* pStyleLabel = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ weld::Label* pSizeLabel = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ weld::Label* pLangFT = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleLabel = m_xWestFontStyleFT.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeLabel = m_xWestFontSizeFT.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangFT = m_xWestFontLanguageFT.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_FONT );
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleLabel = m_xEastFontStyleFT.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeLabel = m_xEastFontSizeFT.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangFT = m_xEastFontLanguageFT.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONT );
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleLabel = m_xCTLFontStyleFT.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeLabel = m_xCTLFontSizeFT.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangFT = m_xCTLFontLanguageFT.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONT );
+ break;
+ }
+
+ const FontList* pFontList = GetFontList();
+ FillFontNames(*pNameBox, *pFontList);
+
+ const SvxFontItem* pFontItem = nullptr;
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ pFontItem = static_cast<const SvxFontItem*>(&( rSet.Get( nWhich ) ));
+ const OUString &rName = pFontItem->GetFamilyName();
+ int nIndex = pNameBox->find_text(rName);
+ pNameBox->set_active(nIndex);
+ // tdf#122992 if it didn't exist in the list, set the entry text to it anyway
+ if (nIndex == -1)
+ pNameBox->set_entry_text(rName);
+ }
+ else
+ {
+ pNameBox->set_active_text( OUString() );
+ }
+
+ FillStyleBox_Impl(*pNameBox);
+
+ bool bStyle = false;
+ bool bStyleAvailable = true;
+ FontItalic eItalic = ITALIC_NONE;
+ FontWeight eWeight = WEIGHT_NORMAL;
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_POSTURE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_POSTURE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_POSTURE ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxPostureItem& rItem = static_cast<const SvxPostureItem&>(rSet.Get( nWhich ));
+ eItalic = rItem.GetValue();
+ bStyle = true;
+ }
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_WEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_WEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_WEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxWeightItem& rItem = static_cast<const SvxWeightItem&>(rSet.Get( nWhich ));
+ eWeight = rItem.GetValue();
+ }
+ else
+ bStyle = false;
+ bStyleAvailable = bStyleAvailable && (eState >= SfxItemState::DONTCARE);
+
+ // currently chosen font
+ if ( bStyle && pFontItem )
+ {
+ FontMetric aFontMetric = pFontList->Get( pFontItem->GetFamilyName(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ else if ( !m_pImpl->m_bInSearchMode || !bStyle )
+ {
+ pStyleBox->set_active_text( OUString() );
+ }
+ else if ( bStyle )
+ {
+ FontMetric aFontMetric = pFontList->Get( OUString(), eWeight, eItalic );
+ pStyleBox->set_active_text( pFontList->GetStyleName( aFontMetric ) );
+ }
+ if (!bStyleAvailable)
+ {
+ pStyleBox->set_sensitive(false);
+ pStyleLabel->set_sensitive(false);
+ }
+
+ FillSizeBox_Impl(*pNameBox);
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_FONTHEIGHT ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ); break;
+ }
+ eState = rSet.GetItemState( nWhich );
+
+ if ( pSizeBox->IsRelativeMode() )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+
+ if( rItem.GetProp() != 100 || MapUnit::MapRelative != rItem.GetPropUnit() )
+ {
+ bool bPtRel = MapUnit::MapPoint == rItem.GetPropUnit();
+ pSizeBox->SetPtRelative( bPtRel );
+ pSizeBox->set_value( bPtRel ? static_cast<short>(rItem.GetProp()) * 10 : rItem.GetProp() );
+ }
+ else
+ {
+ pSizeBox->SetRelative(false);
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ }
+ else if ( eState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ const SvxFontHeightItem& rItem = static_cast<const SvxFontHeightItem&>(rSet.Get( nWhich ));
+ pSizeBox->set_value( CalcToPoint( rItem.GetHeight(), eUnit, 10 ) );
+ }
+ else
+ {
+ pSizeBox->set_active_or_entry_text(OUString());
+ if ( eState <= SfxItemState::READONLY )
+ {
+ pSizeBox->set_sensitive(false);
+ pSizeLabel->set_sensitive(false);
+ }
+ }
+
+ switch ( eLangGrp )
+ {
+ case Western : nWhich = GetWhich( SID_ATTR_CHAR_LANGUAGE ); break;
+ case Asian : nWhich = GetWhich( SID_ATTR_CHAR_CJK_LANGUAGE ); break;
+ case Ctl : nWhich = GetWhich( SID_ATTR_CHAR_CTL_LANGUAGE ); break;
+ }
+ pLangBox->set_active(-1);
+ eState = rSet.GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ pLangFT->hide();
+ pLangBox->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ pLangFT->set_sensitive(false);
+ pLangBox->set_sensitive(false);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxLanguageItem& rItem = static_cast<const SvxLanguageItem&>(rSet.Get( nWhich ));
+ LanguageType eLangType = rItem.GetValue();
+ DBG_ASSERT( eLangType != LANGUAGE_SYSTEM, "LANGUAGE_SYSTEM not allowed" );
+ if (eLangType != LANGUAGE_DONTKNOW)
+ pLangBox->set_active_id(eLangType);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ break;
+ }
+
+ OUString sMapText(pFontList->GetFontMapText(
+ pFontList->Get(pNameBox->get_active_text(), pStyleBox->get_active_text())));
+
+ switch (eLangGrp)
+ {
+ case Western:
+ m_xWestFontTypeFT->set_label(sMapText);
+ break;
+ case Asian:
+ m_xEastFontTypeFT->set_label(sMapText);
+ break;
+ case Ctl:
+ m_xCTLFontTypeFT->set_label(sMapText);
+ break;
+ }
+
+ // save these settings
+ pNameBox->save_value();
+ pStyleBox->save_value();
+ pSizeBox->save_value();
+ pLangBox->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet_Impl( SfxItemSet& rSet, LanguageGroup eLangGrp )
+{
+ bool bModified = false;
+
+ weld::ComboBox* pNameBox = nullptr;
+ FontStyleBox* pStyleBox = nullptr;
+ FontSizeBox* pSizeBox = nullptr;
+ SvxLanguageBox* pLangBox = nullptr;
+ sal_uInt16 nWhich = 0;
+ sal_uInt16 nSlot = 0;
+
+ switch ( eLangGrp )
+ {
+ case Western :
+ pNameBox = m_xWestFontNameLB.get();
+ pStyleBox = m_xWestFontStyleLB.get();
+ pSizeBox = m_xWestFontSizeLB.get();
+ pLangBox = m_xWestFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_FONT;
+ break;
+
+ case Asian :
+ pNameBox = m_xEastFontNameLB.get();
+ pStyleBox = m_xEastFontStyleLB.get();
+ pSizeBox = m_xEastFontSizeLB.get();
+ pLangBox = m_xEastFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CJK_FONT;
+ break;
+
+ case Ctl :
+ pNameBox = m_xCTLFontNameLB.get();
+ pStyleBox = m_xCTLFontStyleLB.get();
+ pSizeBox = m_xCTLFontSizeLB.get();
+ pLangBox = m_xCTLFontLanguageLB.get();
+ nSlot = SID_ATTR_CHAR_CTL_FONT;
+ break;
+ }
+
+ nWhich = GetWhich( nSlot );
+ const SfxPoolItem* pItem = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ const SfxPoolItem* pOld = nullptr;
+
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+
+ bool bChanged = true;
+ const OUString& rFontName = pNameBox->get_active_text();
+ const FontList* pFontList = GetFontList();
+ OUString aStyleBoxText = pStyleBox->get_active_text();
+ int nEntryPos = pStyleBox->find_text(aStyleBoxText);
+ if (nEntryPos >= m_pImpl->m_nExtraEntryPos)
+ aStyleBoxText.clear();
+ FontMetric aInfo( pFontList->Get( rFontName, aStyleBoxText ) );
+ SvxFontItem aFontItem( aInfo.GetFamilyType(), aInfo.GetFamilyName(), aInfo.GetStyleName(),
+ aInfo.GetPitch(), aInfo.GetCharSet(), nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxFontItem& rItem = *static_cast<const SvxFontItem*>(pOld);
+
+ if ( rItem.GetFamilyName() == aFontItem.GetFamilyName() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ bChanged = pNameBox->get_saved_value().isEmpty();
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxFontItem*>(pItem)->GetFamilyName() != aFontItem.GetFamilyName() )
+ bChanged = true;
+
+ if ( bChanged && !rFontName.isEmpty() )
+ {
+ rSet.Put( aFontItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.ClearItem( nWhich );
+
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_WEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_WEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_WEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontWeight eWeight = aInfo.GetWeight();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eWeight = WEIGHT_NORMAL;
+ SvxWeightItem aWeightItem( eWeight, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxWeightItem& rItem = *static_cast<const SvxWeightItem*>(pOld);
+
+ if ( rItem.GetValue() == aWeightItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetWeight() == WEIGHT_NORMAL && aInfo.GetItalic() != ITALIC_NONE )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxWeightItem*>(pItem)->GetValue() != aWeightItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == m_pImpl->m_nExtraEntryPos );
+
+ OUString aText( pStyleBox->get_active_text() ); // Tristate, then text empty
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aWeightItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_POSTURE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_POSTURE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_POSTURE; break;
+ }
+ nWhich = GetWhich( nSlot );
+ FontItalic eItalic = aInfo.GetItalic();
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ eItalic = ITALIC_NONE;
+ SvxPostureItem aPostureItem( eItalic, nWhich );
+ pOld = GetOldItem( rSet, nSlot );
+
+ if ( pOld )
+ {
+ const SvxPostureItem& rItem = *static_cast<const SvxPostureItem*>(pOld);
+
+ if ( rItem.GetValue() == aPostureItem.GetValue() )
+ bChanged = false;
+ }
+
+ if ( !bChanged )
+ {
+ bChanged = pStyleBox->get_saved_value().isEmpty();
+
+ if ( m_pImpl->m_bInSearchMode && bChanged &&
+ aInfo.GetItalic() == ITALIC_NONE && aInfo.GetWeight() != WEIGHT_NORMAL )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ static_cast<const SvxPostureItem*>(pItem)->GetValue() != aPostureItem.GetValue() )
+ bChanged = true;
+
+ if ( nEntryPos >= m_pImpl->m_nExtraEntryPos )
+ bChanged = ( nEntryPos == ( m_pImpl->m_nExtraEntryPos + 1 ) );
+
+ if ( bChanged && !aText.isEmpty() )
+ {
+ rSet.Put( aPostureItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ // FontSize
+ long nSize = pSizeBox->get_value();
+
+ if ( pSizeBox->get_active_text().isEmpty() ) // GetValue() returns the min-value
+ nSize = 0;
+ long nSavedSize = pSizeBox->get_saved_value();
+ const bool bRel = pSizeBox->IsRelative();
+
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_FONTHEIGHT; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_FONTHEIGHT; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_FONTHEIGHT; break;
+ }
+ nWhich = GetWhich( nSlot );
+ const SvxFontHeightItem* pOldHeight = static_cast<const SvxFontHeightItem*>(GetOldItem( rSet, nSlot ));
+ bChanged = ( nSize != nSavedSize );
+
+ if ( !bChanged && pExampleSet &&
+ pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET )
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ long nVal = CalcToUnit( fSize, rSet.GetPool()->GetMetric( nWhich ) );
+ if ( static_cast<const SvxFontHeightItem*>(pItem)->GetHeight() != static_cast<sal_uInt32>(nVal) )
+ bChanged = true;
+ }
+
+ if ( bChanged || !pOldHeight ||
+ bRel != ( MapUnit::MapRelative != pOldHeight->GetPropUnit() || 100 != pOldHeight->GetProp() ) )
+ {
+ MapUnit eUnit = rSet.GetPool()->GetMetric( nWhich );
+ if ( pSizeBox->IsRelative() )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No parent set" );
+ const SvxFontHeightItem& rOldItem =
+ static_cast<const SvxFontHeightItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ SvxFontHeightItem aHeight( 240, 100, nWhich );
+ if ( pSizeBox->IsPtRelative() )
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>( nSize / 10 ), MapUnit::MapPoint, eUnit );
+ else
+ aHeight.SetHeight( rOldItem.GetHeight(), static_cast<sal_uInt16>(nSize) );
+ rSet.Put( aHeight );
+ }
+ else
+ {
+ float fSize = static_cast<float>(nSize) / 10;
+ rSet.Put( SvxFontHeightItem( CalcToUnit( fSize, eUnit ), 100, nWhich ) );
+ }
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ bChanged = true;
+ switch ( eLangGrp )
+ {
+ case Western : nSlot = SID_ATTR_CHAR_LANGUAGE; break;
+ case Asian : nSlot = SID_ATTR_CHAR_CJK_LANGUAGE; break;
+ case Ctl : nSlot = SID_ATTR_CHAR_CTL_LANGUAGE; break;
+ }
+ nWhich = GetWhich( nSlot );
+ pOld = GetOldItem( rSet, nSlot );
+
+ // For language list boxes acting as ComboBox, check for, add and select an
+ // edited entry.
+ if (pLangBox == m_xWestFontLanguageLB.get())
+ {
+ switch (pLangBox->GetEditedAndValid())
+ {
+ case SvxLanguageBox::EditedAndValid::No:
+ ; // nothing to do
+ break;
+ case SvxLanguageBox::EditedAndValid::Valid:
+ {
+ const int nPos = pLangBox->SaveEditedAsEntry();
+ if (nPos != -1)
+ pLangBox->set_active(nPos);
+ }
+ break;
+ case SvxLanguageBox::EditedAndValid::Invalid:
+ pLangBox->set_active_id(pLangBox->get_saved_active_id());
+ break;
+ }
+ }
+
+ int nLangPos = pLangBox->get_active();
+ LanguageType eLangType = pLangBox->get_active_id();
+
+ if (pOld)
+ {
+ const SvxLanguageItem& rItem = *static_cast<const SvxLanguageItem*>(pOld);
+ if (nLangPos == -1 || eLangType == rItem.GetValue())
+ bChanged = false;
+ }
+
+ if (!bChanged)
+ bChanged = pLangBox->get_active_id_changed_from_saved();
+
+ if (bChanged && nLangPos != -1)
+ {
+ rSet.Put(SvxLanguageItem(eLangType, nWhich));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxCharNamePage, UpdateHdl_Impl, Timer *, void)
+{
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharNamePage, FontModifyComboBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ FontModifyHdl_Impl(rBox);
+}
+
+IMPL_LINK(SvxCharNamePage, FontFeatureButtonClicked, weld::Button&, rButton, void)
+{
+ OUString sFontName;
+ weld::ComboBox* pNameBox = nullptr;
+
+ if (&rButton == m_xWestFontFeaturesButton.get())
+ {
+ pNameBox = m_xWestFontNameLB.get();
+ sFontName = GetPreviewFont().GetFamilyName();
+ }
+ else if (&rButton == m_xEastFontFeaturesButton.get())
+ {
+ pNameBox = m_xEastFontNameLB.get();
+ sFontName = GetPreviewCJKFont().GetFamilyName();
+ }
+ else if (&rButton == m_xCTLFontFeaturesButton.get())
+ {
+ pNameBox = m_xCTLFontNameLB.get();
+ sFontName = GetPreviewCTLFont().GetFamilyName();
+ }
+
+ if (!sFontName.isEmpty() && pNameBox)
+ {
+ cui::FontFeaturesDialog aDialog(GetFrameWeld(), sFontName);
+ if (aDialog.run() == RET_OK)
+ {
+ pNameBox->set_entry_text(aDialog.getResultFontName());
+ UpdatePreview_Impl();
+ }
+ }
+}
+
+void SvxCharNamePage::FontModifyHdl_Impl(const weld::Widget& rNameBox)
+{
+ m_pImpl->m_aUpdateIdle.Start();
+
+ if (m_xWestFontNameLB.get() == &rNameBox || m_xEastFontNameLB.get() == &rNameBox || m_xCTLFontNameLB.get() == &rNameBox)
+ {
+ FillStyleBox_Impl(rNameBox);
+ FillSizeBox_Impl(rNameBox);
+ }
+}
+
+void SvxCharNamePage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage( rSet );
+
+ UpdatePreview_Impl(); // instead of asynchronous calling in ctor
+}
+
+DeactivateRC SvxCharNamePage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharNamePage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharNamePage>(pPage, pController, *rSet );
+}
+
+void SvxCharNamePage::Reset( const SfxItemSet* rSet )
+{
+ Reset_Impl( *rSet, Western );
+ Reset_Impl( *rSet, Asian );
+ Reset_Impl( *rSet, Ctl );
+
+ SetPrevFontWidthScale( *rSet );
+ UpdatePreview_Impl();
+}
+
+void SvxCharNamePage::ChangesApplied()
+{
+ m_xWestFontNameLB->save_value();
+ m_xWestFontStyleLB->save_value();
+ m_xWestFontSizeLB->save_value();
+ m_xWestFontLanguageLB->save_active_id();
+ m_xEastFontNameLB->save_value();
+ m_xEastFontStyleLB->save_value();
+ m_xEastFontSizeLB->save_value();
+ m_xEastFontLanguageLB->save_active_id();
+ m_xCTLFontNameLB->save_value();
+ m_xCTLFontStyleLB->save_value();
+ m_xCTLFontSizeLB->save_value();
+ m_xCTLFontLanguageLB->save_active_id();
+}
+
+bool SvxCharNamePage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = FillItemSet_Impl( *rSet, Western );
+ bModified |= FillItemSet_Impl( *rSet, Asian );
+ bModified |= FillItemSet_Impl( *rSet, Ctl );
+ return bModified;
+}
+
+void SvxCharNamePage::SetFontList( const SvxFontListItem& rItem )
+{
+ m_pImpl->m_pFontList = rItem.GetFontList()->Clone();
+}
+
+namespace
+{
+ void enableRelativeMode( SvxCharNamePage const * _pPage, FontSizeBox* _pFontSizeLB, sal_uInt16 _nHeightWhich )
+ {
+ _pFontSizeLB->EnableRelativeMode( 5, 995 ); // min 5%, max 995%, step 5
+
+ const SvxFontHeightItem& rHeightItem =
+ static_cast<const SvxFontHeightItem&>(_pPage->GetItemSet().GetParent()->Get( _nHeightWhich ));
+ MapUnit eUnit = _pPage->GetItemSet().GetPool()->GetMetric( _nHeightWhich );
+ short nCurHeight =
+ static_cast< short >( CalcToPoint( rHeightItem.GetHeight(), eUnit, 1 ) * 10 );
+
+ // based on the current height:
+ // - negative until minimum of 2 pt
+ // - positive until maximum of 999 pt
+ _pFontSizeLB->EnablePtRelativeMode( sal::static_int_cast< short >(-(nCurHeight - 20)), (9999 - nCurHeight) );
+ }
+}
+
+void SvxCharNamePage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no ParentSet!" );
+ enableRelativeMode(this,m_xWestFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_FONTHEIGHT ));
+ enableRelativeMode(this,m_xEastFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CJK_FONTHEIGHT ));
+ enableRelativeMode(this,m_xCTLFontSizeLB.get(),GetWhich( SID_ATTR_CHAR_CTL_FONTHEIGHT ));
+}
+
+void SvxCharNamePage::EnableSearchMode()
+{
+ m_pImpl->m_bInSearchMode = true;
+}
+
+void SvxCharNamePage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( DISABLE_LANGUAGE & nDisable )
+ {
+ if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->set_sensitive(false);
+ if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->set_sensitive(false);
+ if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->set_sensitive(false);
+ if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->set_sensitive(false);
+ if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->set_sensitive(false);
+ if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->set_sensitive(false);
+ }
+
+ if ( DISABLE_HIDE_LANGUAGE & nDisable )
+ {
+ if ( m_xWestFontLanguageFT ) m_xWestFontLanguageFT->hide();
+ if ( m_xWestFontLanguageLB ) m_xWestFontLanguageLB->hide();
+ if ( m_xEastFontLanguageFT ) m_xEastFontLanguageFT->hide();
+ if ( m_xEastFontLanguageLB ) m_xEastFontLanguageLB->hide();
+ if ( m_xCTLFontLanguageFT ) m_xCTLFontLanguageFT->hide();
+ if ( m_xCTLFontLanguageLB ) m_xCTLFontLanguageLB->hide();
+ }
+}
+
+void SvxCharNamePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxFontListItem* pFontListItem = aSet.GetItem<SvxFontListItem>(SID_ATTR_CHAR_FONTLIST, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ const SfxUInt16Item* pDisalbeItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ if (pFontListItem)
+ SetFontList(*pFontListItem);
+
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_RELATIVE_MODE ) == SVX_RELATIVE_MODE )
+ EnableRelativeMode();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+ if (pDisalbeItem)
+ DisableControls(pDisalbeItem->GetValue());
+}
+// class SvxCharEffectsPage ----------------------------------------------
+
+SvxCharEffectsPage::SvxCharEffectsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/effectspage.ui", "EffectsPage", rInSet)
+ , m_bOrigFontColor(false)
+ , m_bNewFontColor(false)
+ , m_bEnableNoneFontColor(false)
+ , m_bUnderlineColorDisabled(false)
+ , m_xFontColorFT(m_xBuilder->weld_label("fontcolorft"))
+ , m_xFontColorLB(new ColorListBox(m_xBuilder->weld_menu_button("fontcolorlb"), pController->getDialog()))
+ , m_xFontTransparencyFT(m_xBuilder->weld_label("fonttransparencyft"))
+ , m_xFontTransparencyMtr(
+ m_xBuilder->weld_metric_spin_button("fonttransparencymtr", FieldUnit::PERCENT))
+ , m_xEffectsFT(m_xBuilder->weld_label("effectsft"))
+ , m_xEffectsLB(m_xBuilder->weld_combo_box("effectslb"))
+ , m_xReliefFT(m_xBuilder->weld_label("reliefft"))
+ , m_xReliefLB(m_xBuilder->weld_combo_box("relieflb"))
+ , m_xOutlineBtn(m_xBuilder->weld_check_button("outlinecb"))
+ , m_xShadowBtn(m_xBuilder->weld_check_button("shadowcb"))
+ , m_xHiddenBtn(m_xBuilder->weld_check_button("hiddencb"))
+ , m_xOverlineLB(m_xBuilder->weld_combo_box("overlinelb"))
+ , m_xOverlineColorFT(m_xBuilder->weld_label("overlinecolorft"))
+ , m_xOverlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("overlinecolorlb"), pController->getDialog()))
+ , m_xStrikeoutLB(m_xBuilder->weld_combo_box("strikeoutlb"))
+ , m_xUnderlineLB(m_xBuilder->weld_combo_box("underlinelb"))
+ , m_xUnderlineColorFT(m_xBuilder->weld_label("underlinecolorft"))
+ , m_xUnderlineColorLB(new ColorListBox(m_xBuilder->weld_menu_button("underlinecolorlb"), pController->getDialog()))
+ , m_xIndividualWordsBtn(m_xBuilder->weld_check_button("individualwordscb"))
+ , m_xEmphasisFT(m_xBuilder->weld_label("emphasisft"))
+ , m_xEmphasisLB(m_xBuilder->weld_combo_box("emphasislb"))
+ , m_xPositionFT(m_xBuilder->weld_label("positionft"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xA11yWarningFT(m_xBuilder->weld_label("a11ywarning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xOverlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xUnderlineColorLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ Initialize();
+}
+
+void SvxCharEffectsPage::EnableNoneFontColor()
+{
+ m_xFontColorLB->SetSlotId(SID_ATTR_CHAR_COLOR, true);
+ m_bEnableNoneFontColor = true;
+}
+
+Color SvxCharEffectsPage::GetPreviewFontColor(const Color& rColor) const
+{
+ if (rColor == COL_AUTO)
+ return COL_BLACK;
+ if (m_bEnableNoneFontColor && rColor == COL_NONE_COLOR)
+ return COL_BLACK;
+ return rColor;
+}
+
+SvxCharEffectsPage::~SvxCharEffectsPage()
+{
+ m_xUnderlineColorLB.reset();
+ m_xOverlineColorLB.reset();
+ m_xFontTransparencyMtr.reset();
+ m_xFontColorLB.reset();
+}
+
+void SvxCharEffectsPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ // HTML-Mode
+ const SfxPoolItem* pItem;
+ SfxObjectShell* pShell;
+ if ( SfxItemState::SET == GetItemSet().GetItemState( SID_HTML_MODE, false, &pItem ) ||
+ ( nullptr != ( pShell = SfxObjectShell::Current() ) &&
+ nullptr != ( pItem = pShell->GetItem( SID_HTML_MODE ) ) ) )
+ {
+ m_nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ if ( ( m_nHtmlMode & HTMLMODE_ON ) == HTMLMODE_ON )
+ {
+ //!!! hide some controls please
+ }
+ }
+
+ m_xFontColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xFontTransparencyMtr->connect_value_changed(
+ LINK(this, SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl));
+
+ // handler
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxCharEffectsPage, SelectListBoxHdl_Impl );
+ m_xUnderlineLB->connect_changed( aLink );
+ m_xUnderlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xOverlineLB->connect_changed( aLink );
+ m_xOverlineColorLB->SetSelectHdl(LINK(this, SvxCharEffectsPage, ColorBoxSelectHdl_Impl));
+ m_xStrikeoutLB->connect_changed( aLink );
+ m_xEmphasisLB->connect_changed( aLink );
+ m_xPositionLB->connect_changed( aLink );
+ m_xEffectsLB->connect_changed( aLink );
+ m_xReliefLB->connect_changed( aLink );
+
+ m_xUnderlineLB->set_active( 0 );
+ m_xOverlineLB->set_active( 0 );
+ m_xStrikeoutLB->set_active( 0 );
+ m_xEmphasisLB->set_active( 0 );
+ m_xPositionLB->set_active( 0 );
+ SelectHdl_Impl(nullptr);
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ m_xEffectsLB->set_active( 0 );
+
+ m_xHiddenBtn->connect_toggled(LINK(this, SvxCharEffectsPage, HiddenBtnClickHdl));
+ m_xIndividualWordsBtn->connect_toggled(LINK(this, SvxCharEffectsPage, CbClickHdl_Impl));
+ m_xOutlineBtn->connect_toggled(LINK(this, SvxCharEffectsPage, OutlineBtnClickHdl));
+ m_xShadowBtn->connect_toggled(LINK(this, SvxCharEffectsPage, ShadowBtnClickHdl));
+
+ if ( !SvtLanguageOptions().IsAsianTypographyEnabled() )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ m_xPositionFT->hide();
+ m_xPositionLB->hide();
+ }
+
+ m_xA11yWarningFT->set_visible(officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get());
+}
+
+void SvxCharEffectsPage::UpdatePreview_Impl()
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const Color& rSelectedColor = m_xFontColorLB->GetSelectEntryColor();
+ rFont.SetColor(GetPreviewFontColor(rSelectedColor));
+ rCJKFont.SetColor(GetPreviewFontColor(rSelectedColor));
+ rCTLFont.SetColor(GetPreviewFontColor(rSelectedColor));
+
+ FontLineStyle eUnderline = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+ FontLineStyle eOverline = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+ FontStrikeout eStrikeout = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+ m_aPreviewWin.SetTextLineColor( m_xUnderlineColorLB->GetSelectEntryColor() );
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+ m_aPreviewWin.SetOverlineColor( m_xOverlineColorLB->GetSelectEntryColor() );
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ auto nEmphasis = m_xEmphasisLB->get_active();
+ if (nEmphasis != -1)
+ {
+ bool bUnder = (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32());
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nEmphasis);
+ eMark |= bUnder ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+ }
+
+ auto nRelief = m_xReliefLB->get_active();
+ if (nRelief != -1)
+ {
+ rFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCJKFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ rCTLFont.SetRelief( static_cast<FontRelief>(nRelief) );
+ }
+
+ rFont.SetOutline( StateToAttr( m_xOutlineBtn->get_state() ) );
+ rCJKFont.SetOutline( rFont.IsOutline() );
+ rCTLFont.SetOutline( rFont.IsOutline() );
+
+ rFont.SetShadow( StateToAttr( m_xShadowBtn->get_state() ) );
+ rCJKFont.SetShadow( rFont.IsShadow() );
+ rCTLFont.SetShadow( rFont.IsShadow() );
+
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ SvxCaseMap eCaps = static_cast<SvxCaseMap>(nCapsPos);
+ rFont.SetCaseMap( eCaps );
+ rCJKFont.SetCaseMap( eCaps );
+ // #i78474# small caps do not exist in CTL fonts
+ rCTLFont.SetCaseMap( eCaps == SvxCaseMap::SmallCaps ? SvxCaseMap::NotMapped : eCaps );
+ }
+
+ bool bWordLine = StateToAttr( m_xIndividualWordsBtn->get_state() );
+ rFont.SetWordLineMode( bWordLine );
+ rCJKFont.SetWordLineMode( bWordLine );
+ rCTLFont.SetWordLineMode( bWordLine );
+
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharEffectsPage::SetCaseMap_Impl( SvxCaseMap eCaseMap )
+{
+ if ( SvxCaseMap::End > eCaseMap )
+ m_xEffectsLB->set_active(
+ sal::static_int_cast< sal_Int32 >( eCaseMap ) );
+ else
+ {
+ // not mapped
+ m_xEffectsLB->set_active(-1);
+ }
+
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ResetColor_Impl( const SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ SfxItemState eState = rSet.GetItemState( nWhich );
+
+ m_bOrigFontColor = false;
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xFontColorFT->hide();
+ m_xFontColorLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xFontColorFT->set_sensitive(false);
+ m_xFontColorLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ //Related: tdf#106080 if there is no font color, then allow "none"
+ //as a color so the listbox can display that state.
+ EnableNoneFontColor();
+ m_xFontColorLB->SetNoSelection();
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ const SvxColorItem& rItem = static_cast<const SvxColorItem&>(rSet.Get( nWhich ));
+ Color aColor = rItem.GetValue();
+ rFont.SetColor(GetPreviewFontColor(aColor));
+ rCJKFont.SetColor(GetPreviewFontColor(aColor));
+ rCTLFont.SetColor(GetPreviewFontColor(aColor));
+
+ m_aPreviewWin.Invalidate();
+
+ Color aRGBColor = aColor;
+ if (aRGBColor.GetTransparency() && aColor != COL_AUTO)
+ {
+ aRGBColor.SetTransparency(0);
+ }
+ m_xFontColorLB->SelectEntry(aRGBColor);
+
+ if (m_xFontTransparencyMtr->get_visible() && aColor != COL_AUTO)
+ {
+ double fTransparency = aColor.GetTransparency() * 100.0 / 255;
+ m_xFontTransparencyMtr->set_value(basegfx::fround(fTransparency),
+ FieldUnit::PERCENT);
+ }
+
+ m_aOrigFontColor = aColor;
+ m_bOrigFontColor = true;
+ break;
+ }
+ }
+ m_bNewFontColor = false;
+}
+
+bool SvxCharEffectsPage::FillItemSetColor_Impl( SfxItemSet& rSet )
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_COLOR );
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ Color aSelectedColor;
+ bool bChanged = m_bNewFontColor;
+
+ if (bChanged)
+ {
+ aSelectedColor = m_xFontColorLB->GetSelectEntryColor();
+
+ if (m_xFontTransparencyMtr->get_value_changed_from_saved())
+ {
+ double fTransparency
+ = m_xFontTransparencyMtr->get_value(FieldUnit::PERCENT) * 255.0 / 100;
+ aSelectedColor.SetTransparency(static_cast<sal_uInt8>(basegfx::fround(fTransparency)));
+ }
+
+ if (m_bOrigFontColor)
+ bChanged = aSelectedColor != m_aOrigFontColor;
+ if (m_bEnableNoneFontColor && bChanged && aSelectedColor == COL_NONE_COLOR)
+ bChanged = false;
+ }
+
+ if (bChanged)
+ rSet.Put( SvxColorItem( aSelectedColor, nWhich ) );
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet.InvalidateItem(nWhich);
+
+ return bChanged;
+}
+
+IMPL_LINK( SvxCharEffectsPage, SelectListBoxHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ SelectHdl_Impl(&rBox);
+}
+
+void SvxCharEffectsPage::SelectHdl_Impl(const weld::ComboBox* pBox)
+{
+ if (m_xEmphasisLB.get() == pBox)
+ {
+ auto nEPos = m_xEmphasisLB->get_active();
+ bool bEnable = nEPos > 0;
+ m_xPositionFT->set_sensitive( bEnable );
+ m_xPositionLB->set_sensitive( bEnable );
+ }
+ else if (m_xReliefLB.get() == pBox)
+ {
+ bool bEnable = ( pBox->get_active() == 0 );
+ m_xOutlineBtn->set_sensitive( bEnable );
+ m_xShadowBtn->set_sensitive( bEnable );
+ }
+ else if (m_xPositionLB.get() != pBox)
+ {
+ bool bUEnable = false;
+ if (!m_bUnderlineColorDisabled)
+ {
+ auto nUPos = m_xUnderlineLB->get_active();
+ bUEnable = nUPos > 0;
+ m_xUnderlineColorFT->set_sensitive(bUEnable);
+ m_xUnderlineColorLB->set_sensitive(bUEnable);
+ }
+
+ auto nOPos = m_xOverlineLB->get_active();
+ bool bOEnable = nOPos > 0;
+ m_xOverlineColorFT->set_sensitive(bOEnable);
+ m_xOverlineColorLB->set_sensitive(bOEnable);
+
+ auto nSPos = m_xStrikeoutLB->get_active();
+ m_xIndividualWordsBtn->set_sensitive( bUEnable || bOEnable || nSPos > 0);
+ }
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, CbClickHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ m_aIndividualWordsState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ColorBoxSelectHdl_Impl, ColorListBox&, rBox, void)
+{
+ if (m_xFontColorLB.get() == &rBox)
+ m_bNewFontColor = true;
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharEffectsPage, ModifyFontTransparencyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_bNewFontColor = true;
+}
+
+DeactivateRC SvxCharEffectsPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharEffectsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxCharEffectsPage>( pPage, pController, *rSet );
+}
+
+void SvxCharEffectsPage::Reset( const SfxItemSet* rSet )
+{
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ bool bEnable = false;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ rFont.SetUnderline( LINESTYLE_NONE );
+ rCJKFont.SetUnderline( LINESTYLE_NONE );
+ rCTLFont.SetUnderline( LINESTYLE_NONE );
+
+ m_xUnderlineLB->set_active( 0 );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xUnderlineLB->set_active(-1);
+ else
+ {
+ const SvxUnderlineItem& rItem = static_cast<const SvxUnderlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eUnderline = rItem.GetValue();
+ rFont.SetUnderline( eUnderline );
+ rCJKFont.SetUnderline( eUnderline );
+ rCTLFont.SetUnderline( eUnderline );
+
+ if ( eUnderline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xUnderlineLB->find_id(OUString::number(eUnderline));
+ if (nPos != -1)
+ {
+ m_xUnderlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xUnderlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xUnderlineColorLB->SelectEntry(COL_AUTO);
+ m_xUnderlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ rFont.SetOverline( LINESTYLE_NONE );
+ rCJKFont.SetOverline( LINESTYLE_NONE );
+ rCTLFont.SetOverline( LINESTYLE_NONE );
+
+ m_xOverlineLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xOverlineLB->set_active(-1);
+ else
+ {
+ const SvxOverlineItem& rItem = static_cast<const SvxOverlineItem&>(rSet->Get( nWhich ));
+ FontLineStyle eOverline = rItem.GetValue();
+ rFont.SetOverline( eOverline );
+ rCJKFont.SetOverline( eOverline );
+ rCTLFont.SetOverline( eOverline );
+
+ if ( eOverline != LINESTYLE_NONE )
+ {
+ auto nPos = m_xOverlineLB->find_id(OUString::number(eOverline));
+ if (nPos != -1)
+ {
+ m_xOverlineLB->set_active(nPos);
+ bEnable = true;
+ }
+ Color aColor = rItem.GetColor();
+ m_xOverlineColorLB->SelectEntry(aColor);
+ }
+ else
+ {
+ m_xOverlineColorLB->SelectEntry(COL_AUTO);
+ m_xOverlineColorLB->set_sensitive(false);
+ }
+ }
+ }
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ rFont.SetStrikeout( STRIKEOUT_NONE );
+ rCJKFont.SetStrikeout( STRIKEOUT_NONE );
+ rCTLFont.SetStrikeout( STRIKEOUT_NONE );
+
+ m_xStrikeoutLB->set_active( 0 );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ if ( eState == SfxItemState::DONTCARE )
+ m_xStrikeoutLB->set_active(-1);
+ else
+ {
+ const SvxCrossedOutItem& rItem = static_cast<const SvxCrossedOutItem&>(rSet->Get( nWhich ));
+ FontStrikeout eStrikeout = rItem.GetValue();
+ rFont.SetStrikeout( eStrikeout );
+ rCJKFont.SetStrikeout( eStrikeout );
+ rCTLFont.SetStrikeout( eStrikeout );
+
+ if ( eStrikeout != STRIKEOUT_NONE )
+ {
+ auto nPos = m_xStrikeoutLB->find_id(OUString::number(eStrikeout));
+ if (nPos != -1)
+ {
+ m_xStrikeoutLB->set_active(nPos);
+ bEnable = true;
+ }
+ }
+ }
+ }
+
+ // WordLineMode
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aIndividualWordsState.bTriStateEnabled = true;
+ m_xIndividualWordsBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxWordLineModeItem& rItem = static_cast<const SvxWordLineModeItem&>(rSet->Get( nWhich ));
+ rFont.SetWordLineMode( rItem.GetValue() );
+ rCJKFont.SetWordLineMode( rItem.GetValue() );
+ rCTLFont.SetWordLineMode( rItem.GetValue() );
+
+ m_aIndividualWordsState.bTriStateEnabled = false;
+ m_xIndividualWordsBtn->set_active(rItem.GetValue());
+ m_xIndividualWordsBtn->set_sensitive(bEnable);
+ break;
+ }
+ }
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxEmphasisMarkItem& rItem = static_cast<const SvxEmphasisMarkItem&>(rSet->Get( nWhich ));
+ FontEmphasisMark eMark = rItem.GetEmphasisMark();
+ rFont.SetEmphasisMark( eMark );
+ rCJKFont.SetEmphasisMark( eMark );
+ rCTLFont.SetEmphasisMark( eMark );
+
+ m_xEmphasisLB->set_active( static_cast<sal_Int32>(FontEmphasisMark( eMark & FontEmphasisMark::Style )) );
+ eMark &= ~FontEmphasisMark::Style;
+ int nEntryData = ( eMark == FontEmphasisMark::PosAbove )
+ ? CHRDLG_POSITION_OVER
+ : ( eMark == FontEmphasisMark::PosBelow ) ? CHRDLG_POSITION_UNDER : 0;
+
+ auto nPos = m_xPositionLB->find_id(OUString::number(nEntryData));
+ if (nPos != -1)
+ m_xPositionLB->set_active(nPos);
+ }
+ else if ( eState == SfxItemState::DONTCARE )
+ m_xEmphasisLB->set_active(-1);
+ else if ( eState == SfxItemState::UNKNOWN )
+ {
+ m_xEmphasisFT->hide();
+ m_xEmphasisLB->hide();
+ }
+ else // SfxItemState::DISABLED or SfxItemState::READONLY
+ {
+ m_xEmphasisFT->set_sensitive(false);
+ m_xEmphasisLB->set_sensitive(false);
+ }
+
+ // the select handler for the underline/overline/strikeout list boxes
+ SelectHdl_Impl(m_xUnderlineLB.get());
+
+ // the select handler for the emphasis listbox
+ SelectHdl_Impl(m_xEmphasisLB.get());
+
+ // Effects
+ SvxCaseMap eCaseMap = SvxCaseMap::End;
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xEffectsFT->hide();
+ m_xEffectsLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xEffectsLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCaseMapItem& rItem = static_cast<const SvxCaseMapItem&>(rSet->Get( nWhich ));
+ eCaseMap = rItem.GetValue();
+ break;
+ }
+ }
+ SetCaseMap_Impl( eCaseMap );
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_xReliefFT->hide();
+ m_xReliefLB->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_xReliefFT->set_sensitive(false);
+ m_xReliefLB->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_xReliefLB->set_active(-1);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharReliefItem& rItem = static_cast<const SvxCharReliefItem&>(rSet->Get( nWhich ));
+ m_xReliefLB->set_active(static_cast<sal_Int32>(rItem.GetValue()));
+ SelectHdl_Impl(m_xReliefLB.get());
+ break;
+ }
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ eState = rSet->GetItemState( nWhich );
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aOutlineState.bTriStateEnabled = true;
+ m_xOutlineBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxContourItem& rItem = static_cast<const SvxContourItem&>(rSet->Get( nWhich ));
+ m_aOutlineState.bTriStateEnabled = false;
+ m_xOutlineBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aShadowState.bTriStateEnabled = true;
+ m_xShadowBtn->set_state( TRISTATE_INDET );
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxShadowedItem& rItem = static_cast<const SvxShadowedItem&>(rSet->Get( nWhich ));
+ m_aShadowState.bTriStateEnabled = false;
+ m_xShadowBtn->set_state( static_cast<TriState>(rItem.GetValue()) );
+ break;
+ }
+ }
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ eState = rSet->GetItemState( nWhich );
+
+ switch ( eState )
+ {
+ case SfxItemState::UNKNOWN:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->hide();
+ break;
+
+ case SfxItemState::DISABLED:
+ case SfxItemState::READONLY:
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_sensitive(false);
+ break;
+
+ case SfxItemState::DONTCARE:
+ m_aHiddenState.bTriStateEnabled = true;
+ m_xHiddenBtn->set_state(TRISTATE_INDET);
+ break;
+
+ case SfxItemState::DEFAULT:
+ case SfxItemState::SET:
+ {
+ const SvxCharHiddenItem& rItem = static_cast<const SvxCharHiddenItem&>(rSet->Get( nWhich ));
+ m_aHiddenState.bTriStateEnabled = false;
+ m_xHiddenBtn->set_state(static_cast<TriState>(rItem.GetValue()));
+ break;
+ }
+ }
+
+ SetPrevFontWidthScale( *rSet );
+ ResetColor_Impl( *rSet );
+
+ // preview update
+ m_aPreviewWin.Invalidate();
+
+ // save this settings
+ ChangesApplied();
+}
+
+IMPL_LINK(SvxCharEffectsPage, HiddenBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aHiddenState.ButtonToggled(rToggle);
+}
+
+IMPL_LINK(SvxCharEffectsPage, OutlineBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aOutlineState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharEffectsPage, ShadowBtnClickHdl, weld::ToggleButton&, rToggle, void)
+{
+ m_aShadowState.ButtonToggled(rToggle);
+ UpdatePreview_Impl();
+}
+
+void SvxCharEffectsPage::ChangesApplied()
+{
+ m_xUnderlineLB->save_value();
+ m_xOverlineLB->save_value();
+ m_xStrikeoutLB->save_value();
+ m_xIndividualWordsBtn->save_state();
+ m_xEmphasisLB->save_value();
+ m_xPositionLB->save_value();
+ m_xEffectsLB->save_value();
+ m_xReliefLB->save_value();
+ m_xOutlineBtn->save_state();
+ m_xShadowBtn->save_state();
+ m_xHiddenBtn->save_state();
+ m_xFontTransparencyMtr->save_value();
+}
+
+bool SvxCharEffectsPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxPoolItem* pOld = nullptr;
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false;
+ bool bChanged = true;
+
+ // Underline
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_UNDERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_UNDERLINE );
+ auto nPos = m_xUnderlineLB->get_active();
+ FontLineStyle eUnder = static_cast<FontLineStyle>(m_xUnderlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxUnderlineItem& rItem = *static_cast<const SvxUnderlineItem*>(pOld);
+ if ( rItem.GetValue() == eUnder &&
+ ( LINESTYLE_NONE == eUnder || rItem.GetColor() == m_xUnderlineColorLB->GetSelectEntryColor() ) &&
+ ! bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ SvxUnderlineItem aNewItem( eUnder, nWhich );
+ aNewItem.SetColor( m_xUnderlineColorLB->GetSelectEntryColor() );
+ rSet->Put( aNewItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Overline
+ nWhich = GetWhich( SID_ATTR_CHAR_OVERLINE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_OVERLINE );
+ nPos = m_xOverlineLB->get_active();
+ FontLineStyle eOver = static_cast<FontLineStyle>(m_xOverlineLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different underline styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the underline style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxOverlineItem& rItem = *static_cast<const SvxOverlineItem*>(pOld);
+ if ( rItem.GetValue() == eOver &&
+ ( LINESTYLE_NONE == eOver || rItem.GetColor() == m_xOverlineColorLB->GetSelectEntryColor() ) &&
+ ! bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ SvxOverlineItem aNewItem( eOver, nWhich );
+ aNewItem.SetColor( m_xOverlineColorLB->GetSelectEntryColor() );
+ rSet->Put( aNewItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Strikeout
+ nWhich = GetWhich( SID_ATTR_CHAR_STRIKEOUT );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_STRIKEOUT );
+ nPos = m_xStrikeoutLB->get_active();
+ FontStrikeout eStrike = static_cast<FontStrikeout>(m_xStrikeoutLB->get_active_id().toInt32());
+
+ if ( pOld )
+ {
+ //! if there are different strikeout styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the strikeout style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCrossedOutItem& rItem = *static_cast<const SvxCrossedOutItem*>(pOld);
+ if ( !m_xStrikeoutLB->get_sensitive()
+ || (rItem.GetValue() == eStrike && !bAllowChg) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxCrossedOutItem( eStrike, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Individual words
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ nWhich = GetWhich( SID_ATTR_CHAR_WORDLINEMODE );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_WORDLINEMODE );
+ TriState eState = m_xIndividualWordsBtn->get_state();
+ const SfxPoolItem* pItem;
+
+ if ( pOld )
+ {
+ const SvxWordLineModeItem& rItem = *static_cast<const SvxWordLineModeItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xIndividualWordsBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxWordLineModeItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxWordLineModeItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Emphasis
+ nWhich = GetWhich( SID_ATTR_CHAR_EMPHASISMARK );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_EMPHASISMARK );
+ int nMarkPos = m_xEmphasisLB->get_active();
+ OUString sMarkPos = m_xEmphasisLB->get_active_text();
+ OUString sPosPos = m_xPositionLB->get_active_text();
+ FontEmphasisMark eMark = static_cast<FontEmphasisMark>(nMarkPos);
+ if (m_xPositionLB->get_sensitive())
+ {
+ eMark |= (CHRDLG_POSITION_UNDER == m_xPositionLB->get_active_id().toInt32())
+ ? FontEmphasisMark::PosBelow : FontEmphasisMark::PosAbove;
+ }
+
+ if ( pOld )
+ {
+ if( rOldSet.GetItemState( nWhich ) != SfxItemState::DONTCARE )
+ {
+ const SvxEmphasisMarkItem& rItem = *static_cast<const SvxEmphasisMarkItem*>(pOld);
+ if ( rItem.GetEmphasisMark() == eMark )
+ bChanged = false;
+ }
+ }
+
+ if (rOldSet.GetItemState( nWhich ) == SfxItemState::DONTCARE &&
+ m_xEmphasisLB->get_saved_value() == sMarkPos && m_xPositionLB->get_saved_value() == sPosPos)
+ {
+ bChanged = false;
+ }
+
+ if (bChanged)
+ {
+ rSet->Put( SvxEmphasisMarkItem( eMark, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Effects
+ nWhich = GetWhich( SID_ATTR_CHAR_CASEMAP );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CASEMAP );
+ SvxCaseMap eCaseMap = SvxCaseMap::NotMapped;
+ bool bChecked = false;
+ auto nCapsPos = m_xEffectsLB->get_active();
+ if (nCapsPos != -1)
+ {
+ eCaseMap = static_cast<SvxCaseMap>(nCapsPos);
+ bChecked = true;
+ }
+
+ if ( pOld )
+ {
+ //! if there are different effect styles in the selection the
+ //! item-state in the 'rOldSet' will be invalid. In this case
+ //! changing the effect style will be allowed if a style is
+ //! selected in the listbox.
+ bool bAllowChg = nPos != -1 &&
+ SfxItemState::DEFAULT > rOldSet.GetItemState( nWhich );
+
+ const SvxCaseMapItem& rItem = *static_cast<const SvxCaseMapItem*>(pOld);
+ if ( rItem.GetValue() == eCaseMap && !bAllowChg )
+ bChanged = false;
+ }
+
+ if ( bChanged && bChecked )
+ {
+ rSet->Put( SvxCaseMapItem( eCaseMap, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ //Relief
+ nWhich = GetWhich(SID_ATTR_CHAR_RELIEF);
+ if (m_xReliefLB->get_value_changed_from_saved())
+ {
+ m_xReliefLB->save_value();
+ SvxCharReliefItem aRelief(static_cast<FontRelief>(m_xReliefLB->get_active()), nWhich);
+ rSet->Put(aRelief);
+ }
+
+ // Outline
+ nWhich = GetWhich( SID_ATTR_CHAR_CONTOUR );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_CONTOUR );
+ eState = m_xOutlineBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxContourItem& rItem = *static_cast<const SvxContourItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xOutlineBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxContourItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxContourItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Shadow
+ nWhich = GetWhich( SID_ATTR_CHAR_SHADOWED );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_SHADOWED );
+ eState = m_xShadowBtn->get_state();
+
+ if ( pOld )
+ {
+ const SvxShadowedItem& rItem = *static_cast<const SvxShadowedItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xShadowBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxShadowedItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxShadowedItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Hidden
+ nWhich = GetWhich( SID_ATTR_CHAR_HIDDEN );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_HIDDEN );
+ eState = m_xHiddenBtn->get_state();
+ bChanged = true;
+
+ if ( pOld )
+ {
+ const SvxCharHiddenItem& rItem = *static_cast<const SvxCharHiddenItem*>(pOld);
+ if ( rItem.GetValue() == StateToAttr( eState ) && m_xHiddenBtn->get_saved_state() == eState )
+ bChanged = false;
+ }
+
+ if ( !bChanged && pExampleSet && pExampleSet->GetItemState( nWhich, false, &pItem ) == SfxItemState::SET &&
+ !StateToAttr( eState ) && static_cast<const SvxCharHiddenItem*>(pItem)->GetValue() )
+ bChanged = true;
+
+ if ( bChanged && eState != TRISTATE_INDET )
+ {
+ rSet->Put( SvxCharHiddenItem( StateToAttr( eState ), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bModified |= FillItemSetColor_Impl( *rSet );
+
+ return bModified;
+}
+
+void SvxCharEffectsPage::DisableControls( sal_uInt16 nDisable )
+{
+ if ( ( DISABLE_CASEMAP & nDisable ) == DISABLE_CASEMAP )
+ {
+ m_xEffectsFT->set_sensitive(false);
+ m_xEffectsLB->set_sensitive(false);
+ }
+
+ if ( ( DISABLE_WORDLINE & nDisable ) == DISABLE_WORDLINE )
+ m_xIndividualWordsBtn->set_sensitive(false);
+
+ if ( ( DISABLE_UNDERLINE_COLOR & nDisable ) == DISABLE_UNDERLINE_COLOR )
+ {
+ // disable the controls
+ m_xUnderlineColorFT->set_sensitive(false);
+ m_xUnderlineColorLB->set_sensitive(false);
+ m_bUnderlineColorDisabled = true;
+ }
+}
+
+void SvxCharEffectsPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pDisableCtlItem = aSet.GetItem<SfxUInt16Item>(SID_DISABLE_CTL, false);
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pDisableCtlItem)
+ DisableControls(pDisableCtlItem->GetValue());
+
+ if (!pFlagItem)
+ return;
+
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ if ((nFlags & SVX_ENABLE_CHAR_TRANSPARENCY) != SVX_ENABLE_CHAR_TRANSPARENCY)
+ {
+ // Only show these in case client code explicitly wants this.
+ m_xFontTransparencyFT->hide();
+ m_xFontTransparencyMtr->hide();
+ }
+}
+
+// class SvxCharPositionPage ---------------------------------------------
+
+SvxCharPositionPage::SvxCharPositionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/positionpage.ui", "PositionPage", rInSet)
+ , m_nSuperEsc(short(DFLT_ESC_SUPER))
+ , m_nSubEsc(short(DFLT_ESC_SUB))
+ , m_nScaleWidthItemSetVal(100)
+ , m_nScaleWidthInitialVal(100)
+ , m_nSuperProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_nSubProp(sal_uInt8(DFLT_ESC_PROP))
+ , m_xHighPosBtn(m_xBuilder->weld_radio_button("superscript"))
+ , m_xNormalPosBtn(m_xBuilder->weld_radio_button("normal"))
+ , m_xLowPosBtn(m_xBuilder->weld_radio_button("subscript"))
+ , m_xHighLowFT(m_xBuilder->weld_label("raiselower"))
+ , m_xHighLowMF(m_xBuilder->weld_metric_spin_button("raiselowersb", FieldUnit::PERCENT))
+ , m_xHighLowRB(m_xBuilder->weld_check_button("automatic"))
+ , m_xFontSizeFT(m_xBuilder->weld_label("relativefontsize"))
+ , m_xFontSizeMF(m_xBuilder->weld_metric_spin_button("fontsizesb", FieldUnit::PERCENT))
+ , m_xRotationContainer(m_xBuilder->weld_widget("rotationcontainer"))
+ , m_xScalingFT(m_xBuilder->weld_label("scale"))
+ , m_xScalingAndRotationFT(m_xBuilder->weld_label("rotateandscale"))
+ , m_x0degRB(m_xBuilder->weld_radio_button("0deg"))
+ , m_x90degRB(m_xBuilder->weld_radio_button("90deg"))
+ , m_x270degRB(m_xBuilder->weld_radio_button("270deg"))
+ , m_xFitToLineCB(m_xBuilder->weld_check_button("fittoline"))
+ , m_xScaleWidthMF(m_xBuilder->weld_metric_spin_button("scalewidthsb", FieldUnit::PERCENT))
+ , m_xKerningMF(m_xBuilder->weld_metric_spin_button("kerningsb", FieldUnit::POINT))
+ , m_xPairKerningBtn(m_xBuilder->weld_check_button("pairkerning"))
+{
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharPositionPage::~SvxCharPositionPage()
+{
+}
+
+
+void SvxCharPositionPage::Initialize()
+{
+ // to handle the changes of the other pages
+ SetExchangeSupport();
+
+ GetPreviewFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCJKFont().SetFontSize( Size( 0, 240 ) );
+ GetPreviewCTLFont().SetFontSize( Size( 0, 240 ) );
+
+ m_xNormalPosBtn->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+
+ Link<weld::ToggleButton&,void> aLink2 = LINK(this, SvxCharPositionPage, PositionHdl_Impl);
+ m_xHighPosBtn->connect_toggled(aLink2);
+ m_xNormalPosBtn->connect_toggled(aLink2);
+ m_xLowPosBtn->connect_toggled(aLink2);
+
+ aLink2 = LINK( this, SvxCharPositionPage, RotationHdl_Impl );
+ m_x0degRB->connect_toggled(aLink2);
+ m_x90degRB->connect_toggled(aLink2);
+ m_x270degRB->connect_toggled(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink3 = LINK(this, SvxCharPositionPage, ValueChangedHdl_Impl);
+ m_xHighLowMF->connect_value_changed(aLink3);
+ m_xFontSizeMF->connect_value_changed(aLink3);
+
+ m_xHighLowRB->connect_toggled(LINK(this, SvxCharPositionPage, AutoPositionHdl_Impl));
+ m_xFitToLineCB->connect_toggled(LINK(this, SvxCharPositionPage, FitToLineHdl_Impl));
+ m_xKerningMF->connect_value_changed(LINK(this, SvxCharPositionPage, KerningModifyHdl_Impl));
+ m_xScaleWidthMF->connect_value_changed(LINK(this, SvxCharPositionPage, ScaleWidthModifyHdl_Impl));
+}
+
+void SvxCharPositionPage::UpdatePreview_Impl( sal_uInt8 nProp, sal_uInt8 nEscProp, short nEsc )
+{
+ SetPrevFontEscapement( nProp, nEscProp, nEsc );
+}
+
+
+void SvxCharPositionPage::SetEscapement_Impl( SvxEscapement nEsc )
+{
+ SvxEscapementItem aEscItm( nEsc, SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( SvxEscapement::Superscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSuperEsc;
+ aEscItm.GetProportionalHeight() = m_nSuperProp;
+ }
+ else if ( SvxEscapement::Subscript == nEsc )
+ {
+ aEscItm.GetEsc() = m_nSubEsc;
+ aEscItm.GetProportionalHeight() = m_nSubProp;
+ }
+
+ short nFac = aEscItm.GetEsc() < 0 ? -1 : 1;
+
+ m_xHighLowMF->set_value(aEscItm.GetEsc() * nFac, FieldUnit::PERCENT);
+ m_xFontSizeMF->set_value(aEscItm.GetProportionalHeight(), FieldUnit::PERCENT);
+
+ if ( SvxEscapement::Off == nEsc )
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+ m_xHighLowRB->set_sensitive(false);
+ }
+ else
+ {
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+ m_xHighLowRB->set_sensitive(true);
+
+ if (!m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ }
+ else
+ AutoPositionHdl_Impl(*m_xHighLowRB);
+ }
+
+ UpdatePreview_Impl( 100, aEscItm.GetProportionalHeight(), aEscItm.GetEsc() );
+}
+
+
+IMPL_LINK_NOARG(SvxCharPositionPage, PositionHdl_Impl, weld::ToggleButton&, void)
+{
+ SvxEscapement nEsc = SvxEscapement::Off; // also when pBtn == NULL
+
+ if (m_xHighPosBtn->get_active())
+ nEsc = SvxEscapement::Superscript;
+ else if (m_xLowPosBtn->get_active())
+ nEsc = SvxEscapement::Subscript;
+
+ SetEscapement_Impl( nEsc );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, RotationHdl_Impl, weld::ToggleButton&, void)
+{
+ bool bEnable = false;
+ if (m_x90degRB->get_active() || m_x270degRB->get_active())
+ bEnable = true;
+ else
+ OSL_ENSURE(m_x0degRB->get_active(), "unexpected button");
+ m_xFitToLineCB->set_sensitive(bEnable);
+}
+
+void SvxCharPositionPage::FontModifyHdl_Impl()
+{
+ sal_uInt8 nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ short nEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ nEsc *= m_xLowPosBtn->get_active() ? -1 : 1;
+ UpdatePreview_Impl( 100, nEscProp, nEsc );
+}
+
+IMPL_LINK(SvxCharPositionPage, AutoPositionHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ else
+ PositionHdl_Impl(m_xHighPosBtn->get_active() ? *m_xHighPosBtn
+ : m_xLowPosBtn->get_active() ? *m_xLowPosBtn
+ : *m_xNormalPosBtn);
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, FitToLineHdl_Impl, weld::ToggleButton&, void)
+{
+ sal_uInt16 nVal = m_nScaleWidthInitialVal;
+ if (m_xFitToLineCB->get_active())
+ nVal = m_nScaleWidthItemSetVal;
+ m_xScaleWidthMF->set_value(nVal, FieldUnit::PERCENT);
+ m_aPreviewWin.SetFontWidthScale( nVal );
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, KerningModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ long nVal = static_cast<long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ nVal = OutputDevice::LogicToLogic( nVal, MapUnit::MapPoint, MapUnit::MapTwip );
+ long nKern = static_cast<short>(m_xKerningMF->denormalize(nVal));
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+ m_aPreviewWin.Invalidate();
+}
+
+IMPL_LINK(SvxCharPositionPage, ValueChangedHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bHigh = m_xHighPosBtn->get_active();
+ bool bLow = m_xLowPosBtn->get_active();
+ DBG_ASSERT( bHigh || bLow, "normal position is not valid" );
+
+ if (m_xHighLowMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT)) * -1;
+ else
+ m_nSuperEsc = static_cast<short>(m_xHighLowMF->get_value(FieldUnit::PERCENT));
+ }
+ else if (m_xFontSizeMF.get() == &rField)
+ {
+ if ( bLow )
+ m_nSubProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ else
+ m_nSuperProp = static_cast<sal_uInt8>(m_xFontSizeMF->get_value(FieldUnit::PERCENT));
+ }
+
+ FontModifyHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxCharPositionPage, ScaleWidthModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ m_aPreviewWin.SetFontWidthScale(sal_uInt16(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)));
+}
+
+DeactivateRC SvxCharPositionPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharPositionPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharPositionPage>(pPage, pController, *rSet);
+}
+
+void SvxCharPositionPage::Reset( const SfxItemSet* rSet )
+{
+ OUString sUser = GetUserData();
+
+ if ( !sUser.isEmpty() )
+ {
+ sal_Int32 nIdx {0};
+ m_nSuperEsc = static_cast<short>(sUser.getToken( 0, ';', nIdx ).toInt32());
+ m_nSubEsc = static_cast<short>(sUser.getToken( 0, ';', nIdx ).toInt32());
+ m_nSuperProp = static_cast<sal_uInt8>(sUser.getToken( 0, ';', nIdx ).toInt32());
+ m_nSubProp = static_cast<sal_uInt8>(sUser.getToken( 0, ';', nIdx ).toInt32());
+
+ m_xHighLowMF->set_max(MAX_ESC_POS, FieldUnit::PERCENT);
+
+ //fdo#75307 validate all the entries and discard all of them if any are
+ //out of range
+ bool bValid = true;
+ if (m_nSuperEsc < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSuperEsc > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubEsc*-1 < m_xHighLowMF->get_min(FieldUnit::PERCENT) || m_nSubEsc*-1 > m_xHighLowMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSuperProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSuperProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+ if (m_nSubProp < m_xFontSizeMF->get_min(FieldUnit::PERCENT) || m_nSubProp > m_xFontSizeMF->get_max(FieldUnit::PERCENT))
+ bValid = false;
+
+ if (!bValid)
+ {
+ m_nSuperEsc = DFLT_ESC_SUPER;
+ m_nSubEsc = DFLT_ESC_SUB;
+ m_nSuperProp = DFLT_ESC_PROP;
+ m_nSubProp = DFLT_ESC_PROP;
+ }
+ }
+
+ short nEsc = 0;
+ sal_uInt8 nEscProp = 100;
+
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ m_xFontSizeFT->set_sensitive(false);
+ m_xFontSizeMF->set_sensitive(false);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxEscapementItem& rItem = static_cast<const SvxEscapementItem&>(rSet->Get( nWhich ));
+ nEsc = rItem.GetEsc();
+ nEscProp = rItem.GetProportionalHeight();
+
+ if ( nEsc != 0 )
+ {
+ m_xHighLowFT->set_sensitive(true);
+ m_xHighLowMF->set_sensitive(true);
+ m_xFontSizeFT->set_sensitive(true);
+ m_xFontSizeMF->set_sensitive(true);
+
+ short nFac;
+ bool bAutomatic(false);
+
+ if ( nEsc > 0 )
+ {
+ nFac = 1;
+ m_xHighPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUPER )
+ {
+ nEsc = DFLT_ESC_SUPER;
+ bAutomatic = true;
+ }
+ }
+ else
+ {
+ nFac = -1;
+ m_xLowPosBtn->set_active(true);
+ if ( nEsc == DFLT_ESC_AUTO_SUB )
+ {
+ nEsc = DFLT_ESC_SUB;
+ bAutomatic = true;
+ }
+ }
+ if (!m_xHighLowRB->get_sensitive())
+ {
+ m_xHighLowRB->set_sensitive(true);
+ }
+ m_xHighLowRB->set_active(bAutomatic);
+
+ if (m_xHighLowRB->get_active())
+ {
+ m_xHighLowFT->set_sensitive(false);
+ m_xHighLowMF->set_sensitive(false);
+ }
+ m_xHighLowMF->set_value(m_xHighLowMF->normalize(nFac * nEsc), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xNormalPosBtn->set_active(true);
+ m_xHighLowRB->set_active(true);
+ PositionHdl_Impl(*m_xNormalPosBtn);
+ }
+ //the height has to be set after the handler is called to keep the value also if the escapement is zero
+ m_xFontSizeMF->set_value(m_xFontSizeMF->normalize(nEscProp), FieldUnit::PERCENT);
+ }
+ else
+ {
+ m_xHighPosBtn->set_active(false);
+ m_xNormalPosBtn->set_active(false);
+ m_xLowPosBtn->set_active(false);
+ }
+
+ // set BspFont
+ SetPrevFontEscapement( 100, nEscProp, nEsc );
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxKerningItem& rItem = static_cast<const SvxKerningItem&>(rSet->Get( nWhich ));
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+ long nBig = static_cast<long>(m_xKerningMF->normalize( static_cast<long>(rItem.GetValue()) ));
+ long nKerning = OutputDevice::LogicToLogic(nBig, eUnit, MapUnit::MapPoint);
+
+ // set Kerning at the Font, convert into Twips before
+ long nKern = OutputDevice::LogicToLogic(rItem.GetValue(), eUnit, MapUnit::MapTwip);
+ rFont.SetFixKerning( static_cast<short>(nKern) );
+ rCJKFont.SetFixKerning( static_cast<short>(nKern) );
+ rCTLFont.SetFixKerning( static_cast<short>(nKern) );
+
+ //the attribute value must be displayed also if it's above the maximum allowed value
+ long nVal = static_cast<long>(m_xKerningMF->get_max(FieldUnit::POINT));
+ if(nVal < nKerning)
+ m_xKerningMF->set_max(nKerning, FieldUnit::POINT);
+ m_xKerningMF->set_value(nKerning, FieldUnit::POINT);
+ }
+ else
+ m_xKerningMF->set_text(OUString());
+
+ // Pair kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxAutoKernItem& rItem = static_cast<const SvxAutoKernItem&>(rSet->Get( nWhich ));
+ m_xPairKerningBtn->set_active(rItem.GetValue());
+ }
+ else
+ m_xPairKerningBtn->set_active(false);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxCharScaleWidthItem& rItem = static_cast<const SvxCharScaleWidthItem&>( rSet->Get( nWhich ) );
+ m_nScaleWidthInitialVal = rItem.GetValue();
+ m_xScaleWidthMF->set_value(m_nScaleWidthInitialVal, FieldUnit::PERCENT);
+ }
+ else
+ m_xScaleWidthMF->set_value(100, FieldUnit::PERCENT);
+
+ nWhich = GetWhich( SID_ATTR_CHAR_WIDTH_FIT_TO_LINE );
+ if ( rSet->GetItemState( nWhich ) >= SfxItemState::DEFAULT )
+ m_nScaleWidthItemSetVal = static_cast<const SfxUInt16Item&>( rSet->Get( nWhich )).GetValue();
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+ if( SfxItemState::UNKNOWN == eState )
+ {
+ m_xRotationContainer->hide();
+ m_xScalingAndRotationFT->hide();
+ m_xScalingFT->show();
+ }
+ else
+ {
+ m_xRotationContainer->show();
+ m_xScalingAndRotationFT->show();
+ m_xScalingFT->hide();
+
+ if( eState >= SfxItemState::DEFAULT )
+ {
+ const SvxCharRotateItem& rItem =
+ static_cast<const SvxCharRotateItem&>( rSet->Get( nWhich ));
+ if (rItem.IsBottomToTop())
+ m_x90degRB->set_active(true);
+ else if (rItem.IsTopToBottom())
+ m_x270degRB->set_active(true);
+ else
+ {
+ DBG_ASSERT( 0 == rItem.GetValue(), "incorrect value" );
+ m_x0degRB->set_active(true);
+ }
+ m_xFitToLineCB->set_active(rItem.IsFitToLine());
+ }
+ else
+ {
+ if( eState == SfxItemState::DONTCARE )
+ {
+ m_x0degRB->set_active(false);
+ m_x90degRB->set_active(false);
+ m_x270degRB->set_active(false);
+ }
+ else
+ m_x0degRB->set_active(true);
+
+ m_xFitToLineCB->set_active(false);
+ }
+ m_xFitToLineCB->set_sensitive(!m_x0degRB->get_active());
+
+ // is this value set?
+ if( SfxItemState::UNKNOWN == rSet->GetItemState( GetWhich(
+ SID_ATTR_CHAR_WIDTH_FIT_TO_LINE ) ))
+ m_xFitToLineCB->hide();
+ }
+ ChangesApplied();
+}
+
+void SvxCharPositionPage::ChangesApplied()
+{
+ m_xHighPosBtn->save_state();
+ m_xNormalPosBtn->save_state();
+ m_xLowPosBtn->save_state();
+ m_xHighLowRB->save_state();
+ m_x0degRB->save_state();
+ m_x90degRB->save_state();
+ m_x270degRB->save_state();
+ m_xFitToLineCB->save_state();
+ m_xScaleWidthMF->save_value();
+ m_xKerningMF->save_value();
+ m_xPairKerningBtn->save_state();
+}
+
+bool SvxCharPositionPage::FillItemSet( SfxItemSet* rSet )
+{
+ // Position (high, normal or low)
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_ESCAPEMENT );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_ESCAPEMENT );
+ const bool bHigh = m_xHighPosBtn->get_active();
+ short nEsc;
+ sal_uInt8 nEscProp;
+
+ if (bHigh || m_xLowPosBtn->get_active())
+ {
+ if (m_xHighLowRB->get_active())
+ nEsc = bHigh ? DFLT_ESC_AUTO_SUPER : DFLT_ESC_AUTO_SUB;
+ else
+ {
+ nEsc = static_cast<short>(m_xHighLowMF->denormalize(m_xHighLowMF->get_value(FieldUnit::PERCENT)));
+ nEsc *= (bHigh ? 1 : -1);
+ }
+ nEscProp = static_cast<sal_uInt8>(m_xFontSizeMF->denormalize(m_xFontSizeMF->get_value(FieldUnit::PERCENT)));
+ }
+ else
+ {
+ nEsc = 0;
+ nEscProp = 100;
+ }
+
+ if ( pOld )
+ {
+ const SvxEscapementItem& rItem = *static_cast<const SvxEscapementItem*>(pOld);
+ if (rItem.GetEsc() == nEsc && rItem.GetProportionalHeight() == nEscProp)
+ bChanged = false;
+ }
+
+ if ( !bChanged && !m_xHighPosBtn->get_saved_state() &&
+ !m_xNormalPosBtn->get_saved_state() && !m_xLowPosBtn->get_saved_state() )
+ bChanged = true;
+
+ if ( bChanged &&
+ ( m_xHighPosBtn->get_active() || m_xNormalPosBtn->get_active() || m_xLowPosBtn->get_active() ) )
+ {
+ rSet->Put( SvxEscapementItem( nEsc, nEscProp, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ bChanged = true;
+
+ // Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_KERNING );
+ pOld = GetOldItem( *rSet, SID_ATTR_CHAR_KERNING );
+ short nKerning = 0;
+ MapUnit eUnit = rSet->GetPool()->GetMetric( nWhich );
+
+ long nTmp = static_cast<long>(m_xKerningMF->get_value(FieldUnit::POINT));
+ long nVal = OutputDevice::LogicToLogic(nTmp, MapUnit::MapPoint, eUnit);
+ nKerning = static_cast<short>(m_xKerningMF->denormalize( nVal ));
+
+ SfxItemState eOldKernState = rOldSet.GetItemState( nWhich, false );
+ if ( pOld )
+ {
+ const SvxKerningItem& rItem = *static_cast<const SvxKerningItem*>(pOld);
+ if ( (eOldKernState >= SfxItemState::DEFAULT || m_xKerningMF->get_text().isEmpty()) && rItem.GetValue() == nKerning )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxKerningItem( nKerning, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == eOldKernState )
+ rSet->InvalidateItem(nWhich);
+
+ // Pair-Kerning
+ nWhich = GetWhich( SID_ATTR_CHAR_AUTOKERN );
+
+ if (m_xPairKerningBtn->get_state_changed_from_saved())
+ {
+ rSet->Put( SvxAutoKernItem( m_xPairKerningBtn->get_active(), nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Scale Width
+ nWhich = GetWhich( SID_ATTR_CHAR_SCALEWIDTH );
+ if (m_xScaleWidthMF->get_value_changed_from_saved())
+ {
+ rSet->Put(SvxCharScaleWidthItem(static_cast<sal_uInt16>(m_xScaleWidthMF->get_value(FieldUnit::PERCENT)), nWhich));
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ // Rotation
+ nWhich = GetWhich( SID_ATTR_CHAR_ROTATED );
+ if ( m_x0degRB->get_state_changed_from_saved() ||
+ m_x90degRB->get_state_changed_from_saved() ||
+ m_x270degRB->get_state_changed_from_saved() ||
+ m_xFitToLineCB->get_state_changed_from_saved() )
+ {
+ SvxCharRotateItem aItem( 0, m_xFitToLineCB->get_active(), nWhich );
+ if (m_x90degRB->get_active())
+ aItem.SetBottomToTop();
+ else if (m_x270degRB->get_active())
+ aItem.SetTopToBottom();
+ rSet->Put( aItem );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+
+void SvxCharPositionPage::FillUserData()
+{
+ const OUString cTok( ";" );
+
+ OUString sUser = OUString::number( m_nSuperEsc ) + cTok +
+ OUString::number( m_nSubEsc ) + cTok +
+ OUString::number( m_nSuperProp ) + cTok +
+ OUString::number( m_nSubProp );
+ SetUserData( sUser );
+}
+
+
+void SvxCharPositionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+// class SvxCharTwoLinesPage ------------------------------------------------
+
+SvxCharTwoLinesPage::SvxCharTwoLinesPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInSet)
+ : SvxCharBasePage(pPage, pController, "cui/ui/twolinespage.ui", "TwoLinesPage", rInSet)
+ , m_nStartBracketPosition( 0 )
+ , m_nEndBracketPosition( 0 )
+ , m_xTwoLinesBtn(m_xBuilder->weld_check_button("twolines"))
+ , m_xEnclosingFrame(m_xBuilder->weld_widget("enclosing"))
+ , m_xStartBracketLB(m_xBuilder->weld_tree_view("startbracket"))
+ , m_xEndBracketLB(m_xBuilder->weld_tree_view("endbracket"))
+{
+ for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_OPEN); ++i)
+ m_xStartBracketLB->append(OUString::number(TWOLINE_OPEN[i].second), CuiResId(TWOLINE_OPEN[i].first));
+ for (size_t i = 0; i < SAL_N_ELEMENTS(TWOLINE_CLOSE); ++i)
+ m_xEndBracketLB->append(OUString::number(TWOLINE_CLOSE[i].second), CuiResId(TWOLINE_CLOSE[i].first));
+
+ m_xPreviewWin.reset(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWin));
+#ifdef IOS
+ m_xPreviewWin->hide();
+#endif
+ Initialize();
+}
+
+SvxCharTwoLinesPage::~SvxCharTwoLinesPage()
+{
+}
+
+void SvxCharTwoLinesPage::Initialize()
+{
+ m_xTwoLinesBtn->set_active(false);
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ m_xTwoLinesBtn->connect_toggled(LINK(this, SvxCharTwoLinesPage, TwoLinesHdl_Impl));
+
+ Link<weld::TreeView&,void> aLink = LINK(this, SvxCharTwoLinesPage, CharacterMapHdl_Impl);
+ m_xStartBracketLB->connect_changed(aLink);
+ m_xEndBracketLB->connect_changed(aLink);
+
+ SvxFont& rFont = GetPreviewFont();
+ SvxFont& rCJKFont = GetPreviewCJKFont();
+ SvxFont& rCTLFont = GetPreviewCTLFont();
+ rFont.SetFontSize( Size( 0, 220 ) );
+ rCJKFont.SetFontSize( Size( 0, 220 ) );
+ rCTLFont.SetFontSize( Size( 0, 220 ) );
+}
+
+void SvxCharTwoLinesPage::SelectCharacter(weld::TreeView* pBox)
+{
+ bool bStart = pBox == m_xStartBracketLB.get();
+ SvxCharacterMap aDlg(GetFrameWeld(), nullptr, nullptr);
+ aDlg.DisableFontSelection();
+
+ if (aDlg.run() == RET_OK)
+ {
+ sal_Unicode cChar = static_cast<sal_Unicode>(aDlg.GetChar());
+ SetBracket( cChar, bStart );
+ }
+ else
+ {
+ pBox->select(bStart ? m_nStartBracketPosition : m_nEndBracketPosition);
+ }
+}
+
+
+void SvxCharTwoLinesPage::SetBracket( sal_Unicode cBracket, bool bStart )
+{
+ int nEntryPos = 0;
+ weld::TreeView* pBox = bStart ? m_xStartBracketLB.get() : m_xEndBracketLB.get();
+ if (cBracket == 0)
+ pBox->select(0);
+ else
+ {
+ bool bFound = false;
+ for (int i = 1; i < pBox->n_children(); ++i)
+ {
+ if (pBox->get_id(i).toInt32() != CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ {
+ const sal_Unicode cChar = pBox->get_text(i)[0];
+ if (cChar == cBracket)
+ {
+ pBox->select(i);
+ nEntryPos = i;
+ bFound = true;
+ break;
+ }
+ }
+ }
+
+ if (!bFound)
+ {
+ pBox->append_text(OUString(cBracket));
+ nEntryPos = pBox->n_children() - 1;
+ pBox->select(nEntryPos);
+ }
+ }
+ if (bStart)
+ m_nStartBracketPosition = nEntryPos;
+ else
+ m_nEndBracketPosition = nEntryPos;
+}
+
+IMPL_LINK_NOARG(SvxCharTwoLinesPage, TwoLinesHdl_Impl, weld::ToggleButton&, void)
+{
+ bool bChecked = m_xTwoLinesBtn->get_active();
+ m_xEnclosingFrame->set_sensitive(bChecked);
+ UpdatePreview_Impl();
+}
+
+IMPL_LINK(SvxCharTwoLinesPage, CharacterMapHdl_Impl, weld::TreeView&, rBox, void)
+{
+ int nPos = rBox.get_selected_index();
+ if (rBox.get_id(nPos).toInt32() == CHRDLG_ENCLOSE_SPECIAL_CHAR)
+ SelectCharacter( &rBox );
+ else
+ {
+ bool bStart = &rBox == m_xStartBracketLB.get();
+ if (bStart)
+ m_nStartBracketPosition = nPos;
+ else
+ m_nEndBracketPosition = nPos;
+ }
+ UpdatePreview_Impl();
+}
+
+void SvxCharTwoLinesPage::ActivatePage( const SfxItemSet& rSet )
+{
+ SvxCharBasePage::ActivatePage(rSet);
+}
+
+DeactivateRC SvxCharTwoLinesPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxCharTwoLinesPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxCharTwoLinesPage>(pPage, pController, *rSet);
+}
+
+void SvxCharTwoLinesPage::Reset( const SfxItemSet* rSet )
+{
+ m_xTwoLinesBtn->set_active(false);
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ SfxItemState eState = rSet->GetItemState( nWhich );
+
+ if ( eState >= SfxItemState::DONTCARE )
+ {
+ const SvxTwoLinesItem& rItem = static_cast<const SvxTwoLinesItem&>(rSet->Get( nWhich ));
+ m_xTwoLinesBtn->set_active(rItem.GetValue());
+
+ if ( rItem.GetValue() )
+ {
+ SetBracket( rItem.GetStartBracket(), true );
+ SetBracket( rItem.GetEndBracket(), false );
+ }
+ }
+ TwoLinesHdl_Impl(*m_xTwoLinesBtn);
+
+ SetPrevFontWidthScale( *rSet );
+}
+
+bool SvxCharTwoLinesPage::FillItemSet( SfxItemSet* rSet )
+{
+ const SfxItemSet& rOldSet = GetItemSet();
+ bool bModified = false, bChanged = true;
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_CHAR_TWO_LINES );
+ const SfxPoolItem* pOld = GetOldItem( *rSet, SID_ATTR_CHAR_TWO_LINES );
+ bool bOn = m_xTwoLinesBtn->get_active();
+ sal_Unicode cStart = ( bOn && m_xStartBracketLB->get_selected_index() > 0 )
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = ( bOn && m_xEndBracketLB->get_selected_index() > 0 )
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+
+ if ( pOld )
+ {
+ const SvxTwoLinesItem& rItem = *static_cast<const SvxTwoLinesItem*>(pOld);
+ if ( rItem.GetValue() == bOn &&
+ ( !bOn || ( rItem.GetStartBracket() == cStart && rItem.GetEndBracket() == cEnd ) ) )
+ bChanged = false;
+ }
+
+ if ( bChanged )
+ {
+ rSet->Put( SvxTwoLinesItem( bOn, cStart, cEnd, nWhich ) );
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich, false ) )
+ rSet->InvalidateItem(nWhich);
+
+ return bModified;
+}
+
+void SvxCharTwoLinesPage::UpdatePreview_Impl()
+{
+ sal_Unicode cStart = m_xStartBracketLB->get_selected_index() > 0
+ ? m_xStartBracketLB->get_selected_text()[0] : 0;
+ sal_Unicode cEnd = m_xEndBracketLB->get_selected_index() > 0
+ ? m_xEndBracketLB->get_selected_text()[0] : 0;
+ m_aPreviewWin.SetBrackets(cStart, cEnd);
+ m_aPreviewWin.SetTwoLines(m_xTwoLinesBtn->get_active());
+ m_aPreviewWin.Invalidate();
+}
+
+void SvxCharTwoLinesPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt32Item* pFlagItem = aSet.GetItem<SfxUInt32Item>(SID_FLAG_TYPE, false);
+ if (pFlagItem)
+ {
+ sal_uInt32 nFlags=pFlagItem->GetValue();
+ if ( ( nFlags & SVX_PREVIEW_CHARACTER ) == SVX_PREVIEW_CHARACTER )
+ // the writer uses SID_ATTR_BRUSH as font background
+ m_bPreviewBackgroundToCharacter = true;
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/chardlg.h b/cui/source/tabpages/chardlg.h
new file mode 100644
index 000000000..b72beae2e
--- /dev/null
+++ b/cui/source/tabpages/chardlg.h
@@ -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 .
+ */
+#ifndef INCLUDED_CUI_SOURCE_TABPAGES_CHARDLG_H
+#define INCLUDED_CUI_SOURCE_TABPAGES_CHARDLG_H
+
+// define ----------------------------------------------------------------
+
+#define CHRDLG_POSITION_OVER 0
+#define CHRDLG_POSITION_UNDER 1
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/connect.cxx b/cui/source/tabpages/connect.cxx
new file mode 100644
index 000000000..70b38bbc9
--- /dev/null
+++ b/cui/source/tabpages/connect.cxx
@@ -0,0 +1,419 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/connctrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/ofaitem.hxx>
+
+#include <svx/svdview.hxx>
+#include <svx/sxekitm.hxx>
+#include <svx/sxelditm.hxx>
+#include <svx/sxenditm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <connect.hxx>
+
+const sal_uInt16 SvxConnectionPage::pRanges[] =
+{
+ SDRATTR_EDGE_FIRST,
+ SDRATTR_EDGE_LAST,
+ 0
+};
+
+/*************************************************************************
+|*
+|* dialog for changing connectors
+|*
+\************************************************************************/
+SvxConnectionDialog::SvxConnectionDialog(weld::Window* pParent, const SfxItemSet& rInAttrs, const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxConnectionPage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_SVXSTR_CONNECTOR));
+}
+
+/*************************************************************************
+|*
+|* page for changing connectors
+|*
+\************************************************************************/
+
+SvxConnectionPage::SvxConnectionPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/connectortabpage.ui", "ConnectorTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , m_xLbType(m_xBuilder->weld_combo_box("LB_TYPE"))
+ , m_xFtLine1(m_xBuilder->weld_label("FT_LINE_1"))
+ , m_xMtrFldLine1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_1", FieldUnit::CM))
+ , m_xFtLine2(m_xBuilder->weld_label("FT_LINE_2"))
+ , m_xMtrFldLine2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_2", FieldUnit::CM))
+ , m_xFtLine3(m_xBuilder->weld_label("FT_LINE_3"))
+ , m_xMtrFldLine3(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_3", FieldUnit::CM))
+ , m_xMtrFldHorz1(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_1", FieldUnit::MM))
+ , m_xMtrFldVert1(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_1", FieldUnit::MM))
+ , m_xMtrFldHorz2(m_xBuilder->weld_metric_spin_button("MTR_FLD_HORZ_2", FieldUnit::MM))
+ , m_xMtrFldVert2(m_xBuilder->weld_metric_spin_button("MTR_FLD_VERT_2", FieldUnit::MM))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool" );
+ eUnit = pPool->GetMetric( SDRATTR_EDGENODE1HORZDIST );
+
+ FillTypeLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldHorz1, eFUnit );
+ SetFieldUnit( *m_xMtrFldHorz2, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert1, eFUnit );
+ SetFieldUnit( *m_xMtrFldVert2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine1, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine2, eFUnit );
+ SetFieldUnit( *m_xMtrFldLine3, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldHorz1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHorz2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldVert2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine1->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine2->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldLine3->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxConnectionPage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldHorz1->connect_value_changed(aLink);
+ m_xMtrFldVert1->connect_value_changed(aLink);
+ m_xMtrFldHorz2->connect_value_changed(aLink);
+ m_xMtrFldVert2->connect_value_changed(aLink);
+ m_xMtrFldLine1->connect_value_changed(aLink);
+ m_xMtrFldLine2->connect_value_changed(aLink);
+ m_xMtrFldLine3->connect_value_changed(aLink);
+ m_xLbType->connect_changed(LINK(this, SvxConnectionPage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxConnectionPage::~SvxConnectionPage()
+{
+ m_xCtlPreview.reset();
+}
+
+/*************************************************************************
+|*
+|* reads passed Item-Set
+|*
+\************************************************************************/
+
+void SvxConnectionPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_EDGENODE1HORZDIST );
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // SdrEdgeNode1HorzDistItem
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE1HORZDIST );
+ SetMetricValue(*m_xMtrFldHorz1, static_cast<const SdrEdgeNode1HorzDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHorz1->save_value();
+
+ // SdrEdgeNode2HorzDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE2HORZDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE2HORZDIST );
+ SetMetricValue(*m_xMtrFldHorz2, static_cast<const SdrEdgeNode2HorzDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHorz2->save_value();
+
+ // SdrEdgeNode1VertDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE1VERTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE1VERTDIST );
+ SetMetricValue(*m_xMtrFldVert1, static_cast<const SdrEdgeNode1VertDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldVert1->save_value();
+
+ // SdrEdgeNode2VertDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGENODE2VERTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGENODE2VERTDIST );
+ SetMetricValue(*m_xMtrFldVert2, static_cast<const SdrEdgeNode2VertDistItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldVert2->save_value();
+
+ // SdrEdgeLine1DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE1DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE1DELTA );
+ SetMetricValue(*m_xMtrFldLine1, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine1->save_value();
+
+ // SdrEdgeLine2DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE2DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE2DELTA );
+ SetMetricValue(*m_xMtrFldLine2, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine2->save_value();
+
+ // SdrEdgeLine3DeltaItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINE3DELTA );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINE3DELTA );
+ SetMetricValue(*m_xMtrFldLine3, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLine3->save_value();
+
+ // SdrEdgeLineDeltaAnzItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGELINEDELTACOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGELINEDELTACOUNT );
+ switch (static_cast<const SdrEdgeLineDeltaCountItem*>(pItem)->GetValue())
+ {
+ case 0:
+ m_xFtLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_sensitive(false);
+ m_xMtrFldLine1->set_text("");
+ [[fallthrough]];
+ case 1:
+ m_xFtLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_sensitive(false);
+ m_xMtrFldLine2->set_text("");
+ [[fallthrough]];
+ case 2:
+ m_xFtLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_sensitive(false);
+ m_xMtrFldLine3->set_text("");
+ break;
+ }
+
+ // SdrEdgeKindItem
+ pItem = GetItem( *rAttrs, SDRATTR_EDGEKIND );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ m_xLbType->set_active(
+ sal::static_int_cast<sal_uInt16>(static_cast<const SdrEdgeKindItem*>(pItem)->GetValue()));
+ m_xLbType->save_value();
+}
+
+/*************************************************************************
+|*
+|* fills the passed Item-Set width Dialogbox attributes
+|*
+\************************************************************************/
+
+bool SvxConnectionPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+
+ if (m_xMtrFldHorz1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ rAttrs->Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldHorz2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldHorz2, eUnit);
+ rAttrs->Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ rAttrs->Put( SdrEdgeNode1VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldVert2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ rAttrs->Put( SdrEdgeNode2VertDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine1->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ rAttrs->Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine2->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ rAttrs->Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ if (m_xMtrFldLine3->get_value_changed_from_saved())
+ {
+ nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ rAttrs->Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbType->get_active();
+ if (m_xLbType->get_value_changed_from_saved())
+ {
+ if (nPos != -1)
+ {
+ rAttrs->Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxConnectionPage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transfer!" );
+
+ m_aCtlPreview.SetView(pView);
+ m_aCtlPreview.Construct();
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+std::unique_ptr<SfxTabPage> SvxConnectionPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxConnectionPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxConnectionPage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbType->get_active();
+ if (nPos != -1)
+ {
+ aAttrSet.Put( SdrEdgeKindItem( static_cast<SdrEdgeKind>(nPos) ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+
+ // get the number of line displacements
+ sal_uInt16 nCount = m_aCtlPreview.GetLineDeltaCount();
+
+ m_xFtLine3->set_sensitive( nCount > 2 );
+ m_xMtrFldLine3->set_sensitive( nCount > 2 );
+ if( nCount > 2 )
+ m_xMtrFldLine3->set_value(m_xMtrFldLine3->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine3->set_text("");
+
+ m_xFtLine2->set_sensitive( nCount > 1 );
+ m_xMtrFldLine2->set_sensitive( nCount > 1 );
+ if( nCount > 1 )
+ m_xMtrFldLine2->set_value(m_xMtrFldLine2->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine2->set_text("");
+
+ m_xFtLine1->set_sensitive( nCount > 0 );
+ m_xMtrFldLine1->set_sensitive( nCount > 0 );
+ if( nCount > 0 )
+ m_xMtrFldLine1->set_value(m_xMtrFldLine1->get_value(FieldUnit::NONE), FieldUnit::NONE);
+ else
+ m_xMtrFldLine1->set_text("");
+}
+
+IMPL_LINK(SvxConnectionPage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, r, void)
+{
+ if (&r == m_xMtrFldHorz1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldHorz1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldHorz2.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHorz2, eUnit );
+ aAttrSet.Put( SdrEdgeNode2HorzDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert1, eUnit);
+ aAttrSet.Put( SdrEdgeNode1VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldVert2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldVert2, eUnit);
+ aAttrSet.Put( SdrEdgeNode2VertDistItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine1.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine1, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine1DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine2.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine2, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine2DeltaItem( nValue ) );
+ }
+
+ if (&r == m_xMtrFldLine3.get())
+ {
+ sal_Int32 nValue = GetCoreValue(*m_xMtrFldLine3, eUnit);
+ aAttrSet.Put( makeSdrEdgeLine3DeltaItem( nValue ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+}
+
+void SvxConnectionPage::FillTypeLB()
+{
+ // fill ListBox with connector names
+ const SfxPoolItem* pItem = GetItem( rOutAttrs, SDRATTR_EDGEKIND );
+ const SfxItemPool* pPool = rOutAttrs.GetPool();
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_EDGEKIND );
+ const SdrEdgeKindItem* pEdgeKindItem = static_cast<const SdrEdgeKindItem*>(pItem);
+ const sal_uInt16 nCount = pEdgeKindItem->GetValueCount();
+ for (sal_uInt16 i = 0; i < nCount; i++)
+ {
+ OUString aStr = SdrEdgeKindItem::GetValueTextByPos(i);
+ m_xLbType->append_text(aStr);
+ }
+}
+void SvxConnectionPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()) );
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/dstribut.cxx b/cui/source/tabpages/dstribut.cxx
new file mode 100644
index 000000000..e1653ca4d
--- /dev/null
+++ b/cui/source/tabpages/dstribut.cxx
@@ -0,0 +1,152 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/basedlgs.hxx>
+#include <dstribut.hxx>
+
+/*************************************************************************
+|*
+|* Dialog
+|*
+\************************************************************************/
+
+SvxDistributeDialog::SvxDistributeDialog(weld::Window* pParent,
+ const SfxItemSet& rInAttrs, SvxDistributeHorizontal eHor,
+ SvxDistributeVertical eVer)
+ : SfxSingleTabDialogController(pParent, &rInAttrs, "cui/ui/distributiondialog.ui",
+ "DistributionDialog")
+{
+ SetTabPage(std::make_unique<SvxDistributePage>(get_content_area(), this, rInAttrs, eHor, eVer));
+ mpPage = static_cast<SvxDistributePage*>(GetTabPage());
+}
+
+SvxDistributeDialog::~SvxDistributeDialog()
+{
+}
+
+/*************************************************************************
+|*
+|* Tabpage
+|*
+\************************************************************************/
+
+SvxDistributePage::SvxDistributePage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rInAttrs, SvxDistributeHorizontal eHor,
+ SvxDistributeVertical eVer)
+ : SfxTabPage(pPage, pController, "cui/ui/distributionpage.ui", "DistributionPage",
+ &rInAttrs)
+ , m_eDistributeHor(eHor)
+ , m_eDistributeVer(eVer)
+ , m_xBtnHorNone(m_xBuilder->weld_radio_button("hornone"))
+ , m_xBtnHorLeft(m_xBuilder->weld_radio_button("horleft"))
+ , m_xBtnHorCenter(m_xBuilder->weld_radio_button("horcenter"))
+ , m_xBtnHorDistance(m_xBuilder->weld_radio_button("hordistance"))
+ , m_xBtnHorRight(m_xBuilder->weld_radio_button("horright"))
+ , m_xBtnVerNone(m_xBuilder->weld_radio_button("vernone"))
+ , m_xBtnVerTop(m_xBuilder->weld_radio_button("vertop"))
+ , m_xBtnVerCenter(m_xBuilder->weld_radio_button("vercenter"))
+ , m_xBtnVerDistance(m_xBuilder->weld_radio_button("verdistance"))
+ , m_xBtnVerBottom(m_xBuilder->weld_radio_button("verbottom"))
+{
+}
+
+SvxDistributePage::~SvxDistributePage()
+{
+}
+
+/*************************************************************************
+|*
+|* read the delivered Item-Set
+|*
+\************************************************************************/
+
+void SvxDistributePage::Reset(const SfxItemSet* )
+{
+ m_xBtnHorNone->set_active(false);
+ m_xBtnHorLeft->set_active(false);
+ m_xBtnHorCenter->set_active(false);
+ m_xBtnHorDistance->set_active(false);
+ m_xBtnHorRight->set_active(false);
+
+ switch(m_eDistributeHor)
+ {
+ case SvxDistributeHorizontal::NONE : m_xBtnHorNone->set_active(true); break;
+ case SvxDistributeHorizontal::Left : m_xBtnHorLeft->set_active(true); break;
+ case SvxDistributeHorizontal::Center : m_xBtnHorCenter->set_active(true); break;
+ case SvxDistributeHorizontal::Distance : m_xBtnHorDistance->set_active(true); break;
+ case SvxDistributeHorizontal::Right : m_xBtnHorRight->set_active(true); break;
+ }
+
+ m_xBtnVerNone->set_active(false);
+ m_xBtnVerTop->set_active(false);
+ m_xBtnVerCenter->set_active(false);
+ m_xBtnVerDistance->set_active(false);
+ m_xBtnVerBottom->set_active(false);
+
+ switch(m_eDistributeVer)
+ {
+ case SvxDistributeVertical::NONE : m_xBtnVerNone->set_active(true); break;
+ case SvxDistributeVertical::Top : m_xBtnVerTop->set_active(true); break;
+ case SvxDistributeVertical::Center : m_xBtnVerCenter->set_active(true); break;
+ case SvxDistributeVertical::Distance : m_xBtnVerDistance->set_active(true); break;
+ case SvxDistributeVertical::Bottom : m_xBtnVerBottom->set_active(true); break;
+ }
+}
+
+/*************************************************************************
+|*
+|* Fill the delivered Item-Set with dialogbox-attributes
+|*
+\************************************************************************/
+
+bool SvxDistributePage::FillItemSet( SfxItemSet* )
+{
+ SvxDistributeHorizontal eDistributeHor(SvxDistributeHorizontal::NONE);
+ SvxDistributeVertical eDistributeVer(SvxDistributeVertical::NONE);
+
+ if(m_xBtnHorLeft->get_active())
+ eDistributeHor = SvxDistributeHorizontal::Left;
+ else if(m_xBtnHorCenter->get_active())
+ eDistributeHor = SvxDistributeHorizontal::Center;
+ else if(m_xBtnHorDistance->get_active())
+ eDistributeHor = SvxDistributeHorizontal::Distance;
+ else if(m_xBtnHorRight->get_active())
+ eDistributeHor = SvxDistributeHorizontal::Right;
+
+ if(m_xBtnVerTop->get_active())
+ eDistributeVer = SvxDistributeVertical::Top;
+ else if(m_xBtnVerCenter->get_active())
+ eDistributeVer = SvxDistributeVertical::Center;
+ else if(m_xBtnVerDistance->get_active())
+ eDistributeVer = SvxDistributeVertical::Distance;
+ else if(m_xBtnVerBottom->get_active())
+ eDistributeVer = SvxDistributeVertical::Bottom;
+
+ if(eDistributeHor != m_eDistributeHor || eDistributeVer != m_eDistributeVer)
+ {
+ m_eDistributeHor = eDistributeHor;
+ m_eDistributeVer = eDistributeVer;
+ return true;
+ }
+
+ return false;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/grfpage.cxx b/cui/source/tabpages/grfpage.cxx
new file mode 100644
index 000000000..7f334e2f1
--- /dev/null
+++ b/cui/source/tabpages/grfpage.cxx
@@ -0,0 +1,785 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <svl/eitem.hxx>
+#include <svl/stritem.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <grfpage.hxx>
+#include <svx/grfcrop.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/debug.hxx>
+#include <tools/fract.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <vcl/fieldvalues.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/unitconv.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+#define CM_1_TO_TWIP 567
+#define TWIP_TO_INCH 1440
+
+
+static int lcl_GetValue(const weld::MetricSpinButton& rMetric, FieldUnit eUnit)
+{
+ return rMetric.denormalize(rMetric.get_value(eUnit));
+}
+
+/*--------------------------------------------------------------------
+ description: crop graphic
+ --------------------------------------------------------------------*/
+
+SvxGrfCropPage::SvxGrfCropPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/croppage.ui", "CropPage", &rSet)
+ , nOldWidth(0)
+ , nOldHeight(0)
+ , bSetOrigSize(false)
+ , m_xCropFrame(m_xBuilder->weld_widget("cropframe"))
+ , m_xZoomConstRB(m_xBuilder->weld_radio_button("keepscale"))
+ , m_xSizeConstRB(m_xBuilder->weld_radio_button("keepsize"))
+ , m_xLeftMF(m_xBuilder->weld_metric_spin_button("left", FieldUnit::CM))
+ , m_xRightMF(m_xBuilder->weld_metric_spin_button("right", FieldUnit::CM))
+ , m_xTopMF(m_xBuilder->weld_metric_spin_button("top", FieldUnit::CM))
+ , m_xBottomMF(m_xBuilder->weld_metric_spin_button("bottom", FieldUnit::CM))
+ , m_xScaleFrame(m_xBuilder->weld_widget("scaleframe"))
+ , m_xWidthZoomMF(m_xBuilder->weld_metric_spin_button("widthzoom", FieldUnit::PERCENT))
+ , m_xHeightZoomMF(m_xBuilder->weld_metric_spin_button("heightzoom", FieldUnit::PERCENT))
+ , m_xSizeFrame(m_xBuilder->weld_widget("sizeframe"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xOrigSizeGrid(m_xBuilder->weld_widget("origsizegrid"))
+ , m_xOrigSizeFT(m_xBuilder->weld_label("origsizeft"))
+ , m_xOrigSizePB(m_xBuilder->weld_button("origsize"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ SetExchangeSupport();
+
+ // set the correct metric
+ const FieldUnit eMetric = GetModuleFieldUnit( rSet );
+
+ SetFieldUnit( *m_xWidthMF, eMetric );
+ SetFieldUnit( *m_xHeightMF, eMetric );
+ SetFieldUnit( *m_xLeftMF, eMetric );
+ SetFieldUnit( *m_xRightMF, eMetric );
+ SetFieldUnit( *m_xTopMF , eMetric );
+ SetFieldUnit( *m_xBottomMF, eMetric );
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxGrfCropPage, SizeHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, ZoomHdl);
+ m_xWidthZoomMF->connect_value_changed( aLk );
+ m_xHeightZoomMF->connect_value_changed( aLk );
+
+ aLk = LINK(this, SvxGrfCropPage, CropModifyHdl);
+ m_xLeftMF->connect_value_changed( aLk );
+ m_xRightMF->connect_value_changed( aLk );
+ m_xTopMF->connect_value_changed( aLk );
+ m_xBottomMF->connect_value_changed( aLk );
+
+ m_xOrigSizePB->connect_clicked(LINK(this, SvxGrfCropPage, OrigSizeHdl));
+}
+
+SvxGrfCropPage::~SvxGrfCropPage()
+{
+ m_xExampleWN.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxGrfCropPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet *rSet)
+{
+ return std::make_unique<SvxGrfCropPage>(pPage, pController, *rSet);
+}
+
+void SvxGrfCropPage::Reset( const SfxItemSet *rSet )
+{
+ const SfxPoolItem* pItem;
+ const SfxItemPool& rPool = *rSet->GetPool();
+
+ if(SfxItemState::SET == rSet->GetItemState( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM ), true, &pItem ))
+ {
+ if( static_cast<const SfxBoolItem*>(pItem)->GetValue() )
+ m_xZoomConstRB->set_active(true);
+ else
+ m_xSizeConstRB->set_active(true);
+ m_xZoomConstRB->save_state();
+ }
+
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ if( SfxItemState::SET == rSet->GetItemState( nW, true, &pItem))
+ {
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ const SvxGrfCrop* pCrop = static_cast<const SvxGrfCrop*>(pItem);
+
+ m_aExampleWN.SetLeft(pCrop->GetLeft());
+ m_aExampleWN.SetRight(pCrop->GetRight());
+ m_aExampleWN.SetTop(pCrop->GetTop());
+ m_aExampleWN.SetBottom(pCrop->GetBottom());
+
+ m_xLeftMF->set_value( m_xLeftMF->normalize( pCrop->GetLeft()), eUnit );
+ m_xRightMF->set_value( m_xRightMF->normalize( pCrop->GetRight()), eUnit );
+ m_xTopMF->set_value( m_xTopMF->normalize( pCrop->GetTop()), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( pCrop->GetBottom()), eUnit );
+ }
+ else
+ {
+ m_xLeftMF->set_value(0, FieldUnit::NONE);
+ m_xRightMF->set_value(0, FieldUnit::NONE);
+ m_xTopMF->set_value(0, FieldUnit::NONE);
+ m_xBottomMF->set_value(0, FieldUnit::NONE);
+ }
+
+ m_xLeftMF->save_value();
+ m_xRightMF->save_value();
+ m_xTopMF->save_value();
+ m_xBottomMF->save_value();
+
+ nW = rPool.GetWhich( SID_ATTR_PAGE_SIZE );
+ if ( SfxItemState::SET == rSet->GetItemState( nW, false, &pItem ) )
+ {
+ // orientation and size from the PageItem
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ aPageSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ auto nMin = m_xWidthMF->normalize( 23 );
+ auto nMax = m_xHeightMF->normalize(aPageSize.Height());
+ m_xHeightMF->set_range(nMin, nMax, eUnit);
+ nMax = m_xWidthMF->normalize(aPageSize.Width());
+ m_xWidthMF->set_range(nMin, nMax, eUnit);
+ }
+ else
+ {
+ aPageSize = OutputDevice::LogicToLogic(
+ Size( CM_1_TO_TWIP, CM_1_TO_TWIP ),
+ MapMode( MapUnit::MapTwip ),
+ MapMode( rSet->GetPool()->GetMetric( nW ) ) );
+ }
+
+ bool bFound = false;
+ if( SfxItemState::SET == rSet->GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
+ {
+ OUString referer;
+ SfxStringItem const * it = static_cast<SfxStringItem const *>(
+ rSet->GetItem(SID_REFERER));
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = static_cast<const SvxBrushItem*>(pItem)->GetGraphic(referer);
+ if( pGrf )
+ {
+ aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() && aOrigSize.Height())
+ {
+ aOrigPixelSize = pGrf->GetSizePixel();
+ }
+
+ if( aOrigSize.Width() && aOrigSize.Height() )
+ {
+ CalcMinMaxBorder();
+ m_aExampleWN.SetGraphic( *pGrf );
+ m_aExampleWN.SetFrameSize( aOrigSize );
+
+ bFound = true;
+ if( !static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink().isEmpty() )
+ aGraphicName = static_cast<const SvxBrushItem*>(pItem)->GetGraphicLink();
+ }
+ }
+ }
+
+ GraphicHasChanged( bFound );
+ ActivatePage( *rSet );
+}
+
+bool SvxGrfCropPage::FillItemSet(SfxItemSet *rSet)
+{
+ const SfxItemPool& rPool = *rSet->GetPool();
+ bool bModified = false;
+ if( m_xWidthMF->get_value_changed_from_saved() ||
+ m_xHeightMF->get_value_changed_from_saved() )
+ {
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_FRMSIZE );
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+
+ std::shared_ptr<SvxSizeItem> aSz(std::make_shared<SvxSizeItem>(nW));
+
+ // size could already have been set from another page
+ const SfxItemSet* pExSet = GetDialogExampleSet();
+ const SfxPoolItem* pItem = nullptr;
+ if( pExSet && SfxItemState::SET ==pExSet->GetItemState( nW, false, &pItem ) )
+ {
+ aSz.reset(static_cast< SvxSizeItem*>(pItem->Clone()));
+ }
+ else
+ {
+ aSz.reset(static_cast< SvxSizeItem*>(GetItemSet().Get(nW).Clone()));
+ }
+
+ Size aTmpSz( aSz->GetSize() );
+ if( m_xWidthMF->get_value_changed_from_saved() )
+ aTmpSz.setWidth( lcl_GetValue( *m_xWidthMF, eUnit ) );
+ if( m_xHeightMF->get_value_changed_from_saved() )
+ aTmpSz.setHeight( lcl_GetValue( *m_xHeightMF, eUnit ) );
+ aSz->SetSize( aTmpSz );
+ m_xWidthMF->save_value();
+ m_xHeightMF->save_value();
+
+ bModified |= nullptr != rSet->Put( *aSz );
+
+ if( bSetOrigSize )
+ {
+ bModified |= nullptr != rSet->Put( SvxSizeItem( rPool.GetWhich(
+ SID_ATTR_GRAF_FRMSIZE_PERCENT ), Size( 0, 0 )) );
+ }
+ }
+ if( m_xLeftMF->get_value_changed_from_saved() || m_xRightMF->get_value_changed_from_saved() ||
+ m_xTopMF->get_value_changed_from_saved() || m_xBottomMF->get_value_changed_from_saved() )
+ {
+ sal_uInt16 nW = rPool.GetWhich( SID_ATTR_GRAF_CROP );
+ FieldUnit eUnit = MapToFieldUnit( rSet->GetPool()->GetMetric( nW ));
+ std::unique_ptr<SvxGrfCrop> pNew(static_cast<SvxGrfCrop*>(rSet->Get( nW ).Clone()));
+
+ pNew->SetLeft( lcl_GetValue( *m_xLeftMF, eUnit ) );
+ pNew->SetRight( lcl_GetValue( *m_xRightMF, eUnit ) );
+ pNew->SetTop( lcl_GetValue( *m_xTopMF, eUnit ) );
+ pNew->SetBottom( lcl_GetValue( *m_xBottomMF, eUnit ) );
+ bModified |= nullptr != rSet->Put( *pNew );
+ }
+
+ if( m_xZoomConstRB->get_state_changed_from_saved() )
+ {
+ bModified |= nullptr != rSet->Put( SfxBoolItem( rPool.GetWhich(
+ SID_ATTR_GRAF_KEEP_ZOOM), m_xZoomConstRB->get_active() ) );
+ }
+
+ return bModified;
+}
+
+void SvxGrfCropPage::ActivatePage(const SfxItemSet& rSet)
+{
+#ifdef DBG_UTIL
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+#endif
+
+ bSetOrigSize = false;
+
+ // Size
+ Size aSize;
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_FRMSIZE, false, &pItem ) )
+ aSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ nOldWidth = aSize.Width();
+ nOldHeight = aSize.Height();
+
+ auto nWidth = m_xWidthMF->normalize(nOldWidth);
+ auto nHeight = m_xHeightMF->normalize(nOldHeight);
+
+ if (nWidth != m_xWidthMF->get_value(FieldUnit::TWIP))
+ m_xWidthMF->set_value(nWidth, FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ if (nHeight != m_xHeightMF->get_value(FieldUnit::TWIP))
+ m_xHeightMF->set_value(nHeight, FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+
+ if( SfxItemState::SET == rSet.GetItemState( SID_ATTR_GRAF_GRAPHIC, false, &pItem ) )
+ {
+ const SvxBrushItem& rBrush = *static_cast<const SvxBrushItem*>(pItem);
+ if( !rBrush.GetGraphicLink().isEmpty() &&
+ aGraphicName != rBrush.GetGraphicLink() )
+ aGraphicName = rBrush.GetGraphicLink();
+
+ OUString referer;
+ SfxStringItem const * it = static_cast<SfxStringItem const *>(
+ rSet.GetItem(SID_REFERER));
+ if (it != nullptr) {
+ referer = it->GetValue();
+ }
+ const Graphic* pGrf = rBrush.GetGraphic(referer);
+ if( pGrf )
+ {
+ m_aExampleWN.SetGraphic( *pGrf );
+ aOrigSize = GetGrfOrigSize( *pGrf );
+ if (pGrf->GetType() == GraphicType::Bitmap && aOrigSize.Width() > 1 && aOrigSize.Height() > 1) {
+ aOrigPixelSize = pGrf->GetSizePixel();
+ }
+ m_aExampleWN.SetFrameSize(aOrigSize);
+ GraphicHasChanged( aOrigSize.Width() && aOrigSize.Height() );
+ CalcMinMaxBorder();
+ }
+ else
+ GraphicHasChanged( false );
+ }
+
+ CalcZoom();
+}
+
+DeactivateRC SvxGrfCropPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+/*--------------------------------------------------------------------
+ description: scale changed, adjust size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, ZoomHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ if (&rField == m_xWidthZoomMF.get())
+ {
+ long nLRBorders = lcl_GetValue(*m_xLeftMF, eUnit)
+ +lcl_GetValue(*m_xRightMF, eUnit);
+ m_xWidthMF->set_value( m_xWidthMF->normalize(
+ ((aOrigSize.Width() - nLRBorders) * rField.get_value(FieldUnit::NONE))/100),
+ eUnit);
+ }
+ else
+ {
+ long nULBorders = lcl_GetValue(*m_xTopMF, eUnit)
+ +lcl_GetValue(*m_xBottomMF, eUnit);
+ m_xHeightMF->set_value( m_xHeightMF->normalize(
+ ((aOrigSize.Height() - nULBorders ) * rField.get_value(FieldUnit::NONE))/100) ,
+ eUnit );
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: change size, adjust scale
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, SizeHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ Size aSize( lcl_GetValue(*m_xWidthMF, eUnit),
+ lcl_GetValue(*m_xHeightMF, eUnit) );
+
+ if(&rField == m_xWidthMF.get())
+ {
+ long nWidth = aOrigSize.Width() -
+ ( lcl_GetValue(*m_xLeftMF, eUnit) +
+ lcl_GetValue(*m_xRightMF, eUnit) );
+ if(!nWidth)
+ nWidth++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Width() * 100 / nWidth);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+ else
+ {
+ long nHeight = aOrigSize.Height() -
+ ( lcl_GetValue(*m_xTopMF, eUnit) +
+ lcl_GetValue(*m_xBottomMF, eUnit));
+ if(!nHeight)
+ nHeight++;
+ sal_uInt16 nZoom = static_cast<sal_uInt16>( aSize.Height() * 100 / nHeight);
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+ }
+}
+
+/*--------------------------------------------------------------------
+ description: evaluate border
+ --------------------------------------------------------------------*/
+
+IMPL_LINK( SvxGrfCropPage, CropModifyHdl, weld::MetricSpinButton&, rField, void )
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ bool bZoom = m_xZoomConstRB->get_active();
+ if (&rField == m_xLeftMF.get() || &rField == m_xRightMF.get())
+ {
+ long nLeft = lcl_GetValue( *m_xLeftMF, eUnit );
+ long nRight = lcl_GetValue( *m_xRightMF, eUnit );
+ long nWidthZoom = static_cast<long>(m_xWidthZoomMF->get_value(FieldUnit::NONE));
+ if (bZoom && nWidthZoom != 0 && ( ( ( aOrigSize.Width() - (nLeft + nRight )) * nWidthZoom )
+ / 100 >= aPageSize.Width() ) )
+ {
+ if (&rField == m_xLeftMF.get())
+ {
+ nLeft = aOrigSize.Width() -
+ ( aPageSize.Width() * 100 / nWidthZoom + nRight );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nLeft ), eUnit );
+ }
+ else
+ {
+ nRight = aOrigSize.Width() -
+ ( aPageSize.Width() * 100 / nWidthZoom + nLeft );
+ m_xRightMF->set_value( m_xRightMF->normalize( nRight ), eUnit );
+ }
+ }
+ if (AllSettings::GetLayoutRTL())
+ {
+ m_aExampleWN.SetLeft(nRight);
+ m_aExampleWN.SetRight(nLeft);
+ }
+ else
+ {
+ m_aExampleWN.SetLeft(nLeft);
+ m_aExampleWN.SetRight(nRight);
+ }
+ if(bZoom)
+ {
+ // scale stays, recompute width
+ ZoomHdl(*m_xWidthZoomMF);
+ }
+ }
+ else
+ {
+ long nTop = lcl_GetValue( *m_xTopMF, eUnit );
+ long nBottom = lcl_GetValue( *m_xBottomMF, eUnit );
+ long nHeightZoom = static_cast<long>(m_xHeightZoomMF->get_value(FieldUnit::NONE));
+ if(bZoom && ( ( ( aOrigSize.Height() - (nTop + nBottom )) * nHeightZoom)
+ / 100 >= aPageSize.Height()))
+ {
+ assert(nHeightZoom && "div-by-zero");
+ if(&rField == m_xTopMF.get())
+ {
+ nTop = aOrigSize.Height() -
+ ( aPageSize.Height() * 100 / nHeightZoom + nBottom);
+ m_xTopMF->set_value( m_xWidthMF->normalize( nTop ), eUnit );
+ }
+ else
+ {
+ nBottom = aOrigSize.Height() -
+ ( aPageSize.Height() * 100 / nHeightZoom + nTop);
+ m_xBottomMF->set_value( m_xWidthMF->normalize( nBottom ), eUnit );
+ }
+ }
+ m_aExampleWN.SetTop( nTop );
+ m_aExampleWN.SetBottom( nBottom );
+ if(bZoom)
+ {
+ // scale stays, recompute height
+ ZoomHdl(*m_xHeightZoomMF);
+ }
+ }
+ m_aExampleWN.Invalidate();
+ // size and border changed -> recompute scale
+ if(!bZoom)
+ CalcZoom();
+ CalcMinMaxBorder();
+}
+/*--------------------------------------------------------------------
+ description: set original size
+ --------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxGrfCropPage, OrigSizeHdl, weld::Button&, void)
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ long nWidth = aOrigSize.Width() -
+ lcl_GetValue( *m_xLeftMF, eUnit ) -
+ lcl_GetValue( *m_xRightMF, eUnit );
+ m_xWidthMF->set_value( m_xWidthMF->normalize( nWidth ), eUnit );
+ long nHeight = aOrigSize.Height() -
+ lcl_GetValue( *m_xTopMF, eUnit ) -
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ m_xHeightMF->set_value( m_xHeightMF->normalize( nHeight ), eUnit );
+ m_xWidthZoomMF->set_value(100, FieldUnit::NONE);
+ m_xHeightZoomMF->set_value(100, FieldUnit::NONE);
+ bSetOrigSize = true;
+}
+/*--------------------------------------------------------------------
+ description: compute scale
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcZoom()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+
+ long nWidth = lcl_GetValue( *m_xWidthMF, eUnit );
+ long nHeight = lcl_GetValue( *m_xHeightMF, eUnit );
+ long nLRBorders = lcl_GetValue( *m_xLeftMF, eUnit ) +
+ lcl_GetValue( *m_xRightMF, eUnit );
+ long nULBorders = lcl_GetValue( *m_xTopMF, eUnit ) +
+ lcl_GetValue( *m_xBottomMF, eUnit );
+ sal_uInt16 nZoom = 0;
+ long nDen;
+ if( (nDen = aOrigSize.Width() - nLRBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nWidth * 1000 / nDen )+5)/10);
+ m_xWidthZoomMF->set_value(nZoom, FieldUnit::NONE);
+ if( (nDen = aOrigSize.Height() - nULBorders) > 0)
+ nZoom = static_cast<sal_uInt16>((( nHeight * 1000 / nDen )+5)/10);
+ else
+ nZoom = 0;
+ m_xHeightZoomMF->set_value(nZoom, FieldUnit::NONE);
+}
+
+/*--------------------------------------------------------------------
+ description: set minimum/maximum values for the margins
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::CalcMinMaxBorder()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ) );
+ long nR = lcl_GetValue(*m_xRightMF, eUnit );
+ long nMinWidth = (aOrigSize.Width() * 10) /11;
+ long nMin = nMinWidth - (nR >= 0 ? nR : 0);
+ m_xLeftMF->set_max( m_xLeftMF->normalize(nMin), eUnit );
+
+ long nL = lcl_GetValue(*m_xLeftMF, eUnit );
+ nMin = nMinWidth - (nL >= 0 ? nL : 0);
+ m_xRightMF->set_max( m_xRightMF->normalize(nMin), eUnit );
+
+ long nUp = lcl_GetValue( *m_xTopMF, eUnit );
+ long nMinHeight = (aOrigSize.Height() * 10) /11;
+ nMin = nMinHeight - (nUp >= 0 ? nUp : 0);
+ m_xBottomMF->set_max( m_xBottomMF->normalize(nMin), eUnit );
+
+ long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ nMin = nMinHeight - (nLow >= 0 ? nLow : 0);
+ m_xTopMF->set_max( m_xTopMF->normalize(nMin), eUnit );
+}
+/*--------------------------------------------------------------------
+ description: set spinsize to 1/20 of the original size,
+ fill FixedText with the original size
+ --------------------------------------------------------------------*/
+
+void SvxGrfCropPage::GraphicHasChanged( bool bFound )
+{
+ if( bFound )
+ {
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( pPool->GetWhich(
+ SID_ATTR_GRAF_CROP ) ));
+
+ sal_Int64 nSpin = m_xLeftMF->normalize(aOrigSize.Width()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit());
+
+ // if the margin is too big, it is set to 1/3 on both pages
+ long nR = lcl_GetValue( *m_xRightMF, eUnit );
+ long nL = lcl_GetValue( *m_xLeftMF, eUnit );
+ if((nL + nR) < - aOrigSize.Width())
+ {
+ long nVal = aOrigSize.Width() / -3;
+ m_xRightMF->set_value( m_xRightMF->normalize( nVal ), eUnit );
+ m_xLeftMF->set_value( m_xLeftMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetLeft(nVal);
+ m_aExampleWN.SetRight(nVal);
+ }
+ long nUp = lcl_GetValue(*m_xTopMF, eUnit );
+ long nLow = lcl_GetValue(*m_xBottomMF, eUnit );
+ if((nUp + nLow) < - aOrigSize.Height())
+ {
+ long nVal = aOrigSize.Height() / -3;
+ m_xTopMF->set_value( m_xTopMF->normalize( nVal ), eUnit );
+ m_xBottomMF->set_value( m_xBottomMF->normalize( nVal ), eUnit );
+ m_aExampleWN.SetTop(nVal);
+ m_aExampleWN.SetBottom(nVal);
+ }
+
+ m_xLeftMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xRightMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ nSpin = m_xTopMF->normalize(aOrigSize.Height()) / 20;
+ nSpin = vcl::ConvertValue( nSpin, aOrigSize.Width(), 0,
+ eUnit, m_xLeftMF->get_unit() );
+ m_xTopMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+ m_xBottomMF->set_increments(nSpin, nSpin * 10, FieldUnit::NONE);
+
+ // display original size
+ const FieldUnit eMetric = GetModuleFieldUnit( GetItemSet() );
+
+ OUString sTemp;
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/spinbox.ui"));
+ std::unique_ptr<weld::MetricSpinButton> xFld(xBuilder->weld_metric_spin_button("spin", FieldUnit::CM));
+ SetFieldUnit( *xFld, eMetric );
+ xFld->set_digits(m_xWidthMF->get_digits());
+ xFld->set_max(INT_MAX - 1, FieldUnit::NONE);
+
+ xFld->set_value(xFld->normalize(aOrigSize.Width()), eUnit);
+ sTemp = xFld->get_text();
+ xFld->set_value(xFld->normalize(aOrigSize.Height()), eUnit);
+ // multiplication sign (U+00D7)
+ sTemp += u"\u00D7" + xFld->get_text();
+ }
+
+ if ( aOrigPixelSize.Width() && aOrigPixelSize.Height() ) {
+ sal_Int32 ax = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Width()) /
+ (static_cast<float>(aOrigSize.Width())/TWIP_TO_INCH)+0.5));
+ sal_Int32 ay = sal_Int32(floor(static_cast<float>(aOrigPixelSize.Height()) /
+ (static_cast<float>(aOrigSize.Height())/TWIP_TO_INCH)+0.5));
+ sTemp += " " + CuiResId( RID_SVXSTR_PPI );
+ OUString sPPI = OUString::number(ax);
+ if (abs(ax - ay) > 1) {
+ sPPI += u"\u00D7" + OUString::number(ay);
+ }
+ sTemp = sTemp.replaceAll("%1", sPPI);
+ }
+ m_xOrigSizeFT->set_label(sTemp);
+ }
+
+ m_xCropFrame->set_sensitive(bFound);
+ m_xScaleFrame->set_sensitive(bFound);
+ m_xSizeFrame->set_sensitive(bFound);
+ m_xOrigSizeGrid->set_sensitive(bFound);
+ m_xZoomConstRB->set_sensitive(bFound);
+}
+
+Size SvxGrfCropPage::GetGrfOrigSize(const Graphic& rGrf)
+{
+ const MapMode aMapTwip( MapUnit::MapTwip );
+ Size aSize( rGrf.GetPrefSize() );
+ if( MapUnit::MapPixel == rGrf.GetPrefMapMode().GetMapUnit() )
+ aSize = Application::GetDefaultDevice()->PixelToLogic(aSize, aMapTwip);
+ else
+ aSize = OutputDevice::LogicToLogic( aSize,
+ rGrf.GetPrefMapMode(), aMapTwip );
+ return aSize;
+}
+
+/*****************************************************************/
+
+SvxCropExample::SvxCropExample()
+ : m_aTopLeft(0, 0)
+ , m_aBottomRight(0, 0)
+{
+}
+
+void SvxCropExample::SetDrawingArea(weld::DrawingArea* pDrawingArea)
+{
+ CustomWidgetController::SetDrawingArea(pDrawingArea);
+ OutputDevice& rDevice = pDrawingArea->get_ref_device();
+ Size aSize(rDevice.LogicToPixel(Size(78, 78), MapMode(MapUnit::MapAppFont)));
+ pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
+
+ m_aMapMode = rDevice.GetMapMode();
+ m_aFrameSize = OutputDevice::LogicToLogic(
+ Size(CM_1_TO_TWIP / 2, CM_1_TO_TWIP / 2),
+ MapMode(MapUnit::MapTwip), m_aMapMode);
+}
+
+void SvxCropExample::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(PushFlags::MAPMODE);
+ rRenderContext.SetMapMode(m_aMapMode);
+
+ // Win BG
+ const Size aWinSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+ rRenderContext.SetLineColor();
+ rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetWindowColor());
+ rRenderContext.DrawRect(::tools::Rectangle(Point(), aWinSize));
+
+ // use AA, the Graphic may be a metafile/svg and would then look ugly
+ rRenderContext.SetAntialiasing(AntialiasingFlags::EnableB2dDraw);
+
+ // draw Graphic
+ ::tools::Rectangle aRect(
+ Point((aWinSize.Width() - m_aFrameSize.Width())/2, (aWinSize.Height() - m_aFrameSize.Height())/2),
+ m_aFrameSize);
+ m_aGrf.Draw(&rRenderContext, aRect.TopLeft(), aRect.GetSize());
+
+ // Remove one more case that uses XOR paint (RasterOp::Invert).
+ // Get colors and logic DashLength from settings, use equal to
+ // PolygonMarkerPrimitive2D, may be changed to that primitive later.
+ // Use this to guarantee good visibility - that was the purpose of
+ // the former used XOR paint.
+ const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer;
+ const Color aColA(aSvtOptionsDrawinglayer.GetStripeColorA().getBColor());
+ const Color aColB(aSvtOptionsDrawinglayer.GetStripeColorB().getBColor());
+ const double fStripeLength(aSvtOptionsDrawinglayer.GetStripeLength());
+ const basegfx::B2DVector aDashVector(rRenderContext.GetInverseViewTransformation() * basegfx::B2DVector(fStripeLength, 0.0));
+ const double fLogicDashLength(aDashVector.getX());
+
+ // apply current crop settings
+ aRect.AdjustLeft(m_aTopLeft.Y());
+ aRect.AdjustTop(m_aTopLeft.X());
+ aRect.AdjustRight(-m_aBottomRight.Y());
+ aRect.AdjustBottom(-m_aBottomRight.X());
+
+ // apply dash with direct paint callbacks
+ basegfx::utils::applyLineDashing(
+ basegfx::utils::createPolygonFromRect(
+ basegfx::B2DRange(aRect.Left(), aRect.Top(), aRect.Right(), aRect.Bottom())),
+ std::vector< double >(2, fLogicDashLength),
+ [&aColA,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColA);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ [&aColB,&rRenderContext](const basegfx::B2DPolygon& rSnippet)
+ {
+ rRenderContext.SetLineColor(aColB);
+ rRenderContext.DrawPolyLine(rSnippet);
+ },
+ 2.0 * fLogicDashLength);
+
+ rRenderContext.Pop();
+}
+
+void SvxCropExample::Resize()
+{
+ SetFrameSize(m_aFrameSize);
+}
+
+void SvxCropExample::SetFrameSize( const Size& rSz )
+{
+ m_aFrameSize = rSz;
+ if (!m_aFrameSize.Width())
+ m_aFrameSize.setWidth( 1 );
+ if (!m_aFrameSize.Height())
+ m_aFrameSize.setHeight( 1 );
+ Size aWinSize( GetOutputSizePixel() );
+ Fraction aXScale( aWinSize.Width() * 4, m_aFrameSize.Width() * 5 );
+ Fraction aYScale( aWinSize.Height() * 4, m_aFrameSize.Height() * 5 );
+
+ if( aYScale < aXScale )
+ aXScale = aYScale;
+
+ m_aMapMode.SetScaleX(aXScale);
+ m_aMapMode.SetScaleY(aXScale);
+
+ Invalidate();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/labdlg.cxx b/cui/source/tabpages/labdlg.cxx
new file mode 100644
index 000000000..39098871b
--- /dev/null
+++ b/cui/source/tabpages/labdlg.cxx
@@ -0,0 +1,514 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <swpossizetabpage.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <svx/svddef.hxx>
+#include <svx/sxcecitm.hxx>
+#include <svx/sxcgitm.hxx>
+#include <svx/sxcllitm.hxx>
+#include <svx/sxctitm.hxx>
+
+#include <svx/dlgutil.hxx>
+#include <labdlg.hxx>
+#include <transfrm.hxx>
+#include <bitmaps.hlst>
+
+// define ----------------------------------------------------------------
+
+#define EXT_OPTIMAL 0
+#define EXT_FROM_TOP 1
+#define EXT_FROM_LEFT 2
+#define EXT_HORIZONTAL 3
+#define EXT_VERTICAL 4
+
+#define POS_TOP 0
+#define POS_MIDDLE 1
+#define POS_BOTTOM 2
+
+#define BMP_CAPTTYPE_1 1
+#define BMP_CAPTTYPE_2 2
+#define BMP_CAPTTYPE_3 3
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxCaptionTabPage::pCaptionRanges[] =
+{
+ SDRATTR_CAPTIONTYPE,
+ SDRATTR_CAPTIONFIXEDANGLE,
+ SDRATTR_CAPTIONANGLE,
+ SDRATTR_CAPTIONGAP,
+ SDRATTR_CAPTIONESCDIR,
+ SDRATTR_CAPTIONESCISREL,
+ SDRATTR_CAPTIONESCREL,
+ SDRATTR_CAPTIONESCABS,
+ SDRATTR_CAPTIONLINELEN,
+ SDRATTR_CAPTIONFITLINELEN,
+ 0
+};
+
+SvxCaptionTabPage::SvxCaptionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/calloutpage.ui", "CalloutPage", &rInAttrs)
+ , nCaptionType(SdrCaptionType::Type1)
+ , nGap(0)
+ , nEscDir(SdrCaptionEscDir::Horizontal)
+ , bEscRel(false)
+ , nEscAbs(0)
+ , nEscRel(0)
+ , nLineLen(0)
+ , bFitLineLen(false)
+ , nPosition(0)
+ , nExtension(0)
+ , rOutAttrs(rInAttrs)
+ , pView(nullptr)
+ , m_xMF_SPACING(m_xBuilder->weld_metric_spin_button("spacing", FieldUnit::MM))
+ , m_xLB_EXTENSION(m_xBuilder->weld_combo_box("extension"))
+ , m_xFT_BYFT(m_xBuilder->weld_label("byft"))
+ , m_xMF_BY(m_xBuilder->weld_metric_spin_button("by", FieldUnit::MM))
+ , m_xFT_POSITIONFT(m_xBuilder->weld_label("positionft"))
+ , m_xLB_POSITION(m_xBuilder->weld_combo_box("position"))
+ , m_xLineTypes(m_xBuilder->weld_combo_box("linetypes"))
+ , m_xFT_LENGTHFT(m_xBuilder->weld_label("lengthft"))
+ , m_xMF_LENGTH(m_xBuilder->weld_metric_spin_button("length", FieldUnit::MM))
+ , m_xCB_OPTIMAL(m_xBuilder->weld_check_button("optimal"))
+ , m_xCT_CAPTTYPE(new ValueSet(m_xBuilder->weld_scrolled_window("valuesetwin")))
+ , m_xCT_CAPTTYPEWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xCT_CAPTTYPE))
+{
+ Size aSize(m_xCT_CAPTTYPE->GetDrawingArea()->get_ref_device().LogicToPixel(Size(187, 38), MapMode(MapUnit::MapAppFont)));
+ m_xCT_CAPTTYPEWin->set_size_request(aSize.Width(), aSize.Height());
+
+ assert(m_xLB_POSITION->get_count() == 6);
+ for (int i = 0; i < 3; ++i)
+ m_aStrHorzList.push_back(m_xLB_POSITION->get_text(i));
+ for (int i = 3; i < 6; ++i)
+ m_aStrVertList.push_back(m_xLB_POSITION->get_text(i));
+ m_xLB_POSITION->clear();
+
+ assert(m_xLineTypes->get_count() == 3);
+ std::vector<OUString> aLineTypes;
+ aLineTypes.reserve(3);
+ for (int i = 0; i < 3; ++i)
+ aLineTypes.push_back(m_xLineTypes->get_text(i));
+
+ static_assert(CAPTYPE_BITMAPS_COUNT == 3, "unexpected");
+ m_aBmpCapTypes[0] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP1);
+ m_aBmpCapTypes[1] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP2);
+ m_aBmpCapTypes[2] = Image(StockImage::Yes, RID_SVXBMP_LEGTYP3);
+
+ //------------install ValueSet--------------------------
+ m_xCT_CAPTTYPE->SetStyle( m_xCT_CAPTTYPE->GetStyle() | WB_ITEMBORDER | WB_DOUBLEBORDER | WB_NAMEFIELD );
+ m_xCT_CAPTTYPE->SetColCount(5);//XXX
+ m_xCT_CAPTTYPE->SetLineCount(1);
+ m_xCT_CAPTTYPE->SetSelectHdl(LINK( this, SvxCaptionTabPage, SelectCaptTypeHdl_Impl));
+
+ Image aImage;
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_1, aImage, aLineTypes[0]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_2, aImage, aLineTypes[1]);
+ m_xCT_CAPTTYPE->InsertItem(BMP_CAPTTYPE_3, aImage, aLineTypes[2]);
+
+ FillValueSet();
+
+ m_xLB_EXTENSION->connect_changed(LINK(this, SvxCaptionTabPage, ExtensionSelectHdl_Impl));
+ m_xLB_POSITION->connect_changed(LINK(this, SvxCaptionTabPage, PositionSelectHdl_Impl));
+ m_xCB_OPTIMAL->connect_toggled(LINK(this, SvxCaptionTabPage, LineOptHdl_Impl));
+}
+
+SvxCaptionTabPage::~SvxCaptionTabPage()
+{
+ m_xCT_CAPTTYPEWin.reset();
+ m_xCT_CAPTTYPE.reset();
+}
+
+void SvxCaptionTabPage::Construct()
+{
+ // set rectangle and working area
+ DBG_ASSERT( pView, "No valid View transferred!" );
+}
+
+bool SvxCaptionTabPage::FillItemSet( SfxItemSet* _rOutAttrs)
+{
+ SfxItemPool* pPool = _rOutAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ MapUnit eUnit;
+
+ nCaptionType = static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()-1);
+
+ _rOutAttrs->Put( SdrCaptionTypeItem( nCaptionType ) );
+
+ if (m_xMF_SPACING->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONGAP ) );
+ _rOutAttrs->Put( SdrCaptionGapItem( GetCoreValue(*m_xMF_SPACING, eUnit ) ) );
+ }
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ _rOutAttrs->Put( SdrCaptionEscDirItem( nEscDir ) );
+
+ bEscRel = m_xLB_POSITION->get_visible();
+ _rOutAttrs->Put( SdrCaptionEscIsRelItem( bEscRel ) );
+
+ if( bEscRel )
+ {
+ long nVal = 0;
+
+ switch (m_xLB_POSITION->get_active())
+ {
+ case POS_TOP: nVal=0;break;
+ case POS_MIDDLE: nVal=5000;break;
+ case POS_BOTTOM: nVal=10000;break;
+ }
+ _rOutAttrs->Put( SdrCaptionEscRelItem( nVal ) );
+ }
+ else
+ {
+ if (m_xMF_BY->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONESCABS ) );
+ _rOutAttrs->Put( SdrCaptionEscAbsItem( GetCoreValue(*m_xMF_BY, eUnit ) ) );
+ }
+ }
+
+ bFitLineLen = m_xCB_OPTIMAL->get_active();
+ _rOutAttrs->Put( SdrCaptionFitLineLenItem( bFitLineLen ) );
+
+ if( ! bFitLineLen )
+ {
+ if (m_xMF_LENGTH->get_value_changed_from_saved())
+ {
+ eUnit = pPool->GetMetric( GetWhich( SDRATTR_CAPTIONLINELEN ) );
+ _rOutAttrs->Put( SdrCaptionLineLenItem( GetCoreValue(*m_xMF_LENGTH, eUnit ) ) );
+ }
+ }
+
+//NYI-------------the angles have to be added here!!! XXX----------------------
+
+ return true;
+}
+
+void SvxCaptionTabPage::Reset( const SfxItemSet* )
+{
+
+ //------------set metric-----------------------------
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rOutAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::CM:
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMF_SPACING, eFUnit );
+ SetFieldUnit( *m_xMF_BY, eFUnit );
+ SetFieldUnit( *m_xMF_LENGTH, eFUnit );
+
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ sal_uInt16 nWhich;
+ MapUnit eUnit;
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCABS );
+ eUnit = pPool->GetMetric( nWhich );
+ nEscAbs = static_cast<const SdrCaptionEscAbsItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_BY, nEscAbs, eUnit );
+ nEscAbs = m_xMF_BY->get_value(FieldUnit::NONE);
+
+ nWhich = GetWhich( SDRATTR_CAPTIONESCREL );
+ nEscRel = static_cast<long>(static_cast<const SdrCaptionEscRelItem&>( rOutAttrs.Get( nWhich ) ).GetValue());
+
+ //------- line length ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONLINELEN );
+ eUnit = pPool->GetMetric( nWhich );
+ nLineLen = static_cast<const SdrCaptionLineLenItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_LENGTH, nLineLen, eUnit );
+ nLineLen = m_xMF_LENGTH->get_value(FieldUnit::NONE);
+
+ //------- distance to box ----------
+ nWhich = GetWhich( SDRATTR_CAPTIONGAP );
+ eUnit = pPool->GetMetric( nWhich );
+ nGap = static_cast<const SdrCaptionGapItem&>( rOutAttrs.Get( nWhich ) ).GetValue();
+ SetMetricValue( *m_xMF_SPACING, nGap, eUnit );
+ nGap = m_xMF_SPACING->get_value(FieldUnit::NONE);
+
+ nCaptionType = static_cast<const SdrCaptionTypeItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONTYPE ) ) ).GetValue();
+ bFitLineLen = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONFITLINELEN ) ) ).GetValue();
+ nEscDir = static_cast<const SdrCaptionEscDirItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCDIR ) ) ).GetValue();
+ bEscRel = static_cast<const SfxBoolItem&>( rOutAttrs.Get( GetWhich( SDRATTR_CAPTIONESCISREL ) ) ).GetValue();
+
+ // special treatment!!! XXX
+ if( nCaptionType==SdrCaptionType::Type1 )
+ {
+ switch( nEscDir )
+ {
+ case SdrCaptionEscDir::Horizontal: nEscDir=SdrCaptionEscDir::Vertical;break;
+ case SdrCaptionEscDir::Vertical: nEscDir=SdrCaptionEscDir::Horizontal;break;
+ default: break;
+ }
+ }
+
+ nPosition = POS_MIDDLE;
+ nExtension = EXT_OPTIMAL;
+
+ m_xMF_SPACING->set_value(nGap, FieldUnit::NONE);
+
+ if( nEscDir == SdrCaptionEscDir::Horizontal )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_HORIZONTAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_TOP;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::Vertical )
+ {
+ if( bEscRel )
+ {
+ if( nEscRel < 3333 )
+ nPosition = POS_TOP;
+ if( nEscRel > 6666 )
+ nPosition = POS_BOTTOM;
+ nExtension = EXT_VERTICAL;
+ }
+ else
+ {
+ nExtension = EXT_FROM_LEFT;
+ m_xMF_BY->set_value(nEscAbs, FieldUnit::NONE);
+ }
+ }
+ else if( nEscDir == SdrCaptionEscDir::BestFit )
+ {
+ nExtension = EXT_OPTIMAL;
+ }
+
+ m_xCB_OPTIMAL->set_active(bFitLineLen);
+ m_xMF_LENGTH->set_value(nLineLen, FieldUnit::NONE);
+
+ m_xLB_EXTENSION->set_active(nExtension);
+
+ SetupExtension_Impl( nExtension );
+ m_xCT_CAPTTYPE->SelectItem( static_cast<int>(nCaptionType)+1 ); // Enum starts at 0!
+ SetupType_Impl( nCaptionType );
+}
+
+std::unique_ptr<SfxTabPage> SvxCaptionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxCaptionTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxCaptionTabPage::SetupExtension_Impl( sal_uInt16 nType )
+{
+ switch( nType )
+ {
+ case EXT_OPTIMAL:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::BestFit;
+ break;
+
+ case EXT_FROM_TOP:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_FROM_LEFT:
+ m_xMF_BY->show();
+ m_xFT_BYFT->show();
+ m_xFT_POSITIONFT->hide();
+ m_xLB_POSITION->hide();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+
+ case EXT_HORIZONTAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrHorzList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Horizontal;
+ break;
+
+ case EXT_VERTICAL:
+ m_xLB_POSITION->clear();
+ for (const OUString & i : m_aStrVertList)
+ m_xLB_POSITION->append_text(i);
+ m_xLB_POSITION->set_active(nPosition);
+
+ m_xMF_BY->hide();
+ m_xFT_BYFT->hide();
+ m_xFT_POSITIONFT->show();
+ m_xLB_POSITION->show();
+ nEscDir = SdrCaptionEscDir::Vertical;
+ break;
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, ExtensionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_EXTENSION.get())
+ {
+ SetupExtension_Impl(m_xLB_EXTENSION->get_active());
+ }
+}
+
+IMPL_LINK(SvxCaptionTabPage, PositionSelectHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (&rListBox == m_xLB_POSITION.get())
+ {
+ nPosition = m_xLB_POSITION->get_active();
+ }
+}
+
+IMPL_LINK( SvxCaptionTabPage, LineOptHdl_Impl, weld::ToggleButton&, rButton, void )
+{
+ if (&rButton != m_xCB_OPTIMAL.get())
+ return;
+
+ if (m_xCB_OPTIMAL->get_active() || !m_xCB_OPTIMAL->get_sensitive())
+ {
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xMF_LENGTH->set_sensitive(false);
+ }
+ else
+ {
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xMF_LENGTH->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxCaptionTabPage, SelectCaptTypeHdl_Impl, ValueSet*, void)
+{
+ SetupType_Impl( static_cast<SdrCaptionType>(m_xCT_CAPTTYPE->GetSelectedItemId()) );
+}
+
+void SvxCaptionTabPage::SetupType_Impl( SdrCaptionType nType )
+{
+ switch( nType )
+ {
+ case SdrCaptionType::Type1:
+ case SdrCaptionType::Type2:
+ m_xFT_LENGTHFT->set_sensitive(false);
+ m_xCB_OPTIMAL->set_sensitive(false);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ case SdrCaptionType::Type3:
+ case SdrCaptionType::Type4:
+ m_xFT_LENGTHFT->set_sensitive(true);
+ m_xCB_OPTIMAL->set_sensitive(true);
+ LineOptHdl_Impl(*m_xCB_OPTIMAL);
+ break;
+ }
+}
+
+void SvxCaptionTabPage::FillValueSet()
+{
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_1, m_aBmpCapTypes[0] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_2, m_aBmpCapTypes[1] );
+ m_xCT_CAPTTYPE->SetItemImage(BMP_CAPTTYPE_3, m_aBmpCapTypes[2] );
+}
+
+SvxCaptionTabDialog::SvxCaptionTabDialog(weld::Window* pParent, const SdrView* pSdrView,
+ SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/calloutdialog.ui", "CalloutDialog")
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ assert(pView); // No valid View transferred!
+
+ //different positioning page in Writer
+ if (nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create,
+ SvxSwPosSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create,
+ SvxPositionSizeTabPage::GetRanges );
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+ AddTabPage("RID_SVXPAGE_CAPTION", SvxCaptionTabPage::Create,
+ SvxCaptionTabPage::GetRanges );
+}
+
+void SvxCaptionTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ static_cast<SvxPositionSizeTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxPositionSizeTabPage&>( rPage ).Construct();
+ if( nAnchorCtrls & SvxAnchorIds::NoResize )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableResize();
+
+ if( nAnchorCtrls & SvxAnchorIds::NoProtect )
+ static_cast<SvxPositionSizeTabPage&>( rPage ).DisableProtect();
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPage = static_cast<SvxSwPosSizeTabPage&>(rPage);
+ rSwPage.EnableAnchorTypes(nAnchorCtrls);
+ rSwPage.SetValidateFramePosLink( aValidateLink );
+ }
+ else if (rId == "RID_SVXPAGE_CAPTION")
+ {
+ static_cast<SvxCaptionTabPage&>( rPage ).SetView( pView );
+ static_cast<SvxCaptionTabPage&>( rPage ).Construct();
+ }
+}
+
+void SvxCaptionTabDialog::SetValidateFramePosLink( const Link<SvxSwFrameValidation&,void>& rLink )
+{
+ aValidateLink = rLink;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/macroass.cxx b/cui/source/tabpages/macroass.cxx
new file mode 100644
index 000000000..df3e47bf4
--- /dev/null
+++ b/cui/source/tabpages/macroass.cxx
@@ -0,0 +1,389 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <macroass.hxx>
+
+#include <osl/diagnose.h>
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+#include <svl/macitem.hxx>
+#include <svx/svxids.hrc>
+#include <tools/debug.hxx>
+#include <vcl/idle.hxx>
+#include <cfgutil.hxx>
+#include <sfx2/evntconf.hxx>
+#include <headertablistbox.hxx>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::frame::XFrame;
+
+class SfxMacroTabPage_Impl
+{
+public:
+ SfxMacroTabPage_Impl();
+
+ OUString m_aStaticMacroLBLabel;
+ std::unique_ptr<weld::Button> m_xAssignPB;
+ std::unique_ptr<weld::Button> m_xDeletePB;
+ std::unique_ptr<MacroEventListBox> m_xEventLB;
+ std::unique_ptr<weld::Widget> m_xGroupFrame;
+ std::unique_ptr<CuiConfigGroupListBox> m_xGroupLB;
+ std::unique_ptr<weld::Frame> m_xMacroFrame;
+ std::unique_ptr<CuiConfigFunctionListBox> m_xMacroLB;
+
+ Idle m_aFillGroupIdle;
+ bool m_bGotEvents;
+};
+
+SfxMacroTabPage_Impl::SfxMacroTabPage_Impl()
+ : m_bGotEvents(false)
+{
+}
+
+static sal_uInt16 aPageRg[] = {
+ SID_ATTR_MACROITEM, SID_ATTR_MACROITEM,
+ 0
+};
+
+static OUString ConvertToUIName_Impl( SvxMacro const *pMacro )
+{
+ OUString aName( pMacro->GetMacName() );
+ if ( pMacro->GetLanguage() != "JavaScript" )
+ {
+ const sal_Int32 nCount = comphelper::string::getTokenCount(aName, '.');
+ OUString aEntry = aName.getToken( nCount-1, '.' );
+ if ( nCount > 2 )
+ {
+ aEntry += "(" + aName.getToken( 0, '.' ) + "." + aName.getToken( nCount-2, '.' ) + ")";
+ }
+ return aEntry;
+ }
+ else
+ return aName;
+}
+
+void SfxMacroTabPage::EnableButtons()
+{
+ // don't do anything as long as the eventbox is empty
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rTreeView.get_selected_index();
+ if (nSelected != -1)
+ {
+ // get bound macro
+ const SvxMacro* pM = aTbl.Get(static_cast<SvMacroItemId>(rTreeView.get_selected_id().toInt32()));
+ mpImpl->m_xDeletePB->set_sensitive(nullptr != pM);
+
+ OUString sEventMacro = rTreeView.get_text(nSelected, 1);
+
+ OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ mpImpl->m_xAssignPB->set_sensitive(!sScriptURI.equalsIgnoreAsciiCase(sEventMacro));
+ }
+ else
+ mpImpl->m_xAssignPB->set_sensitive(false);
+}
+
+SfxMacroTabPage::SfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rAttrSet )
+ : SfxTabPage(pPage, pController, "cui/ui/eventassignpage.ui", "EventAssignPage", &rAttrSet)
+{
+ mpImpl.reset(new SfxMacroTabPage_Impl);
+
+ mpImpl->m_aFillGroupIdle.SetInvokeHandler( LINK( this, SfxMacroTabPage, TimeOut_Impl ) );
+ mpImpl->m_aFillGroupIdle.SetPriority( TaskPriority::HIGHEST );
+ mpImpl->m_aFillGroupIdle.SetDebugName( "SfxMacroTabPage m_aFillGroupIdle" );
+
+ mpImpl->m_xEventLB.reset(new MacroEventListBox(m_xBuilder->weld_tree_view("assignments")));
+ mpImpl->m_xAssignPB = m_xBuilder->weld_button("assign");
+ mpImpl->m_xDeletePB = m_xBuilder->weld_button("delete");
+ mpImpl->m_xGroupFrame = m_xBuilder->weld_widget("groupframe");
+ mpImpl->m_xGroupLB.reset(new CuiConfigGroupListBox(m_xBuilder->weld_tree_view("libraries")));
+ mpImpl->m_xMacroFrame = m_xBuilder->weld_frame("macroframe");
+ mpImpl->m_aStaticMacroLBLabel = mpImpl->m_xMacroFrame->get_label();
+ mpImpl->m_xMacroLB.reset(new CuiConfigFunctionListBox(m_xBuilder->weld_tree_view("macros")));
+
+ SetFrame( rxDocumentFrame );
+
+ InitAndSetHandler();
+
+ ScriptChanged();
+}
+
+SfxMacroTabPage::~SfxMacroTabPage()
+{
+ mpImpl.reset();
+}
+
+void SfxMacroTabPage::AddEvent(const OUString& rEventName, SvMacroItemId nEventId)
+{
+ weld::TreeView& rTreeView = mpImpl->m_xEventLB->GetListBox();
+ rTreeView.append(OUString::number(static_cast<sal_Int32>(nEventId)), rEventName);
+
+ // if the table is valid already
+ SvxMacro* pM = aTbl.Get(nEventId);
+ if (pM)
+ {
+ OUString sNew(ConvertToUIName_Impl(pM));
+ rTreeView.set_text(rTreeView.n_children() - 1, sNew, 1);
+ }
+}
+
+void SfxMacroTabPage::ScriptChanged()
+{
+ // get new areas and their functions
+ mpImpl->m_xGroupFrame->show();
+ mpImpl->m_xMacroFrame->show();
+
+ EnableButtons();
+}
+
+bool SfxMacroTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ SvxMacroItem aItem( GetWhich( aPageRg[0] ) );
+ const_cast<SvxMacroTableDtor&>(aItem.GetMacroTable()) = aTbl;
+
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET != GetItemSet().GetItemState( aItem.Which(), true, &pItem )
+ || aItem != *static_cast<const SvxMacroItem*>(pItem) )
+ {
+ rSet->Put( aItem );
+ return true;
+ }
+ return false;
+}
+
+void SfxMacroTabPage::LaunchFillGroup()
+{
+ if (! mpImpl->m_aFillGroupIdle.IsActive() )
+ mpImpl->m_aFillGroupIdle.Start();
+}
+
+void SfxMacroTabPage::ActivatePage( const SfxItemSet& )
+{
+ LaunchFillGroup();
+}
+
+void SfxMacroTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxPoolItem* pEventsItem;
+ if( !mpImpl->m_bGotEvents && SfxItemState::SET == aSet.GetItemState( SID_EVENTCONFIG, true, &pEventsItem ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = static_cast<const SfxEventNamesItem*>(pEventsItem)->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+}
+
+void SfxMacroTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet->GetItemState( GetWhich( aPageRg[0] ), true, &pItem ))
+ aTbl = static_cast<const SvxMacroItem*>(pItem)->GetMacroTable();
+
+ const SfxPoolItem* pEventsItem;
+ if( !mpImpl->m_bGotEvents && SfxItemState::SET == rSet->GetItemState( SID_EVENTCONFIG, true, &pEventsItem ) )
+ {
+ mpImpl->m_bGotEvents = true;
+ const SfxEventNamesList& rList = static_cast<const SfxEventNamesItem*>(pEventsItem)->GetEvents();
+ for ( size_t nNo = 0, nCnt = rList.size(); nNo < nCnt; ++nNo )
+ {
+ const SfxEventName &rOwn = rList.at(nNo);
+ AddEvent( rOwn.maUIName, rOwn.mnId );
+ }
+ }
+
+ FillEvents();
+
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ std::unique_ptr<weld::TreeIter> xIter(rListBox.make_iterator());
+ if (rListBox.get_iter_first(*xIter))
+ rListBox.set_cursor(*xIter);
+}
+
+bool SfxMacroTabPage::IsReadOnly() const
+{
+ return false;
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectEvent_Impl, weld::TreeView&, void)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ ScriptChanged();
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectGroup_Impl, weld::TreeView&, void)
+{
+ mpImpl->m_xGroupLB->GroupSelected();
+ const OUString sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ OUString aLabelText;
+ if( !sScriptURI.isEmpty() )
+ aLabelText = mpImpl->m_aStaticMacroLBLabel;
+ mpImpl->m_xMacroFrame->set_label( aLabelText );
+
+ EnableButtons();
+}
+
+IMPL_LINK_NOARG(SfxMacroTabPage, SelectMacro_Impl, weld::TreeView&, void)
+{
+ EnableButtons();
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ AssignDeleteHdl(&rBtn);
+}
+
+IMPL_LINK(SfxMacroTabPage, AssignDeleteHdl_Impl, weld::TreeView&, rBtn, bool)
+{
+ AssignDeleteHdl(&rBtn);
+ return true;
+}
+
+void SfxMacroTabPage::AssignDeleteHdl(const weld::Widget* pBtn)
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ int nSelected = rListBox.get_selected_index();
+ if (nSelected == -1)
+ {
+ DBG_ASSERT(nSelected != -1, "Where does the empty entry come from?");
+ return;
+ }
+
+ const bool bAssEnabled = pBtn != mpImpl->m_xDeletePB.get() && mpImpl->m_xAssignPB->get_sensitive();
+
+ // remove from the table
+ SvMacroItemId nEvent = static_cast<SvMacroItemId>(rListBox.get_selected_id().toInt32());
+ aTbl.Erase( nEvent );
+
+ OUString sScriptURI;
+ if( bAssEnabled )
+ {
+ sScriptURI = mpImpl->m_xMacroLB->GetSelectedScriptURI();
+ if( sScriptURI.startsWith( "vnd.sun.star.script:" ) )
+ {
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_SF ) );
+ }
+ else
+ {
+ OSL_ENSURE( false, "SfxMacroTabPage::AssignDeleteHdl_Impl: this branch is *not* dead? (out of interest: tell fs, please!)" );
+ aTbl.Insert(
+ nEvent, SvxMacro( sScriptURI, SVX_MACRO_LANGUAGE_STARBASIC ) );
+ }
+ }
+
+ rListBox.set_text(nSelected, sScriptURI, 1);
+
+ EnableButtons();
+}
+
+IMPL_LINK( SfxMacroTabPage, TimeOut_Impl, Timer*,, void )
+{
+ // FillMacroList() can take a long time -> show wait cursor and disable input
+ weld::Window* pDialog = GetFrameWeld();
+ // perhaps the tabpage is part of a SingleTabDialog then pDialog == nullptr
+ std::unique_ptr<weld::WaitObject> xWait(pDialog ? new weld::WaitObject(pDialog) : nullptr);
+ // fill macro list
+ mpImpl->m_xGroupLB->Init(comphelper::getProcessComponentContext(), GetFrame(),
+ OUString(), false);
+}
+
+void SfxMacroTabPage::InitAndSetHandler()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+ Link<weld::TreeView&,bool> aLnk(LINK(this, SfxMacroTabPage, AssignDeleteHdl_Impl));
+ mpImpl->m_xMacroLB->connect_row_activated( aLnk);
+ mpImpl->m_xDeletePB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ mpImpl->m_xAssignPB->connect_clicked(LINK(this, SfxMacroTabPage, AssignDeleteClickHdl_Impl));
+ rListBox.connect_row_activated(aLnk);
+
+ rListBox.connect_changed(LINK(this, SfxMacroTabPage, SelectEvent_Impl));
+ mpImpl->m_xGroupLB->connect_changed(LINK(this, SfxMacroTabPage, SelectGroup_Impl));
+ mpImpl->m_xMacroLB->connect_changed(LINK(this, SfxMacroTabPage, SelectMacro_Impl));
+
+ std::vector<int> aWidths;
+ aWidths.push_back(rListBox.get_approximate_digit_width() * 35);
+ rListBox.set_column_fixed_widths(aWidths);
+
+ mpImpl->m_xEventLB->show();
+
+ mpImpl->m_xEventLB->set_sensitive(true);
+ mpImpl->m_xGroupLB->set_sensitive(true);
+ mpImpl->m_xMacroLB->set_sensitive(true);
+
+ mpImpl->m_xGroupLB->SetFunctionListBox(mpImpl->m_xMacroLB.get());
+}
+
+void SfxMacroTabPage::FillEvents()
+{
+ weld::TreeView& rListBox = mpImpl->m_xEventLB->GetListBox();
+
+ int nEntryCnt = rListBox.n_children();
+
+ // get events from the table and fill the EventListBox respectively
+ for (int n = 0 ; n < nEntryCnt; ++n)
+ {
+ OUString sOld = rListBox.get_text(n, 1);
+ OUString sNew;
+ SvMacroItemId nEventId = static_cast<SvMacroItemId>(rListBox.get_id(n).toInt32());
+ if (aTbl.IsKeyValid(nEventId))
+ sNew = ConvertToUIName_Impl(aTbl.Get(nEventId));
+
+ if (sOld == sNew)
+ continue;
+
+ rListBox.set_text(n, sNew, 1);
+ }
+}
+
+namespace
+{
+ std::unique_ptr<SfxMacroTabPage> CreateSfxMacroTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttrSet)
+ {
+ return std::make_unique<SfxMacroTabPage>( pPage, pController, nullptr, rAttrSet );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SfxMacroTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return CreateSfxMacroTabPage(pPage, pController, *rAttrSet);
+}
+
+SfxMacroAssignDlg::SfxMacroAssignDlg(weld::Widget* pParent,
+ const Reference< XFrame >& rxDocumentFrame, const SfxItemSet& rSet)
+ : SfxSingleTabDialogController(pParent, &rSet,"cui/ui/eventassigndialog.ui",
+ "EventAssignDialog")
+{
+ std::unique_ptr<SfxMacroTabPage> xPage = CreateSfxMacroTabPage(get_content_area(), this, rSet);
+ xPage->SetFrame(rxDocumentFrame);
+ SetTabPage(std::move(xPage));
+ GetTabPage()->LaunchFillGroup();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/measure.cxx b/cui/source/tabpages/measure.cxx
new file mode 100644
index 000000000..e7a7fbe12
--- /dev/null
+++ b/cui/source/tabpages/measure.cxx
@@ -0,0 +1,754 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+#include <svx/svxids.hrc>
+#include <svx/dlgutil.hxx>
+#include <svx/measctrl.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/strarray.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sxmbritm.hxx>
+#include <svx/sxmlhitm.hxx>
+#include <svx/sxmtfitm.hxx>
+#include <svx/sxmtpitm.hxx>
+#include <svx/sxmtritm.hxx>
+#include <svx/sxmuitm.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <measure.hxx>
+
+const sal_uInt16 SvxMeasurePage::pRanges[] =
+{
+ SDRATTR_MEASURE_FIRST,
+ SDRATTR_MEASURE_LAST,
+ 0
+};
+
+/*************************************************************************
+|*
+|* Dialog to change measure-attributes
+|*
+\************************************************************************/
+SvxMeasureDialog::SvxMeasureDialog(weld::Window* pParent, const SfxItemSet& rInAttrs,
+ const SdrView* pSdrView)
+ : SfxSingleTabDialogController(pParent, &rInAttrs)
+{
+ auto xPage = std::make_unique<SvxMeasurePage>(get_content_area(), this, rInAttrs);
+
+ xPage->SetView(pSdrView);
+ xPage->Construct();
+
+ SetTabPage(std::move(xPage));
+ m_xDialog->set_title(CuiResId(RID_SVXSTR_DIMENSION_LINE));
+}
+
+/*************************************************************************
+|*
+|* Tabpage for changing measure-attributes
+|*
+\************************************************************************/
+
+SvxMeasurePage::SvxMeasurePage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/dimensionlinestabpage.ui", "DimensionLinesTabPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aAttrSet(*rInAttrs.GetPool())
+ , pView(nullptr)
+ , eUnit(MapUnit::Map100thMM)
+ , bPositionModified(false)
+ , m_aCtlPosition(this)
+ , m_xMtrFldLineDist(m_xBuilder->weld_metric_spin_button("MTR_LINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelplineOverhang(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_OVERHANG", FieldUnit::MM))
+ , m_xMtrFldHelplineDist(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE_DIST", FieldUnit::MM))
+ , m_xMtrFldHelpline1Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE1_LEN", FieldUnit::MM))
+ , m_xMtrFldHelpline2Len(m_xBuilder->weld_metric_spin_button("MTR_FLD_HELPLINE2_LEN", FieldUnit::MM))
+ , m_xTsbBelowRefEdge(m_xBuilder->weld_check_button("TSB_BELOW_REF_EDGE"))
+ , m_xMtrFldDecimalPlaces(m_xBuilder->weld_spin_button("MTR_FLD_DECIMALPLACES"))
+ , m_xTsbAutoPosV(m_xBuilder->weld_check_button("TSB_AUTOPOSV"))
+ , m_xTsbAutoPosH(m_xBuilder->weld_check_button("TSB_AUTOPOSH"))
+ , m_xTsbShowUnit(m_xBuilder->weld_check_button("TSB_SHOW_UNIT"))
+ , m_xLbUnit(m_xBuilder->weld_combo_box("LB_UNIT"))
+ , m_xTsbParallel(m_xBuilder->weld_check_button("TSB_PARALLEL"))
+ , m_xFtAutomatic(m_xBuilder->weld_label("STR_MEASURE_AUTOMATIC"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ m_aCtlPreview.SetAttributes(rInAttrs);
+
+ FillUnitLB();
+
+ const FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineOverhang, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelplineDist, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline1Len, eFUnit );
+ SetFieldUnit( *m_xMtrFldHelpline2Len, eFUnit );
+ if( eFUnit == FieldUnit::MM )
+ {
+ m_xMtrFldLineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineOverhang->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelplineDist->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline1Len->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrFldHelpline2Len->set_increments(50, 500, FieldUnit::NONE);
+ }
+
+ m_xTsbAutoPosV->connect_toggled(LINK( this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+ m_xTsbAutoPosH->connect_toggled(LINK(this, SvxMeasurePage, ClickAutoPosHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink(LINK(this, SvxMeasurePage, ChangeAttrEditHdl_Impl));
+ m_xMtrFldLineDist->connect_value_changed(aLink);
+ m_xMtrFldHelplineOverhang->connect_value_changed(aLink);
+ m_xMtrFldHelplineDist->connect_value_changed(aLink);
+ m_xMtrFldHelpline1Len->connect_value_changed(aLink);
+ m_xMtrFldHelpline2Len->connect_value_changed(aLink);
+ m_xMtrFldDecimalPlaces->connect_value_changed(LINK(this, SvxMeasurePage, ChangeAttrSpinHdl_Impl));
+ m_xTsbBelowRefEdge->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbParallel->connect_toggled( LINK( this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xTsbShowUnit->connect_toggled(LINK(this, SvxMeasurePage, ChangeAttrClickHdl_Impl));
+ m_xLbUnit->connect_changed(LINK(this, SvxMeasurePage, ChangeAttrListBoxHdl_Impl));
+}
+
+SvxMeasurePage::~SvxMeasurePage()
+{
+ m_xCtlPreview.reset();
+ m_xCtlPosition.reset();
+}
+
+/*************************************************************************
+|*
+|* read the delivered Item-Set
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_MEASURELINEDIST );
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_MEASURELINEDIST );
+
+ // SdrMeasureLineDistItem
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASURELINEDIST );
+ SetMetricValue(*m_xMtrFldLineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLineDist->save_value();
+
+ // SdrMeasureHelplineOverhangItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEOVERHANG );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEOVERHANG );
+ SetMetricValue(*m_xMtrFldHelplineOverhang, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineOverhang->save_value();
+
+ // SdrMeasureHelplineDistItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINEDIST );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINEDIST );
+ SetMetricValue(*m_xMtrFldHelplineDist, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelplineDist->save_value();
+
+ // SdrMeasureHelpline1LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE1LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE1LEN );
+ SetMetricValue(*m_xMtrFldHelpline1Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline1Len->save_value();
+
+ // SdrMeasureHelpline2LenItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREHELPLINE2LEN );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREHELPLINE2LEN );
+ SetMetricValue(*m_xMtrFldHelpline2Len, static_cast<const SdrMetricItem*>(pItem)->GetValue(),
+ eUnit);
+ m_xMtrFldHelpline2Len->save_value();
+
+ // SdrMeasureBelowRefEdgeItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREBELOWREFEDGE ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbBelowRefEdge->set_state( rAttrs->Get( SDRATTR_MEASUREBELOWREFEDGE ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbBelowRefEdge->set_state( TRISTATE_INDET );
+ }
+ m_xTsbBelowRefEdge->save_state();
+
+ // SdrMeasureDecimalPlacesItem
+ pItem = GetItem( *rAttrs, SDRATTR_MEASUREDECIMALPLACES );
+ if( pItem == nullptr )
+ pItem = &pPool->GetDefaultItem( SDRATTR_MEASUREDECIMALPLACES );
+ m_xMtrFldDecimalPlaces->set_value(
+ static_cast<const SdrMeasureDecimalPlacesItem*>(pItem)->GetValue());
+ m_xMtrFldDecimalPlaces->save_value();
+
+ // SdrMeasureTextRota90Item
+ // Attention: negate !
+ if( rAttrs->GetItemState( SDRATTR_MEASURETEXTROTA90 ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbParallel->set_state( rAttrs->Get( SDRATTR_MEASURETEXTROTA90 ).
+ GetValue() ? TRISTATE_FALSE : TRISTATE_TRUE );
+ }
+ else
+ {
+ m_xTsbParallel->set_state( TRISTATE_INDET );
+ }
+ m_xTsbParallel->save_state();
+
+ // SdrMeasureShowUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASURESHOWUNIT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbShowUnit->set_state( rAttrs->Get( SDRATTR_MEASURESHOWUNIT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbShowUnit->set_state( TRISTATE_INDET );
+ }
+ m_xTsbShowUnit->save_state();
+
+ // SdrMeasureUnitItem
+ if( rAttrs->GetItemState( SDRATTR_MEASUREUNIT ) != SfxItemState::DONTCARE )
+ {
+ long nFieldUnit = static_cast<long>(rAttrs->Get( SDRATTR_MEASUREUNIT ).GetValue());
+
+ for (sal_Int32 i = 0; i < m_xLbUnit->get_count(); ++i)
+ {
+ if (m_xLbUnit->get_id(i).toInt32() == nFieldUnit)
+ {
+ m_xLbUnit->set_active(i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ m_xLbUnit->set_active(-1);
+ }
+ m_xLbUnit->save_value();
+
+ // Position
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextVertPos eVPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTVPOS ).GetValue();
+ {
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ css::drawing::MeasureTextHorzPos eHPos =
+ rAttrs->Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ RectPoint eRP = RectPoint::MM;
+ switch( eVPos )
+ {
+ case css::drawing::MeasureTextVertPos_EAST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LT; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MT; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RT; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MT; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_CENTERED:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_WEST:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LB; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MB; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RB; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MB; break;
+ default: break;
+ }
+ break;
+ case css::drawing::MeasureTextVertPos_AUTO:
+ switch( eHPos )
+ {
+ case css::drawing::MeasureTextHorzPos_LEFTOUTSIDE: eRP = RectPoint::LM; break;
+ case css::drawing::MeasureTextHorzPos_INSIDE: eRP = RectPoint::MM; break;
+ case css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE: eRP = RectPoint::RM; break;
+ case css::drawing::MeasureTextHorzPos_AUTO: eRP = RectPoint::MM; break;
+ default: break;
+ }
+ break;
+ default: ;//prevent warning
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (eHPos == css::drawing::MeasureTextHorzPos_AUTO)
+ {
+ m_xTsbAutoPosH->set_state( TRISTATE_TRUE );
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (eVPos == css::drawing::MeasureTextVertPos_AUTO)
+ {
+ m_xTsbAutoPosV->set_state( TRISTATE_TRUE );
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ m_aCtlPosition.SetState(nState);
+ m_aCtlPosition.SetActualRP(eRP);
+ }
+ }
+ }
+ else
+ {
+ m_aCtlPosition.Reset();
+ m_xTsbAutoPosV->set_state( TRISTATE_INDET );
+ m_xTsbAutoPosH->set_state( TRISTATE_INDET );
+ }
+
+ // put the attributes to the preview-control,
+ // otherwise the control don't know about
+ // the settings of the dialog (#67930)
+ ChangeAttrHdl_Impl(m_xTsbShowUnit.get());
+ m_aCtlPreview.SetAttributes(*rAttrs);
+
+ bPositionModified = false;
+}
+
+/*************************************************************************
+|*
+|* Fill the delivered Item-Set with dialogbox-attributes
+|*
+\************************************************************************/
+
+bool SvxMeasurePage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureLineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineOverhang->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineOverhangItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelplineDist->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ rAttrs->Put( makeSdrMeasureHelplineDistItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline1Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldHelpline2Len->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ rAttrs->Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbBelowRefEdge->get_state();
+ if( m_xTsbBelowRefEdge->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ if( m_xMtrFldDecimalPlaces->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDecimalPlaces->get_value();
+ rAttrs->Put(
+ SdrMeasureDecimalPlacesItem(
+ sal::static_int_cast< sal_Int16 >( nValue ) ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbParallel->get_state();
+ if( m_xTsbParallel->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ bModified = true;
+ }
+
+ eState = m_xTsbShowUnit->get_state();
+ if( m_xTsbShowUnit->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( SdrYesNoItem(SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ int nPos = m_xLbUnit->get_active();
+ if( m_xLbUnit->get_value_changed_from_saved() )
+ {
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ rAttrs->Put( SdrMeasureUnitItem( _eUnit ) );
+ bModified = true;
+ }
+ }
+
+ if( bPositionModified )
+ {
+ // Position
+ css::drawing::MeasureTextVertPos eVPos, eOldVPos;
+ css::drawing::MeasureTextHorzPos eHPos, eOldHPos;
+
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTVPOS ) != SfxItemState::DONTCARE )
+ {
+ eOldVPos = rOutAttrs.Get(SDRATTR_MEASURETEXTVPOS).GetValue();
+ if( eOldVPos != eVPos )
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextVPosItem( eVPos ) );
+ bModified = true;
+ }
+
+ if ( rAttrs->GetItemState( SDRATTR_MEASURETEXTHPOS ) != SfxItemState::DONTCARE )
+ {
+ eOldHPos = rOutAttrs.Get( SDRATTR_MEASURETEXTHPOS ).GetValue();
+ if( eOldHPos != eHPos )
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+ else
+ {
+ rAttrs->Put( SdrMeasureTextHPosItem( eHPos ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* The View have to set at the measure-object to be able to notify
+|* unit and floatingpoint-values
+|*
+\************************************************************************/
+
+void SvxMeasurePage::Construct()
+{
+ DBG_ASSERT( pView, "No valid View transferred!" );
+
+ // TTTT
+ // pMeasureObj is member of SvxXMeasurePreview and can only be accessed due to
+ // SvxMeasurePage being a friend. It has its own SdrModel (also in SvxXMeasurePreview)
+ // and 'setting' the SdrModel is a hack. The comment above about 'notify unit and
+ // floatingpoint-values' is not clear, but has to be done another way - if needed.
+ // Checked on original aw080, is just commented out there, too.
+
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxMeasurePage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxMeasurePage>(pPage, pController, *rAttrs);
+}
+
+void SvxMeasurePage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint /*eRP*/)
+{
+ ChangeAttrHdl_Impl(pDrawingArea);
+}
+
+IMPL_LINK( SvxMeasurePage, ClickAutoPosHdl_Impl, weld::ToggleButton&, rBox, void )
+{
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrClickHdl_Impl, weld::ToggleButton&, r, void)
+{
+ ChangeAttrHdl_Impl(&r);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrListBoxHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK(SvxMeasurePage, ChangeAttrEditHdl_Impl, weld::MetricSpinButton&, rBox, void)
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+IMPL_LINK( SvxMeasurePage, ChangeAttrSpinHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ChangeAttrHdl_Impl(&rBox);
+}
+
+void SvxMeasurePage::ChangeAttrHdl_Impl( void const * p )
+{
+ if (p == m_xMtrFldLineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldLineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureLineDistItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelplineOverhang.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineOverhang, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineOverhangItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelplineDist.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelplineDist, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelplineDistItem( nValue) );
+ }
+
+ if (p == m_xMtrFldHelpline1Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline1Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline1LenItem( nValue ) );
+ }
+
+ if (p == m_xMtrFldHelpline2Len.get())
+ {
+ sal_Int32 nValue = GetCoreValue( *m_xMtrFldHelpline2Len, eUnit );
+ aAttrSet.Put( makeSdrMeasureHelpline2LenItem( nValue ) );
+ }
+
+ if (p == m_xTsbBelowRefEdge.get())
+ {
+ TriState eState = m_xTsbBelowRefEdge->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureBelowRefEdgeItem( TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xMtrFldDecimalPlaces.get())
+ {
+ sal_Int16 nValue = sal::static_int_cast< sal_Int16 >(
+ m_xMtrFldDecimalPlaces->get_value() );
+ aAttrSet.Put( SdrMeasureDecimalPlacesItem( nValue ) );
+ }
+
+ if (p == m_xTsbParallel.get())
+ {
+ TriState eState = m_xTsbParallel->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrMeasureTextRota90Item( TRISTATE_FALSE == eState ) );
+ }
+
+ if (p == m_xTsbShowUnit.get())
+ {
+ TriState eState = m_xTsbShowUnit->get_state();
+ if( eState != TRISTATE_INDET )
+ aAttrSet.Put( SdrYesNoItem( SDRATTR_MEASURESHOWUNIT, TRISTATE_TRUE == eState ) );
+ }
+
+ if (p == m_xLbUnit.get())
+ {
+ int nPos = m_xLbUnit->get_active();
+ if (nPos != -1)
+ {
+ sal_uInt16 nFieldUnit = m_xLbUnit->get_id(nPos).toUInt32();
+ FieldUnit _eUnit = static_cast<FieldUnit>(nFieldUnit);
+ aAttrSet.Put( SdrMeasureUnitItem( _eUnit ) );
+ }
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get() || p == m_aCtlPosition.GetDrawingArea())
+ {
+ bPositionModified = true;
+
+ // Position
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ css::drawing::MeasureTextVertPos eVPos;
+ css::drawing::MeasureTextHorzPos eHPos;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::LB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_LEFTOUTSIDE; break;
+ case RectPoint::MT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::MB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_INSIDE; break;
+ case RectPoint::RT: eVPos = css::drawing::MeasureTextVertPos_EAST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RM: eVPos = css::drawing::MeasureTextVertPos_CENTERED;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ case RectPoint::RB: eVPos = css::drawing::MeasureTextVertPos_WEST;
+ eHPos = css::drawing::MeasureTextHorzPos_RIGHTOUTSIDE; break;
+ }
+
+ CTL_STATE nState = CTL_STATE::NONE;
+
+ if (m_xTsbAutoPosH->get_state() == TRISTATE_TRUE)
+ {
+ eHPos = css::drawing::MeasureTextHorzPos_AUTO;
+ nState = CTL_STATE::NOHORZ;
+ }
+
+ if (m_xTsbAutoPosV->get_state() == TRISTATE_TRUE)
+ {
+ eVPos = css::drawing::MeasureTextVertPos_AUTO;
+ nState |= CTL_STATE::NOVERT;
+ }
+
+ if (p == m_xTsbAutoPosV.get() || p == m_xTsbAutoPosH.get())
+ m_aCtlPosition.SetState( nState );
+
+ aAttrSet.Put( SdrMeasureTextVPosItem( eVPos ) );
+ aAttrSet.Put( SdrMeasureTextHPosItem( eHPos ) );
+ }
+
+ m_aCtlPreview.SetAttributes(aAttrSet);
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxMeasurePage::FillUnitLB()
+{
+ // fill ListBox with metrics
+
+ FieldUnit nUnit = FieldUnit::NONE;
+ OUString aStrMetric(m_xFtAutomatic->get_label());
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+
+ for( sal_uInt32 i = 0; i < SvxFieldUnitTable::Count(); ++i )
+ {
+ aStrMetric = SvxFieldUnitTable::GetString(i);
+ nUnit = SvxFieldUnitTable::GetValue(i);
+ m_xLbUnit->append(OUString::number(sal_uInt32(nUnit)), aStrMetric);
+ }
+}
+
+void SvxMeasurePage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const OfaPtrItem* pOfaPtrItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+
+ if (pOfaPtrItem)
+ SetView( static_cast<SdrView *>(pOfaPtrItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numfmt.cxx b/cui/source/tabpages/numfmt.cxx
new file mode 100644
index 000000000..5e3e4252a
--- /dev/null
+++ b/cui/source/tabpages/numfmt.cxx
@@ -0,0 +1,1767 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <o3tl/safeint.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/outdev.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <i18nlangtag/lang.h>
+#include <svx/svxids.hrc>
+#include <svtools/colorcfg.hxx>
+
+#include <numcategories.hrc>
+#include <strings.hrc>
+
+#include <svx/numinf.hxx>
+
+#include <numfmt.hxx>
+#include <svx/numfmtsh.hxx>
+#include <dialmgr.hxx>
+#include <sfx2/basedlgs.hxx>
+#include <svx/flagsdef.hxx>
+#include <vector>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <memory>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::lang::XServiceInfo;
+using ::com::sun::star::uno::UNO_QUERY;
+
+#define NUMKEY_UNDEFINED SAL_MAX_UINT32
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxNumberFormatTabPage::pRanges[] =
+{
+ SID_ATTR_NUMBERFORMAT_VALUE,
+ SID_ATTR_NUMBERFORMAT_INFO,
+ SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
+ SID_ATTR_NUMBERFORMAT_NOLANGUAGE,
+ SID_ATTR_NUMBERFORMAT_ONE_AREA,
+ SID_ATTR_NUMBERFORMAT_ONE_AREA,
+ SID_ATTR_NUMBERFORMAT_SOURCE,
+ SID_ATTR_NUMBERFORMAT_SOURCE,
+ 0
+};
+
+/*************************************************************************
+#* Method: SvxNumberPreview
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Constructor of the class SvxNumberPreview
+#* Input: Window, Resource-ID
+#* Output: ---
+#*
+#************************************************************************/
+
+SvxNumberPreview::SvxNumberPreview()
+ : mnPos(-1)
+ , mnChar(0x0)
+{
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for changing the preview string
+#* Input: String, color
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::NotifyChange( const OUString& rPrevStr,
+ const Color* pColor )
+{
+ // detect and strip out '*' related placeholders
+ aPrevStr = rPrevStr;
+ mnPos = aPrevStr.indexOf( 0x1B );
+ if ( mnPos != -1 )
+ {
+ // Right during user input the star symbol is the very
+ // last character before the user enters another one.
+ if (mnPos < aPrevStr.getLength() - 1)
+ {
+ mnChar = aPrevStr[ mnPos + 1 ];
+ // delete placeholder and char to repeat
+ aPrevStr = aPrevStr.replaceAt( mnPos, 2, "" );
+ }
+ else
+ {
+ // delete placeholder
+ aPrevStr = aPrevStr.replaceAt( mnPos, 1, "" );
+ // do not attempt to draw a 0 fill character
+ mnPos = -1;
+ }
+ }
+ svtools::ColorConfig aColorConfig;
+ Color aWindowTextColor( aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor );
+ aPrevCol = pColor ? *pColor : aWindowTextColor;
+ Invalidate();
+}
+
+/*************************************************************************
+#* Method: Paint
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberPreview
+#* Function: Function for repainting the window.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ rRenderContext.Push(PushFlags::ALL);
+
+ svtools::ColorConfig aColorConfig;
+ rRenderContext.SetTextColor(aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor);
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ rRenderContext.SetBackground(rStyleSettings.GetWindowColor());
+
+ vcl::Font aDrawFont = rRenderContext.GetFont();
+ Size aSzWnd(GetOutputSizePixel());
+ OUString aTmpStr( aPrevStr );
+ long nLeadSpace = (aSzWnd.Width() - rRenderContext.GetTextWidth(aTmpStr)) / 2;
+
+ aDrawFont.SetTransparent(true);
+ aDrawFont.SetColor(aPrevCol);
+ rRenderContext.SetFont(aDrawFont);
+
+ if (mnPos != -1)
+ {
+ long nCharWidth = rRenderContext.GetTextWidth(OUString(mnChar));
+
+ int nNumCharsToInsert = 0;
+ if (nCharWidth > 0)
+ nNumCharsToInsert = nLeadSpace / nCharWidth;
+
+ if (nNumCharsToInsert > 0)
+ {
+ for (int i = 0; i < nNumCharsToInsert; ++i)
+ aTmpStr = aTmpStr.replaceAt(mnPos, 0, OUString(mnChar));
+ }
+ }
+
+ long nX = 0;
+ if (mnPos == -1 && nLeadSpace > 0) //tdf#122120 if it won't fit anyway, then left align it
+ {
+ nX = nLeadSpace;
+ }
+
+ Point aPosText(nX, (aSzWnd.Height() - GetTextHeight()) / 2);
+ rRenderContext.DrawText(aPosText, aTmpStr);
+ rRenderContext.Pop();
+}
+
+// class SvxNumberFormatTabPage ------------------------------------------
+
+#define REMOVE_DONTKNOW() \
+ if (!m_xFtLanguage->get_sensitive()) \
+ { \
+ m_xFtLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_sensitive(true); \
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage()); \
+ }
+
+#define HDL(hdl) LINK( this, SvxNumberFormatTabPage, hdl )
+
+SvxNumberFormatTabPage::SvxNumberFormatTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rCoreAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingformatpage.ui", "NumberingFormatPage", &rCoreAttrs)
+ , nInitFormat(ULONG_MAX)
+ , m_nLbFormatSelPosEdComment(SELPOS_NONE)
+ , bLegacyAutomaticCurrency(false)
+ , sAutomaticLangEntry(CuiResId(RID_SVXSTR_AUTO_ENTRY))
+ , m_xFtCategory(m_xBuilder->weld_label("categoryft"))
+ , m_xLbCategory(m_xBuilder->weld_tree_view("categorylb"))
+ , m_xFtFormat(m_xBuilder->weld_label("formatft"))
+ , m_xLbCurrency(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xLbFormat(m_xBuilder->weld_tree_view("formatlb"))
+ , m_xFtLanguage(m_xBuilder->weld_label("languageft"))
+ , m_xCbSourceFormat(m_xBuilder->weld_check_button("sourceformat"))
+ , m_xFtOptions(m_xBuilder->weld_label("optionsft"))
+ , m_xFtDecimals(m_xBuilder->weld_label("decimalsft"))
+ , m_xEdDecimals(m_xBuilder->weld_spin_button("decimalsed"))
+ , m_xFtDenominator(m_xBuilder->weld_label("denominatorft"))
+ , m_xEdDenominator(m_xBuilder->weld_spin_button("denominatored"))
+ , m_xBtnNegRed(m_xBuilder->weld_check_button("negnumred"))
+ , m_xFtLeadZeroes(m_xBuilder->weld_label("leadzerosft"))
+ , m_xEdLeadZeroes(m_xBuilder->weld_spin_button("leadzerosed"))
+ , m_xBtnThousand(m_xBuilder->weld_check_button("thousands"))
+ , m_xBtnEngineering(m_xBuilder->weld_check_button("engineering"))
+ , m_xFormatCodeFrame(m_xBuilder->weld_widget("formatcode"))
+ , m_xEdFormat(m_xBuilder->weld_entry("formatted"))
+ , m_xIbAdd(m_xBuilder->weld_button("add"))
+ , m_xIbInfo(m_xBuilder->weld_button("edit"))
+ , m_xIbRemove(m_xBuilder->weld_button("delete"))
+ , m_xFtComment(m_xBuilder->weld_label("commentft"))
+ , m_xEdComment(m_xBuilder->weld_entry("commented"))
+ , m_xLbLanguage(new SvxLanguageBox(m_xBuilder->weld_combo_box("languagelb")))
+ , m_xWndPreview(new weld::CustomWeld(*m_xBuilder, "preview", m_aWndPreview))
+{
+ for (size_t i = 0; i < SAL_N_ELEMENTS(NUM_CATEGORIES); ++i)
+ m_xLbCategory->append_text(CuiResId(NUM_CATEGORIES[i]));
+
+ auto nWidth = m_xLbCategory->get_approximate_digit_width() * 22;
+ m_xLbCategory->set_size_request(nWidth, m_xLbCategory->get_height_rows(7));
+ m_xLbFormat->set_size_request(nWidth, m_xLbFormat->get_height_rows(5));
+ m_xLbCurrency->set_size_request(nWidth, -1); // force using (narrower) width of its LbFormat sibling
+
+ // Initially remove the "Automatically" entry.
+ m_xLbCurrency->set_active(-1); // First ensure that nothing is selected.
+ sAutomaticCurrencyEntry = m_xLbCurrency->get_text(0);
+ m_xLbCurrency->remove(0);
+
+ Init_Impl();
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ nFixedCategory=-1;
+}
+
+SvxNumberFormatTabPage::~SvxNumberFormatTabPage()
+{
+ pNumFmtShell.reset();
+ pNumItem.reset();
+ m_xWndPreview.reset();
+ m_xLbLanguage.reset();
+}
+
+void SvxNumberFormatTabPage::Init_Impl()
+{
+ bNumItemFlag=true;
+ bOneAreaFlag=false;
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdComment->hide();
+
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(false);
+ m_xCbSourceFormat->hide();
+
+ Link<weld::TreeView&,void> aLink2 = LINK(this, SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl);
+ Link<weld::ComboBox&,void> aLink3 = LINK(this, SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl);
+ m_xLbCategory->connect_changed(aLink2);
+ m_xLbCategory->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_changed(aLink2);
+ m_xLbFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbLanguage->connect_changed(aLink3);
+ m_xLbLanguage->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbCurrency->connect_changed(aLink3);
+ m_xLbCurrency->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xCbSourceFormat->connect_clicked(LINK(this, SvxNumberFormatTabPage, SelFormatClickHdl_Impl));
+ m_xCbSourceFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ Link<weld::SpinButton&,void> aLink = LINK( this, SvxNumberFormatTabPage, OptEditHdl_Impl );
+
+ m_xEdDecimals->connect_value_changed(aLink);
+ m_xEdDecimals->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdDenominator->connect_value_changed(aLink);
+ m_xEdDenominator->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xEdLeadZeroes->connect_value_changed(aLink);
+ m_xEdLeadZeroes->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+
+ m_xBtnNegRed->connect_clicked(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnNegRed->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnThousand->connect_clicked(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnThousand->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xBtnEngineering->connect_clicked(LINK(this, SvxNumberFormatTabPage, OptClickHdl_Impl));
+ m_xBtnEngineering->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xLbFormat->connect_row_activated(HDL(DoubleClickHdl_Impl));
+ m_xEdFormat->connect_changed(HDL(EditModifyHdl_Impl));
+ m_xEdFormat->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbAdd->connect_clicked(HDL(ClickHdl_Impl));
+ m_xIbAdd->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbRemove->connect_clicked(HDL(ClickHdl_Impl));
+ m_xIbRemove->connect_focus_in(LINK(this, SvxNumberFormatTabPage, LostFocusHdl_Impl));
+ m_xIbInfo->connect_clicked(HDL(ClickHdl_Impl));
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+
+ // initialize language ListBox
+
+ m_xLbLanguage->SetLanguageList(SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN,
+ false, false, false, true, LANGUAGE_SYSTEM,
+ css::i18n::ScriptType::WEAK);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumberFormatTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxNumberFormatTabPage>(pPage, pController, *rAttrSet);
+}
+
+
+/*************************************************************************
+#* Method: Reset
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: The dialog's attributes are reset
+#* using the Itemset.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::set_active_currency(sal_Int32 nPos)
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ if (nPos == 0 && !bLegacyAutomaticCurrency)
+ {
+ // Insert "Automatically" if currently used so it is selectable.
+ m_xLbCurrency->insert_text(0, sAutomaticCurrencyEntry);
+ bLegacyAutomaticCurrency = true;
+ }
+ if (nPos != -1 && !bLegacyAutomaticCurrency)
+ --nPos;
+ m_xLbCurrency->set_active(nPos);
+}
+
+sal_uInt32 SvxNumberFormatTabPage::get_active_currency() const
+{
+ static_assert(SELPOS_NONE == -1, "SELPOS_NONE was -1 at time of writing");
+ sal_Int32 nCurrencyPos = m_xLbCurrency->get_active();
+ if (nCurrencyPos != -1 && !bLegacyAutomaticCurrency)
+ ++nCurrencyPos;
+ return nCurrencyPos;
+}
+
+void SvxNumberFormatTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxUInt32Item* pValFmtAttr = nullptr;
+ const SfxPoolItem* pItem = nullptr;
+ const SfxBoolItem* pAutoEntryAttr = nullptr;
+
+ sal_uInt16 nCatLbSelPos = 0;
+ sal_uInt16 nFmtLbSelPos = 0;
+ LanguageType eLangType = LANGUAGE_DONTKNOW;
+ std::vector<OUString> aFmtEntryList;
+ SvxNumberValueType eValType = SvxNumberValueType::Undefined;
+ double nValDouble = 0;
+ OUString aValString;
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_NOLANGUAGE ),true,&pItem);
+
+ if(eState==SfxItemState::SET)
+ {
+ const SfxBoolItem* pBoolLangItem = static_cast<const SfxBoolItem*>(
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_NOLANGUAGE));
+
+ if(pBoolLangItem!=nullptr && pBoolLangItem->GetValue())
+ {
+ HideLanguage();
+ }
+ else
+ {
+ HideLanguage(false);
+ }
+
+ }
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_INFO ),true,&pItem);
+
+ if(eState==SfxItemState::SET)
+ {
+ if(pNumItem==nullptr)
+ {
+ bNumItemFlag=true;
+ pNumItem.reset( static_cast<SvxNumberInfoItem *>(pItem->Clone()) );
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+ }
+ else
+ {
+ bNumItemFlag=false;
+ }
+
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ONE_AREA ));
+
+ if(eState==SfxItemState::SET)
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ONE_AREA));
+
+ if(pBoolItem!=nullptr)
+ {
+ bOneAreaFlag= pBoolItem->GetValue();
+ }
+ }
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_SOURCE ) );
+
+ if ( eState == SfxItemState::SET )
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_SOURCE ));
+ if ( pBoolItem )
+ m_xCbSourceFormat->set_active(pBoolItem->GetValue());
+ else
+ m_xCbSourceFormat->set_active( false );
+ m_xCbSourceFormat->set_sensitive(true);
+ m_xCbSourceFormat->show();
+ }
+ else
+ {
+ bool bInit = false; // set to sal_True for debug test
+ m_xCbSourceFormat->set_active( bInit );
+ m_xCbSourceFormat->set_sensitive( bInit );
+ m_xCbSourceFormat->set_visible( bInit );
+ }
+
+ // pNumItem must have been set from outside!
+ DBG_ASSERT( pNumItem, "No NumberInfo, no NumberFormatter, goodbye. CRASH. :-(" );
+
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_VALUE ) );
+
+ if ( SfxItemState::DONTCARE != eState )
+ pValFmtAttr = GetItem( *rSet, SID_ATTR_NUMBERFORMAT_VALUE );
+
+ eValType = pNumItem->GetValueType();
+
+ switch ( eValType )
+ {
+ case SvxNumberValueType::String:
+ aValString = pNumItem->GetValueString();
+ break;
+ case SvxNumberValueType::Number:
+ // #50441# string may be set in addition to the value
+ aValString = pNumItem->GetValueString();
+ nValDouble = pNumItem->GetValueDouble();
+ break;
+ case SvxNumberValueType::Undefined:
+ default:
+ break;
+ }
+
+ pNumFmtShell.reset(); // delete old shell if applicable (== reset)
+
+ nInitFormat = pValFmtAttr // memorize init key
+ ? pValFmtAttr->GetValue() // (for FillItemSet())
+ : ULONG_MAX; // == DONT_KNOW
+
+
+ if ( eValType == SvxNumberValueType::String )
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ aValString ) );
+ else
+ pNumFmtShell.reset( SvxNumberFormatShell::Create(
+ pNumItem->GetNumberFormatter(),
+ pValFmtAttr ? nInitFormat : 0,
+ eValType,
+ nValDouble,
+ &aValString ) );
+
+
+ bool bUseStarFormat = false;
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+ if ( pDocSh )
+ {
+ // is this a calc document
+ Reference< XServiceInfo > xSI( pDocSh->GetModel(), UNO_QUERY );
+ if ( xSI.is() )
+ bUseStarFormat = xSI->supportsService("com.sun.star.sheet.SpreadsheetDocument");
+ }
+ pNumFmtShell->SetUseStarFormat( bUseStarFormat );
+
+ FillCurrencyBox();
+
+ OUString aPrevString;
+ Color* pDummy = nullptr;
+ pNumFmtShell->GetInitSettings( nCatLbSelPos, eLangType, nFmtLbSelPos,
+ aFmtEntryList, aPrevString, pDummy );
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ nFixedCategory=nCatLbSelPos;
+ if(bOneAreaFlag)
+ {
+ OUString sFixedCategory = m_xLbCategory->get_text(nFixedCategory);
+ m_xLbCategory->clear();
+ m_xLbCategory->append_text(sFixedCategory);
+ SetCategory(0);
+ }
+ else
+ {
+ SetCategory(nCatLbSelPos );
+ }
+ eState = rSet->GetItemState( GetWhich( SID_ATTR_NUMBERFORMAT_ADD_AUTO ) );
+ if(SfxItemState::SET == eState)
+ pAutoEntryAttr = static_cast<const SfxBoolItem*>(
+ GetItem( *rSet, SID_ATTR_NUMBERFORMAT_ADD_AUTO ));
+ // no_NO is an alias for nb_NO and normally isn't listed, we need it for
+ // backwards compatibility, but only if the format passed is of
+ // LanguageType no_NO.
+ if ( eLangType == LANGUAGE_NORWEGIAN )
+ {
+ m_xLbLanguage->remove_id(eLangType); // in case we're already called
+ m_xLbLanguage->InsertLanguage( eLangType );
+ }
+ m_xLbLanguage->set_active_id(eLangType);
+ if(pAutoEntryAttr)
+ AddAutomaticLanguage_Impl(eLangType, pAutoEntryAttr->GetValue());
+ UpdateFormatListBox_Impl(false,true);
+
+//! This spoils everything because it rematches currency formats based on
+//! the selected m_xLbCurrency entry instead of the current format.
+//! Besides that everything seems to be initialized by now, so why call it?
+// SelFormatHdl_Impl(m_xLbCategory.get());
+
+ if ( pValFmtAttr )
+ {
+ EditHdl_Impl(m_xEdFormat.get()); // UpdateOptions_Impl() as a side effect
+ }
+ else // DONT_KNOW
+ {
+ // everything disabled except direct input or changing the category
+ Obstructing();
+ }
+
+ if ( m_xCbSourceFormat->get_active() )
+ {
+ // everything disabled except SourceFormat checkbox
+ EnableBySourceFormat_Impl();
+ }
+}
+
+/*************************************************************************
+#* Method: Obstructing
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Disable the controls except from changing the category
+#* and direct input.
+#* Input: ---
+#* Output: ---
+#*
+#************************************************************************/
+void SvxNumberFormatTabPage::Obstructing()
+{
+ m_xLbFormat->select(-1);
+ m_xLbLanguage->set_active(-1);
+ m_xFtLanguage->set_sensitive(false);
+ m_xLbLanguage->set_sensitive(false);
+
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtOptions->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ m_aWndPreview.NotifyChange( OUString() );
+
+ m_xLbCategory->select(0);
+ m_xEdFormat->set_text( OUString() );
+ m_xFtComment->set_label( OUString() );
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // string for user defined
+
+ m_xEdFormat->grab_focus();
+}
+
+
+/*************************************************************************
+#* Enable/Disable dialog parts depending on the value of the SourceFormat
+#* checkbox.
+#************************************************************************/
+void SvxNumberFormatTabPage::EnableBySourceFormat_Impl()
+{
+ bool bEnable = !m_xCbSourceFormat->get_active();
+ if ( !bEnable )
+ m_xCbSourceFormat->grab_focus();
+ m_xFtCategory->set_sensitive( bEnable );
+ m_xLbCategory->set_sensitive( bEnable );
+ m_xFtFormat->set_sensitive( bEnable );
+ m_xLbCurrency->set_sensitive( bEnable );
+ m_xLbFormat->set_sensitive( bEnable );
+ m_xFtLanguage->set_sensitive( bEnable );
+ m_xLbLanguage->set_sensitive( bEnable );
+ m_xFtDecimals->set_sensitive( bEnable );
+ m_xEdDecimals->set_sensitive( bEnable );
+ m_xFtDenominator->set_sensitive( bEnable );
+ m_xEdDenominator->set_sensitive( bEnable );
+ m_xFtLeadZeroes->set_sensitive( bEnable );
+ m_xEdLeadZeroes->set_sensitive( bEnable );
+ m_xBtnNegRed->set_sensitive( bEnable );
+ m_xBtnThousand->set_sensitive( bEnable );
+ m_xBtnEngineering->set_sensitive( bEnable );
+ m_xFtOptions->set_sensitive( bEnable );
+ m_xFormatCodeFrame->set_sensitive( bEnable );
+}
+
+
+/*************************************************************************
+#* Method: HideLanguage
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Hides the language settings:
+#* Input: sal_Bool nFlag
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::HideLanguage(bool bFlag)
+{
+ m_xFtLanguage->set_visible(!bFlag);
+ m_xLbLanguage->set_visible(!bFlag);
+}
+
+/*************************************************************************
+#* Method: FillItemSet
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the attributes in the ItemSet,
+#* and - if bNumItemFlag is not set - the
+#* numItem in the DocShell.
+#* Input: SfxItemSet
+#* Output: ---
+#*
+#************************************************************************/
+
+bool SvxNumberFormatTabPage::FillItemSet( SfxItemSet* rCoreAttrs )
+{
+ bool bDataChanged = m_xFtLanguage->get_sensitive() || m_xCbSourceFormat->get_sensitive();
+ if ( bDataChanged )
+ {
+ const SfxItemSet& rMyItemSet = GetItemSet();
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_VALUE );
+ SfxItemState eItemState = rMyItemSet.GetItemState( nWhich, false );
+
+ // OK chosen - Is format code input entered already taken over?
+ // If not, simulate Add. Upon syntax error ignore input and prevent Put.
+ OUString aFormat = m_xEdFormat->get_text();
+ sal_uInt32 nCurKey = pNumFmtShell->GetCurNumFmtKey();
+
+ if ( m_xIbAdd->get_sensitive() || pNumFmtShell->IsTmpCurrencyFormat(aFormat) )
+ { // #79599# It is not sufficient to just add the format code (or
+ // delete it in case of bOneAreaFlag and resulting category change).
+ // Upon switching tab pages we need all settings to be consistent
+ // in case this page will be redisplayed later.
+ bDataChanged = Click_Impl(*m_xIbAdd);
+ nCurKey = pNumFmtShell->GetCurNumFmtKey();
+ }
+ else if(nCurKey == NUMKEY_UNDEFINED)
+ { // something went wrong, e.g. in Writer #70281#
+ pNumFmtShell->FindEntry(aFormat, &nCurKey);
+ }
+
+
+ // Chosen format:
+
+ if ( bDataChanged )
+ {
+ bDataChanged = ( nInitFormat != nCurKey );
+
+ if (bDataChanged)
+ {
+ rCoreAttrs->Put( SfxUInt32Item( nWhich, nCurKey ) );
+ }
+ else if(SfxItemState::DEFAULT == eItemState)
+ {
+ rCoreAttrs->ClearItem( nWhich );
+ }
+ }
+
+
+ // List of changed user defined formats:
+
+ std::vector<sal_uInt32> const & aDelFormats = pNumFmtShell->GetUpdateData();
+
+ if ( !aDelFormats.empty() )
+ {
+
+ pNumItem->SetDelFormats( aDelFormats );
+
+ if(bNumItemFlag)
+ {
+ rCoreAttrs->Put( *pNumItem );
+ }
+ else
+ {
+ SfxObjectShell* pDocSh = SfxObjectShell::Current();
+
+ DBG_ASSERT( pDocSh, "DocShell not found!" );
+
+
+ if ( pDocSh )
+ pDocSh->PutItem( *pNumItem );
+ }
+ }
+
+
+ // Whether source format is to be taken or not:
+
+ if ( m_xCbSourceFormat->get_sensitive() )
+ {
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_NUMBERFORMAT_SOURCE );
+ SfxItemState _eItemState = rMyItemSet.GetItemState( _nWhich, false );
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(
+ GetItem( rMyItemSet, SID_ATTR_NUMBERFORMAT_SOURCE ));
+ bool bOld = pBoolItem && pBoolItem->GetValue();
+ rCoreAttrs->Put( SfxBoolItem( _nWhich, m_xCbSourceFormat->get_active() ) );
+ if ( !bDataChanged )
+ bDataChanged = (bOld != m_xCbSourceFormat->get_active() ||
+ _eItemState != SfxItemState::SET);
+ }
+
+ // FillItemSet is only called on OK, here we can notify the
+ // NumberFormatShell that all new user defined formats are valid.
+ pNumFmtShell->ValidateNewEntries();
+ if(m_xLbLanguage->get_visible() &&
+ m_xLbLanguage->find_text(sAutomaticLangEntry) != -1)
+ rCoreAttrs->Put(SfxBoolItem(SID_ATTR_NUMBERFORMAT_ADD_AUTO,
+ m_xLbLanguage->get_active_text() == sAutomaticLangEntry));
+ }
+
+ return bDataChanged;
+}
+
+
+DeactivateRC SvxNumberFormatTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumberFormatTabPage::FillFormatListBox_Impl( std::vector<OUString>& rEntries )
+{
+ OUString aEntry;
+ OUString aTmpString;
+ size_t i = 0;
+ short nTmpCatPos;
+
+ m_xLbFormat->clear();
+ if (rEntries.empty())
+ return;
+
+ m_xLbFormat->freeze();
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL:
+ case CAT_TEXT:
+ case CAT_NUMBER: i=1;
+ aEntry=rEntries[0];
+ if (nTmpCatPos == CAT_TEXT)
+ aTmpString=aEntry;
+ else
+ aTmpString = pNumFmtShell->GetStandardName();
+ m_xLbFormat->append_text(aTmpString);
+ break;
+
+ default: break;
+ }
+
+ if(pNumFmtShell!=nullptr)
+ {
+ for ( ; i < rEntries.size(); ++i )
+ {
+ aEntry = rEntries[i];
+ short aPrivCat = pNumFmtShell->GetCategory4Entry( static_cast<short>(i) );
+ if(aPrivCat!=CAT_TEXT)
+ {
+ Color* pPreviewColor = nullptr;
+ OUString aPreviewString( GetExpColorString( pPreviewColor, aEntry, aPrivCat ) );
+ m_xLbFormat->append_text(aPreviewString);
+ if (pPreviewColor)
+ m_xLbFormat->set_font_color(m_xLbFormat->n_children() - 1, *pPreviewColor);
+ }
+ else
+ {
+ m_xLbFormat->append_text(aEntry);
+ }
+ }
+ }
+ m_xLbFormat->thaw();
+ rEntries.clear();
+}
+
+/*************************************************************************
+#* Method: UpdateOptions_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Adjusts the options attributes
+#* depending on the selected format.
+#* Input: Flag, whether the category has changed.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateOptions_Impl( bool bCheckCatChange /*= sal_False*/ )
+{
+ OUString theFormat = m_xEdFormat->get_text();
+ sal_Int32 nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nCategory = static_cast<sal_uInt16>(nCurCategory);
+ sal_uInt16 nDecimals = 0;
+ sal_uInt16 nZeroes = 0;
+ bool bNegRed = false;
+ bool bThousand = false;
+ sal_Int32 nCurrencyPos = get_active_currency();
+
+ if(bOneAreaFlag)
+ nCurCategory=nFixedCategory;
+
+
+ pNumFmtShell->GetOptions( theFormat,
+ bThousand, bNegRed,
+ nDecimals, nZeroes,
+ nCategory );
+ bool bDoIt=false;
+ if(nCategory==CAT_CURRENCY)
+ {
+ sal_uInt16 nTstPos=pNumFmtShell->FindCurrencyFormat(theFormat);
+ if(nCurrencyPos!=static_cast<sal_Int32>(nTstPos) && nTstPos!=sal_uInt16(-1))
+ {
+ set_active_currency(nTstPos);
+ pNumFmtShell->SetCurrencySymbol(nTstPos);
+ bDoIt=true;
+ }
+ }
+
+ if ( nCategory != nCurCategory || bDoIt)
+ {
+ if ( bCheckCatChange )
+ {
+ if(bOneAreaFlag)
+ SetCategory(0);
+ else
+ SetCategory(nCategory );
+
+ UpdateFormatListBox_Impl( true, false );
+ }
+ }
+ else if ( m_xLbFormat->n_children() > 0 )
+ {
+ sal_uInt32 nCurEntryKey=NUMKEY_UNDEFINED;
+ if(!pNumFmtShell->FindEntry( m_xEdFormat->get_text(),&nCurEntryKey))
+ {
+ m_xLbFormat->select(-1);
+ }
+ }
+ if(bOneAreaFlag)
+ {
+ nCategory=nFixedCategory;
+ }
+
+ UpdateThousandEngineeringCheckBox();
+ UpdateDecimalsDenominatorEditBox();
+ switch ( nCategory )
+ {
+ case CAT_SCIENTIFIC: // bThousand is for Engineering notation
+ {
+ sal_uInt16 nIntDigits = pNumFmtShell->GetFormatIntegerDigits(theFormat);
+ bThousand = (nIntDigits > 0) && (nIntDigits % 3 == 0);
+ m_xBtnEngineering->set_sensitive(true);
+ m_xBtnEngineering->set_active( bThousand );
+ }
+ [[fallthrough]];
+ case CAT_NUMBER:
+ case CAT_PERCENT:
+ case CAT_CURRENCY:
+ case CAT_FRACTION:
+ case CAT_TIME:
+ m_xFtOptions->set_sensitive(true);
+ if ( nCategory == CAT_FRACTION )
+ {
+ m_xFtDenominator->set_sensitive(true);
+ m_xEdDenominator->set_sensitive(true);
+ }
+ else
+ {
+ m_xFtDecimals->set_sensitive(true);
+ m_xEdDecimals->set_sensitive(true);
+ }
+ m_xFtLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xEdLeadZeroes->set_sensitive( nCategory != CAT_TIME );
+ m_xBtnNegRed->set_sensitive(true);
+ if ( nCategory == CAT_NUMBER && m_xLbFormat->get_selected_index() == 0 )
+ m_xEdDecimals->set_text( "" ); //General format tdf#44399
+ else
+ if ( nCategory == CAT_FRACTION )
+ m_xEdDenominator->set_value( nDecimals );
+ else
+ m_xEdDecimals->set_value( nDecimals );
+ if ( nCategory != CAT_TIME )
+ m_xEdLeadZeroes->set_value( nZeroes );
+ m_xBtnNegRed->set_active( bNegRed );
+ if ( nCategory != CAT_SCIENTIFIC )
+ {
+ m_xBtnThousand->set_sensitive( nCategory != CAT_TIME );
+ m_xBtnThousand->set_active( bThousand && nCategory != CAT_TIME );
+ }
+ break;
+
+ case CAT_ALL:
+ case CAT_USERDEFINED:
+ case CAT_TEXT:
+ case CAT_DATE:
+ case CAT_BOOLEAN:
+ default:
+ m_xFtOptions->set_sensitive(false);
+ m_xFtDecimals->set_sensitive(false);
+ m_xEdDecimals->set_sensitive(false);
+ m_xFtDenominator->set_sensitive(false);
+ m_xEdDenominator->set_sensitive(false);
+ m_xFtLeadZeroes->set_sensitive(false);
+ m_xEdLeadZeroes->set_sensitive(false);
+ m_xBtnNegRed->set_sensitive(false);
+ m_xBtnThousand->set_sensitive(false);
+ m_xBtnEngineering->set_sensitive(false);
+ m_xEdDecimals->set_text( OUString() );
+ m_xEdLeadZeroes->set_text( OUString() );
+ m_xBtnNegRed->set_active( false );
+ m_xBtnThousand->set_active( false );
+ m_xBtnEngineering->set_active( false );
+ }
+}
+
+
+/*************************************************************************
+#* Method: UpdateFormatListBox_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Updates the format listbox and additionally the
+#* string in the editbox is changed depending on
+#* the bUpdateEdit flag.
+#* Input: Flags for category and editbox.
+#* Output: ---
+#*
+#************************************************************************/
+
+void SvxNumberFormatTabPage::UpdateFormatListBox_Impl
+ (
+ bool bCat, // Category or country/language ListBox?
+ bool bUpdateEdit
+ )
+{
+ std::vector<OUString> aEntryList;
+ short nFmtLbSelPos = 0;
+ short nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+
+ if ( bCat )
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+
+ pNumFmtShell->CategoryChanged(nTmpCatPos,nFmtLbSelPos, aEntryList);
+ }
+ else
+ pNumFmtShell->LanguageChanged(m_xLbLanguage->get_active_id(),
+ nFmtLbSelPos,aEntryList);
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+
+ if ( (!aEntryList.empty()) && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ if(bUpdateEdit)
+ {
+ OUString aFormat=aEntryList[nFmtLbSelPos];
+ m_xEdFormat->set_text(aFormat);
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ }
+
+ if(!bOneAreaFlag || !bCat)
+ {
+ FillFormatListBox_Impl( aEntryList );
+ m_xLbFormat->select(nFmtLbSelPos);
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+
+ }
+ else
+ {
+ FillFormatListBox_Impl( aEntryList );
+ if(nFmtLbSelPos != SELPOS_NONE)
+ {
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+
+ m_xFtComment->set_label(pNumFmtShell->GetComment4Entry(nFmtLbSelPos));
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(pNumFmtShell->GetComment4Entry(nFmtLbSelPos).isEmpty())
+ {
+ m_xFtComment->set_label(m_xLbCategory->get_text(1));
+ }
+ }
+ }
+ else
+ {
+ m_xLbFormat->select(-1);
+ }
+
+ if ( bUpdateEdit )
+ {
+ m_xEdFormat->set_text( OUString() );
+ m_aWndPreview.NotifyChange( OUString() );
+ }
+ }
+
+ aEntryList.clear();
+}
+
+
+/**
+ * Change visible checkbox according to category format
+ * if scientific format "Engineering notation"
+ * else "Thousands separator"
+ */
+
+void SvxNumberFormatTabPage::UpdateThousandEngineeringCheckBox()
+{
+ bool bIsScientific = m_xLbCategory->get_selected_index() == CAT_SCIENTIFIC;
+ m_xBtnThousand->set_visible( !bIsScientific );
+ m_xBtnEngineering->set_visible( bIsScientific );
+}
+
+
+/**
+ * Change visible Edit box and Fixed text according to category format
+ * if fraction format "Denominator places"
+ * else "Decimal places"
+ */
+
+void SvxNumberFormatTabPage::UpdateDecimalsDenominatorEditBox()
+{
+ bool bIsFraction = m_xLbCategory->get_selected_index() == CAT_FRACTION;
+ m_xFtDecimals->set_visible( !bIsFraction );
+ m_xEdDecimals->set_visible( !bIsFraction );
+ m_xFtDenominator->set_visible( bIsFraction );
+ m_xEdDenominator->set_visible( bIsFraction );
+}
+
+
+/*************************************************************************
+#* Handle: DoubleClickHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: On a double click in the format listbox the
+#* value is adopted and the OK button pushed.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+IMPL_LINK(SvxNumberFormatTabPage, DoubleClickHdl_Impl, weld::TreeView&, rLb, bool)
+{
+ SelFormatHdl_Impl(&rLb);
+
+ SfxOkDialogController* pController = GetDialogController();
+ assert(pController);
+ weld::Button& rOkButton = pController->GetOKButton();
+ rOkButton.clicked();
+
+ return true;
+}
+
+/*************************************************************************
+#* Method: SelFormatHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Is called when the language, the category or the format
+#* is changed. Accordingly the settings are adjusted.
+#* Input: Pointer on the Listbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatClickHdl_Impl, weld::Button&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatTreeListBoxHdl_Impl, weld::TreeView&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, SelFormatListBoxHdl_Impl, weld::ComboBox&, rLb, void)
+{
+ SelFormatHdl_Impl(&rLb);
+}
+
+void SvxNumberFormatTabPage::SelFormatHdl_Impl(weld::Widget* pLb)
+{
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Click handler is called before focus change handler, so finish
+ // comment editing of previous format, otherwise a new format will have
+ // the old comment displayed after LostFocusHdl_Impl() is called
+ // later. Also, clicking into another category invalidates the format
+ // list and SvxNumberFormatShell::SetComment4Entry() could either
+ // access a wrong format from aCurEntryList[nEntry] or crash there if
+ // the new vector has less elements.
+ LostFocusHdl_Impl(*pLb);
+ }
+
+ if (pLb == m_xCbSourceFormat.get())
+ {
+ EnableBySourceFormat_Impl(); // enable/disable everything else
+ if ( m_xCbSourceFormat->get_active() )
+ return; // just disabled everything else
+
+ // Reinit options enable/disable for current selection.
+
+ // Current category may be UserDefined with no format entries defined.
+ if (m_xLbFormat->get_selected_index() == -1)
+ pLb = m_xLbCategory.get(); // continue with the current category selected
+ else
+ pLb = m_xLbFormat.get(); // continue with the current format selected
+ }
+
+ sal_Int32 nTmpCatPos;
+
+ if(bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=m_xLbCategory->get_selected_index();
+ }
+
+ if (nTmpCatPos==CAT_CURRENCY && pLb == m_xLbCurrency.get())
+ pNumFmtShell->SetCurrencySymbol(get_active_currency());
+
+ // Format-ListBox ----------------------------------------------------
+ if (pLb == m_xLbFormat.get())
+ {
+ sal_uLong nSelPos = m_xLbFormat->get_selected_index();
+ short nFmtLbSelPos = static_cast<short>(nSelPos);
+
+ OUString aFormat = pNumFmtShell->GetFormat4Entry(nFmtLbSelPos);
+ OUString aComment = pNumFmtShell->GetComment4Entry(nFmtLbSelPos);
+
+ if(pNumFmtShell->GetUserDefined4Entry(nFmtLbSelPos))
+ {
+ if(aComment.isEmpty())
+ {
+ aComment = m_xLbCategory->get_text(1);
+ }
+ }
+
+ if ( !aFormat.isEmpty() )
+ {
+ if (!m_xEdFormat->has_focus())
+ m_xEdFormat->set_text( aFormat );
+ m_xFtComment->set_label(aComment);
+ ChangePreviewText( static_cast<sal_uInt16>(nSelPos) );
+ }
+
+ REMOVE_DONTKNOW() // possibly UI-Enable
+
+ if ( pNumFmtShell->FindEntry( aFormat) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bIsUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bIsUserDef);
+ m_xIbInfo->set_sensitive(bIsUserDef);
+
+ }
+ else
+ {
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // category-ListBox -------------------------------------------------
+ if (pLb == m_xLbCategory.get() || pLb == m_xLbCurrency.get())
+ {
+ UpdateFormatListBox_Impl( true, true );
+ EditHdl_Impl( nullptr );
+ UpdateOptions_Impl( false );
+
+ return;
+ }
+
+
+ // language/country-ListBox ----------------------------------------------
+ if (pLb == m_xLbLanguage->get_widget())
+ {
+ UpdateFormatListBox_Impl( false, true );
+ EditHdl_Impl(m_xEdFormat.get());
+
+ return;
+ }
+}
+
+
+/*************************************************************************
+#* Method: ClickHdl_Impl, weld::Button& rIB
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Called when the add or delete button is pushed,
+#* adjusts the number format list.
+#* Input: Toolbox- Button
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK( SvxNumberFormatTabPage, ClickHdl_Impl, weld::Button&, rIB, void)
+{
+ Click_Impl(rIB);
+}
+
+bool SvxNumberFormatTabPage::Click_Impl(weld::Button& rIB)
+{
+ sal_uLong nReturn = 0;
+ const sal_uLong nReturnChanged = 0x1; // THE boolean return value
+ const sal_uLong nReturnAdded = 0x2; // temp: format added
+ const sal_uLong nReturnOneArea = 0x4; // temp: one area but category changed => ignored
+
+ if (&rIB == m_xIbAdd.get())
+ { // Also called from FillItemSet() if a temporary currency format has
+ // to be added, not only if the Add button is enabled.
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ std::vector<OUString> a2EntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+ sal_Int32 nErrPos=0;
+
+ pNumFmtShell->SetCurCurrencyEntry(nullptr);
+ bool bAdded = pNumFmtShell->AddFormat( aFormat, nErrPos,
+ nCatLbSelPos, nFmtLbSelPos,
+ aEntryList);
+ if ( bAdded )
+ nReturn |= nReturnChanged | nReturnAdded;
+
+ if (m_xEdComment->get_visible())
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ m_xFtComment->set_label(m_xEdComment->get_text());
+ }
+
+ if ( !nErrPos ) // Syntax ok?
+ {
+ // May be sorted under a different locale if LCID was parsed.
+ if (bAdded)
+ m_xLbLanguage->set_active_id(pNumFmtShell->GetCurLanguage());
+
+ if (nCatLbSelPos==CAT_CURRENCY)
+ set_active_currency(pNumFmtShell->GetCurrencySymbol());
+
+ if(bOneAreaFlag && (nFixedCategory!=nCatLbSelPos))
+ {
+ if(bAdded) aEntryList.clear();
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ a2EntryList);
+ a2EntryList.clear();
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(0, -1);
+ nReturn |= nReturnOneArea;
+ }
+ else
+ {
+ if ( bAdded && (nFmtLbSelPos != SELPOS_NONE) )
+ {
+ // everything all right
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ FillFormatListBox_Impl( aEntryList );
+ if (m_xEdComment->get_text()!=m_xLbCategory->get_text(1))
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ m_xEdComment->get_text());
+ }
+ else
+ {
+ pNumFmtShell->SetComment4Entry(nFmtLbSelPos,
+ OUString());
+ }
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1)); // String for user defined
+
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ }
+ }
+ else // syntax error
+ {
+ m_xEdFormat->grab_focus();
+ m_xEdFormat->select_region(nErrPos == -1 ? m_xEdFormat->get_text().getLength() : nErrPos, -1);
+ }
+ EditHdl_Impl(m_xEdFormat.get());
+ nReturn = ((nReturn & nReturnOneArea) ? 0 : (nReturn & nReturnChanged));
+
+ aEntryList.clear();
+ a2EntryList.clear();
+ }
+ else if (&rIB == m_xIbRemove.get())
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ std::vector<OUString> aEntryList;
+ sal_uInt16 nCatLbSelPos = 0;
+ short nFmtLbSelPos = SELPOS_NONE;
+
+ pNumFmtShell->RemoveFormat( aFormat,
+ nCatLbSelPos,
+ nFmtLbSelPos,
+ aEntryList );
+
+ m_xEdComment->set_text(m_xLbCategory->get_text(1));
+
+ if( nFmtLbSelPos>=0 && o3tl::make_unsigned(nFmtLbSelPos)<aEntryList.size() )
+ {
+ aFormat = aEntryList[nFmtLbSelPos];
+ }
+
+ FillFormatListBox_Impl( aEntryList );
+
+ if ( nFmtLbSelPos != SELPOS_NONE )
+ {
+ if(bOneAreaFlag) //@@ ???
+ SetCategory(0);
+ else
+ SetCategory(nCatLbSelPos );
+
+ m_xLbFormat->select(static_cast<sal_uInt16>(nFmtLbSelPos));
+ m_xEdFormat->set_text( aFormat );
+ ChangePreviewText( static_cast<sal_uInt16>(nFmtLbSelPos) );
+ }
+ else
+ {
+ // set to "all/standard"
+ SetCategory(0);
+ SelFormatHdl_Impl(m_xLbCategory.get());
+ }
+
+ EditHdl_Impl(m_xEdFormat.get());
+
+ aEntryList.clear();
+ }
+ else if (&rIB == m_xIbInfo.get())
+ {
+ if (!m_xEdComment->get_visible())
+ {
+ if (!m_xIbAdd->get_sensitive())
+ // Editing for existing format.
+ m_nLbFormatSelPosEdComment = m_xLbFormat->get_selected_index();
+
+ m_xEdComment->set_text(m_xFtComment->get_label());
+ m_xEdComment->show();
+ m_xFtComment->hide();
+ m_xEdComment->grab_focus();
+ }
+ else
+ {
+ m_xEdFormat->grab_focus();
+ m_xFtComment->set_label( m_xEdComment->get_text());
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ }
+ }
+
+ return nReturn;
+}
+
+
+/*************************************************************************
+#* Method: EditHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: When the entry in the edit field is changed
+#* the preview is updated and
+#* Input: Pointer on Editbox
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::EditHdl_Impl(const weld::Entry* pEdFormat)
+{
+ sal_uInt32 nCurKey = NUMKEY_UNDEFINED;
+
+ if ( m_xEdFormat->get_text().isEmpty() )
+ {
+ m_xIbAdd->set_sensitive(false );
+ m_xIbRemove->set_sensitive(false );
+ m_xIbInfo->set_sensitive(false );
+ m_xFtComment->set_label(OUString());
+ }
+ else
+ {
+ OUString aFormat = m_xEdFormat->get_text();
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat, &nCurKey ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+
+ if(bUserDef)
+ {
+ sal_uInt16 nTmpCurPos=pNumFmtShell->FindCurrencyFormat(aFormat );
+ if (nTmpCurPos != sal_uInt16(-1))
+ set_active_currency(nTmpCurPos);
+ }
+ short nPosi=pNumFmtShell->GetListPos4Entry( nCurKey, aFormat);
+ if(nPosi>=0)
+ m_xLbFormat->select(static_cast<sal_uInt16>(nPosi));
+
+ }
+ else
+ {
+
+ m_xIbAdd->set_sensitive(true);
+ m_xIbInfo->set_sensitive(true);
+ m_xIbRemove->set_sensitive(false );
+
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ }
+ }
+
+ if (pEdFormat)
+ {
+ pNumFmtShell->SetCurNumFmtKey( nCurKey );
+ UpdateOptions_Impl( true );
+ }
+}
+
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK(SvxNumberFormatTabPage, OptClickHdl_Impl, weld::Button&, rOptCtrl, void)
+{
+ OptHdl_Impl(&rOptCtrl);
+}
+
+IMPL_LINK(SvxNumberFormatTabPage, OptEditHdl_Impl, weld::SpinButton&, rEdit, void)
+{
+ OptHdl_Impl(&rEdit);
+}
+
+void SvxNumberFormatTabPage::OptHdl_Impl(const weld::Widget* pOptCtrl)
+{
+ if ( !(pOptCtrl == m_xEdLeadZeroes.get()
+ || pOptCtrl == m_xEdDecimals.get()
+ || pOptCtrl == m_xEdDenominator.get()
+ || pOptCtrl == m_xBtnNegRed.get()
+ || pOptCtrl == m_xBtnThousand.get()
+ || pOptCtrl == m_xBtnEngineering.get()))
+ return;
+
+ OUString aFormat;
+ bool bThousand = ( m_xBtnThousand->get_visible() && m_xBtnThousand->get_sensitive() && m_xBtnThousand->get_active() )
+ || ( m_xBtnEngineering->get_visible() && m_xBtnEngineering->get_sensitive() && m_xBtnEngineering->get_active() );
+ bool bNegRed = m_xBtnNegRed->get_sensitive() && m_xBtnNegRed->get_active();
+ sal_uInt16 nPrecision = (m_xEdDecimals->get_sensitive() && m_xEdDecimals->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDecimals->get_value())
+ : ( (m_xEdDenominator->get_sensitive() && m_xEdDenominator->get_visible())
+ ? static_cast<sal_uInt16>(m_xEdDenominator->get_value())
+ : sal_uInt16(0) );
+ sal_uInt16 nLeadZeroes = (m_xEdLeadZeroes->get_sensitive())
+ ? static_cast<sal_uInt16>(m_xEdLeadZeroes->get_value())
+ : sal_uInt16(0);
+ if ( pNumFmtShell->GetStandardName() == m_xEdFormat->get_text() )
+ {
+ m_xEdDecimals->set_value(nPrecision);
+ }
+
+ pNumFmtShell->MakeFormat( aFormat,
+ bThousand, bNegRed,
+ nPrecision, nLeadZeroes,
+ static_cast<sal_uInt16>(m_xLbFormat->get_selected_index()) );
+
+ m_xEdFormat->set_text( aFormat );
+ MakePreviewText( aFormat );
+
+ if ( pNumFmtShell->FindEntry( aFormat ) )
+ {
+ m_xIbAdd->set_sensitive(false );
+ bool bUserDef=pNumFmtShell->IsUserDefined( aFormat );
+ m_xIbRemove->set_sensitive(bUserDef);
+ m_xIbInfo->set_sensitive(bUserDef);
+ EditHdl_Impl(m_xEdFormat.get());
+
+ }
+ else
+ {
+ EditHdl_Impl( nullptr );
+ m_xLbFormat->select(-1);
+ }
+}
+
+/*************************************************************************
+#* Method: LostFocusHdl_Impl
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+IMPL_LINK_NOARG(SvxNumberFormatTabPage, LostFocusHdl_Impl, weld::Widget&, void)
+{
+ if (!pNumFmtShell)
+ return;
+
+ const bool bAddSensitive = m_xIbAdd->get_sensitive();
+ if (bAddSensitive || m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ // Comment editing was possible.
+ m_xFtComment->set_label(m_xEdComment->get_text());
+
+ m_xEdComment->hide();
+ m_xFtComment->show();
+ if (m_nLbFormatSelPosEdComment != SELPOS_NONE)
+ {
+ // Save edited comment of existing format.
+ pNumFmtShell->SetComment4Entry( m_nLbFormatSelPosEdComment, m_xEdComment->get_text());
+ m_nLbFormatSelPosEdComment = SELPOS_NONE;
+ }
+ if (!bAddSensitive)
+ {
+ // String for user defined, if present
+ OUString sEntry = m_xLbCategory->n_children() > 1 ? m_xLbCategory->get_text(1) : OUString();
+ m_xEdComment->set_text(sEntry);
+ }
+}
+
+/*************************************************************************
+#* Method: NotifyChange
+#*------------------------------------------------------------------------
+#*
+#* Class: SvxNumberFormatTabPage
+#* Function: Does changes in the number attributes.
+#* Input: Options- Controls
+#* Output: ---
+#*
+#************************************************************************/
+
+OUString SvxNumberFormatTabPage::GetExpColorString(
+ Color*& rpPreviewColor, const OUString& rFormatStr, short nTmpCatPos)
+{
+ SvxNumValCategory i;
+ switch (nTmpCatPos)
+ {
+ case CAT_ALL: i=SvxNumValCategory::Standard; break;
+
+ case CAT_NUMBER: i=SvxNumValCategory::Standard; break;
+
+ case CAT_PERCENT: i=SvxNumValCategory::Percent; break;
+
+ case CAT_CURRENCY: i=SvxNumValCategory::Currency; break;
+
+ case CAT_DATE: i=SvxNumValCategory::Date; break;
+
+ case CAT_TIME: i=SvxNumValCategory::Time; break;
+
+ case CAT_SCIENTIFIC: i=SvxNumValCategory::Scientific; break;
+
+ case CAT_FRACTION: i=SvxNumValCategory::Fraction; break;
+
+ case CAT_BOOLEAN: i=SvxNumValCategory::Boolean; break;
+
+ case CAT_USERDEFINED: i=SvxNumValCategory::Standard; break;
+
+ case CAT_TEXT:
+ default: i=SvxNumValCategory::NoValue;break;
+ }
+ double fVal = fSvxNumValConst[i];
+
+ OUString aPreviewString;
+ pNumFmtShell->MakePrevStringFromVal( rFormatStr, aPreviewString, rpPreviewColor, fVal );
+ return aPreviewString;
+}
+
+void SvxNumberFormatTabPage::MakePreviewText( const OUString& rFormat )
+{
+ OUString aPreviewString;
+ Color* pPreviewColor = nullptr;
+ pNumFmtShell->MakePreviewString( rFormat, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::ChangePreviewText( sal_uInt16 nPos )
+{
+ OUString aPreviewString;
+ Color* pPreviewColor = nullptr;
+ pNumFmtShell->FormatChanged( nPos, aPreviewString, pPreviewColor );
+ m_aWndPreview.NotifyChange( aPreviewString, pPreviewColor );
+}
+
+void SvxNumberFormatTabPage::FillCurrencyBox()
+{
+ std::vector<OUString> aList;
+
+ sal_uInt16 nSelPos=0;
+ pNumFmtShell->GetCurrencySymbols(aList, &nSelPos);
+
+ m_xLbCurrency->freeze();
+ m_xLbCurrency->clear();
+ bLegacyAutomaticCurrency = false;
+ for (std::vector<OUString>::iterator i = aList.begin() + 1;i != aList.end(); ++i)
+ m_xLbCurrency->append_text(*i);
+ m_xLbCurrency->thaw();
+
+ set_active_currency(nSelPos);
+}
+
+void SvxNumberFormatTabPage::SetCategory(sal_uInt16 nPos)
+{
+ int nCurCategory = m_xLbCategory->get_selected_index();
+ sal_uInt16 nTmpCatPos;
+
+ if (bOneAreaFlag)
+ {
+ nTmpCatPos=nFixedCategory;
+ }
+ else
+ {
+ nTmpCatPos=nPos;
+ }
+
+ if(m_xLbCategory->n_children()==1 || nCurCategory!=nPos)
+ {
+ if(nTmpCatPos!=CAT_CURRENCY)
+ m_xLbCurrency->hide();
+ else
+ m_xLbCurrency->show();
+ }
+ m_xLbCategory->select(nPos);
+}
+
+/* to support Writer text field language handling an
+ additional entry needs to be inserted into the ListBox
+ which marks a certain language as automatically detected
+ Additionally the "Default" language is removed
+*/
+void SvxNumberFormatTabPage::AddAutomaticLanguage_Impl(LanguageType eAutoLang, bool bSelect)
+{
+ m_xLbLanguage->remove_id(LANGUAGE_SYSTEM);
+ m_xLbLanguage->append(eAutoLang, sAutomaticLangEntry);
+ if (bSelect)
+ m_xLbLanguage->set_active_id(eAutoLang);
+}
+
+void SvxNumberFormatTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxNumberInfoItem* pNumberInfoItem = aSet.GetItem<SvxNumberInfoItem>(SID_ATTR_NUMBERFORMAT_INFO, false);
+ if (pNumberInfoItem && !pNumItem)
+ pNumItem.reset(pNumberInfoItem->Clone());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/numpages.cxx b/cui/source/tabpages/numpages.cxx
new file mode 100644
index 000000000..b921e6cde
--- /dev/null
+++ b/cui/source/tabpages/numpages.cxx
@@ -0,0 +1,3354 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+
+#include <numpages.hxx>
+#include <dialmgr.hxx>
+#include <tools/mapunit.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <editeng/numitem.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/strarray.hxx>
+#include <svx/gallery.hxx>
+#include <editeng/brushitem.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/settings.hxx>
+#include <cui/cuicharmap.hxx>
+#include <editeng/flstitem.hxx>
+#include <svx/numvset.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/ctrltool.hxx>
+#include <svtools/unitconv.hxx>
+#include <com/sun/star/style/NumberingType.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/text/XDefaultNumberingProvider.hpp>
+#include <com/sun/star/text/XNumberingFormatter.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svx/svxids.hrc>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+#include <sfx2/opengrf.hxx>
+
+#include <strings.hrc>
+#include <svl/stritem.hxx>
+#include <svl/slstitm.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <unotools/ucbstreamhelper.hxx>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <sal/log.hxx>
+#include <vcl/cvtgrf.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+#include <tools/urlobj.hxx>
+#include <osl/diagnose.h>
+
+using namespace css;
+using namespace css::uno;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::text;
+using namespace css::container;
+using namespace css::style;
+
+#define SHOW_NUMBERING 0
+#define SHOW_BULLET 1
+#define SHOW_BITMAP 2
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+#define SEARCHPATH_DELIMITER u';'
+#define SEARCHFILENAME_DELIMITER u'/'
+
+static bool bLastRelative = false;
+
+static SvxNumSettings_Impl* lcl_CreateNumSettingsPtr(const Sequence<PropertyValue>& rLevelProps)
+{
+ const PropertyValue* pValues = rLevelProps.getConstArray();
+ SvxNumSettings_Impl* pNew = new SvxNumSettings_Impl;
+ for(sal_Int32 j = 0; j < rLevelProps.getLength(); j++)
+ {
+ if ( pValues[j].Name == "NumberingType" )
+ {
+ sal_Int16 nTmp;
+ if (pValues[j].Value >>= nTmp)
+ pNew->nNumberType = static_cast<SvxNumType>(nTmp);
+ }
+ else if ( pValues[j].Name == "Prefix" )
+ pValues[j].Value >>= pNew->sPrefix;
+ else if ( pValues[j].Name == "Suffix" )
+ pValues[j].Value >>= pNew->sSuffix;
+ else if ( pValues[j].Name == "ParentNumbering" )
+ pValues[j].Value >>= pNew->nParentNumbering;
+ else if ( pValues[j].Name == "BulletChar" )
+ pValues[j].Value >>= pNew->sBulletChar;
+ else if ( pValues[j].Name == "BulletFontName" )
+ pValues[j].Value >>= pNew->sBulletFont;
+ }
+ return pNew;
+}
+
+// the selection of bullets from the OpenSymbol
+static const sal_Unicode aBulletTypes[] =
+{
+ 0x2022,
+ 0x25cf,
+ 0xe00c,
+ 0xe00a,
+ 0x2794,
+ 0x27a2,
+ 0x2717,
+ 0x2714
+};
+
+// Is one of the masked formats set?
+static bool lcl_IsNumFmtSet(SvxNumRule const * pNum, sal_uInt16 nLevelMask)
+{
+ bool bRet = false;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < SVX_MAX_NUM && !bRet; i++ )
+ {
+ if(nLevelMask & nMask)
+ bRet |= nullptr != pNum->Get( i );
+ nMask <<= 1 ;
+ }
+ return bRet;
+}
+
+static const vcl::Font& lcl_GetDefaultBulletFont()
+{
+ static vcl::Font aDefBulletFont = [&]()
+ {
+ vcl::Font tmp("OpenSymbol", "", Size(0, 14));
+ tmp.SetCharSet( RTL_TEXTENCODING_SYMBOL );
+ tmp.SetFamily( FAMILY_DONTKNOW );
+ tmp.SetPitch( PITCH_DONTKNOW );
+ tmp.SetWeight( WEIGHT_DONTKNOW );
+ tmp.SetTransparent( true );
+ return tmp;
+ }();
+ return aDefBulletFont;
+}
+
+SvxSingleNumPickTabPage::SvxSingleNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/picknumberingpage.ui", "PickNumberingPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin")))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::SINGLENUM);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxSingleNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxSingleNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence< Sequence< PropertyValue > > aNumberings;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aNumberings =
+ xDefNum->getDefaultContinuousNumberingLevels( rLocale );
+
+
+ sal_Int32 nLength = std::min<sal_Int32>(aNumberings.getLength(), NUM_VALUSET_COUNT);
+
+ const Sequence<PropertyValue>* pValuesArr = aNumberings.getConstArray();
+ for(sal_Int32 i = 0; i < nLength; i++)
+ {
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(pValuesArr[i]);
+ aNumSettingsArr.push_back(std::unique_ptr<SvxNumSettings_Impl>(pNew));
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetNumberingSettings(aNumberings, xFormat, rLocale);
+}
+
+SvxSingleNumPickTabPage::~SvxSingleNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxSingleNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSingleNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxSingleNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pSaveNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxSingleNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bIsPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nActNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+
+ bModified = false;
+}
+
+DeactivateRC SvxSingleNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSingleNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+ DBG_ASSERT(aNumSettingsArr.size() > nIdx, "wrong index");
+ if(aNumSettingsArr.size() <= nIdx)
+ return;
+ SvxNumSettings_Impl* _pSet = aNumSettingsArr[nIdx].get();
+ SvxNumType eNewType = _pSet->nNumberType;
+ const sal_Unicode cLocalPrefix = !_pSet->sPrefix.isEmpty() ? _pSet->sPrefix[0] : 0;
+ const sal_Unicode cLocalSuffix = !_pSet->sSuffix.isEmpty() ? _pSet->sSuffix[0] : 0;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(eNewType);
+ if(cLocalPrefix == ' ')
+ aFmt.SetPrefix( "" );
+ else
+ aFmt.SetPrefix(_pSet->sPrefix);
+ if(cLocalSuffix == ' ')
+ aFmt.SetSuffix( "" );
+ else
+ aFmt.SetSuffix(_pSet->sSuffix);
+ aFmt.SetCharFormatName("");
+ aFmt.SetBulletRelSize(100);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxSingleNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+SvxBulletPickTabPage::SvxBulletPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickbulletpage.ui", "PickBulletPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , bModified(false)
+ , bPreset(false)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin")))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+ m_xExamplesVS->init(NumberingPageType::BULLET);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBulletPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBulletPickTabPage, DoubleClickHdl_Impl));
+}
+
+SvxBulletPickTabPage::~SvxBulletPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBulletPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBulletPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxBulletPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxBulletPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bIsPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nActNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBulletPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxBulletPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_Unicode cChar = aBulletTypes[m_xExamplesVS->GetSelectedItemId() - 1];
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( SVX_NUM_CHAR_SPECIAL );
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetPrefix( OUString() );
+ aFmt.SetSuffix( OUString() );
+ aFmt.SetBulletFont(&rActBulletFont);
+ aFmt.SetBulletChar(cChar );
+ aFmt.SetCharFormatName(sBulletCharFormatName);
+ aFmt.SetBulletRelSize(45);
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBulletPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxBulletPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+ if (pBulletCharFmt)
+ sBulletCharFormatName = pBulletCharFmt->GetValue();
+}
+
+SvxNumPickTabPage::SvxNumPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickoutlinepage.ui", "PickOutlinePage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xExamplesVS(new SvxNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin")))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init(NumberingPageType::OUTLINE);
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxNumPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxNumPickTabPage, DoubleClickHdl_Impl));
+
+ Reference<XDefaultNumberingProvider> xDefNum = SvxNumOptionsTabPageHelper::GetNumberingProvider();
+ if(!xDefNum.is())
+ return;
+
+ Sequence<Reference<XIndexAccess> > aOutlineAccess;
+ const Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ try
+ {
+ aOutlineAccess = xDefNum->getDefaultOutlineNumberings( rLocale );
+
+ for(sal_Int32 nItem = 0;
+ nItem < aOutlineAccess.getLength() && nItem < NUM_VALUSET_COUNT;
+ nItem++ )
+ {
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[ nItem ];
+
+ Reference<XIndexAccess> xLevel = aOutlineAccess.getConstArray()[nItem];
+ for(sal_Int32 nLevel = 0; nLevel < xLevel->getCount() && nLevel < 5; nLevel++)
+ {
+ Any aValueAny = xLevel->getByIndex(nLevel);
+ Sequence<PropertyValue> aLevelProps;
+ aValueAny >>= aLevelProps;
+ SvxNumSettings_Impl* pNew = lcl_CreateNumSettingsPtr(aLevelProps);
+ rItemArr.push_back( std::unique_ptr<SvxNumSettings_Impl>(pNew) );
+ }
+ }
+ }
+ catch(const Exception&)
+ {
+ }
+ Reference<XNumberingFormatter> xFormat(xDefNum, UNO_QUERY);
+ m_xExamplesVS->SetOutlineNumberingSettings(aOutlineAccess, xFormat, rLocale);
+}
+
+SvxNumPickTabPage::~SvxNumPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxNumPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+ return bModified;
+}
+
+void SvxNumPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bIsPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nActNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxNumPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+void SvxNumPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+
+}
+
+// all levels are changed here
+IMPL_LINK_NOARG(SvxNumPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+
+ const FontList* pList = nullptr;
+
+ SvxNumSettingsArr_Impl& rItemArr = aNumSettingsArrays[m_xExamplesVS->GetSelectedItemId() - 1];
+
+ const vcl::Font& rActBulletFont = lcl_GetDefaultBulletFont();
+ SvxNumSettings_Impl* pLevelSettings = nullptr;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(rItemArr.size() > i)
+ pLevelSettings = rItemArr[i].get();
+ if(!pLevelSettings)
+ break;
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType( pLevelSettings->nNumberType );
+ sal_uInt16 nUpperLevelOrChar = static_cast<sal_uInt16>(pLevelSettings->nParentNumbering);
+ if(aFmt.GetNumberingType() == SVX_NUM_CHAR_SPECIAL)
+ {
+ // #i93908# clear suffix for bullet lists
+ aFmt.SetPrefix(OUString());
+ aFmt.SetSuffix(OUString());
+ if( !pLevelSettings->sBulletFont.isEmpty() &&
+ pLevelSettings->sBulletFont != rActBulletFont.GetFamilyName())
+ {
+ //search for the font
+ if(!pList)
+ {
+ SfxObjectShell* pCurDocShell = SfxObjectShell::Current();
+ const SvxFontListItem* pFontListItem =
+ static_cast<const SvxFontListItem*>( pCurDocShell
+ ->GetItem( SID_ATTR_CHAR_FONTLIST ));
+ pList = pFontListItem ? pFontListItem->GetFontList() : nullptr;
+ }
+ if(pList && pList->IsAvailable( pLevelSettings->sBulletFont ) )
+ {
+ FontMetric aFontMetric = pList->Get(
+ pLevelSettings->sBulletFont,WEIGHT_NORMAL, ITALIC_NONE);
+ vcl::Font aFont(aFontMetric);
+ aFmt.SetBulletFont(&aFont);
+ }
+ else
+ {
+ //if it cannot be found then create a new one
+ vcl::Font aCreateFont( pLevelSettings->sBulletFont,
+ OUString(), Size( 0, 14 ) );
+ aCreateFont.SetCharSet( RTL_TEXTENCODING_DONTKNOW );
+ aCreateFont.SetFamily( FAMILY_DONTKNOW );
+ aCreateFont.SetPitch( PITCH_DONTKNOW );
+ aCreateFont.SetWeight( WEIGHT_DONTKNOW );
+ aCreateFont.SetTransparent( true );
+ aFmt.SetBulletFont( &aCreateFont );
+ }
+ }
+ else
+ aFmt.SetBulletFont( &rActBulletFont );
+
+ aFmt.SetBulletChar( !pLevelSettings->sBulletChar.isEmpty()
+ ? pLevelSettings->sBulletChar[0]
+ : 0 );
+ aFmt.SetCharFormatName( sBulletCharFormatName );
+ aFmt.SetBulletRelSize(45);
+ }
+ else
+ {
+ aFmt.SetIncludeUpperLevels(sal::static_int_cast< sal_uInt8 >(0 != nUpperLevelOrChar ? pActNum->GetLevelCount() : 0));
+ aFmt.SetCharFormatName(sNumCharFmtName);
+ aFmt.SetBulletRelSize(100);
+ // #i93908#
+ aFmt.SetPrefix(pLevelSettings->sPrefix);
+ aFmt.SetSuffix(pLevelSettings->sSuffix);
+ }
+ pActNum->SetLevel(i, aFmt);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+void SvxNumPickTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFormatNames( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+}
+
+SvxBitmapPickTabPage::SvxBitmapPickTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/pickgraphicpage.ui", "PickGraphicPage", &rSet)
+ , nActNumLvl(SAL_MAX_UINT16)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , m_xErrorText(m_xBuilder->weld_label("errorft"))
+ , m_xBtBrowseFile(m_xBuilder->weld_button("browseBtn"))
+ , m_xExamplesVS(new SvxBmpNumValueSet(m_xBuilder->weld_scrolled_window("valuesetwin")))
+ , m_xExamplesVSWin(new weld::CustomWeld(*m_xBuilder, "valueset", *m_xExamplesVS))
+{
+ SetExchangeSupport();
+
+ m_xExamplesVS->init();
+ m_xExamplesVS->SetSelectHdl(LINK(this, SvxBitmapPickTabPage, NumSelectHdl_Impl));
+ m_xExamplesVS->SetDoubleClickHdl(LINK(this, SvxBitmapPickTabPage, DoubleClickHdl_Impl));
+ m_xBtBrowseFile->connect_clicked(LINK(this, SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl));
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // determine graphic name
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames);
+
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+
+ INetURLObject aObj(grfName);
+ if(aObj.GetProtocol() == INetProtocol::File)
+ grfName = aObj.PathToFileName();
+
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ m_xExamplesVS->Invalidate();
+ }
+}
+
+SvxBitmapPickTabPage::~SvxBitmapPickTabPage()
+{
+ m_xExamplesVSWin.reset();
+ m_xExamplesVS.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapPickTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxBitmapPickTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBitmapPickTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ bPreset = false;
+ bool bIsPreset = false;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bIsPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nActNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+ if(pActNum && *pSaveNum != *pActNum)
+ {
+ *pActNum = *pSaveNum;
+ m_xExamplesVS->SetNoSelection();
+ }
+
+ if(!aGrfNames.empty() &&
+ (pActNum && (!lcl_IsNumFmtSet(pActNum.get(), nActNumLvl) || bIsPreset)))
+ {
+ m_xExamplesVS->SelectItem(1);
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ bPreset = true;
+ }
+ bPreset |= bIsPreset;
+ bModified = false;
+}
+
+DeactivateRC SvxBitmapPickTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxBitmapPickTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if ( aGrfNames.empty() )
+ {
+ return false;
+ }
+ if( (bPreset || bModified) && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ) );
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, bPreset));
+ }
+
+ return bModified;
+}
+
+void SvxBitmapPickTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, NumSelectHdl_Impl, ValueSet*, void)
+{
+ if(!pActNum)
+ return;
+
+ bPreset = false;
+ bModified = true;
+ sal_uInt16 nIdx = m_xExamplesVS->GetSelectedItemId() - 1;
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aFmt(pActNum->GetLevel(i));
+ aFmt.SetNumberingType(SVX_NUM_BITMAP);
+ aFmt.SetPrefix( "" );
+ aFmt.SetSuffix( "" );
+ aFmt.SetCharFormatName( "" );
+
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, nIdx, &aGraphic))
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ sal_Int16 eOrient = text::VertOrientation::LINE_CENTER;
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+ SvxBrushItem aBrush(aGraphic, GPOS_AREA, SID_ATTR_BRUSH );
+ aFmt.SetGraphicBrush( &aBrush, &aSize, &eOrient );
+ }
+ else if(aGrfNames.size() > nIdx)
+ aFmt.SetGraphic( aGrfNames[nIdx] );
+ pActNum->SetLevel(i, aFmt);
+ }
+ nMask <<= 1;
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, DoubleClickHdl_Impl, ValueSet*, void)
+{
+ NumSelectHdl_Impl(m_xExamplesVS.get());
+ weld::Button& rOk = GetDialogController()->GetOKButton();
+ rOk.clicked();
+}
+
+IMPL_LINK_NOARG(SvxBitmapPickTabPage, ClickAddBrowseHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aFileDialog(0, FileDialogFlags::NONE, GetFrameWeld());
+ aFileDialog.SetTitle(CuiResId(RID_SVXSTR_ADD_IMAGE));
+ if ( aFileDialog.Execute() != ERRCODE_NONE )
+ return;
+
+ OUString aPath = SvtPathOptions().GetGalleryPath();
+ OUString aPathToken = aPath.getToken( 1 , SEARCHPATH_DELIMITER );
+
+ OUString aUserImageURL = aFileDialog.GetPath();
+
+ OUString aFileName;
+ const sal_Int32 nPos {aUserImageURL.lastIndexOf(SEARCHFILENAME_DELIMITER)+1};
+ if (nPos<=0)
+ aFileName = aUserImageURL;
+ else if (nPos<aUserImageURL.getLength())
+ aFileName = aUserImageURL.copy(nPos);
+
+ OUString aUserGalleryURL = aPathToken + "/" + aFileName;
+ INetURLObject aURL( aUserImageURL );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ GraphicDescriptor aDescriptor(aURL);
+ if (!aDescriptor.Detect())
+ return;
+
+ uno::Reference< lang::XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
+ uno::Reference<ucb::XSimpleFileAccess3> xSimpleFileAccess(
+ ucb::SimpleFileAccess::create( ::comphelper::getComponentContext(xFactory) ) );
+ if ( !xSimpleFileAccess->exists( aUserImageURL ))
+ return;
+
+ xSimpleFileAccess->copy( aUserImageURL, aUserGalleryURL );
+ INetURLObject gURL( aUserGalleryURL );
+ std::unique_ptr<SvStream> pIn(::utl::UcbStreamHelper::CreateStream(
+ gURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), StreamMode::READ ));
+ if ( !pIn )
+ return;
+
+ Graphic aGraphic;
+ GraphicConverter::Import( *pIn, aGraphic );
+
+ BitmapEx aBitmap = aGraphic.GetBitmapEx();
+ long nPixelX = aBitmap.GetSizePixel().Width();
+ long nPixelY = aBitmap.GetSizePixel().Height();
+ double ratio = nPixelY/static_cast<double>(nPixelX);
+ if(nPixelX > 30)
+ {
+ nPixelX = 30;
+ nPixelY = static_cast<long>(nPixelX*ratio);
+ }
+ if(nPixelY > 30)
+ {
+ nPixelY = 30;
+ nPixelX = static_cast<long>(nPixelY/ratio);
+ }
+
+ aBitmap.Scale( Size( nPixelX, nPixelY ), BmpScaleFlag::Fast );
+ Graphic aScaledGraphic( aBitmap );
+ GraphicFilter& rFilter = GraphicFilter::GetGraphicFilter();
+
+ Sequence< PropertyValue > aFilterData( 2 );
+ aFilterData[ 0 ].Name = "Compression";
+ aFilterData[ 0 ].Value <<= sal_Int32(-1) ;
+ aFilterData[ 1 ].Name = "Quality";
+ aFilterData[ 1 ].Value <<= sal_Int32(1);
+
+ sal_uInt16 nFilterFormat = rFilter.GetExportFormatNumberForShortName( gURL.GetFileExtension() );
+ rFilter.ExportGraphic( aScaledGraphic, gURL , nFilterFormat, &aFilterData );
+ GalleryExplorer::InsertURL( GALLERY_THEME_BULLETS, aUserGalleryURL );
+
+ aGrfNames.push_back(aUserGalleryURL);
+ size_t i = 0;
+ for (auto & grfName : aGrfNames)
+ {
+ m_xExamplesVS->InsertItem( i + 1, i);
+ INetURLObject aObj(grfName);
+ if(aObj.GetProtocol() == INetProtocol::File)
+ grfName = aObj.PathToFileName();
+ m_xExamplesVS->SetItemText( i + 1, grfName );
+ ++i;
+ }
+
+ if(aGrfNames.empty())
+ {
+ m_xErrorText->show();
+ }
+ else
+ {
+ m_xExamplesVS->Show();
+ m_xExamplesVS->SetFormat();
+ }
+}
+
+// tabpage numbering options
+SvxNumOptionsTabPage::SvxNumOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingoptionspage.ui", "NumberingOptionsPage", &rSet)
+ , m_pLevelHdlEvent(nullptr)
+ , bLastWidthModified(false)
+ , bModified(false)
+ , bPreset(false)
+ , bAutomaticCharStyles(true)
+ , bHTMLMode(false)
+ , nBullet(0xff)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , m_xGrid(m_xBuilder->weld_widget("grid2"))
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xFmtLB(m_xBuilder->weld_combo_box("numfmtlb"))
+ , m_xSeparatorFT(m_xBuilder->weld_label("separator"))
+ , m_xPrefixFT(m_xBuilder->weld_label("prefixft"))
+ , m_xPrefixED(m_xBuilder->weld_entry("prefix"))
+ , m_xSuffixFT(m_xBuilder->weld_label("suffixft"))
+ , m_xSuffixED(m_xBuilder->weld_entry("suffix"))
+ , m_xCharFmtFT(m_xBuilder->weld_label("charstyleft"))
+ , m_xCharFmtLB(m_xBuilder->weld_combo_box("charstyle"))
+ , m_xBulColorFT(m_xBuilder->weld_label("colorft"))
+ , m_xBulColLB(new ColorListBox(m_xBuilder->weld_menu_button("color"), pController->getDialog()))
+ , m_xBulRelSizeFT(m_xBuilder->weld_label("relsizeft"))
+ , m_xBulRelSizeMF(m_xBuilder->weld_metric_spin_button("relsize", FieldUnit::PERCENT))
+ , m_xAllLevelFT(m_xBuilder->weld_label("sublevelsft"))
+ , m_xAllLevelNF(m_xBuilder->weld_spin_button("sublevels"))
+ , m_xStartFT(m_xBuilder->weld_label("startatft"))
+ , m_xStartED(m_xBuilder->weld_spin_button("startat"))
+ , m_xBulletFT(m_xBuilder->weld_label("bulletft"))
+ , m_xBulletPB(m_xBuilder->weld_button("bullet"))
+ , m_xBitmapFT(m_xBuilder->weld_label("bitmapft"))
+ , m_xBitmapMB(m_xBuilder->weld_menu_button("bitmap"))
+ , m_xWidthFT(m_xBuilder->weld_label("widthft"))
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("widthmf", FieldUnit::CM))
+ , m_xHeightFT(m_xBuilder->weld_label("heightft"))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("heightmf", FieldUnit::CM))
+ , m_xRatioCB(m_xBuilder->weld_check_button("keepratio"))
+ , m_xOrientFT(m_xBuilder->weld_label("orientft"))
+ , m_xOrientLB(m_xBuilder->weld_combo_box("orientlb"))
+ , m_xAllLevelsFrame(m_xBuilder->weld_widget("levelsframe"))
+ , m_xSameLevelCB(m_xBuilder->weld_check_button("allsame"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ m_xBulColLB->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xBulRelSizeMF->set_min(SVX_NUM_REL_SIZE_MIN, FieldUnit::PERCENT);
+ m_xBulRelSizeMF->set_increments(5, 50, FieldUnit::PERCENT);
+ SetExchangeSupport();
+ aActBulletFont = lcl_GetDefaultBulletFont();
+
+ m_xBulletPB->connect_clicked(LINK(this, SvxNumOptionsTabPage, BulletHdl_Impl));
+ m_xFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl));
+ m_xBitmapMB->connect_selected(LINK(this, SvxNumOptionsTabPage, GraphicHdl_Impl));
+ m_xBitmapMB->connect_toggled(LINK(this, SvxNumOptionsTabPage, PopupActivateHdl_Impl));
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumOptionsTabPage, LevelHdl_Impl));
+ m_xCharFmtLB->connect_changed(LINK(this, SvxNumOptionsTabPage, CharFmtHdl_Impl));
+ m_xWidthMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xHeightMF->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SizeHdl_Impl));
+ m_xRatioCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, RatioHdl_Impl));
+ m_xStartED->connect_value_changed(LINK(this, SvxNumOptionsTabPage, SpinModifyHdl_Impl));
+ m_xPrefixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xSuffixED->connect_changed(LINK(this, SvxNumOptionsTabPage, EditModifyHdl_Impl));
+ m_xAllLevelNF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, AllLevelHdl_Impl));
+ m_xOrientLB->connect_changed(LINK(this, SvxNumOptionsTabPage, OrientHdl_Impl));
+ m_xSameLevelCB->connect_toggled(LINK(this, SvxNumOptionsTabPage, SameLevelHdl_Impl));
+ m_xBulRelSizeMF->connect_value_changed(LINK(this,SvxNumOptionsTabPage, BulRelSizeHdl_Impl));
+ m_xBulColLB->SetSelectHdl(LINK(this, SvxNumOptionsTabPage, BulColorHdl_Impl));
+ aInvalidateTimer.SetInvokeHandler(LINK(this, SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl));
+ aInvalidateTimer.SetTimeout(50);
+
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+
+ // Fill ListBox with predefined / translated numbering types.
+ sal_uInt32 nCount = SvxNumberingTypeTable::Count();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ m_xFmtLB->append(OUString::number(SvxNumberingTypeTable::GetValue(i)), SvxNumberingTypeTable::GetString(i));
+ }
+
+ // Get advanced numbering types from the component.
+ // Watch out for the ugly
+ // 136 == 0x88 == SVX_NUM_BITMAP|0x80 == SVX_NUM_BITMAP|LINK_TOKEN
+ // to not remove that.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering( *m_xFmtLB, (SVX_NUM_BITMAP | LINK_TOKEN));
+
+ m_xFmtLB->set_active(0);
+
+ m_xCharFmtLB->set_size_request(m_xCharFmtLB->get_approximate_digit_width() * 10, -1);
+ Size aSize(m_xGrid->get_preferred_size());
+ m_xGrid->set_size_request(aSize.Width(), -1);
+}
+
+SvxNumOptionsTabPage::~SvxNumOptionsTabPage()
+{
+ m_xPreviewWIN.reset();
+ m_xBulColLB.reset();
+ pActNum.reset();
+ pSaveNum.reset();
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+}
+
+void SvxNumOptionsTabPage::SetMetric(FieldUnit eMetric)
+{
+ if(eMetric == FieldUnit::MM)
+ {
+ m_xWidthMF->set_digits(1);
+ m_xHeightMF->set_digits(1);
+ }
+ m_xWidthMF->set_unit(eMetric);
+ m_xHeightMF->set_unit(eMetric);
+}
+
+std::unique_ptr<SfxTabPage> SvxNumOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumOptionsTabPage>(pPage, pController, *rAttrSet);
+};
+
+void SvxNumOptionsTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ sal_uInt16 nTmpNumLvl = 1;
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nTmpNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pActNum == *pSaveNum && nActNumLvl == nTmpNumLvl)
+ return;
+
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if(nActNumLvl != SAL_MAX_UINT16)
+ {
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ }
+ *pActNum = *pSaveNum;
+
+ InitControls();
+}
+
+DeactivateRC SvxNumOptionsTabPage::DeactivatePage(SfxItemSet * _pSet)
+{
+ if(_pSet)
+ FillItemSet(_pSet);
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumOptionsTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+};
+
+void SvxNumOptionsTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->n_children())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->n_children() - 1);
+
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select( pSaveNum->GetLevelCount() );
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select( i );
+ nMask <<= 1 ;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+ m_xSameLevelCB->set_active(pActNum->IsContinuousNumbering());
+
+ SfxObjectShell* pShell;
+ if ( SfxItemState::SET == rSet->GetItemState( SID_HTML_MODE, false, &pItem )
+ || ( nullptr != ( pShell = SfxObjectShell::Current()) &&
+ nullptr != ( pItem = pShell->GetItem( SID_HTML_MODE ) ) ) )
+ {
+ sal_uInt16 nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ bHTMLMode = 0 != (nHtmlMode&HTMLMODE_ON);
+ }
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(bCharFmt);
+ m_xCharFmtLB->set_visible(bCharFmt);
+
+ bool bContinuous = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+
+ bool bAllLevel = bContinuous && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+
+ m_xAllLevelsFrame->set_visible(bContinuous);
+
+ // again misusage: in Draw there is numeration only until the bitmap
+ // without SVX_NUM_NUMBER_NONE
+ //remove types that are unsupported by Draw/Impress
+ if(!bContinuous)
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if(/*SVX_NUM_NUMBER_NONE == nEntryData ||*/
+ (SVX_NUM_BITMAP|LINK_TOKEN) == nEntryData)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+ //one must be enabled
+ if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_LINKED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP|LINK_TOKEN));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+ else if(!pActNum->IsFeatureSupported(SvxNumRuleFlags::ENABLE_EMBEDDED_BMP))
+ {
+ auto nPos = m_xFmtLB->find_id(OUString::number(SVX_NUM_BITMAP));
+ if (nPos != -1)
+ m_xFmtLB->remove(nPos);
+ }
+
+ // MegaHack: because of a not-fixable 'design mistake/error' in Impress
+ // delete all kinds of numeric enumerations
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::NO_NUMBERS))
+ {
+ sal_Int32 nFmtCount = m_xFmtLB->get_count();
+ for(sal_Int32 i = nFmtCount; i; i--)
+ {
+ sal_uInt16 nEntryData = m_xFmtLB->get_id(i - 1).toUInt32();
+ if( /*nEntryData >= SVX_NUM_CHARS_UPPER_LETTER &&*/ nEntryData <= SVX_NUM_NUMBER_NONE)
+ m_xFmtLB->remove(i - 1);
+ }
+ }
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumOptionsTabPage::InitControls()
+{
+ bool bShowBullet = true;
+ bool bShowBitmap = true;
+ bool bSameType = true;
+ bool bSameStart = true;
+ bool bSamePrefix = true;
+ bool bSameSuffix = true;
+ bool bAllLevel = true;
+ bool bSameCharFmt = true;
+ bool bSameVOrient = true;
+ bool bSameSize = true;
+ bool bSameBulColor = true;
+ bool bSameBulRelSize= true;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ OUString sFirstCharFmt;
+ sal_Int16 eFirstOrient = text::VertOrientation::NONE;
+ Size aFirstSize(0,0);
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ sal_uInt16 nHighestLevel = 0;
+
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ bool bBullRelSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ bShowBullet &= aNumFmtArr[i]->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
+ bShowBitmap &= (aNumFmtArr[i]->GetNumberingType()&(~LINK_TOKEN)) == SVX_NUM_BITMAP;
+ if(SAL_MAX_UINT16 == nLvl)
+ {
+ nLvl = i;
+ sFirstCharFmt = aNumFmtArr[i]->GetCharFormatName();
+ eFirstOrient = aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap)
+ aFirstSize = aNumFmtArr[i]->GetGraphicSize();
+ }
+ if( i > nLvl)
+ {
+ bSameType &= aNumFmtArr[i]->GetNumberingType() == aNumFmtArr[nLvl]->GetNumberingType();
+ bSameStart = aNumFmtArr[i]->GetStart() == aNumFmtArr[nLvl]->GetStart();
+
+ bSamePrefix = aNumFmtArr[i]->GetPrefix() == aNumFmtArr[nLvl]->GetPrefix();
+ bSameSuffix = aNumFmtArr[i]->GetSuffix() == aNumFmtArr[nLvl]->GetSuffix();
+ bAllLevel &= aNumFmtArr[i]->GetIncludeUpperLevels() == aNumFmtArr[nLvl]->GetIncludeUpperLevels();
+ bSameCharFmt &= sFirstCharFmt == aNumFmtArr[i]->GetCharFormatName();
+ bSameVOrient &= eFirstOrient == aNumFmtArr[i]->GetVertOrient();
+ if(bShowBitmap && bSameSize)
+ bSameSize &= aNumFmtArr[i]->GetGraphicSize() == aFirstSize;
+ bSameBulColor &= aNumFmtArr[i]->GetBulletColor() == aNumFmtArr[nLvl]->GetBulletColor();
+ bSameBulRelSize &= aNumFmtArr[i]->GetBulletRelSize() == aNumFmtArr[nLvl]->GetBulletRelSize();
+ }
+ nHighestLevel = i;
+ }
+ else
+ aNumFmtArr[i] = nullptr;
+
+ nMask <<= 1 ;
+ }
+ SwitchNumberType(bShowBullet ? 1 : bShowBitmap ? 2 : 0);
+
+ sal_uInt16 nNumberingType;
+ if (nLvl != SAL_MAX_UINT16)
+ nNumberingType = aNumFmtArr[nLvl]->GetNumberingType();
+ else
+ {
+ nNumberingType = SVX_NUM_NUMBER_NONE;
+ bAllLevel = false;
+ bSameBulRelSize = false;
+ bSameBulColor = false;
+ bSameStart = false;
+ bSamePrefix = false;
+ bSameSuffix = false;
+ }
+
+ CheckForStartValue_Impl(nNumberingType);
+
+ if(bShowBitmap)
+ {
+ if(!bSameVOrient || eFirstOrient == text::VertOrientation::NONE)
+ m_xOrientLB->set_active(-1);
+ else
+ m_xOrientLB->set_active(
+ sal::static_int_cast< sal_Int32 >(eFirstOrient - 1));
+ // no text::VertOrientation::NONE
+
+ if(bSameSize)
+ {
+ SetMetricValue(*m_xHeightMF, aFirstSize.Height(), eCoreUnit);
+ SetMetricValue(*m_xWidthMF, aFirstSize.Width(), eCoreUnit);
+ }
+ else
+ {
+ m_xHeightMF->set_text("");
+ m_xWidthMF->set_text("");
+ }
+ }
+
+ if(bSameType)
+ {
+ sal_uInt16 nLBData = nNumberingType;
+ m_xFmtLB->set_active_id(OUString::number(nLBData));
+ }
+ else
+ m_xFmtLB->set_active(-1);
+
+ m_xAllLevelNF->set_sensitive(nHighestLevel > 0 && !m_xSameLevelCB->get_active());
+ m_xAllLevelNF->set_max(nHighestLevel + 1);
+ if(bAllLevel)
+ {
+ m_xAllLevelNF->set_value(aNumFmtArr[nLvl]->GetIncludeUpperLevels());
+ }
+ else
+ {
+ m_xAllLevelNF->set_text("");
+ }
+
+ if(bBullRelSize)
+ {
+ if(bSameBulRelSize)
+ m_xBulRelSizeMF->set_value(aNumFmtArr[nLvl]->GetBulletRelSize(), FieldUnit::PERCENT);
+ else
+ m_xBulRelSizeMF->set_text("");
+ }
+ if(bBullColor)
+ {
+ if(bSameBulColor)
+ m_xBulColLB->SelectEntry(aNumFmtArr[nLvl]->GetBulletColor());
+ else
+ m_xBulColLB->SetNoSelection();
+ }
+ switch(nBullet)
+ {
+ case SHOW_NUMBERING:
+ if(bSameStart)
+ {
+ m_xStartED->set_value(aNumFmtArr[nLvl]->GetStart());
+ }
+ else
+ m_xStartED->set_text("");
+ break;
+ case SHOW_BULLET:
+ break;
+ case SHOW_BITMAP:
+ break;
+ }
+
+ if(bSamePrefix)
+ m_xPrefixED->set_text(aNumFmtArr[nLvl]->GetPrefix());
+ else
+ m_xPrefixED->set_text("");
+ if(bSameSuffix)
+ m_xSuffixED->set_text(aNumFmtArr[nLvl]->GetSuffix());
+ else
+ m_xSuffixED->set_text("");
+
+ if(bSameCharFmt)
+ {
+ if (!sFirstCharFmt.isEmpty())
+ m_xCharFmtLB->set_active_text(sFirstCharFmt);
+ else
+ m_xCharFmtLB->set_active(0);
+ }
+ else
+ m_xCharFmtLB->set_active(-1);
+
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+// 0 - Number; 1 - Bullet; 2 - Bitmap
+void SvxNumOptionsTabPage::SwitchNumberType( sal_uInt8 nType )
+{
+ if(nBullet == nType)
+ return;
+ nBullet = nType;
+ bool bBullet = (nType == SHOW_BULLET);
+ bool bBitmap = (nType == SHOW_BITMAP);
+ bool bEnableBitmap = (nType == SHOW_BITMAP);
+ bool bNumeric = !(bBitmap||bBullet);
+ m_xSeparatorFT->set_visible(bNumeric);
+ m_xPrefixFT->set_visible(bNumeric);
+ m_xPrefixED->set_visible(bNumeric);
+ m_xSuffixFT->set_visible(bNumeric);
+ m_xSuffixED->set_visible(bNumeric);
+
+ bool bCharFmt = pActNum->IsFeatureSupported(SvxNumRuleFlags::CHAR_STYLE);
+ m_xCharFmtFT->set_visible(!bBitmap && bCharFmt);
+ m_xCharFmtLB->set_visible(!bBitmap && bCharFmt);
+
+ // this is rather misusage, as there is no own flag
+ // for complete numeration
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ bool bAllLevel = bNumeric && bAllLevelFeature && !bHTMLMode;
+ m_xAllLevelFT->set_visible(bAllLevel);
+ m_xAllLevelNF->set_visible(bAllLevel);
+
+ m_xStartFT->set_visible(!(bBullet||bBitmap));
+ m_xStartED->set_visible(!(bBullet||bBitmap));
+
+ m_xBulletFT->set_visible(bBullet);
+ m_xBulletPB->set_visible(bBullet);
+ bool bBullColor = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_COLOR);
+ m_xBulColorFT->set_visible(!bBitmap && bBullColor);
+ m_xBulColLB->set_visible(!bBitmap && bBullColor);
+ bool bBullResSize = pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE);
+ m_xBulRelSizeFT->set_visible(!bBitmap && bBullResSize);
+ m_xBulRelSizeMF->set_visible(!bBitmap && bBullResSize);
+
+ m_xBitmapFT->set_visible(bBitmap);
+ m_xBitmapMB->set_visible(bBitmap);
+
+ m_xWidthFT->set_visible(bBitmap);
+ m_xWidthMF->set_visible(bBitmap);
+ m_xHeightFT->set_visible(bBitmap);
+ m_xHeightMF->set_visible(bBitmap);
+ m_xRatioCB->set_visible(bBitmap);
+
+ m_xOrientFT->set_visible(bBitmap && bAllLevelFeature);
+ m_xOrientLB->set_visible(bBitmap && bAllLevelFeature);
+
+ m_xWidthFT->set_sensitive(bEnableBitmap);
+ m_xWidthMF->set_sensitive(bEnableBitmap);
+ m_xHeightFT->set_sensitive(bEnableBitmap);
+ m_xHeightMF->set_sensitive(bEnableBitmap);
+ m_xRatioCB->set_sensitive(bEnableBitmap);
+ m_xOrientFT->set_sensitive(bEnableBitmap);
+ m_xOrientLB->set_sensitive(bEnableBitmap);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127112 (borrowing tdf#127120 solution) multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumOptionsTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ InitControls();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PreviewInvalidateHdl_Impl, Timer *, void)
+{
+ m_aPreviewWIN.Invalidate();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, AllLevelHdl_Impl, weld::SpinButton&, rBox, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 e = 0; e < pActNum->GetLevelCount(); e++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(e));
+ aNumFmt.SetIncludeUpperLevels(static_cast<sal_uInt8>(std::min(rBox.get_value(), int(e + 1))) );
+ pActNum->SetLevel(e, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, NumberTypeSelectHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ OUString sSelectStyle;
+ bool bShowOrient = false;
+ bool bBmp = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ // PAGEDESC does not exist
+ SvxNumType nNumType = static_cast<SvxNumType>(rBox.get_active_id().toUInt32());
+ aNumFmt.SetNumberingType(nNumType);
+ sal_uInt16 nNumberingType = aNumFmt.GetNumberingType();
+ if(SVX_NUM_BITMAP == (nNumberingType&(~LINK_TOKEN)))
+ {
+ bBmp |= nullptr != aNumFmt.GetBrush();
+ aNumFmt.SetIncludeUpperLevels( 0 );
+ aNumFmt.SetSuffix( "" );
+ aNumFmt.SetPrefix( "" );
+ if(!bBmp)
+ aNumFmt.SetGraphic("");
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BITMAP);
+ bShowOrient = true;
+ }
+ else if( SVX_NUM_CHAR_SPECIAL == nNumberingType )
+ {
+ aNumFmt.SetIncludeUpperLevels( 0 );
+ aNumFmt.SetSuffix( "" );
+ aNumFmt.SetPrefix( "" );
+ if( !aNumFmt.GetBulletFont() )
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ if( !aNumFmt.GetBulletChar() )
+ aNumFmt.SetBulletChar( SVX_DEF_BULLET );
+ pActNum->SetLevel(i, aNumFmt);
+ SwitchNumberType(SHOW_BULLET);
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sBulletCharFormatName;
+ }
+ }
+ else
+ {
+ aNumFmt.SetPrefix( m_xPrefixED->get_text() );
+ aNumFmt.SetSuffix( m_xSuffixED->get_text() );
+ SwitchNumberType(SHOW_NUMBERING);
+ pActNum->SetLevel(i, aNumFmt);
+ CheckForStartValue_Impl(nNumberingType);
+
+ // allocation of the drawing pattern is automatic
+ if(bAutomaticCharStyles)
+ {
+ sSelectStyle = m_sNumCharFmtName;
+ }
+ }
+ }
+ nMask <<= 1;
+ }
+ bool bAllLevelFeature = pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS);
+ if(bShowOrient && bAllLevelFeature)
+ {
+ m_xOrientFT->show();
+ m_xOrientLB->show();
+ }
+ else
+ {
+ m_xOrientFT->hide();
+ m_xOrientLB->hide();
+ }
+ SetModified();
+ if(!sSelectStyle.isEmpty())
+ {
+ m_xCharFmtLB->set_active_text(sSelectStyle);
+ CharFmtHdl_Impl(*m_xCharFmtLB);
+ bAutomaticCharStyles = true;
+ }
+}
+
+void SvxNumOptionsTabPage::CheckForStartValue_Impl(sal_uInt16 nNumberingType)
+{
+ bool bIsNull = m_xStartED->get_value() == 0;
+ bool bNoZeroAllowed = nNumberingType < SVX_NUM_ARABIC ||
+ SVX_NUM_CHARS_UPPER_LETTER_N == nNumberingType ||
+ SVX_NUM_CHARS_LOWER_LETTER_N == nNumberingType;
+ m_xStartED->set_min(bNoZeroAllowed ? 1 : 0);
+ if (bIsNull && bNoZeroAllowed)
+ EditModifyHdl_Impl(*m_xStartED);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, OrientHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+ nPos ++; // no VERT_NONE
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ const Size& rSize = aNumFmt.GetGraphicSize();
+ sal_Int16 eOrient = static_cast<sal_Int16>(nPos);
+ aNumFmt.SetGraphicBrush( pBrushItem, &rSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SameLevelHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ bool bSet = rBox.get_active();
+ pActNum->SetContinuousNumbering(bSet);
+ bool bRepaint = false;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(aNumFmt.GetNumberingType() != SVX_NUM_NUMBER_NONE)
+ {
+ bRepaint = true;
+ break;
+ }
+ }
+ SetModified(bRepaint);
+ InitControls();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulColorHdl_Impl, ColorListBox&, rColorBox, void)
+{
+ Color nSetColor = rColorBox.GetSelectEntryColor();
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletColor(nSetColor);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, BulRelSizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ sal_uInt16 nRelSize = rField.get_value(FieldUnit::PERCENT);
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletRelSize(nRelSize);
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
+{
+ OUString aGrfName;
+ Size aSize;
+ bool bSucc(false);
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_SVXSTR_EDIT_GRAPHIC), GetFrameWeld());
+
+ OString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ auto idx = sNumber.toUInt32();
+ if (idx < aGrfNames.size())
+ {
+ aGrfName = aGrfNames[idx];
+ Graphic aGraphic;
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, idx, &aGraphic))
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ else if (rIdent == "fromfile")
+ {
+ aGrfDlg.EnableLink( false );
+ aGrfDlg.AsLink( false );
+ if ( !aGrfDlg.Execute() )
+ {
+ // memorize selected filter
+ aGrfName = aGrfDlg.GetPath();
+
+ Graphic aGraphic;
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ aSize = SvxNumberFormat::GetGraphicSizeMM100(&aGraphic);
+ bSucc = true;
+ }
+ }
+ }
+ if(!bSucc)
+ return;
+
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(eCoreUnit));
+
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetCharFormatName(m_sNumCharFmtName);
+ aNumFmt.SetGraphic(aGrfName);
+
+ // set size for a later comparison
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ // initiate asynchronous loading
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ aInitSize[i] = aNumFmt.GetGraphicSize();
+
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ m_xRatioCB->set_sensitive(true);
+ m_xWidthFT->set_sensitive(true);
+ m_xHeightFT->set_sensitive(true);
+ m_xWidthMF->set_sensitive(true);
+ m_xHeightMF->set_sensitive(true);
+ SetMetricValue(*m_xWidthMF, aSize.Width(), eCoreUnit);
+ SetMetricValue(*m_xHeightMF, aSize.Height(), eCoreUnit);
+ m_xOrientFT->set_sensitive(true);
+ m_xOrientLB->set_sensitive(true);
+ SetModified();
+ //needed due to asynchronous loading of graphics in the SvxBrushItem
+ aInvalidateTimer.Start();
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, PopupActivateHdl_Impl, weld::ToggleButton&, void)
+{
+ if (m_xGalleryMenu)
+ return;
+
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+
+ if (!GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, aGrfNames))
+ return;
+
+ GalleryExplorer::BeginLocking(GALLERY_THEME_BULLETS);
+
+ Graphic aGraphic;
+ OUString sGrfName;
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ size_t i = 0;
+ for (const auto & grfName : aGrfNames)
+ {
+ sGrfName = grfName;
+ OUString sItemId = "gallery" + OUString::number(i);
+ INetURLObject aObj(sGrfName);
+ if(aObj.GetProtocol() == INetProtocol::File)
+ sGrfName = aObj.PathToFileName();
+ if(GalleryExplorer::GetGraphicObj( GALLERY_THEME_BULLETS, i, &aGraphic))
+ {
+ BitmapEx aBitmap(aGraphic.GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH ||
+ aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel(), false);
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(sItemId, sGrfName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(sItemId, sGrfName);
+ }
+ ++i;
+ }
+ GalleryExplorer::EndLocking(GALLERY_THEME_BULLETS);
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, BulletHdl_Impl, weld::Button&, void)
+{
+ SvxCharacterMap aMap(GetFrameWeld(), nullptr, nullptr);
+
+ sal_uInt16 nMask = 1;
+ const vcl::Font* pFmtFont = nullptr;
+ bool bSameBullet = true;
+ sal_Unicode cBullet = 0;
+ bool bFirst = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat& rCurFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ cBullet = rCurFmt.GetBulletChar();
+ }
+ else if(rCurFmt.GetBulletChar() != cBullet )
+ {
+ bSameBullet = false;
+ break;
+ }
+ if(!pFmtFont)
+ pFmtFont = rCurFmt.GetBulletFont();
+ bFirst = false;
+ }
+ nMask <<= 1;
+
+ }
+
+ if (pFmtFont)
+ aMap.SetCharFont(*pFmtFont);
+ else
+ aMap.SetCharFont(aActBulletFont);
+ if (bSameBullet)
+ aMap.SetChar(cBullet);
+ if (aMap.run() != RET_OK)
+ return;
+
+ // change Font Numrules
+ aActBulletFont = aMap.GetCharFont();
+
+ sal_uInt16 _nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & _nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ aNumFmt.SetBulletFont(&aActBulletFont);
+ aNumFmt.SetBulletChar( static_cast<sal_Unicode>(aMap.GetChar()) );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ _nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK( SvxNumOptionsTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ bool bWidth = &rField == m_xWidthMF.get();
+ bLastWidthModified = bWidth;
+ bool bRatio = m_xRatioCB->get_active();
+ long nWidthVal = static_cast<long>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::MM_100TH)));
+ long nHeightVal = static_cast<long>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic( nWidthVal ,
+ MapUnit::Map100thMM, eCoreUnit );
+ nHeightVal = OutputDevice::LogicToLogic( nHeightVal,
+ MapUnit::Map100thMM, eCoreUnit);
+ double fSizeRatio;
+
+ bool bRepaint = false;
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(SVX_NUM_BITMAP == (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ Size aSize(aNumFmt.GetGraphicSize() );
+ Size aSaveSize(aSize);
+
+ if (aInitSize[i].Height())
+ fSizeRatio = static_cast<double>(aInitSize[i].Width()) / static_cast<double>(aInitSize[i].Height());
+ else
+ fSizeRatio = double(1);
+
+ if(bWidth)
+ {
+ long nDelta = nWidthVal - aInitSize[i].Width();
+ aSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ aSize.setHeight( aInitSize[i].Height() + static_cast<long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Height(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ long nDelta = nHeightVal - aInitSize[i].Height();
+ aSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ aSize.setWidth( aInitSize[i].Width() + static_cast<long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_xWidthMF->set_value(m_xWidthMF->normalize(
+ OutputDevice::LogicToLogic( aSize.Width(), eCoreUnit, MapUnit::Map100thMM )),
+ FieldUnit::MM_100TH);
+ }
+ }
+ const SvxBrushItem* pBrushItem = aNumFmt.GetBrush();
+ sal_Int16 eOrient = aNumFmt.GetVertOrient();
+ if(aSize != aSaveSize)
+ bRepaint = true;
+ aNumFmt.SetGraphicBrush( pBrushItem, &aSize, &eOrient );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ }
+ nMask <<= 1;
+ }
+ SetModified(bRepaint);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, RatioHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (bLastWidthModified)
+ SizeHdl_Impl(*m_xWidthMF);
+ else
+ SizeHdl_Impl(*m_xHeightMF);
+ }
+}
+
+IMPL_LINK_NOARG(SvxNumOptionsTabPage, CharFmtHdl_Impl, weld::ComboBox&, void)
+{
+ bAutomaticCharStyles = false;
+ sal_Int32 nEntryPos = m_xCharFmtLB->get_active();
+ OUString sEntry = m_xCharFmtLB->get_active_text();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if( 0 == nEntryPos )
+ aNumFmt.SetCharFormatName("");
+ else
+ {
+ if(SVX_NUM_BITMAP != (aNumFmt.GetNumberingType()&(~LINK_TOKEN)))
+ aNumFmt.SetCharFormatName(sEntry);
+ }
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified(false);
+};
+
+IMPL_LINK(SvxNumOptionsTabPage, EditModifyHdl_Impl, weld::Entry&, rEdit, void)
+{
+ EditModifyHdl_Impl(&rEdit);
+}
+
+IMPL_LINK(SvxNumOptionsTabPage, SpinModifyHdl_Impl, weld::SpinButton&, rSpinButton, void)
+{
+ EditModifyHdl_Impl(&rSpinButton);
+}
+
+void SvxNumOptionsTabPage::EditModifyHdl_Impl(const weld::Entry* pEdit)
+{
+ bool bPrefix = pEdit == m_xPrefixED.get();
+ bool bSuffix = pEdit == m_xSuffixED.get();
+ bool bStart = pEdit == m_xStartED.get();
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+ if(bPrefix)
+ aNumFmt.SetPrefix(m_xPrefixED->get_text());
+ else if(bSuffix)
+ aNumFmt.SetSuffix(m_xSuffixED->get_text());
+ else if(bStart)
+ aNumFmt.SetStart(m_xStartED->get_value());
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+static long lcl_DrawGraphic(VirtualDevice* pVDev, const SvxNumberFormat &rFmt, long nXStart,
+ long nYMiddle, long nDivision)
+{
+ const SvxBrushItem* pBrushItem = rFmt.GetBrush();
+ long nRet = 0;
+ if(pBrushItem)
+ {
+ const Graphic* pGrf = pBrushItem->GetGraphic();
+ if(pGrf)
+ {
+ Size aGSize( rFmt.GetGraphicSize() );
+ aGSize.setWidth( aGSize.Width() / nDivision );
+ nRet = aGSize.Width();
+ aGSize.setHeight( aGSize.Height() / nDivision );
+ pGrf->Draw( pVDev, Point(nXStart,nYMiddle - ( aGSize.Height() / 2) ),
+ pVDev->PixelToLogic( aGSize ) );
+ }
+ }
+ return nRet;
+
+}
+
+static long lcl_DrawBullet(VirtualDevice* pVDev,
+ const SvxNumberFormat& rFmt, long nXStart,
+ long nYStart, const Size& rSize)
+{
+ vcl::Font aTmpFont(pVDev->GetFont());
+
+ // via Uno it's possible that no font has been set!
+ vcl::Font aFont(rFmt.GetBulletFont() ? *rFmt.GetBulletFont() : aTmpFont);
+ Size aTmpSize(rSize);
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ // in case of a height of zero it is drawn in original height
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ aFont.SetTransparent(true);
+ Color aBulletColor = rFmt.GetBulletColor();
+ if(aBulletColor == COL_AUTO)
+ aBulletColor = pVDev->GetFillColor().IsDark() ? COL_WHITE : COL_BLACK;
+ else if(aBulletColor == pVDev->GetFillColor())
+ aBulletColor.Invert();
+ aFont.SetColor(aBulletColor);
+ pVDev->SetFont( aFont );
+ OUString aText(rFmt.GetBulletChar());
+ long nY = nYStart;
+ nY -= ((aTmpSize.Height() - rSize.Height())/ 2);
+ pVDev->DrawText( Point(nXStart, nY), aText );
+ long nRet = pVDev->GetTextWidth(aText);
+
+ pVDev->SetFont(aTmpFont);
+ return nRet;
+}
+
+SvxNumberingPreview::SvxNumberingPreview()
+ : pActNum(nullptr)
+ , bPosition(false)
+ , nActLevel(SAL_MAX_UINT16)
+{
+}
+
+// paint preview of numeration
+void SvxNumberingPreview::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle& /*rRect*/)
+{
+ Size aSize(rRenderContext.PixelToLogic(GetOutputSizePixel()));
+
+ const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
+ const Color aBackColor = rStyleSettings.GetFieldColor();
+ const Color aTextColor = rStyleSettings.GetFieldTextColor();
+
+ ScopedVclPtrInstance<VirtualDevice> pVDev(rRenderContext);
+ pVDev->EnableRTL(rRenderContext.IsRTLEnabled());
+ pVDev->SetMapMode(rRenderContext.GetMapMode());
+ pVDev->SetOutputSize(aSize);
+
+ Color aLineColor(COL_LIGHTGRAY);
+ if (aLineColor == aBackColor)
+ aLineColor.Invert();
+ pVDev->SetLineColor(aLineColor);
+ pVDev->SetFillColor(aBackColor);
+
+ if (pActNum)
+ {
+ long nWidthRelation = 30; // chapter dialog
+
+ // height per level
+ long nXStep = aSize.Width() / (3 * pActNum->GetLevelCount());
+ if (pActNum->GetLevelCount() < 10)
+ nXStep /= 2;
+ long nYStart = 4;
+ // the whole height mustn't be used for a single level
+ long nYStep = (aSize.Height() - 6)/ (pActNum->GetLevelCount() > 1 ? pActNum->GetLevelCount() : 5);
+
+ aStdFont = OutputDevice::GetDefaultFont(DefaultFontType::UI_SANS, MsLangId::getSystemLanguage(), GetDefaultFontFlags::OnlyOne);
+ aStdFont.SetColor(aTextColor);
+ aStdFont.SetFillColor(aBackColor);
+
+ long nFontHeight = nYStep * 6 / 10;
+ if (bPosition)
+ nFontHeight = nYStep * 15 / 10;
+ aStdFont.SetFontSize(Size( 0, nFontHeight ));
+
+ SvxNodeNum aNum;
+ sal_uInt16 nPreNum = pActNum->GetLevel(0).GetStart();
+
+ if (bPosition)
+ {
+ long nLineHeight = nFontHeight * 8 / 7;
+ sal_uInt8 nStart = 0;
+ while (!(nActLevel & (1<<nStart)))
+ {
+ nStart++;
+ }
+ if (nStart)
+ nStart--;
+ sal_uInt8 nEnd = std::min(sal_uInt8(nStart + 3), sal_uInt8(pActNum->GetLevelCount()));
+ for (sal_uInt8 nLevel = nStart; nLevel < nEnd; ++nLevel)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[nLevel] = rFmt.GetStart();
+
+ long nXStart( 0 );
+ short nTextOffset( 0 );
+ long nNumberXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ nTextOffset = rFmt.GetCharTextDistance() / nWidthRelation;
+ nNumberXPos = nXStart;
+ long nFirstLineOffset = (-rFmt.GetFirstLineOffset()) / nWidthRelation;
+
+ if (nFirstLineOffset <= nNumberXPos)
+ nNumberXPos = nNumberXPos - nFirstLineOffset;
+ else
+ nNumberXPos = 0;
+ // in draw this is valid
+ if (nTextOffset < 0)
+ nNumberXPos = nNumberXPos + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const long nTmpNumberXPos((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpNumberXPos < 0)
+ {
+ nNumberXPos = 0;
+ }
+ else
+ {
+ nNumberXPos = nTmpNumberXPos;
+ }
+ }
+
+ long nBulletWidth = 0;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType() &(~LINK_TOKEN)))
+ {
+ long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawGraphic(pVDev.get(), rFmt, nNumberXPos, nYMiddle, nWidthRelation) : 0;
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ nBulletWidth = rFmt.IsShowSymbol() ? lcl_DrawBullet(pVDev.get(), rFmt, nNumberXPos, nYStart, aStdFont.GetFontSize()) : 0;
+ }
+ else
+ {
+ pVDev->SetFont(aStdFont);
+ aNum.SetLevel(nLevel);
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString( aNum ));
+ vcl::Font aSaveFont = pVDev->GetFont();
+ vcl::Font aColorFont(aSaveFont);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK;
+ else if (aTmpBulletColor == aBackColor)
+ aTmpBulletColor.Invert();
+ aColorFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aColorFont);
+ pVDev->DrawText(Point(nNumberXPos, nYStart), aText);
+ pVDev->SetFont(aSaveFont);
+ nBulletWidth = pVDev->GetTextWidth(aText);
+ nPreNum++;
+ }
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT &&
+ rFmt.GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ pVDev->SetFont(aStdFont);
+ OUString aText(' ');
+ pVDev->DrawText( Point(nNumberXPos, nYStart), aText );
+ nBulletWidth = nBulletWidth + pVDev->GetTextWidth(aText);
+ }
+
+ long nTextXPos( 0 );
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nTextXPos = nXStart;
+ if (nTextOffset < 0)
+ nTextXPos = nTextXPos + nTextOffset;
+ if (nNumberXPos + nBulletWidth + nTextOffset > nTextXPos)
+ nTextXPos = nNumberXPos + nBulletWidth + nTextOffset;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ switch (rFmt.GetLabelFollowedBy())
+ {
+ case SvxNumberFormat::LISTTAB:
+ {
+ nTextXPos = rFmt.GetListtabPos() / nWidthRelation;
+ if (nTextXPos < nNumberXPos + nBulletWidth)
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ }
+ break;
+ case SvxNumberFormat::SPACE:
+ case SvxNumberFormat::NOTHING:
+ case SvxNumberFormat::NEWLINE:
+ {
+ nTextXPos = nNumberXPos + nBulletWidth;
+ }
+ break;
+ }
+
+ nXStart = rFmt.GetIndentAt() / nWidthRelation;
+ }
+
+ ::tools::Rectangle aRect1(Point(nTextXPos, nYStart + nFontHeight / 2), Size(aSize.Width() / 2, 2));
+ pVDev->SetFillColor(aBackColor);
+ pVDev->DrawRect(aRect1);
+
+ ::tools::Rectangle aRect2(Point(nXStart, nYStart + nLineHeight + nFontHeight / 2 ), Size(aSize.Width() / 2, 2));
+ pVDev->DrawRect(aRect2);
+ nYStart += 2 * nLineHeight;
+ }
+ }
+ else
+ {
+ //#i5153# painting gray or black rectangles as 'normal' numbering text
+ long nWidth = pVDev->GetTextWidth("Preview");
+ long nTextHeight = pVDev->GetTextHeight();
+ long nRectHeight = nTextHeight * 2 / 3;
+ long nTopOffset = nTextHeight - nRectHeight;
+ Color aBlackColor(COL_BLACK);
+ if (aBlackColor == aBackColor)
+ aBlackColor.Invert();
+
+ for (sal_uInt16 nLevel = 0; nLevel < pActNum->GetLevelCount(); ++nLevel, nYStart = nYStart + nYStep)
+ {
+ const SvxNumberFormat &rFmt = pActNum->GetLevel(nLevel);
+ aNum.GetLevelVal()[ nLevel ] = rFmt.GetStart();
+ long nXStart( 0 );
+ pVDev->SetFillColor( aBackColor );
+
+ if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION)
+ {
+ nXStart = rFmt.GetAbsLSpace() / nWidthRelation;
+ }
+ else if (rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT)
+ {
+ const long nTmpXStart((rFmt.GetIndentAt() + rFmt.GetFirstLineIndent() ) / nWidthRelation);
+ if (nTmpXStart < 0)
+ {
+ nXStart = 0;
+ }
+ else
+ {
+ nXStart = nTmpXStart;
+ }
+ }
+ nXStart /= 2;
+ nXStart += 2;
+ long nTextOffset = 2 * nXStep;
+ if (SVX_NUM_BITMAP == (rFmt.GetNumberingType()&(~LINK_TOKEN)))
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ long nYMiddle = nYStart + ( nFontHeight / 2 );
+ nTextOffset = lcl_DrawGraphic(pVDev.get(), rFmt, nXStart, nYMiddle, nWidthRelation);
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else if (SVX_NUM_CHAR_SPECIAL == rFmt.GetNumberingType())
+ {
+ if (rFmt.IsShowSymbol())
+ {
+ nTextOffset = lcl_DrawBullet(pVDev.get(), rFmt, nXStart, nYStart, aStdFont.GetFontSize());
+ nTextOffset = nTextOffset + nXStep;
+ }
+ }
+ else
+ {
+ vcl::Font aFont(aStdFont);
+ Size aTmpSize(aStdFont.GetFontSize());
+ if(pActNum->IsFeatureSupported(SvxNumRuleFlags::BULLET_REL_SIZE))
+ {
+ aTmpSize.setWidth( aTmpSize.Width() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setWidth( aTmpSize.Width() / 100 ) ;
+ aTmpSize.setHeight( aTmpSize.Height() * ( rFmt.GetBulletRelSize()) );
+ aTmpSize.setHeight( aTmpSize.Height() / 100 ) ;
+ }
+ if(!aTmpSize.Height())
+ aTmpSize.setHeight( 1 );
+ aFont.SetFontSize(aTmpSize);
+ Color aTmpBulletColor = rFmt.GetBulletColor();
+ if (aTmpBulletColor == COL_AUTO)
+ aTmpBulletColor = aBackColor.IsDark() ? COL_WHITE : COL_BLACK;
+ else if (aTmpBulletColor == aBackColor)
+ aTmpBulletColor.Invert();
+ aFont.SetColor(aTmpBulletColor);
+ pVDev->SetFont(aFont);
+ aNum.SetLevel( nLevel );
+ if (pActNum->IsContinuousNumbering())
+ aNum.GetLevelVal()[nLevel] = nPreNum;
+ OUString aText(pActNum->MakeNumString(aNum));
+ long nY = nYStart;
+ nY -= (pVDev->GetTextHeight() - nTextHeight - pVDev->GetFontMetric().GetDescent());
+ pVDev->DrawText(Point(nXStart, nY), aText);
+ nTextOffset = pVDev->GetTextWidth(aText);
+ nTextOffset = nTextOffset + nXStep;
+ nPreNum++;
+ pVDev->SetFont(aStdFont);
+ }
+ //#i5153# the selected rectangle(s) should be black
+ if (0 != (nActLevel & (1<<nLevel)))
+ {
+ pVDev->SetFillColor( aBlackColor );
+ pVDev->SetLineColor( aBlackColor );
+ }
+ else
+ {
+ //#i5153# unselected levels are gray
+ pVDev->SetFillColor( aLineColor );
+ pVDev->SetLineColor( aLineColor );
+ }
+ ::tools::Rectangle aRect1(Point(nXStart + nTextOffset, nYStart + nTopOffset), Size(nWidth, nRectHeight));
+ pVDev->DrawRect(aRect1);
+ }
+ }
+ }
+ rRenderContext.DrawOutDev(Point(), aSize, Point(), aSize, *pVDev);
+}
+
+
+//See uiconfig/swriter/ui/outlinepositionpage.ui for effectively a duplicate
+//dialog to this one, except with a different preview window impl.
+//TODO, determine if SwNumPositionTabPage and SvxNumPositionTabPage can be
+//merged
+SvxNumPositionTabPage::SvxNumPositionTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/numberingpositionpage.ui", "NumberingPositionPage", &rSet)
+ , m_pLevelHdlEvent(nullptr)
+ , nActNumLvl(1)
+ , nNumItemId(SID_ATTR_NUMBERING_RULE)
+ , bModified(false)
+ , bPreset(false)
+ , bInInintControl(false)
+ , bLabelAlignmentPosAndSpaceModeActive(false)
+ , m_xLevelLB(m_xBuilder->weld_tree_view("levellb"))
+ , m_xDistBorderFT(m_xBuilder->weld_label("indent"))
+ , m_xDistBorderMF(m_xBuilder->weld_metric_spin_button("indentmf", FieldUnit::CM))
+ , m_xRelativeCB(m_xBuilder->weld_check_button("relative"))
+ , m_xIndentFT(m_xBuilder->weld_label("numberingwidth"))
+ , m_xIndentMF(m_xBuilder->weld_metric_spin_button("numberingwidthmf", FieldUnit::CM))
+ , m_xDistNumFT(m_xBuilder->weld_label("numdist"))
+ , m_xDistNumMF(m_xBuilder->weld_metric_spin_button("numdistmf", FieldUnit::CM))
+ , m_xAlignFT(m_xBuilder->weld_label("numalign"))
+ , m_xAlignLB(m_xBuilder->weld_combo_box("numalignlb"))
+ , m_xLabelFollowedByFT(m_xBuilder->weld_label("numfollowedby"))
+ , m_xLabelFollowedByLB(m_xBuilder->weld_combo_box("numfollowedbylb"))
+ , m_xListtabFT(m_xBuilder->weld_label("at"))
+ , m_xListtabMF(m_xBuilder->weld_metric_spin_button("atmf", FieldUnit::CM))
+ , m_xAlign2FT(m_xBuilder->weld_label("num2align"))
+ , m_xAlign2LB(m_xBuilder->weld_combo_box("num2alignlb"))
+ , m_xAlignedAtFT(m_xBuilder->weld_label("alignedat"))
+ , m_xAlignedAtMF(m_xBuilder->weld_metric_spin_button("alignedatmf", FieldUnit::CM))
+ , m_xIndentAtFT(m_xBuilder->weld_label("indentat"))
+ , m_xIndentAtMF(m_xBuilder->weld_metric_spin_button("indentatmf", FieldUnit::CM))
+ , m_xStandardPB(m_xBuilder->weld_button("standard"))
+ , m_xPreviewWIN(new weld::CustomWeld(*m_xBuilder, "preview", m_aPreviewWIN))
+{
+ SetExchangeSupport();
+
+ m_xAlignedAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xListtabMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+ m_xIndentAtMF->set_range(0, SAL_MAX_INT32, FieldUnit::NONE);
+
+ m_xRelativeCB->set_active(true);
+ m_xAlignLB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ m_xAlign2LB->connect_changed(LINK(this, SvxNumPositionTabPage, EditModifyHdl_Impl));
+ for ( sal_Int32 i = 0; i < m_xAlignLB->get_count(); ++i )
+ {
+ m_xAlign2LB->append_text(m_xAlignLB->get_text(i));
+ }
+
+ Link<weld::MetricSpinButton&,void> aLk3 = LINK(this, SvxNumPositionTabPage, DistanceHdl_Impl);
+ m_xDistBorderMF->connect_value_changed(aLk3);
+ m_xDistNumMF->connect_value_changed(aLk3);
+ m_xIndentMF->connect_value_changed(aLk3);
+
+ m_xLabelFollowedByLB->connect_changed(LINK(this, SvxNumPositionTabPage, LabelFollowedByHdl_Impl));
+
+ m_xListtabMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, ListtabPosHdl_Impl));
+ m_xAlignedAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, AlignAtHdl_Impl));
+ m_xIndentAtMF->connect_value_changed(LINK(this, SvxNumPositionTabPage, IndentAtHdl_Impl));
+
+ m_xLevelLB->set_selection_mode(SelectionMode::Multiple);
+ m_xLevelLB->connect_changed(LINK(this, SvxNumPositionTabPage, LevelHdl_Impl));
+ m_xRelativeCB->connect_toggled(LINK(this, SvxNumPositionTabPage, RelativeHdl_Impl));
+ m_xStandardPB->connect_clicked(LINK(this, SvxNumPositionTabPage, StandardHdl_Impl));
+
+ m_xRelativeCB->set_active(bLastRelative);
+ m_aPreviewWIN.SetPositionMode();
+ eCoreUnit = rSet.GetPool()->GetMetric(rSet.GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE));
+}
+
+SvxNumPositionTabPage::~SvxNumPositionTabPage()
+{
+ if (m_pLevelHdlEvent)
+ {
+ Application::RemoveUserEvent(m_pLevelHdlEvent);
+ m_pLevelHdlEvent = nullptr;
+ }
+ m_xPreviewWIN.reset();
+}
+
+/*-------------------------------------------------------*/
+
+void SvxNumPositionTabPage::InitControls()
+{
+ bInInintControl = true;
+ const bool bRelative = !bLabelAlignmentPosAndSpaceModeActive &&
+ m_xRelativeCB->get_sensitive() && m_xRelativeCB->get_active();
+ const bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 &&
+ SAL_MAX_UINT16 != nActNumLvl;
+
+ m_xDistBorderMF->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+ m_xDistBorderFT->set_sensitive( !bLabelAlignmentPosAndSpaceModeActive &&
+ ( bSingleSelection || bRelative ) );
+
+ bool bSetDistEmpty = false;
+ bool bSameDistBorderNum = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameDist = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndent = !bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAdjust = true;
+
+ bool bSameLabelFollowedBy = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameListtab = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameAlignAt = bLabelAlignmentPosAndSpaceModeActive;
+ bool bSameIndentAt = bLabelAlignmentPosAndSpaceModeActive;
+
+ const SvxNumberFormat* aNumFmtArr[SVX_MAX_NUM];
+ sal_uInt16 nMask = 1;
+ sal_uInt16 nLvl = SAL_MAX_UINT16;
+ long nFirstBorderTextRelative = -1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ aNumFmtArr[i] = &pActNum->GetLevel(i);
+ if(nActNumLvl & nMask)
+ {
+ if(SAL_MAX_UINT16 == nLvl)
+ nLvl = i;
+
+ if( i > nLvl)
+ {
+ bSameAdjust &= aNumFmtArr[i]->GetNumAdjust() == aNumFmtArr[nLvl]->GetNumAdjust();
+ if ( !bLabelAlignmentPosAndSpaceModeActive )
+ {
+ if(bRelative)
+ {
+ if(nFirstBorderTextRelative == -1)
+ nFirstBorderTextRelative =
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ else
+ bSameDistBorderNum &= nFirstBorderTextRelative ==
+ (aNumFmtArr[i]->GetAbsLSpace() + aNumFmtArr[i]->GetFirstLineOffset() -
+ aNumFmtArr[i - 1]->GetAbsLSpace() + aNumFmtArr[i - 1]->GetFirstLineOffset());
+ }
+ else
+ bSameDistBorderNum &=
+ aNumFmtArr[i]->GetAbsLSpace() - aNumFmtArr[i]->GetFirstLineOffset() ==
+ aNumFmtArr[i - 1]->GetAbsLSpace() - aNumFmtArr[i - 1]->GetFirstLineOffset();
+
+ bSameDist &= aNumFmtArr[i]->GetCharTextDistance() == aNumFmtArr[nLvl]->GetCharTextDistance();
+ bSameIndent &= aNumFmtArr[i]->GetFirstLineOffset() == aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ else
+ {
+ bSameLabelFollowedBy &=
+ aNumFmtArr[i]->GetLabelFollowedBy() == aNumFmtArr[nLvl]->GetLabelFollowedBy();
+ bSameListtab &=
+ aNumFmtArr[i]->GetListtabPos() == aNumFmtArr[nLvl]->GetListtabPos();
+ bSameAlignAt &=
+ ( ( aNumFmtArr[i]->GetIndentAt() + aNumFmtArr[i]->GetFirstLineIndent() )
+ == ( aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent() ) );
+ bSameIndentAt &=
+ aNumFmtArr[i]->GetIndentAt() == aNumFmtArr[nLvl]->GetIndentAt();
+ }
+ }
+ }
+ nMask <<= 1;
+
+ }
+ if (SVX_MAX_NUM <= nLvl)
+ {
+ OSL_ENSURE(false, "cannot happen.");
+ return;
+ }
+
+ if(bSameDistBorderNum)
+ {
+ long nDistBorderNum;
+ if(bRelative)
+ {
+ nDistBorderNum = static_cast<long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ if(nLvl)
+ nDistBorderNum -= static_cast<long>(aNumFmtArr[nLvl - 1]->GetAbsLSpace())+ aNumFmtArr[nLvl - 1]->GetFirstLineOffset();
+ }
+ else
+ {
+ nDistBorderNum = static_cast<long>(aNumFmtArr[nLvl]->GetAbsLSpace())+ aNumFmtArr[nLvl]->GetFirstLineOffset();
+ }
+ SetMetricValue(*m_xDistBorderMF, nDistBorderNum, eCoreUnit);
+ }
+ else
+ bSetDistEmpty = true;
+
+ if(bSameDist)
+ SetMetricValue(*m_xDistNumMF, aNumFmtArr[nLvl]->GetCharTextDistance(), eCoreUnit);
+ else
+ m_xDistNumMF->set_text("");
+ if(bSameIndent)
+ SetMetricValue(*m_xIndentMF, - aNumFmtArr[nLvl]->GetFirstLineOffset(), eCoreUnit);
+ else
+ m_xIndentMF->set_text("");
+
+ if(bSameAdjust)
+ {
+ sal_Int32 nPos = 1; // centered
+ if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Left)
+ nPos = 0;
+ else if(aNumFmtArr[nLvl]->GetNumAdjust() == SvxAdjust::Right)
+ nPos = 2;
+ m_xAlignLB->set_active(nPos);
+ m_xAlign2LB->set_active(nPos);
+ }
+ else
+ {
+ m_xAlignLB->set_active(-1);
+ m_xAlign2LB->set_active(-1);
+ }
+
+ if ( bSameLabelFollowedBy )
+ {
+ sal_Int32 nPos = 0; // LISTTAB
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::SPACE )
+ {
+ nPos = 1;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NOTHING )
+ {
+ nPos = 2;
+ }
+ else if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::NEWLINE )
+ {
+ nPos = 3;
+ }
+ m_xLabelFollowedByLB->set_active(nPos);
+ }
+ else
+ {
+ m_xLabelFollowedByLB->set_active(-1);
+ }
+
+ if ( aNumFmtArr[nLvl]->GetLabelFollowedBy() == SvxNumberFormat::LISTTAB )
+ {
+ m_xListtabFT->set_sensitive(true);
+ m_xListtabMF->set_sensitive(true);
+ if ( bSameListtab )
+ {
+ SetMetricValue(*m_xListtabMF, aNumFmtArr[nLvl]->GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text("");
+ }
+ }
+ else
+ {
+ m_xListtabFT->set_sensitive(false);
+ m_xListtabMF->set_sensitive(false);
+ m_xListtabMF->set_text("");
+ }
+
+ if ( bSameAlignAt )
+ {
+ SetMetricValue(*m_xAlignedAtMF,
+ aNumFmtArr[nLvl]->GetIndentAt() + aNumFmtArr[nLvl]->GetFirstLineIndent(),
+ eCoreUnit);
+ }
+ else
+ {
+ m_xAlignedAtMF->set_text("");
+ }
+
+ if ( bSameIndentAt )
+ {
+ SetMetricValue(*m_xIndentAtMF, aNumFmtArr[nLvl]->GetIndentAt(), eCoreUnit);
+ }
+ else
+ {
+ m_xIndentAtMF->set_text("");
+ }
+
+ if ( bSetDistEmpty )
+ m_xDistBorderMF->set_text("");
+
+ bInInintControl = false;
+}
+
+void SvxNumPositionTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const SfxPoolItem* pItem;
+ sal_uInt16 nTmpNumLvl = 1;
+ const SfxItemSet* pExampleSet = GetDialogExampleSet();
+ if(pExampleSet)
+ {
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_NUM_PRESET, false, &pItem))
+ bPreset = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ if(SfxItemState::SET == pExampleSet->GetItemState(SID_PARAM_CUR_NUM_LEVEL, false, &pItem))
+ nTmpNumLvl = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ if(SfxItemState::SET == rSet.GetItemState(nNumItemId, false, &pItem))
+ {
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+ }
+ bModified = (!pActNum->Get( 0 ) || bPreset);
+ if(*pSaveNum != *pActNum ||
+ nActNumLvl != nTmpNumLvl )
+ {
+ *pActNum = *pSaveNum;
+ nActNumLvl = nTmpNumLvl;
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ m_xLevelLB->select(pActNum->GetLevelCount());
+ if (nActNumLvl != SAL_MAX_UINT16)
+ for (sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if (nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1 ;
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ }
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+DeactivateRC SvxNumPositionTabPage::DeactivatePage(SfxItemSet *_pSet)
+{
+ if(_pSet)
+ {
+ if (m_xDistBorderMF->get_sensitive())
+ DistanceHdl_Impl(*m_xDistBorderMF);
+ DistanceHdl_Impl(*m_xIndentMF);
+ FillItemSet(_pSet);
+ }
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxNumPositionTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ rSet->Put(SfxUInt16Item(SID_PARAM_CUR_NUM_LEVEL, nActNumLvl));
+
+ if(bModified && pActNum)
+ {
+ *pSaveNum = *pActNum;
+ rSet->Put(SvxNumBulletItem( *pSaveNum, nNumItemId ));
+ rSet->Put(SfxBoolItem(SID_PARAM_NUM_PRESET, false));
+ }
+ return bModified;
+}
+
+void SvxNumPositionTabPage::Reset( const SfxItemSet* rSet )
+{
+ const SfxPoolItem* pItem;
+ // in Draw the item exists as WhichId, in Writer only as SlotId
+ SfxItemState eState = rSet->GetItemState(SID_ATTR_NUMBERING_RULE, false, &pItem);
+ if(eState != SfxItemState::SET)
+ {
+ nNumItemId = rSet->GetPool()->GetWhich(SID_ATTR_NUMBERING_RULE);
+ eState = rSet->GetItemState(nNumItemId, false, &pItem);
+
+ if( eState != SfxItemState::SET )
+ {
+ pItem = &static_cast< const SvxNumBulletItem& >( rSet->Get( nNumItemId ) );
+ eState = SfxItemState::SET;
+ }
+
+ }
+ DBG_ASSERT(eState == SfxItemState::SET, "no item found!");
+ pSaveNum.reset( new SvxNumRule(*static_cast<const SvxNumBulletItem*>(pItem)->GetNumRule()) );
+
+ // insert levels
+ if (!m_xLevelLB->count_selected_rows())
+ {
+ for(sal_uInt16 i = 1; i <= pSaveNum->GetLevelCount(); i++)
+ m_xLevelLB->append_text(OUString::number(i));
+ if(pSaveNum->GetLevelCount() > 1)
+ {
+ OUString sEntry = "1 - " + OUString::number( pSaveNum->GetLevelCount() );
+ m_xLevelLB->append_text(sEntry);
+ m_xLevelLB->select_text(sEntry);
+ }
+ else
+ m_xLevelLB->select(0);
+ }
+ else
+ m_xLevelLB->select(m_xLevelLB->count_selected_rows() - 1);
+ sal_uInt16 nMask = 1;
+ m_xLevelLB->unselect_all();
+ if (nActNumLvl == SAL_MAX_UINT16)
+ {
+ m_xLevelLB->select(pSaveNum->GetLevelCount());
+ }
+ else
+ {
+ for(sal_uInt16 i = 0; i < pSaveNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ m_xLevelLB->select(i);
+ nMask <<= 1;
+ }
+ }
+
+ if(!pActNum)
+ pActNum.reset( new SvxNumRule(*pSaveNum) );
+ else if(*pSaveNum != *pActNum)
+ *pActNum = *pSaveNum;
+ m_aPreviewWIN.SetNumRule(pActNum.get());
+
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+
+ InitControls();
+ bModified = false;
+}
+
+void SvxNumPositionTabPage::InitPosAndSpaceMode()
+{
+ if ( pActNum == nullptr )
+ {
+ SAL_WARN( "cui.tabpages",
+ "<SvxNumPositionTabPage::InitPosAndSpaceMode()> - misusage of method -> <pAktNum> has to be already set!" );
+ return;
+ }
+
+ SvxNumberFormat::SvxNumPositionAndSpaceMode ePosAndSpaceMode =
+ SvxNumberFormat::LABEL_ALIGNMENT;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ ePosAndSpaceMode = aNumFmt.GetPositionAndSpaceMode();
+ if ( ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ break;
+ }
+ }
+ nMask <<= 1;
+ }
+
+ bLabelAlignmentPosAndSpaceModeActive =
+ ePosAndSpaceMode == SvxNumberFormat::LABEL_ALIGNMENT;
+}
+
+void SvxNumPositionTabPage::ShowControlsDependingOnPosAndSpaceMode()
+{
+ m_xDistBorderFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistBorderMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xRelativeCB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xDistNumFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS) );
+ m_xDistNumMF->set_visible( !bLabelAlignmentPosAndSpaceModeActive &&
+ pActNum->IsFeatureSupported(SvxNumRuleFlags::CONTINUOUS));
+ m_xAlignFT->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignLB->set_visible( !bLabelAlignmentPosAndSpaceModeActive );
+
+ m_xLabelFollowedByFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xLabelFollowedByLB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xListtabMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2FT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlign2LB->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xAlignedAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtFT->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+ m_xIndentAtMF->set_visible( bLabelAlignmentPosAndSpaceModeActive );
+}
+
+std::unique_ptr<SfxTabPage> SvxNumPositionTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxNumPositionTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxNumPositionTabPage::SetMetric(FieldUnit eMetric)
+{
+ if (eMetric == FieldUnit::MM)
+ {
+ m_xDistBorderMF->set_digits(1);
+ m_xDistNumMF->set_digits(1);
+ m_xIndentMF->set_digits(1);
+ m_xListtabMF->set_digits(1);
+ m_xAlignedAtMF->set_digits(1);
+ m_xIndentAtMF->set_digits(1);
+ }
+ m_xDistBorderMF->set_unit(eMetric);
+ m_xDistNumMF->set_unit(eMetric);
+ m_xIndentMF->set_unit(eMetric);
+ m_xListtabMF->set_unit(eMetric);
+ m_xAlignedAtMF->set_unit(eMetric);
+ m_xIndentAtMF->set_unit(eMetric);
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, EditModifyHdl_Impl, weld::ComboBox&, void)
+{
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt(pActNum->GetLevel(i));
+
+ const sal_Int32 nPos = m_xAlignLB->get_visible()
+ ? m_xAlignLB->get_active()
+ : m_xAlign2LB->get_active();
+ SvxAdjust eAdjust = SvxAdjust::Center;
+ if(nPos == 0)
+ eAdjust = SvxAdjust::Left;
+ else if(nPos == 2)
+ eAdjust = SvxAdjust::Right;
+ aNumFmt.SetNumAdjust( eAdjust );
+ pActNum->SetLevel(i, aNumFmt);
+ }
+ nMask <<= 1;
+ }
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl_Impl, weld::TreeView&, void)
+{
+ if (m_pLevelHdlEvent)
+ return;
+ // tdf#127120 multiselection may be implemented by deselect follow by select so
+ // fire off the handler to happen on next event loop and only process the
+ // final state
+ m_pLevelHdlEvent = Application::PostUserEvent(LINK(this, SvxNumPositionTabPage, LevelHdl));
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LevelHdl, void*, void)
+{
+ m_pLevelHdlEvent = nullptr;
+
+ sal_uInt16 nSaveNumLvl = nActNumLvl;
+ nActNumLvl = 0;
+ std::vector<int> aSelectedRows = m_xLevelLB->get_selected_rows();
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), pActNum->GetLevelCount()) != aSelectedRows.end() &&
+ (aSelectedRows.size() == 1 || nSaveNumLvl != 0xffff))
+ {
+ nActNumLvl = 0xFFFF;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ m_xLevelLB->unselect(i);
+ }
+ else if (!aSelectedRows.empty())
+ {
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if (std::find(aSelectedRows.begin(), aSelectedRows.end(), i) != aSelectedRows.end())
+ nActNumLvl |= nMask;
+ nMask <<= 1;
+ }
+ m_xLevelLB->unselect(pActNum->GetLevelCount());
+ }
+ else
+ {
+ nActNumLvl = nSaveNumLvl;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++ )
+ {
+ if(nActNumLvl & nMask)
+ {
+ m_xLevelLB->select(i);
+ break;
+ }
+ nMask <<=1;
+ }
+ }
+ m_xRelativeCB->set_sensitive(nActNumLvl != 1);
+ SetModified();
+ InitPosAndSpaceMode();
+ ShowControlsDependingOnPosAndSpaceMode();
+ InitControls();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, DistanceHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ if(bInInintControl)
+ return;
+ long nValue = GetCoreValue(rFld, eCoreUnit);
+ sal_uInt16 nMask = 1;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ if (&rFld == m_xDistBorderMF.get())
+ {
+
+ if (m_xRelativeCB->get_active())
+ {
+ if(0 == i)
+ {
+ auto const nTmp = aNumFmt.GetFirstLineOffset();
+ aNumFmt.SetAbsLSpace( nValue - nTmp);
+ }
+ else
+ {
+ long nTmp = pActNum->GetLevel( i - 1 ).GetAbsLSpace() +
+ pActNum->GetLevel( i - 1 ).GetFirstLineOffset() -
+ pActNum->GetLevel( i ).GetFirstLineOffset();
+
+ aNumFmt.SetAbsLSpace( nValue + nTmp);
+ }
+ }
+ else
+ {
+ aNumFmt.SetAbsLSpace( nValue - aNumFmt.GetFirstLineOffset());
+ }
+ }
+ else if (&rFld == m_xDistNumMF.get())
+ {
+ aNumFmt.SetCharTextDistance( static_cast<short>(nValue) );
+ }
+ else if (&rFld == m_xIndentMF.get())
+ {
+ // together with the FirstLineOffset the AbsLSpace must be changed, too
+ long nDiff = nValue + aNumFmt.GetFirstLineOffset();
+ auto const nAbsLSpace = aNumFmt.GetAbsLSpace();
+ aNumFmt.SetAbsLSpace(nAbsLSpace + nDiff);
+ aNumFmt.SetFirstLineOffset( -nValue );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+ if (!m_xDistBorderMF->get_sensitive())
+ {
+ m_xDistBorderMF->set_text("");
+ }
+}
+
+IMPL_LINK(SvxNumPositionTabPage, RelativeHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ bool bOn = rBox.get_active();
+ bool bSingleSelection = m_xLevelLB->count_selected_rows() == 1 && SAL_MAX_UINT16 != nActNumLvl;
+ bool bSetValue = false;
+ long nValue = 0;
+ if(bOn || bSingleSelection)
+ {
+ sal_uInt16 nMask = 1;
+ bool bFirst = true;
+ bSetValue = true;
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ const SvxNumberFormat &rNumFmt = pActNum->GetLevel(i);
+ if(bFirst)
+ {
+ nValue = rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset();
+ if(bOn && i)
+ nValue -= (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ }
+ else
+ bSetValue = nValue ==
+ (rNumFmt.GetAbsLSpace() + rNumFmt.GetFirstLineOffset()) -
+ (pActNum->GetLevel(i - 1).GetAbsLSpace() + pActNum->GetLevel(i - 1).GetFirstLineOffset());
+ bFirst = false;
+ }
+ nMask <<= 1;
+ }
+
+ }
+ if(bSetValue)
+ SetMetricValue(*m_xDistBorderMF, nValue, eCoreUnit);
+ else
+ m_xDistBorderMF->set_text("");
+ m_xDistBorderMF->set_sensitive(bOn || bSingleSelection);
+ m_xDistBorderFT->set_sensitive(bOn || bSingleSelection);
+ bLastRelative = bOn;
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, LabelFollowedByHdl_Impl, weld::ComboBox&, void)
+{
+ // determine value to be set at the chosen list levels
+ SvxNumberFormat::LabelFollowedBy eLabelFollowedBy = SvxNumberFormat::LISTTAB;
+ {
+ const auto nPos = m_xLabelFollowedByLB->get_active();
+ if ( nPos == 1 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::SPACE;
+ }
+ else if ( nPos == 2 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NOTHING;
+ }
+ else if ( nPos == 3 )
+ {
+ eLabelFollowedBy = SvxNumberFormat::NEWLINE;
+ }
+ }
+
+ // set value at the chosen list levels
+ bool bSameListtabPos = true;
+ sal_uInt16 nFirstLvl = SAL_MAX_UINT16;
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetLabelFollowedBy( eLabelFollowedBy );
+ pActNum->SetLevel( i, aNumFmt );
+
+ if ( nFirstLvl == SAL_MAX_UINT16 )
+ {
+ nFirstLvl = i;
+ }
+ else
+ {
+ bSameListtabPos &= aNumFmt.GetListtabPos() ==
+ pActNum->GetLevel( nFirstLvl ).GetListtabPos();
+ }
+ }
+ nMask <<= 1;
+ }
+
+ // enable/disable metric field for list tab stop position depending on
+ // selected item following the list label.
+ m_xListtabFT->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ m_xListtabMF->set_sensitive( eLabelFollowedBy == SvxNumberFormat::LISTTAB );
+ if ( bSameListtabPos && eLabelFollowedBy == SvxNumberFormat::LISTTAB )
+ {
+ SetMetricValue(*m_xListtabMF, pActNum->GetLevel( nFirstLvl ).GetListtabPos(), eCoreUnit);
+ }
+ else
+ {
+ m_xListtabMF->set_text(OUString());
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, ListtabPosHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ aNumFmt.SetListtabPos( nValue );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, AlignAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const long nFirstLineIndent = nValue - aNumFmt.GetIndentAt();
+ aNumFmt.SetFirstLineIndent( nFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK(SvxNumPositionTabPage, IndentAtHdl_Impl, weld::MetricSpinButton&, rFld, void)
+{
+ // determine value to be set at the chosen list levels
+ const long nValue = GetCoreValue(rFld, eCoreUnit);
+
+ // set value at the chosen list levels
+ sal_uInt16 nMask = 1;
+ for( sal_uInt16 i = 0; i < pActNum->GetLevelCount(); ++i )
+ {
+ if ( nActNumLvl & nMask )
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel(i) );
+ const long nAlignedAt = aNumFmt.GetIndentAt() +
+ aNumFmt.GetFirstLineIndent();
+ aNumFmt.SetIndentAt( nValue );
+ const long nNewFirstLineIndent = nAlignedAt - nValue;
+ aNumFmt.SetFirstLineIndent( nNewFirstLineIndent );
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ SetModified();
+}
+
+IMPL_LINK_NOARG(SvxNumPositionTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nMask = 1;
+ SvxNumRule aTmpNumRule( pActNum->GetFeatureFlags(),
+ pActNum->GetLevelCount(),
+ pActNum->IsContinuousNumbering(),
+ SvxNumRuleType::NUMBERING,
+ pActNum->GetLevel( 0 ).GetPositionAndSpaceMode() );
+ for(sal_uInt16 i = 0; i < pActNum->GetLevelCount(); i++)
+ {
+ if(nActNumLvl & nMask)
+ {
+ SvxNumberFormat aNumFmt( pActNum->GetLevel( i ) );
+ const SvxNumberFormat& aTempFmt(aTmpNumRule.GetLevel( i ));
+ aNumFmt.SetPositionAndSpaceMode( aTempFmt.GetPositionAndSpaceMode() );
+ if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
+ {
+ aNumFmt.SetAbsLSpace( aTempFmt.GetAbsLSpace() );
+ aNumFmt.SetCharTextDistance( aTempFmt.GetCharTextDistance() );
+ aNumFmt.SetFirstLineOffset( aTempFmt.GetFirstLineOffset() );
+ }
+ else if ( aTempFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
+ {
+ aNumFmt.SetNumAdjust( aTempFmt.GetNumAdjust() );
+ aNumFmt.SetLabelFollowedBy( aTempFmt.GetLabelFollowedBy() );
+ aNumFmt.SetListtabPos( aTempFmt.GetListtabPos() );
+ aNumFmt.SetFirstLineIndent( aTempFmt.GetFirstLineIndent() );
+ aNumFmt.SetIndentAt( aTempFmt.GetIndentAt() );
+ }
+
+ pActNum->SetLevel( i, aNumFmt );
+ }
+ nMask <<= 1;
+ }
+
+ InitControls();
+ SetModified();
+}
+
+void SvxNumPositionTabPage::SetModified()
+{
+ bModified = true;
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+}
+
+void SvxNumOptionsTabPage::SetModified(bool bRepaint)
+{
+ bModified = true;
+ if (bRepaint)
+ {
+ m_aPreviewWIN.SetLevel(nActNumLvl);
+ m_aPreviewWIN.Invalidate();
+ }
+}
+
+void SvxNumOptionsTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxStringListItem* pListItem = aSet.GetItem<SfxStringListItem>(SID_CHAR_FMT_LIST_BOX, false);
+ const SfxStringItem* pNumCharFmt = aSet.GetItem<SfxStringItem>(SID_NUM_CHAR_FMT, false);
+ const SfxStringItem* pBulletCharFmt = aSet.GetItem<SfxStringItem>(SID_BULLET_CHAR_FMT, false);
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pNumCharFmt &&pBulletCharFmt)
+ SetCharFmts( pNumCharFmt->GetValue(),pBulletCharFmt->GetValue());
+
+ if (pListItem)
+ {
+ const std::vector<OUString> &aList = pListItem->GetList();
+ sal_uInt32 nCount = aList.size();
+ for(sal_uInt32 i = 0; i < nCount; i++)
+ m_xCharFmtLB->append_text(aList[i]);
+ }
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+void SvxNumPositionTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pMetricItem = aSet.GetItem<SfxUInt16Item>(SID_METRIC_ITEM, false);
+
+ if (pMetricItem)
+ SetMetric(static_cast<FieldUnit>(pMetricItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/page.cxx b/cui/source/tabpages/page.cxx
new file mode 100644
index 000000000..1b5fc2851
--- /dev/null
+++ b/cui/source/tabpages/page.cxx
@@ -0,0 +1,1554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <sfx2/objsh.hxx>
+#include <sfx2/printer.hxx>
+#include <sfx2/viewsh.hxx>
+#include <svl/languageoptions.hxx>
+#include <svtools/unitconv.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <sal/macros.h>
+
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <page.hxx>
+#include <svx/pageitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/shaditem.hxx>
+#include <editeng/pbinitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/sizeitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/paperinf.hxx>
+#include <svl/stritem.hxx>
+#include <editeng/eerdll.hxx>
+#include <editeng/editrids.hrc>
+#include <svx/svxids.hrc>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svl/slstitm.hxx>
+#include <svx/xdef.hxx>
+#include <svx/unobrushitemhelper.hxx>
+#include <svx/SvxNumOptionsTabPageHelper.hxx>
+
+// static ----------------------------------------------------------------
+
+// #i19922# - tdf#126051 see svx/source/dialog/hdft.cxx and sw/source/uibase/sidebar/PageMarginControl.hxx
+static const long MINBODY = 56; // 1mm in twips rounded
+
+const sal_uInt16 SvxPageDescPage::pRanges[] =
+{
+ SID_ATTR_BORDER_OUTER,
+ SID_ATTR_BORDER_SHADOW,
+ SID_ATTR_LRSPACE,
+ SID_ATTR_PAGE_SHARED,
+ SID_SWREGISTER_COLLECTION,
+ SID_SWREGISTER_MODE,
+ 0
+};
+// ------- Mapping page layout ------------------------------------------
+
+const SvxPageUsage aArr[] =
+{
+ SvxPageUsage::All,
+ SvxPageUsage::Mirror,
+ SvxPageUsage::Right,
+ SvxPageUsage::Left
+};
+
+
+static sal_uInt16 PageUsageToPos_Impl( SvxPageUsage nUsage )
+{
+ for ( size_t i = 0; i < SAL_N_ELEMENTS(aArr); ++i )
+ if ( aArr[i] == nUsage )
+ return i;
+ return 3;
+}
+
+
+static SvxPageUsage PosToPageUsage_Impl( sal_uInt16 nPos )
+{
+ if ( nPos >= SAL_N_ELEMENTS(aArr) )
+ return SvxPageUsage::NONE;
+ return aArr[nPos];
+}
+
+
+static Size GetMinBorderSpace_Impl( const SvxShadowItem& rShadow, const SvxBoxItem& rBox )
+{
+ Size aSz;
+ aSz.setHeight( rShadow.CalcShadowSpace( SvxShadowItemSide::BOTTOM ) + rBox.CalcLineSpace( SvxBoxItemLine::BOTTOM ) );
+ aSz.AdjustHeight(rShadow.CalcShadowSpace( SvxShadowItemSide::TOP ) + rBox.CalcLineSpace( SvxBoxItemLine::TOP ) );
+ aSz.setWidth( rShadow.CalcShadowSpace( SvxShadowItemSide::LEFT ) + rBox.CalcLineSpace( SvxBoxItemLine::LEFT ) );
+ aSz.AdjustWidth(rShadow.CalcShadowSpace( SvxShadowItemSide::RIGHT ) + rBox.CalcLineSpace( SvxBoxItemLine::RIGHT ) );
+ return aSz;
+}
+
+
+static long ConvertLong_Impl( const long nIn, MapUnit eUnit )
+{
+ return OutputDevice::LogicToLogic( nIn, eUnit, MapUnit::MapTwip );
+}
+
+static bool IsEqualSize_Impl( const SvxSizeItem* pSize, const Size& rSize )
+{
+ if ( pSize )
+ {
+ Size aSize = pSize->GetSize();
+ long nDiffW = std::abs( rSize.Width () - aSize.Width () );
+ long nDiffH = std::abs( rSize.Height() - aSize.Height() );
+ return ( nDiffW < 10 && nDiffH < 10 );
+ }
+ else
+ return false;
+}
+
+
+#define MARGIN_LEFT ( MarginPosition(0x0001) )
+#define MARGIN_RIGHT ( MarginPosition(0x0002) )
+#define MARGIN_TOP ( MarginPosition(0x0004) )
+#define MARGIN_BOTTOM ( MarginPosition(0x0008) )
+
+// class SvxPageDescPage --------------------------------------------------
+
+std::unique_ptr<SfxTabPage> SvxPageDescPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPageDescPage>(pPage, pController, *rSet);
+}
+
+SvxPageDescPage::SvxPageDescPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/pageformatpage.ui", "PageFormatPage", &rAttr)
+ , bLandscape(false)
+ , eMode(SVX_PAGE_MODE_STANDARD)
+ , ePaperStart(PAPER_A3)
+ , m_nPos(0)
+ , mpDefPrinter(nullptr)
+ , mbDelPrinter(false)
+ , mbEnableDrawingLayerFillStyles(false)
+ , m_xPaperSizeBox(new SvxPaperSizeListBox(m_xBuilder->weld_combo_box("comboPageFormat")))
+ , m_xPaperWidthEdit(m_xBuilder->weld_metric_spin_button("spinWidth", FieldUnit::CM))
+ , m_xPaperHeightEdit(m_xBuilder->weld_metric_spin_button("spinHeight", FieldUnit::CM))
+ , m_xOrientationFT(m_xBuilder->weld_label("labelOrientation"))
+ , m_xPortraitBtn(m_xBuilder->weld_radio_button("radiobuttonPortrait"))
+ , m_xLandscapeBtn(m_xBuilder->weld_radio_button("radiobuttonLandscape"))
+ , m_xTextFlowLbl(m_xBuilder->weld_label("labelTextFlow"))
+ , m_xTextFlowBox(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboTextFlowBox")))
+ , m_xPaperTrayBox(m_xBuilder->weld_combo_box("comboPaperTray"))
+ , m_xLeftMarginLbl(m_xBuilder->weld_label("labelLeftMargin"))
+ , m_xLeftMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargLeft", FieldUnit::CM))
+ , m_xRightMarginLbl(m_xBuilder->weld_label("labelRightMargin"))
+ , m_xRightMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargRight", FieldUnit::CM))
+ , m_xTopMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargTop", FieldUnit::CM))
+ , m_xBottomMarginEdit(m_xBuilder->weld_metric_spin_button("spinMargBot", FieldUnit::CM))
+ , m_xPageText(m_xBuilder->weld_label("labelPageLayout"))
+ , m_xLayoutBox(m_xBuilder->weld_combo_box("comboPageLayout"))
+ , m_xNumberFormatText(m_xBuilder->weld_label("labelPageNumbers"))
+ , m_xNumberFormatBox(new SvxPageNumberListBox(m_xBuilder->weld_combo_box("comboLayoutFormat")))
+ , m_xTblAlignFT(m_xBuilder->weld_label("labelTblAlign"))
+ , m_xHorzBox(m_xBuilder->weld_check_button("checkbuttonHorz"))
+ , m_xVertBox(m_xBuilder->weld_check_button("checkbuttonVert"))
+ , m_xAdaptBox(m_xBuilder->weld_check_button("checkAdaptBox"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkRegisterTrue"))
+ , m_xRegisterFT(m_xBuilder->weld_label("labelRegisterStyle"))
+ , m_xRegisterLB(m_xBuilder->weld_combo_box("comboRegisterStyle"))
+ // Strings stored in UI
+ , m_xInsideLbl(m_xBuilder->weld_label("labelInner"))
+ , m_xOutsideLbl(m_xBuilder->weld_label("labelOuter"))
+ , m_xPrintRangeQueryText(m_xBuilder->weld_label("labelMsg"))
+ , m_xBspWin(new weld::CustomWeld(*m_xBuilder, "drawingareaPageDirection", m_aBspWin))
+{
+ m_xRegisterLB->set_size_request(m_xRegisterLB->get_approximate_digit_width() * 20, -1);
+
+ bBorderModified = false;
+ m_aBspWin.EnableRTL(false);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ SvtLanguageOptions aLangOptions;
+ bool bCJK = aLangOptions.IsAsianTypographyEnabled();
+ bool bCTL = aLangOptions.IsCTLFontEnabled();
+ bool bWeb = false;
+ const SfxPoolItem* pItem;
+
+ SfxObjectShell* pShell;
+ if(SfxItemState::SET == rAttr.GetItemState(SID_HTML_MODE, false, &pItem) ||
+ ( nullptr != (pShell = SfxObjectShell::Current()) &&
+ nullptr != (pItem = pShell->GetItem(SID_HTML_MODE))))
+ bWeb = 0 != (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON);
+
+ // fill text flow listbox with valid entries
+
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_HORI));
+
+ if (bCTL)
+ m_xTextFlowBox->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_HORI));
+
+
+ // #109989# do not show vertical directions in Writer/Web
+ if( !bWeb && bCJK )
+ {
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_RL_TB, SvxResId(RID_SVXSTR_PAGEDIR_RTL_VERT));
+ m_xTextFlowBox->append(SvxFrameDirection::Vertical_LR_TB, SvxResId(RID_SVXSTR_PAGEDIR_LTR_VERT));
+ }
+
+ // #109989# show the text direction box in Writer/Web too
+ if( (bCJK || bCTL) &&
+ SfxItemState::UNKNOWN < rAttr.GetItemState(GetWhich( SID_ATTR_FRAMEDIRECTION )))
+ {
+ m_xTextFlowLbl->show();
+ m_xTextFlowBox->show();
+ m_xTextFlowBox->connect_changed(LINK(this, SvxPageDescPage, FrameDirectionModify_Impl));
+
+ m_aBspWin.EnableFrameDirection(true);
+ }
+ Init_Impl();
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit( *m_xLeftMarginEdit, eFUnit );
+ SetFieldUnit( *m_xRightMarginEdit, eFUnit );
+ SetFieldUnit( *m_xTopMarginEdit, eFUnit );
+ SetFieldUnit( *m_xBottomMarginEdit, eFUnit );
+ SetFieldUnit( *m_xPaperWidthEdit, eFUnit );
+ SetFieldUnit( *m_xPaperHeightEdit, eFUnit );
+
+ if ( SfxViewShell::Current() && SfxViewShell::Current()->GetPrinter() )
+ {
+ mpDefPrinter = SfxViewShell::Current()->GetPrinter();
+ }
+ else
+ {
+ mpDefPrinter = VclPtr<Printer>::Create();
+ mbDelPrinter = true;
+ }
+
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for the margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense when the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X()), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() ), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y()), FieldUnit::TWIP );
+ nLastLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(aPrintOffset.X() + aPrintSize.Width()), FieldUnit::TWIP);
+ nLastTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+ nLastBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(aPrintOffset.Y() + aPrintSize.Height()), FieldUnit::TWIP);
+
+ // #i4219# get DrawingLayer options
+ const SvtOptionsDrawinglayer aDrawinglayerOpt;
+
+ // #i4219# take Maximum now from configuration (1/100th cm)
+ // was: 11900 -> 119 cm ;new value 3 meters -> 300 cm -> 30000
+ m_xPaperWidthEdit->set_max(m_xPaperWidthEdit->normalize(aDrawinglayerOpt.GetMaximumPaperWidth()), FieldUnit::CM);
+ m_xPaperHeightEdit->set_max(m_xPaperHeightEdit->normalize(aDrawinglayerOpt.GetMaximumPaperHeight()), FieldUnit::CM);
+
+ // #i4219# also for margins (1/100th cm). Was: 9999, keeping.
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(aDrawinglayerOpt.GetMaximumPaperLeftMargin()), FieldUnit::MM);
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(aDrawinglayerOpt.GetMaximumPaperRightMargin()), FieldUnit::MM);
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(aDrawinglayerOpt.GetMaximumPaperTopMargin()), FieldUnit::MM);
+ m_xBottomMarginEdit->set_max(m_xBottomMarginEdit->normalize(aDrawinglayerOpt.GetMaximumPaperBottomMargin()), FieldUnit::MM);
+
+ // Get the i18n framework numberings and add them to the listbox.
+ SvxNumOptionsTabPageHelper::GetI18nNumbering(m_xNumberFormatBox->get_widget(), std::numeric_limits<sal_uInt16>::max());
+}
+
+SvxPageDescPage::~SvxPageDescPage()
+{
+ if(mbDelPrinter)
+ {
+ mpDefPrinter.disposeAndClear();
+ mbDelPrinter = false;
+ }
+}
+
+void SvxPageDescPage::Init_Impl()
+{
+ // adjust the handler
+ m_xLayoutBox->connect_changed(LINK(this, SvxPageDescPage, LayoutHdl_Impl));
+
+ m_xPaperSizeBox->connect_changed(LINK(this, SvxPageDescPage, PaperSizeSelect_Impl));
+ m_xPaperWidthEdit->connect_value_changed( LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xPaperHeightEdit->connect_value_changed(LINK(this, SvxPageDescPage, PaperSizeModify_Impl));
+ m_xLandscapeBtn->connect_clicked(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_clicked(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ Link<weld::MetricSpinButton&, void> aLink = LINK(this, SvxPageDescPage, BorderModify_Impl);
+ m_xLeftMarginEdit->connect_value_changed(aLink);
+ m_xRightMarginEdit->connect_value_changed(aLink);
+ m_xTopMarginEdit->connect_value_changed(aLink);
+ m_xBottomMarginEdit->connect_value_changed(aLink);
+
+ m_xHorzBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+ m_xVertBox->connect_toggled(LINK(this, SvxPageDescPage, CenterHdl_Impl));
+}
+
+void SvxPageDescPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) );
+
+ // adjust margins (right/left)
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( pItem )
+ {
+ const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(*pItem);
+ SetMetricValue( *m_xLeftMarginEdit, rLRSpace.GetLeft(), eUnit );
+ m_aBspWin.SetLeft(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetLeft(), eUnit )) );
+ SetMetricValue( *m_xRightMarginEdit, rLRSpace.GetRight(), eUnit );
+ m_aBspWin.SetRight(
+ static_cast<sal_uInt16>(ConvertLong_Impl( rLRSpace.GetRight(), eUnit )) );
+ }
+
+ // adjust margins (top/bottom)
+ pItem = GetItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( pItem )
+ {
+ const SvxULSpaceItem& rULSpace = static_cast<const SvxULSpaceItem&>(*pItem);
+ SetMetricValue( *m_xTopMarginEdit, rULSpace.GetUpper(), eUnit );
+ m_aBspWin.SetTop(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<long>(rULSpace.GetUpper()), eUnit )) );
+ SetMetricValue( *m_xBottomMarginEdit, rULSpace.GetLower(), eUnit );
+ m_aBspWin.SetBottom(
+ static_cast<sal_uInt16>(ConvertLong_Impl( static_cast<long>(rULSpace.GetLower()), eUnit )) );
+ }
+
+ // general page data
+ SvxNumType eNumType = SVX_NUM_ARABIC;
+ bLandscape = ( mpDefPrinter->GetOrientation() == Orientation::Landscape );
+ SvxPageUsage nUse = SvxPageUsage::All;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE );
+
+ if ( pItem )
+ {
+ const SvxPageItem& rItem = static_cast<const SvxPageItem&>(*pItem);
+ eNumType = rItem.GetNumType();
+ nUse = rItem.GetPageUsage();
+ bLandscape = rItem.IsLandscape();
+ }
+
+ // alignment
+ m_xLayoutBox->set_active(::PageUsageToPos_Impl(nUse));
+ m_aBspWin.SetUsage( nUse );
+ LayoutHdl_Impl( *m_xLayoutBox );
+
+ //adjust numeration type of the page style
+ m_xNumberFormatBox->set_active_id(eNumType);
+
+ m_xPaperTrayBox->clear();
+ sal_uInt8 nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( pItem )
+ {
+ nPaperBin = static_cast<const SvxPaperBinItem*>(pItem)->GetValue();
+
+ if ( nPaperBin >= mpDefPrinter->GetPaperBinCount() )
+ nPaperBin = PAPERBIN_PRINTER_SETTINGS;
+ }
+
+ OUString aBinName;
+
+ if ( PAPERBIN_PRINTER_SETTINGS == nPaperBin )
+ aBinName = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS);
+ else
+ aBinName = mpDefPrinter->GetPaperBinName( static_cast<sal_uInt16>(nPaperBin) );
+
+ m_xPaperTrayBox->append(OUString::number(nPaperBin), aBinName);
+ m_xPaperTrayBox->set_active_text(aBinName);
+ // reset focus handler to default first so know none already connected
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+ // update the list when widget gets focus
+ m_xPaperTrayBox->connect_focus_in(LINK(this, SvxPageDescPage, PaperBinHdl_Impl));
+
+ Size aPaperSize = SvxPaperInfo::GetPaperSize( mpDefPrinter );
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ aPaperSize = static_cast<const SvxSizeItem*>(pItem)->GetSize();
+
+ bool bOrientationSupport =
+ mpDefPrinter->HasSupport( PrinterSupport::SetOrientation );
+
+ if ( !bOrientationSupport &&
+ aPaperSize.Width() > aPaperSize.Height() )
+ bLandscape = true;
+
+ // tdf#130548 disable callbacks on the other of a pair of the radiogroup
+ // when toggling its partner
+ m_xLandscapeBtn->connect_clicked(Link<weld::Button&, void>());
+ m_xPortraitBtn->connect_clicked(Link<weld::Button&, void>());
+
+ m_xLandscapeBtn->set_active(bLandscape);
+ m_xPortraitBtn->set_active(!bLandscape);
+
+ m_xLandscapeBtn->connect_clicked(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+ m_xPortraitBtn->connect_clicked(LINK(this, SvxPageDescPage, SwapOrientation_Impl));
+
+ m_aBspWin.SetSize( Size( ConvertLong_Impl( aPaperSize.Width(), eUnit ),
+ ConvertLong_Impl( aPaperSize.Height(), eUnit ) ) );
+
+ aPaperSize = OutputDevice::LogicToLogic(aPaperSize, MapMode(eUnit), MapMode(MapUnit::Map100thMM));
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // Actual Paper Format
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aPaperSize, MapUnit::Map100thMM );
+
+ if ( PAPER_USER != ePaper )
+ aPaperSize = SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM );
+
+ if ( bLandscape )
+ Swap( aPaperSize );
+
+ // write values into the edits
+ SetMetricValue( *m_xPaperHeightEdit, aPaperSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aPaperSize.Width(), MapUnit::Map100thMM );
+ m_xPaperSizeBox->clear();
+
+ m_xPaperSizeBox->FillPaperSizeEntries( ( ePaperStart == PAPER_A3 ) ? PaperSizeApp::Std : PaperSizeApp::Draw );
+ m_xPaperSizeBox->set_active_id( ePaper );
+
+ // application specific
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ m_xTblAlignFT->show();
+ m_xHorzBox->show();
+ m_xVertBox->show();
+ DisableVerticalPageDir();
+
+ // horizontal alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xHorzBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // vertical alignment
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT2 );
+ m_xVertBox->set_active(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue());
+
+ // set example window on the table
+ m_aBspWin.SetTable( true );
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ DisableVerticalPageDir();
+ m_xAdaptBox->show();
+ pItem = GetItem( *rSet, SID_ATTR_PAGE_EXT1 );
+ m_xAdaptBox->set_active( pItem &&
+ static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+
+ //!!! hidden, because not implemented by StarDraw
+ m_xLayoutBox->hide();
+ m_xPageText->hide();
+
+ break;
+ }
+ default: ;//prevent warning
+ }
+
+
+ // display background and border in the example
+ ResetBackground_Impl( *rSet );
+//! UpdateExample_Impl();
+ RangeHdl_Impl();
+
+ InitHeadFoot_Impl( *rSet );
+
+ bBorderModified = false;
+ SwapFirstValues_Impl( false );
+ UpdateExample_Impl();
+
+ m_xLeftMarginEdit->save_value();
+ m_xRightMarginEdit->save_value();
+ m_xTopMarginEdit->save_value();
+ m_xBottomMarginEdit->save_value();
+ m_xLayoutBox->save_value();
+ m_xNumberFormatBox->save_value();
+ m_xPaperSizeBox->save_value();
+ m_xPaperWidthEdit->save_value();
+ m_xPaperHeightEdit->save_value();
+ m_xPortraitBtn->save_state();
+ m_xLandscapeBtn->save_state();
+ m_xPaperTrayBox->save_value();
+ m_xVertBox->save_state();
+ m_xHorzBox->save_state();
+ m_xAdaptBox->save_state();
+
+ CheckMarginEdits( true );
+
+
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_MODE))
+ {
+ m_xRegisterCB->set_active(static_cast<const SfxBoolItem&>(rSet->Get(
+ SID_SWREGISTER_MODE)).GetValue());
+ m_xRegisterCB->save_state();
+ RegisterModify(*m_xRegisterCB);
+ }
+ if(SfxItemState::SET == rSet->GetItemState(SID_SWREGISTER_COLLECTION))
+ {
+ m_xRegisterLB->set_active_text(
+ static_cast<const SfxStringItem&>(rSet->Get(SID_SWREGISTER_COLLECTION)).GetValue());
+ m_xRegisterLB->save_value();
+ }
+
+ SfxItemState eState = rSet->GetItemState( GetWhich( SID_ATTR_FRAMEDIRECTION ),
+ true, &pItem );
+ if( SfxItemState::UNKNOWN != eState )
+ {
+ SvxFrameDirection nVal = SfxItemState::SET == eState
+ ? static_cast<const SvxFrameDirectionItem*>(pItem)->GetValue()
+ : SvxFrameDirection::Horizontal_LR_TB;
+ m_xTextFlowBox->set_active_id(nVal);
+
+ m_xTextFlowBox->save_value();
+ m_aBspWin.SetFrameDirection(nVal);
+ }
+}
+
+void SvxPageDescPage::FillUserData()
+{
+ if (SVX_PAGE_MODE_PRESENTATION == eMode)
+ SetUserData(m_xAdaptBox->get_active() ? OUString("1") : OUString("0")) ;
+
+}
+
+bool SvxPageDescPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ const SfxItemSet& rOldSet = GetItemSet();
+ SfxItemPool* pPool = rOldSet.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ const SfxPoolItem* pOld = nullptr;
+
+ // copy old left and right margins
+ SvxLRSpaceItem aMargin( static_cast<const SvxLRSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ // copy old top and bottom margins
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ SvxULSpaceItem aTopMargin( static_cast<const SvxULSpaceItem&>(rOldSet.Get( nWhich )) );
+
+ if (m_xLeftMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetLeft( static_cast<sal_uInt16>(GetCoreValue( *m_xLeftMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ if (m_xRightMarginEdit->get_value_changed_from_saved())
+ {
+ aMargin.SetRight( static_cast<sal_uInt16>(GetCoreValue( *m_xRightMarginEdit, eUnit )) );
+ bModified = true;
+ }
+
+ // set left and right margins
+ if (bModified)
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_LRSPACE );
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin )
+ rSet->Put( aMargin );
+ else
+ bModified = false;
+ }
+
+ bool bMod = false;
+
+ if (m_xTopMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetUpper( static_cast<sal_uInt16>(GetCoreValue( *m_xTopMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ if (m_xBottomMarginEdit->get_value_changed_from_saved())
+ {
+ aTopMargin.SetLower( static_cast<sal_uInt16>(GetCoreValue( *m_xBottomMarginEdit, eUnit )) );
+ bMod = true;
+ }
+
+ // set top and bottom margins
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_ULSPACE );
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aTopMargin )
+ {
+ bModified = true;
+ rSet->Put( aTopMargin );
+ }
+ }
+
+ // paper tray
+ nWhich = GetWhich( SID_ATTR_PAGE_PAPERBIN );
+ sal_Int32 nPos = m_xPaperTrayBox->get_active();
+ sal_uInt16 nBin = m_xPaperTrayBox->get_id(nPos).toInt32();
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_PAPERBIN );
+
+ if ( !pOld || static_cast<const SvxPaperBinItem*>(pOld)->GetValue() != nBin )
+ {
+ rSet->Put( SvxPaperBinItem( nWhich, static_cast<sal_uInt8>(nBin) ) );
+ bModified = true;
+ }
+
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+ bool bChecked = m_xLandscapeBtn->get_active();
+
+ if ( PAPER_USER == ePaper )
+ {
+ if ( m_xPaperSizeBox->get_value_changed_from_saved() ||
+ m_xPaperWidthEdit->get_value_changed_from_saved() ||
+ m_xPaperHeightEdit->get_value_changed_from_saved() ||
+ m_xLandscapeBtn->get_state_changed_from_saved() )
+ {
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+ else
+ {
+ if (m_xPaperSizeBox->get_value_changed_from_saved() || m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, eUnit ) );
+
+ if ( bChecked )
+ Swap( aSize );
+
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( !pOld || static_cast<const SvxSizeItem*>(pOld)->GetSize() != aSize )
+ {
+ rSet->Put( SvxSizeItem( GetWhich(SID_ATTR_PAGE_SIZE), aSize ) );
+ bModified = true;
+ }
+ }
+ }
+
+ nWhich = GetWhich( SID_ATTR_PAGE );
+ SvxPageItem aPage( static_cast<const SvxPageItem&>(rOldSet.Get( nWhich )) );
+ bMod = m_xLayoutBox->get_value_changed_from_saved();
+
+ if ( bMod )
+ aPage.SetPageUsage(::PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+
+ if (m_xLandscapeBtn->get_state_changed_from_saved())
+ {
+ aPage.SetLandscape(bChecked);
+ bMod = true;
+ }
+
+ //Get the NumType value
+ if (m_xNumberFormatBox->get_value_changed_from_saved())
+ {
+ SvxNumType nEntryData = m_xNumberFormatBox->get_active_id();
+ aPage.SetNumType( nEntryData );
+ bMod = true;
+ }
+
+ if ( bMod )
+ {
+ pOld = GetOldItem( *rSet, SID_ATTR_PAGE );
+
+ if ( !pOld || *static_cast<const SvxPageItem*>(pOld) != aPage )
+ {
+ rSet->Put( aPage );
+ bModified = true;
+ }
+ }
+ else if ( SfxItemState::DEFAULT == rOldSet.GetItemState( nWhich ) )
+ rSet->ClearItem( nWhich );
+ else
+ rSet->Put( rOldSet.Get( nWhich ) );
+
+ // evaluate mode specific controls
+
+ switch ( eMode )
+ {
+ case SVX_PAGE_MODE_CENTER:
+ {
+ if (m_xHorzBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aHorz( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xHorzBox->get_active() );
+ rSet->Put( aHorz );
+ bModified = true;
+ }
+
+ if (m_xVertBox->get_state_changed_from_saved())
+ {
+ SfxBoolItem aVert( GetWhich( SID_ATTR_PAGE_EXT2 ),
+ m_xVertBox->get_active() );
+ rSet->Put( aVert );
+ bModified = true;
+ }
+ break;
+ }
+
+ case SVX_PAGE_MODE_PRESENTATION:
+ {
+ // always put so that draw can evaluate this
+ rSet->Put( SfxBoolItem( GetWhich( SID_ATTR_PAGE_EXT1 ),
+ m_xAdaptBox->get_active() ) );
+ bModified = true;
+ break;
+ }
+ default: ;//prevent warning
+
+ }
+
+ if (m_xRegisterCB->get_visible() &&
+ (m_xRegisterCB->get_active() || m_xRegisterCB->get_state_changed_from_saved()))
+ {
+ const SfxBoolItem& rRegItem = static_cast<const SfxBoolItem&>(rOldSet.Get(SID_SWREGISTER_MODE));
+ std::unique_ptr<SfxBoolItem> pRegItem(rRegItem.Clone());
+ bool bCheck = m_xRegisterCB->get_active();
+ pRegItem->SetValue(bCheck);
+ rSet->Put(std::move(pRegItem));
+ bModified = true;
+ if(bCheck)
+ {
+ bModified = true;
+ rSet->Put(SfxStringItem(SID_SWREGISTER_COLLECTION,
+ m_xRegisterLB->get_active_text()));
+ }
+ }
+
+ if (m_xTextFlowBox->get_visible() && m_xTextFlowBox->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDirection = m_xTextFlowBox->get_active_id();
+ rSet->Put( SvxFrameDirectionItem( eDirection, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, LayoutHdl_Impl, weld::ComboBox&, void)
+{
+ // switch inside outside
+ const SvxPageUsage nUsage = PosToPageUsage_Impl(m_xLayoutBox->get_active());
+
+ if (nUsage == SvxPageUsage::Mirror)
+ {
+ m_xLeftMarginLbl->hide();
+ m_xRightMarginLbl->hide();
+ m_xInsideLbl->show();
+ m_xOutsideLbl->show();
+ }
+ else
+ {
+ m_xLeftMarginLbl->show();
+ m_xRightMarginLbl->show();
+ m_xInsideLbl->hide();
+ m_xOutsideLbl->hide();
+ }
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperBinHdl_Impl, weld::Widget&, void)
+{
+ // tdf#124226 disconnect so not called again, unless Reset occurs
+ m_xPaperTrayBox->connect_focus_in(Link<weld::Widget&, void>());
+
+ OUString aOldName = m_xPaperTrayBox->get_active_text();
+ m_xPaperTrayBox->freeze();
+ m_xPaperTrayBox->clear();
+ m_xPaperTrayBox->append(OUString::number(PAPERBIN_PRINTER_SETTINGS), EditResId(RID_SVXSTR_PAPERBIN_SETTINGS));
+ OUString aPaperBin(EditResId(RID_SVXSTR_PAPERBIN));
+ const sal_uInt16 nBinCount = mpDefPrinter->GetPaperBinCount();
+
+ for (sal_uInt16 i = 0; i < nBinCount; ++i)
+ {
+ OUString aName = mpDefPrinter->GetPaperBinName(i);
+ if (aName.isEmpty())
+ {
+ aName = aPaperBin + " " + OUString::number( i+1 );
+ }
+ m_xPaperTrayBox->append(OUString::number(i), aName);
+ }
+ m_xPaperTrayBox->set_active_text(aOldName);
+ m_xPaperTrayBox->thaw();
+
+ // tdf#123650 explicitly grab-focus after the modification otherwise gtk loses track
+ // of there the focus should be
+ m_xPaperTrayBox->grab_focus();
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeSelect_Impl, weld::ComboBox&, void)
+{
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper == PAPER_USER )
+ return;
+
+ Size aSize( SvxPaperInfo::GetPaperSize( ePaper, MapUnit::Map100thMM ) );
+
+ if (m_xLandscapeBtn->get_active())
+ Swap( aSize );
+
+ if ( aSize.Height() < m_xPaperHeightEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperHeightEdit->set_min(
+ m_xPaperHeightEdit->normalize( aSize.Height() ), FieldUnit::MM_100TH );
+ if ( aSize.Width() < m_xPaperWidthEdit->get_min( FieldUnit::MM_100TH ) )
+ m_xPaperWidthEdit->set_min(
+ m_xPaperWidthEdit->normalize( aSize.Width() ), FieldUnit::MM_100TH );
+ SetMetricValue( *m_xPaperHeightEdit, aSize.Height(), MapUnit::Map100thMM );
+ SetMetricValue( *m_xPaperWidthEdit, aSize.Width(), MapUnit::Map100thMM );
+
+ CalcMargin_Impl();
+
+ RangeHdl_Impl();
+ UpdateExample_Impl( true );
+
+ if ( eMode != SVX_PAGE_MODE_PRESENTATION )
+ return;
+
+ // Draw: if paper format the margin shall be 1 cm
+ long nTmp = 0;
+ bool bScreen = (( PAPER_SCREEN_4_3 == ePaper )||( PAPER_SCREEN_16_9 == ePaper)||( PAPER_SCREEN_16_10 == ePaper));
+
+ if ( !bScreen )
+ // no margin if screen
+ nTmp = 1; // accordingly 1 cm
+
+ if ( bScreen || m_xRightMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xLeftMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xBottomMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapCM );
+ if ( bScreen || m_xTopMarginEdit->get_value(FieldUnit::NONE) == 0 )
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapCM );
+ UpdateExample_Impl( true );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, PaperSizeModify_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWhich );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ if ( aSize.Width() > aSize.Height() )
+ {
+ m_xLandscapeBtn->set_active(true);
+ bLandscape = true;
+ }
+ else
+ {
+ m_xPortraitBtn->set_active(true);
+ bLandscape = false;
+ }
+
+ Paper ePaper = SvxPaperInfo::GetSvxPaper( aSize, eUnit );
+ m_xPaperSizeBox->set_active_id( ePaper );
+ UpdateExample_Impl( true );
+
+ RangeHdl_Impl();
+}
+
+IMPL_LINK(SvxPageDescPage, SwapOrientation_Impl, weld::Button&, rBtn, void)
+{
+ if (
+ !((!bLandscape && &rBtn == m_xLandscapeBtn.get()) ||
+ (bLandscape && &rBtn == m_xPortraitBtn.get()))
+ )
+ return;
+
+ bLandscape = m_xLandscapeBtn->get_active();
+
+ const long lWidth = GetCoreValue( *m_xPaperWidthEdit, MapUnit::Map100thMM );
+ const long lHeight = GetCoreValue( *m_xPaperHeightEdit, MapUnit::Map100thMM );
+
+ // swap width and height
+ SetMetricValue(*m_xPaperWidthEdit, lHeight, MapUnit::Map100thMM);
+ SetMetricValue(*m_xPaperHeightEdit, lWidth, MapUnit::Map100thMM);
+
+ // recalculate margins if necessary
+ CalcMargin_Impl();
+
+ PaperSizeSelect_Impl(m_xPaperSizeBox->get_widget());
+ RangeHdl_Impl();
+ SwapFirstValues_Impl(bBorderModified);
+ UpdateExample_Impl(true);
+}
+
+void SvxPageDescPage::SwapFirstValues_Impl( bool bSet )
+{
+ MapMode aOldMode = mpDefPrinter->GetMapMode();
+ Orientation eOri = Orientation::Portrait;
+
+ if ( bLandscape )
+ eOri = Orientation::Landscape;
+ Orientation eOldOri = mpDefPrinter->GetOrientation();
+ mpDefPrinter->SetOrientation( eOri );
+ mpDefPrinter->SetMapMode(MapMode(MapUnit::MapTwip));
+
+ // set first- and last-values for margins
+ Size aPaperSize = mpDefPrinter->GetPaperSize();
+ Size aPrintSize = mpDefPrinter->GetOutputSize();
+ /*
+ * To convert a point ( 0,0 ) into logic coordinates
+ * looks like nonsense; but it makes sense if the
+ * coordinate system's origin has been moved.
+ */
+ Point aPrintOffset = mpDefPrinter->GetPageOffset() - mpDefPrinter->PixelToLogic( Point() );
+ mpDefPrinter->SetMapMode( aOldMode );
+ mpDefPrinter->SetOrientation( eOldOri );
+
+ sal_Int64 nSetL = m_xLeftMarginEdit->denormalize(
+ m_xLeftMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetR = m_xRightMarginEdit->denormalize(
+ m_xRightMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetT = m_xTopMarginEdit->denormalize(
+ m_xTopMarginEdit->get_value( FieldUnit::TWIP ) );
+ sal_Int64 nSetB = m_xBottomMarginEdit->denormalize(
+ m_xBottomMarginEdit->get_value( FieldUnit::TWIP ) );
+
+ long nNewL = aPrintOffset.X();
+ long nNewR = aPaperSize.Width() - aPrintSize.Width() - aPrintOffset.X();
+ long nNewT = aPrintOffset.Y();
+ long nNewB = aPaperSize.Height() - aPrintSize.Height() - aPrintOffset.Y();
+
+ nFirstLeftMargin = m_xLeftMarginEdit->convert_value_from(m_xLeftMarginEdit->normalize(nNewL), FieldUnit::TWIP);
+ nFirstRightMargin = m_xRightMarginEdit->convert_value_from(m_xRightMarginEdit->normalize(nNewR), FieldUnit::TWIP);
+ nFirstTopMargin = m_xTopMarginEdit->convert_value_from(m_xTopMarginEdit->normalize(nNewT), FieldUnit::TWIP);
+ nFirstBottomMargin = m_xBottomMarginEdit->convert_value_from(m_xBottomMarginEdit->normalize(nNewB), FieldUnit::TWIP);
+
+ if ( !bSet )
+ return;
+
+ if ( nSetL < nNewL )
+ m_xLeftMarginEdit->set_value( m_xLeftMarginEdit->normalize( nNewL ),
+ FieldUnit::TWIP );
+ if ( nSetR < nNewR )
+ m_xRightMarginEdit->set_value( m_xRightMarginEdit->normalize( nNewR ),
+ FieldUnit::TWIP );
+ if ( nSetT < nNewT )
+ m_xTopMarginEdit->set_value( m_xTopMarginEdit->normalize( nNewT ),
+ FieldUnit::TWIP );
+ if ( nSetB < nNewB )
+ m_xBottomMarginEdit->set_value( m_xBottomMarginEdit->normalize( nNewB ),
+ FieldUnit::TWIP );
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, BorderModify_Impl, weld::MetricSpinButton&, void)
+{
+ if ( !bBorderModified )
+ bBorderModified = true;
+ UpdateExample_Impl();
+
+ RangeHdl_Impl();
+}
+
+void SvxPageDescPage::UpdateExample_Impl( bool bResetbackground )
+{
+ // Size
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip ),
+ GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip ) );
+
+ m_aBspWin.SetSize( aSize );
+
+ // Margins
+ m_aBspWin.SetTop( GetCoreValue( *m_xTopMarginEdit, MapUnit::MapTwip ) );
+ m_aBspWin.SetBottom( GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip ) );
+ m_aBspWin.SetLeft( GetCoreValue( *m_xLeftMarginEdit, MapUnit::MapTwip ) );
+ m_aBspWin.SetRight( GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip ) );
+
+ // Layout
+ m_aBspWin.SetUsage(PosToPageUsage_Impl(m_xLayoutBox->get_active()));
+ if ( bResetbackground )
+ m_aBspWin.ResetBackground();
+ m_aBspWin.Invalidate();
+}
+
+
+void SvxPageDescPage::ResetBackground_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nWhich(GetWhich(SID_ATTR_PAGE_HEADERSET));
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich, false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = static_cast< const SfxBoolItem& >(rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON)));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSet aTempSet(*rTmpSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+ }
+
+ nWhich = GetWhich(SID_ATTR_PAGE_FOOTERSET);
+
+ if (SfxItemState::SET == rSet.GetItemState(nWhich, false))
+ {
+ const SvxSetItem& rSetItem = static_cast< const SvxSetItem& >(rSet.Get(nWhich,false));
+ const SfxItemSet& rTmpSet = rSetItem.GetItemSet();
+ const SfxBoolItem& rOn = static_cast< const SfxBoolItem& >(rTmpSet.Get(GetWhich(SID_ATTR_PAGE_ON)));
+
+ if(rOn.GetValue())
+ {
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rTmpSet);
+ }
+ else
+ {
+ nWhich = GetWhich(SID_ATTR_BRUSH);
+
+ if(SfxItemState::SET == rTmpSet.GetItemState(nWhich))
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rTmpSet.Get(nWhich));
+ SfxItemSet aTempSet(*rTmpSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+ }
+ }
+
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aPageFillAttributes;
+ const SfxPoolItem* pItem = nullptr;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rSet);
+ }
+ else
+ {
+ pItem = GetItem(rSet, SID_ATTR_BRUSH);
+
+ if(pItem)
+ {
+ // create FillAttributes from SvxBrushItem
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(*pItem);
+ SfxItemSet aTempSet(*rSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aPageFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setPageFillAttributes(aPageFillAttributes);
+}
+
+void SvxPageDescPage::InitHeadFoot_Impl( const SfxItemSet& rSet )
+{
+ bLandscape = m_xLandscapeBtn->get_active();
+ const SfxPoolItem* pItem = GetItem( rSet, SID_ATTR_PAGE_SIZE );
+
+ if ( pItem )
+ m_aBspWin.SetSize( static_cast<const SvxSizeItem*>(pItem)->GetSize() );
+
+ const SvxSetItem* pSetItem = nullptr;
+
+ // evaluate header attributes
+
+ if ( SfxItemState::SET ==
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_HEADERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ {
+ const SfxItemSet& rHeaderSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rHeaderOn =
+ static_cast<const SfxBoolItem&>(rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_ON ) ));
+
+ if ( rHeaderOn.GetValue() )
+ {
+ const SvxSizeItem& rSize = static_cast<const SvxSizeItem&>(
+ rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) ));
+ const SvxULSpaceItem& rUL = static_cast<const SvxULSpaceItem&>(
+ rHeaderSet.Get( GetWhich( SID_ATTR_ULSPACE ) ));
+ long nDist = rUL.GetLower();
+ m_aBspWin.SetHdHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetHdDist( nDist );
+ const SvxLRSpaceItem& rLR = static_cast<const SvxLRSpaceItem&>(
+ rHeaderSet.Get( GetWhich( SID_ATTR_LRSPACE ) ));
+ m_aBspWin.SetHdLeft( rLR.GetLeft() );
+ m_aBspWin.SetHdRight( rLR.GetRight() );
+ m_aBspWin.SetHeader( true );
+ }
+ else
+ m_aBspWin.SetHeader( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aHeaderFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rHeaderSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rHeaderSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetHdColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast< const SvxBrushItem& >(rHeaderSet.Get(nWhich));
+ SfxItemSet aTempSet(*rHeaderSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aHeaderFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setHeaderFillAttributes(aHeaderFillAttributes);
+ }
+
+ // evaluate footer attributes
+
+ if ( SfxItemState::SET !=
+ rSet.GetItemState( GetWhich( SID_ATTR_PAGE_FOOTERSET ),
+ false, reinterpret_cast<const SfxPoolItem**>(&pSetItem) ) )
+ return;
+
+ const SfxItemSet& rFooterSet = pSetItem->GetItemSet();
+ const SfxBoolItem& rFooterOn =
+ static_cast<const SfxBoolItem&>(rFooterSet.Get( GetWhich( SID_ATTR_PAGE_ON ) ));
+
+ if ( rFooterOn.GetValue() )
+ {
+ const SvxSizeItem& rSize = static_cast<const SvxSizeItem&>(
+ rFooterSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) ));
+ const SvxULSpaceItem& rUL = static_cast<const SvxULSpaceItem&>(
+ rFooterSet.Get( GetWhich( SID_ATTR_ULSPACE ) ));
+ long nDist = rUL.GetUpper();
+ m_aBspWin.SetFtHeight( rSize.GetSize().Height() - nDist );
+ m_aBspWin.SetFtDist( nDist );
+ const SvxLRSpaceItem& rLR = static_cast<const SvxLRSpaceItem&>(
+ rFooterSet.Get( GetWhich( SID_ATTR_LRSPACE ) ));
+ m_aBspWin.SetFtLeft( rLR.GetLeft() );
+ m_aBspWin.SetFtRight( rLR.GetRight() );
+ m_aBspWin.SetFooter( true );
+ }
+ else
+ m_aBspWin.SetFooter( false );
+
+ // show background and border in the example
+ drawinglayer::attribute::SdrAllFillAttributesHelperPtr aFooterFillAttributes;
+
+ if(mbEnableDrawingLayerFillStyles)
+ {
+ // create FillAttributes directly from DrawingLayer FillStyle entries
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(rFooterSet);
+ }
+ else
+ {
+ const sal_uInt16 nWhich(GetWhich(SID_ATTR_BRUSH));
+
+ if(rFooterSet.GetItemState(nWhich) >= SfxItemState::DEFAULT)
+ {
+ // aBspWin.SetFtColor(rItem.GetColor());
+ const SvxBrushItem& rItem = static_cast<const SvxBrushItem&>(rFooterSet.Get(nWhich));
+ SfxItemSet aTempSet(*rFooterSet.GetPool(), svl::Items<XATTR_FILL_FIRST, XATTR_FILL_LAST>{});
+
+ setSvxBrushItemAsFillAttributesToTargetSet(rItem, aTempSet);
+ aFooterFillAttributes = std::make_shared<drawinglayer::attribute::SdrAllFillAttributesHelper>(aTempSet);
+ }
+ }
+
+ m_aBspWin.setFooterFillAttributes(aFooterFillAttributes);
+}
+
+void SvxPageDescPage::ActivatePage( const SfxItemSet& rSet )
+{
+ InitHeadFoot_Impl( rSet );
+ UpdateExample_Impl();
+ ResetBackground_Impl( rSet );
+ RangeHdl_Impl();
+}
+
+DeactivateRC SvxPageDescPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ // Inquiry whether the page margins are beyond the printing area.
+ // If not, ask user whether they shall be taken.
+ // If not, stay on the TabPage.
+ Paper ePaper = m_xPaperSizeBox->get_active_id();
+
+ if ( ePaper != PAPER_SCREEN_4_3 && ePaper != PAPER_SCREEN_16_9 && ePaper != PAPER_SCREEN_16_10 && IsMarginOutOfRange() )
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_xPrintRangeQueryText->get_label()));
+ xQueryBox->set_default_response(RET_NO);
+ if (xQueryBox->run() == RET_NO)
+ {
+ weld::MetricSpinButton* pField = nullptr;
+ if ( IsPrinterRangeOverflow( *m_xLeftMarginEdit, nFirstLeftMargin, nLastLeftMargin, MARGIN_LEFT ) )
+ pField = m_xLeftMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xRightMarginEdit, nFirstRightMargin, nLastRightMargin, MARGIN_RIGHT )
+ && !pField )
+ pField = m_xRightMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xTopMarginEdit, nFirstTopMargin, nLastTopMargin, MARGIN_TOP )
+ && !pField )
+ pField = m_xTopMarginEdit.get();
+ if ( IsPrinterRangeOverflow( *m_xBottomMarginEdit, nFirstBottomMargin, nLastBottomMargin, MARGIN_BOTTOM )
+ && !pField )
+ pField = m_xBottomMarginEdit.get();
+ if ( pField )
+ pField->grab_focus();
+ UpdateExample_Impl();
+ return DeactivateRC::KeepPage;
+ }
+ else
+ CheckMarginEdits( false );
+ }
+
+ if ( _pSet )
+ {
+ FillItemSet( _pSet );
+
+ // put portray/landscape if applicable
+ sal_uInt16 nWh = GetWhich( SID_ATTR_PAGE_SIZE );
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( nWh );
+ Size aSize( GetCoreValue( *m_xPaperWidthEdit, eUnit ),
+ GetCoreValue( *m_xPaperHeightEdit, eUnit ) );
+
+ // put, if current size is different to the value in _pSet
+ const SvxSizeItem* pSize = GetItem( *_pSet, SID_ATTR_PAGE_SIZE );
+ if ( aSize.Width() && ( !pSize || !IsEqualSize_Impl( pSize, aSize ) ) )
+ _pSet->Put( SvxSizeItem( nWh, aSize ) );
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxPageDescPage::RangeHdl_Impl()
+{
+ // example window
+ long nHHeight = m_aBspWin.GetHdHeight();
+ long nHDist = m_aBspWin.GetHdDist();
+
+ long nFHeight = m_aBspWin.GetFtHeight();
+ long nFDist = m_aBspWin.GetFtDist();
+
+ long nHFLeft = std::max(m_aBspWin.GetHdLeft(), m_aBspWin.GetFtLeft());
+ long nHFRight = std::max(m_aBspWin.GetHdRight(), m_aBspWin.GetFtRight());
+
+ // current values for page margins
+ long nBT = static_cast<long>(m_xTopMarginEdit->denormalize(m_xTopMarginEdit->get_value(FieldUnit::TWIP)));
+ long nBB = static_cast<long>(m_xBottomMarginEdit->denormalize(m_xBottomMarginEdit->get_value(FieldUnit::TWIP)));
+ long nBL = static_cast<long>(m_xLeftMarginEdit->denormalize(m_xLeftMarginEdit->get_value(FieldUnit::TWIP)));
+ long nBR = static_cast<long>(m_xRightMarginEdit->denormalize(m_xRightMarginEdit->get_value(FieldUnit::TWIP)));
+
+ // calculate width of page border
+ const SfxItemSet* _pSet = &GetItemSet();
+ Size aBorder;
+
+ if ( _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_SHADOW) ) >=
+ SfxItemState::DEFAULT &&
+ _pSet->GetItemState( GetWhich(SID_ATTR_BORDER_OUTER) ) >=
+ SfxItemState::DEFAULT )
+ {
+ aBorder = GetMinBorderSpace_Impl(
+ static_cast<const SvxShadowItem&>(_pSet->Get(GetWhich(SID_ATTR_BORDER_SHADOW))),
+ static_cast<const SvxBoxItem&>(_pSet->Get(GetWhich(SID_ATTR_BORDER_OUTER))));
+ }
+
+ // limits paper
+ // maximum is 54 cm
+
+ long nMin = nHHeight + nHDist + nFDist + nFHeight + nBT + nBB +
+ MINBODY + aBorder.Height();
+ m_xPaperHeightEdit->set_min(m_xPaperHeightEdit->normalize(nMin), FieldUnit::TWIP);
+
+ nMin = MINBODY + nBL + nBR + aBorder.Width();
+ m_xPaperWidthEdit->set_min(m_xPaperWidthEdit->normalize(nMin), FieldUnit::TWIP);
+
+ long nH = static_cast<long>(m_xPaperHeightEdit->denormalize(m_xPaperHeightEdit->get_value(FieldUnit::TWIP)));
+ long nW = static_cast<long>(m_xPaperWidthEdit->denormalize(m_xPaperWidthEdit->get_value(FieldUnit::TWIP)));
+
+ // Top
+ long nMax = nH - nBB - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xTopMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Bottom
+ nMax = nH - nBT - aBorder.Height() - MINBODY -
+ nFDist - nFHeight - nHDist - nHHeight;
+
+ m_xBottomMarginEdit->set_max(m_xTopMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Left
+ nMax = nW - nBR - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xLeftMarginEdit->set_max(m_xLeftMarginEdit->normalize(nMax), FieldUnit::TWIP);
+
+ // Right
+ nMax = nW - nBL - MINBODY - aBorder.Width() - nHFLeft - nHFRight;
+ m_xRightMarginEdit->set_max(m_xRightMarginEdit->normalize(nMax), FieldUnit::TWIP);
+}
+
+void SvxPageDescPage::CalcMargin_Impl()
+{
+ // current values for page margins
+ long nBT = GetCoreValue( *m_xTopMarginEdit, MapUnit::MapTwip );
+ long nBB = GetCoreValue( *m_xBottomMarginEdit, MapUnit::MapTwip );
+
+ long nBL = GetCoreValue( *m_xLeftMarginEdit, MapUnit::MapTwip );
+ long nBR = GetCoreValue( *m_xRightMarginEdit, MapUnit::MapTwip );
+
+ long nH = GetCoreValue( *m_xPaperHeightEdit, MapUnit::MapTwip );
+ long nW = GetCoreValue( *m_xPaperWidthEdit, MapUnit::MapTwip );
+
+ long nWidth = nBL + nBR + MINBODY;
+ long nHeight = nBT + nBB + MINBODY;
+
+ if ( !(nWidth > nW || nHeight > nH) )
+ return;
+
+ if ( nWidth > nW )
+ {
+ long nTmp = nBL <= nBR ? nBR : nBL;
+ nTmp -= nWidth - nW;
+
+ if ( nBL <= nBR )
+ SetMetricValue( *m_xRightMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xLeftMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+
+ if ( nHeight > nH )
+ {
+ long nTmp = nBT <= nBB ? nBB : nBT;
+ nTmp -= nHeight - nH;
+
+ if ( nBT <= nBB )
+ SetMetricValue( *m_xBottomMarginEdit, nTmp, MapUnit::MapTwip );
+ else
+ SetMetricValue( *m_xTopMarginEdit, nTmp, MapUnit::MapTwip );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, CenterHdl_Impl, weld::ToggleButton&, void)
+{
+ m_aBspWin.SetHorz(m_xHorzBox->get_active());
+ m_aBspWin.SetVert(m_xVertBox->get_active());
+ UpdateExample_Impl();
+}
+
+void SvxPageDescPage::SetCollectionList(const std::vector<OUString> &aList)
+{
+ OSL_ENSURE(!aList.empty(), "Empty string list");
+
+ sStandardRegister = aList[0];
+ m_xRegisterLB->freeze();
+ for (size_t i = 1; i < aList.size(); ++i)
+ m_xRegisterLB->append_text(aList[i]);
+ m_xRegisterLB->thaw();
+
+ m_xRegisterCB->show();
+ m_xRegisterFT->show();
+ m_xRegisterLB->show();
+ m_xRegisterCB->connect_toggled(LINK(this, SvxPageDescPage, RegisterModify));
+}
+
+IMPL_LINK(SvxPageDescPage, RegisterModify, weld::ToggleButton&, rBox, void)
+{
+ bool bEnable = false;
+ if (rBox.get_active())
+ {
+ bEnable = true;
+ if (m_xRegisterLB->get_active() == -1)
+ m_xRegisterLB->set_active_text(sStandardRegister);
+ }
+ m_xRegisterFT->set_sensitive(bEnable);
+ m_xRegisterLB->set_sensitive(bEnable);
+}
+
+void SvxPageDescPage::DisableVerticalPageDir()
+{
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_RL_TB);
+ m_xTextFlowBox->remove_id(SvxFrameDirection::Vertical_LR_TB);
+ if (m_xTextFlowBox->get_count() < 2)
+ {
+ m_xTextFlowLbl->hide();
+ m_xTextFlowBox->hide();
+ m_aBspWin.EnableFrameDirection( false );
+ }
+}
+
+IMPL_LINK_NOARG(SvxPageDescPage, FrameDirectionModify_Impl, weld::ComboBox&, void)
+{
+ m_aBspWin.SetFrameDirection(m_xTextFlowBox->get_active_id());
+ m_aBspWin.Invalidate();
+}
+
+bool SvxPageDescPage::IsPrinterRangeOverflow(
+ weld::MetricSpinButton& rField, long nFirstMargin, long nLastMargin, MarginPosition nPos )
+{
+ bool bRet = false;
+ bool bCheck = ( ( m_nPos & nPos ) == 0 );
+ long nValue = rField.get_value(FieldUnit::NONE);
+ if ( bCheck &&
+ ( nValue < nFirstMargin || nValue > nLastMargin ) &&
+ rField.get_value_changed_from_saved() )
+ {
+ rField.set_value(nValue < nFirstMargin ? nFirstMargin : nLastMargin, FieldUnit::NONE);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+/** Check if a value of a margin edit is outside the printer paper margins
+ and save this information.
+*/
+void SvxPageDescPage::CheckMarginEdits( bool _bClear )
+{
+ if ( _bClear )
+ m_nPos = 0;
+
+ sal_Int64 nValue = m_xLeftMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstLeftMargin || nValue > nLastLeftMargin )
+ m_nPos |= MARGIN_LEFT;
+ nValue = m_xRightMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstRightMargin || nValue > nLastRightMargin )
+ m_nPos |= MARGIN_RIGHT;
+ nValue = m_xTopMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstTopMargin || nValue > nLastTopMargin )
+ m_nPos |= MARGIN_TOP;
+ nValue = m_xBottomMarginEdit->get_value(FieldUnit::NONE);
+ if ( nValue < nFirstBottomMargin || nValue > nLastBottomMargin )
+ m_nPos |= MARGIN_BOTTOM;
+}
+
+bool SvxPageDescPage::IsMarginOutOfRange() const
+{
+ bool bRet = ( ( ( !( m_nPos & MARGIN_LEFT ) &&
+ m_xLeftMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xLeftMarginEdit->get_value(FieldUnit::NONE) < nFirstLeftMargin ||
+ m_xLeftMarginEdit->get_value(FieldUnit::NONE) > nLastLeftMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_RIGHT ) &&
+ m_xRightMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xRightMarginEdit->get_value(FieldUnit::NONE) < nFirstRightMargin ||
+ m_xRightMarginEdit->get_value(FieldUnit::NONE) > nLastRightMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_TOP ) &&
+ m_xTopMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xTopMarginEdit->get_value(FieldUnit::NONE) < nFirstTopMargin ||
+ m_xTopMarginEdit->get_value(FieldUnit::NONE) > nLastTopMargin ) ) ||
+ ( ( !( m_nPos & MARGIN_BOTTOM ) &&
+ m_xBottomMarginEdit->get_value_changed_from_saved() ) &&
+ ( m_xBottomMarginEdit->get_value(FieldUnit::NONE) < nFirstBottomMargin ||
+ m_xBottomMarginEdit->get_value(FieldUnit::NONE) > nLastBottomMargin ) ) );
+ return bRet;
+}
+
+void SvxPageDescPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pModeItem = aSet.GetItem(SID_ENUM_PAGE_MODE, false);
+ const SfxUInt16Item* pPaperStartItem = aSet.GetItem(SID_PAPER_START, false);
+ const SfxUInt16Item* pPaperEndItem = aSet.GetItem(SID_PAPER_END, false);
+ const SfxStringListItem* pCollectListItem = aSet.GetItem<SfxStringListItem>(SID_COLLECT_LIST, false);
+ const SfxBoolItem* pSupportDrawingLayerFillStyleItem = aSet.GetItem<SfxBoolItem>(SID_DRAWINGLAYER_FILLSTYLES, false);
+ const SfxBoolItem* pIsImpressDoc = aSet.GetItem<SfxBoolItem>(SID_IMPRESS_DOC, false);
+
+ if (pModeItem)
+ {
+ eMode = static_cast<SvxModeType>(pModeItem->GetValue());
+ }
+
+ if(pPaperStartItem && pPaperEndItem)
+ {
+ SetPaperFormatRanges(static_cast<Paper>(pPaperStartItem->GetValue()));
+ }
+
+ if(pCollectListItem)
+ {
+ SetCollectionList(pCollectListItem->GetList());
+ }
+
+ if(pSupportDrawingLayerFillStyleItem)
+ {
+ const bool bNew(pSupportDrawingLayerFillStyleItem->GetValue());
+
+ mbEnableDrawingLayerFillStyles = bNew;
+ }
+
+ if (pIsImpressDoc)
+ m_xNumberFormatText->set_label(SvxResId(STR_SLIDE_NUMBERS));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/paragrph.cxx b/cui/source/tabpages/paragrph.cxx
new file mode 100644
index 000000000..5f6ae38d3
--- /dev/null
+++ b/cui/source/tabpages/paragrph.cxx
@@ -0,0 +1,2311 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <osl/diagnose.h>
+#include <svl/style.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/mnemonic.hxx>
+#include <vcl/settings.hxx>
+#include <svx/flagsdef.hxx>
+#include <svx/svxids.hrc>
+
+#include <svl/languageoptions.hxx>
+#include <svl/cjkoptions.hxx>
+#include <editeng/pgrditem.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <paragrph.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <editeng/lspcitem.hxx>
+#include <editeng/adjustitem.hxx>
+#include <editeng/orphitem.hxx>
+#include <editeng/widwitem.hxx>
+#include <editeng/tstpitem.hxx>
+#include <editeng/pmdlitem.hxx>
+#include <editeng/spltitem.hxx>
+#include <editeng/hyphenzoneitem.hxx>
+#include <editeng/ulspitem.hxx>
+#include <editeng/lrspitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/keepitem.hxx>
+#include <svx/dlgutil.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <editeng/paravertalignitem.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+
+#include <sfx2/viewfrm.hxx>
+
+const sal_uInt16 SvxStdParagraphTabPage::pStdRanges[] =
+{
+ SID_ATTR_PARA_LINESPACE, // 10033
+ SID_ATTR_PARA_LINESPACE,
+ SID_ATTR_LRSPACE, // 10048 -
+ SID_ATTR_ULSPACE, // 10049
+ SID_ATTR_PARA_REGISTER, // 10413
+ SID_ATTR_PARA_REGISTER,
+ 0
+};
+
+const sal_uInt16 SvxParaAlignTabPage::pAlignRanges[] =
+{
+ SID_ATTR_PARA_ADJUST, // 10027
+ SID_ATTR_PARA_ADJUST,
+ 0
+};
+
+const sal_uInt16 SvxExtParagraphTabPage::pExtRanges[] =
+{
+ SID_ATTR_PARA_PAGEBREAK, // 10037 -
+ SID_ATTR_PARA_WIDOWS, // 10041
+ SID_ATTR_PARA_MODEL, // 10065 -
+ SID_ATTR_PARA_KEEP, // 10066
+ 0
+};
+
+#define MAX_DURCH 5670 // 10 cm makes sense as maximum interline lead
+ // according to BP
+#define FIX_DIST_DEF 283 // standard fix distance 0,5 cm
+
+namespace {
+
+enum LineSpaceList
+{
+ LLINESPACE_1 = 0,
+ LLINESPACE_115 = 1,
+ LLINESPACE_15 = 2,
+ LLINESPACE_2 = 3,
+ LLINESPACE_PROP = 4,
+ LLINESPACE_MIN = 5,
+ LLINESPACE_DURCH= 6,
+ LLINESPACE_FIX = 7
+};
+
+}
+
+static void SetLineSpace_Impl( SvxLineSpacingItem&, int, long lValue = 0 );
+
+void SetLineSpace_Impl( SvxLineSpacingItem& rLineSpace,
+ int eSpace, long lValue )
+{
+ switch ( eSpace )
+ {
+ case LLINESPACE_1:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+
+ case LLINESPACE_115:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 115 );
+ break;
+
+ case LLINESPACE_15:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 150 );
+ break;
+
+ case LLINESPACE_2:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( 200 );
+ break;
+
+ case LLINESPACE_PROP:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetPropLineSpace( static_cast<sal_uInt16>(lValue) );
+ break;
+
+ case LLINESPACE_MIN:
+ rLineSpace.SetLineHeight( static_cast<sal_uInt16>(lValue) );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+
+ case LLINESPACE_DURCH:
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Auto );
+ rLineSpace.SetInterLineSpace( static_cast<sal_uInt16>(lValue) );
+ break;
+
+ case LLINESPACE_FIX:
+ rLineSpace.SetLineHeight(static_cast<sal_uInt16>(lValue));
+ rLineSpace.SetLineSpaceRule( SvxLineSpaceRule::Fix );
+ rLineSpace.SetInterLineSpaceRule( SvxInterLineSpaceRule::Off );
+ break;
+ }
+}
+
+static sal_uInt16 GetHtmlMode_Impl(const SfxItemSet& rSet)
+{
+ sal_uInt16 nHtmlMode = 0;
+ const SfxPoolItem* pItem = nullptr;
+ SfxObjectShell* pShell;
+ if(SfxItemState::SET == rSet.GetItemState(SID_HTML_MODE, false, &pItem) ||
+ ( nullptr != (pShell = SfxObjectShell::Current()) &&
+ nullptr != (pItem = pShell->GetItem(SID_HTML_MODE))))
+ {
+ nHtmlMode = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+ }
+ return nHtmlMode;
+
+}
+
+void SvxStdParagraphTabPage::ELRLoseFocus()
+{
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit =
+ MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ sal_Int64 nL = m_xLeftIndent->denormalize(m_xLeftIndent->get_value(eUnit));
+ sal_Int64 nR = m_xRightIndent->denormalize(m_xRightIndent->get_value(eUnit));
+ OUString aTmp = m_xFLineIndent->get_text();
+
+ if (m_xLeftIndent->get_min(FieldUnit::NONE) < 0)
+ m_xFLineIndent->set_min(-99999, FieldUnit::MM);
+ else
+ m_xFLineIndent->set_min(m_xFLineIndent->normalize(-nL), eUnit);
+
+ // Check only for concrete width (Shell)
+ sal_Int64 nTmp = nWidth - nL - nR - MM50;
+ m_xFLineIndent->set_max(m_xFLineIndent->normalize(nTmp), eUnit);
+
+ if (aTmp.isEmpty())
+ m_xFLineIndent->set_text(OUString());
+ // maximum left right
+ aTmp = m_xLeftIndent->get_text();
+ nTmp = nWidth - nR - MM50;
+ m_xLeftIndent->set_max(m_xLeftIndent->normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_xLeftIndent->set_text(OUString());
+ aTmp = m_xRightIndent->get_text();
+ nTmp = nWidth - nL - MM50;
+ m_xRightIndent->set_max(m_xRightIndent->normalize(nTmp), eUnit);
+
+ if ( aTmp.isEmpty() )
+ m_xRightIndent->set_text(OUString());
+
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ELRLoseFocusHdl, weld::MetricSpinButton&, void)
+{
+ ELRLoseFocus();
+}
+
+std::unique_ptr<SfxTabPage> SvxStdParagraphTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxStdParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxStdParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ SfxItemState eState = SfxItemState::UNKNOWN;
+ const SfxPoolItem* pOld = nullptr;
+ SfxItemPool* pPool = rOutSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ bool bModified = false;
+ sal_uInt16 nWhich;
+ int nPos = m_xLineDist->get_active();
+
+ if ( nPos != -1 &&
+ ( m_bLineDistToggled ||
+ m_xLineDist->get_value_changed_from_saved() ||
+ m_xLineDistAtPercentBox->get_value_changed_from_saved() ||
+ m_xLineDistAtMetricBox->get_value_changed_from_saved() ) )
+ {
+ nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ MapUnit eUnit = SfxViewFrame::Current()->GetPool().GetMetric( nWhich );
+ SvxLineSpacingItem aSpacing(
+ static_cast<const SvxLineSpacingItem&>(GetItemSet().Get( nWhich )) );
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ SetLineSpace_Impl( aSpacing, nPos );
+ break;
+
+ case LLINESPACE_PROP:
+ SetLineSpace_Impl( aSpacing, nPos,
+ static_cast<long>(m_xLineDistAtPercentBox->denormalize(
+ m_xLineDistAtPercentBox->get_value(FieldUnit::NONE) )) );
+ break;
+
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ SetLineSpace_Impl( aSpacing, nPos,
+ GetCoreValue( *m_xLineDistAtMetricBox, eUnit ) );
+ break;
+
+ default:
+ OSL_FAIL( "unknown LineDist entry" );
+ break;
+ }
+ eState = GetItemSet().GetItemState( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_LINESPACE );
+
+ if ( m_bLineDistToggled ||
+ !pOld || !( *static_cast<const SvxLineSpacingItem*>(pOld) == aSpacing ) ||
+ SfxItemState::DONTCARE == eState )
+ {
+ rOutSet->Put( aSpacing );
+ bModified = true;
+ }
+ }
+
+ if ( m_xTopDist->get_value_changed_from_saved() || m_xBottomDist->get_value_changed_from_saved()
+ || m_xContextualCB->get_state_changed_from_saved())
+ {
+ nWhich = GetWhich( SID_ATTR_ULSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_ULSPACE );
+ SvxULSpaceItem aMargin( nWhich );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if ( m_xTopDist->IsRelative() )
+ aMargin.SetUpper( rOldItem.GetUpper(),
+ static_cast<sal_uInt16>(m_xTopDist->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetUpper( static_cast<sal_uInt16>(m_xTopDist->GetCoreValue(eUnit)) );
+
+ if ( m_xBottomDist->IsRelative() )
+ aMargin.SetLower( rOldItem.GetLower(),
+ static_cast<sal_uInt16>(m_xBottomDist->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetLower( static_cast<sal_uInt16>(m_xBottomDist->GetCoreValue(eUnit)) );
+
+ }
+ else
+ {
+ aMargin.SetUpper(static_cast<sal_uInt16>(m_xTopDist->GetCoreValue(eUnit)));
+ aMargin.SetLower(static_cast<sal_uInt16>(m_xBottomDist->GetCoreValue(eUnit)));
+ }
+ aMargin.SetContextValue(m_xContextualCB->get_active());
+ eState = GetItemSet().GetItemState( nWhich );
+
+ if ( !pOld || *static_cast<const SvxULSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == eState )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+ bool bNullTab = false;
+
+ if ( m_xLeftIndent->get_value_changed_from_saved() ||
+ m_xFLineIndent->get_value_changed_from_saved() ||
+ m_xRightIndent->get_value_changed_from_saved() ||
+ m_xAutoCB->get_state_changed_from_saved() )
+ {
+ nWhich = GetWhich( SID_ATTR_LRSPACE );
+ MapUnit eUnit = pPool->GetMetric( nWhich );
+ SvxLRSpaceItem aMargin( nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_LRSPACE );
+
+ if ( bRelativeMode )
+ {
+ DBG_ASSERT( GetItemSet().GetParent(), "No ParentSet" );
+
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(GetItemSet().GetParent()->Get( nWhich ));
+
+ if (m_xLeftIndent->IsRelative())
+ aMargin.SetTextLeft( rOldItem.GetTextLeft(),
+ static_cast<sal_uInt16>(m_xLeftIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextLeft(m_xLeftIndent->GetCoreValue(eUnit));
+
+ if ( m_xRightIndent->IsRelative() )
+ aMargin.SetRight( rOldItem.GetRight(),
+ static_cast<sal_uInt16>(m_xRightIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetRight(m_xRightIndent->GetCoreValue(eUnit));
+
+ if ( m_xFLineIndent->IsRelative() )
+ aMargin.SetTextFirstLineOffset( rOldItem.GetTextFirstLineOffset(),
+ static_cast<sal_uInt16>(m_xFLineIndent->get_value(FieldUnit::NONE)) );
+ else
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_xFLineIndent->GetCoreValue(eUnit)));
+ }
+ else
+ {
+ aMargin.SetTextLeft(m_xLeftIndent->GetCoreValue(eUnit));
+ aMargin.SetRight(m_xRightIndent->GetCoreValue(eUnit));
+ aMargin.SetTextFirstLineOffset(static_cast<sal_uInt16>(m_xFLineIndent->GetCoreValue(eUnit)));
+ }
+ aMargin.SetAutoFirst(m_xAutoCB->get_active());
+ if ( aMargin.GetTextFirstLineOffset() < 0 )
+ bNullTab = true;
+ eState = GetItemSet().GetItemState( nWhich );
+
+ if ( !pOld || *static_cast<const SvxLRSpaceItem*>(pOld) != aMargin ||
+ SfxItemState::DONTCARE == eState )
+ {
+ rOutSet->Put( aMargin );
+ bModified = true;
+ }
+ }
+
+ if ( bNullTab )
+ {
+ MapUnit eUnit = pPool->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ if ( MapUnit::Map100thMM != eUnit )
+ {
+
+ // negative first line indent -> set null default tabstob if applicable
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_TABSTOP );
+ const SfxItemSet& rInSet = GetItemSet();
+
+ if ( rInSet.GetItemState( _nWhich ) >= SfxItemState::DEFAULT )
+ {
+ const SvxTabStopItem& rTabItem =
+ static_cast<const SvxTabStopItem&>(rInSet.Get( _nWhich ));
+ SvxTabStopItem aNullTab( rTabItem );
+ SvxTabStop aNull( 0, SvxTabAdjust::Default );
+ aNullTab.Insert( aNull );
+ rOutSet->Put( aNullTab );
+ }
+ }
+ }
+ if (m_xRegisterCB->get_visible())
+ {
+ const SfxBoolItem* pBoolItem = static_cast<const SfxBoolItem*>(GetOldItem(
+ *rOutSet, SID_ATTR_PARA_REGISTER));
+ if (!pBoolItem)
+ return bModified;
+ std::unique_ptr<SfxBoolItem> pRegItem(pBoolItem->Clone());
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ bool bSet = pRegItem->GetValue();
+
+ if (m_xRegisterCB->get_active() != bSet)
+ {
+ pRegItem->SetValue(!bSet);
+ rOutSet->Put(*pRegItem);
+ bModified = true;
+ }
+ else if ( SfxItemState::DEFAULT == GetItemSet().GetItemState( _nWhich, false ) )
+ rOutSet->ClearItem(_nWhich);
+ }
+
+ return bModified;
+}
+
+void SvxStdParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( *rSet );
+
+ bool bApplyCharUnit = GetApplyCharUnit( *rSet );
+
+ SvtCJKOptions aCJKOptions;
+ if(aCJKOptions.IsAsianTypographyEnabled() && bApplyCharUnit )
+ eFUnit = FieldUnit::CHAR;
+
+ m_xLeftIndent->SetFieldUnit(eFUnit);
+ m_xRightIndent->SetFieldUnit(eFUnit);
+ m_xFLineIndent->SetFieldUnit(eFUnit);
+ if ( eFUnit == FieldUnit::CHAR )
+ {
+ m_xTopDist->SetFieldUnit(FieldUnit::LINE);
+ m_xBottomDist->SetFieldUnit(FieldUnit::LINE);
+ SetFieldUnit(*m_xLineDistAtMetricBox, FieldUnit::POINT);
+ }
+ else
+ {
+ m_xTopDist->SetFieldUnit(eFUnit);
+ m_xBottomDist->SetFieldUnit(eFUnit);
+ SetFieldUnit(*m_xLineDistAtMetricBox, eFUnit);
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_LRSPACE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ if ( bRelativeMode )
+ {
+ const SvxLRSpaceItem& rOldItem =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ if ( rOldItem.GetPropLeft() != 100 )
+ {
+ m_xLeftIndent->SetRelative( true );
+ m_xLeftIndent->set_value(rOldItem.GetPropLeft(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xLeftIndent->SetRelative(false);
+ m_xLeftIndent->SetFieldUnit(eFUnit);
+ m_xLeftIndent->SetMetricValue(rOldItem.GetTextLeft(), eUnit);
+ }
+
+ if ( rOldItem.GetPropRight() != 100 )
+ {
+ m_xRightIndent->SetRelative( true );
+ m_xRightIndent->set_value(rOldItem.GetPropRight(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xRightIndent->SetRelative(false);
+ m_xRightIndent->SetFieldUnit(eFUnit);
+ m_xRightIndent->SetMetricValue(rOldItem.GetRight(), eUnit);
+ }
+
+ if ( rOldItem.GetPropTextFirstLineOffset() != 100 )
+ {
+ m_xFLineIndent->SetRelative(true);
+ m_xFLineIndent->set_value(rOldItem.GetPropTextFirstLineOffset(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xFLineIndent->SetRelative(false);
+ m_xFLineIndent->set_min(-9999, FieldUnit::NONE);
+ m_xFLineIndent->SetFieldUnit(eFUnit);
+ m_xFLineIndent->SetMetricValue(rOldItem.GetTextFirstLineOffset(), eUnit);
+ }
+ m_xAutoCB->set_active(rOldItem.IsAutoFirst());
+ }
+ else
+ {
+ const SvxLRSpaceItem& rSpace =
+ static_cast<const SvxLRSpaceItem&>(rSet->Get( _nWhich ));
+
+ m_xLeftIndent->SetMetricValue(rSpace.GetTextLeft(), eUnit);
+ m_xRightIndent->SetMetricValue(rSpace.GetRight(), eUnit);
+ m_xFLineIndent->SetMetricValue(rSpace.GetTextFirstLineOffset(), eUnit);
+ m_xAutoCB->set_active(rSpace.IsAutoFirst());
+ }
+ AutoHdl_Impl(*m_xAutoCB);
+ }
+ else
+ {
+ m_xLeftIndent->set_text(OUString());
+ m_xRightIndent->set_text(OUString());
+ m_xFLineIndent->set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_ULSPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ MapUnit eUnit = pPool->GetMetric( _nWhich );
+
+ const SvxULSpaceItem& rOldItem =
+ static_cast<const SvxULSpaceItem&>(rSet->Get( _nWhich ));
+ if ( bRelativeMode )
+ {
+
+ if ( rOldItem.GetPropUpper() != 100 )
+ {
+ m_xTopDist->SetRelative( true );
+ m_xTopDist->set_value(rOldItem.GetPropUpper(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xTopDist->SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_xTopDist->SetFieldUnit(FieldUnit::LINE);
+ else
+ m_xTopDist->SetFieldUnit(eFUnit);
+ m_xTopDist->SetMetricValue(rOldItem.GetUpper(), eUnit);
+ }
+
+ if ( rOldItem.GetPropLower() != 100 )
+ {
+ m_xBottomDist->SetRelative( true );
+ m_xBottomDist->set_value(rOldItem.GetPropLower(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xBottomDist->SetRelative(false);
+ if (eFUnit == FieldUnit::CHAR)
+ m_xBottomDist->SetFieldUnit(FieldUnit::LINE);
+ else
+ m_xBottomDist->SetFieldUnit(eFUnit);
+ m_xBottomDist->SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ }
+ else
+ {
+ m_xTopDist->SetMetricValue(rOldItem.GetUpper(), eUnit);
+ m_xBottomDist->SetMetricValue(rOldItem.GetLower(), eUnit);
+ }
+ m_xContextualCB->set_active(rOldItem.GetContext());
+ }
+ else
+ {
+ m_xTopDist->set_text(OUString());
+ m_xBottomDist->set_text(OUString());
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_LINESPACE );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ SetLineSpacing_Impl( static_cast<const SvxLineSpacingItem &>(rSet->Get( _nWhich )) );
+ else
+ m_xLineDist->set_active(-1);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_REGISTER );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ m_xRegisterCB->set_active( static_cast<const SfxBoolItem &>(rSet->Get( _nWhich )).GetValue());
+ m_xRegisterCB->save_state();
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xRegisterFL->hide();
+ m_xRegisterCB->hide();
+ m_xAutoCB->hide();
+ }
+
+ // this sets the min/max limits; do this _after_ setting the values,
+ // because for Impress the min of first-line indent depends on value of
+ // left-indent!
+ ELRLoseFocus();
+ ChangesApplied();
+}
+
+void SvxStdParagraphTabPage::ChangesApplied()
+{
+ m_xLeftIndent->save_value();
+ m_xRightIndent->save_value();
+ m_xFLineIndent->save_value();
+ m_xLineDist->save_value();
+ m_xLineDistAtPercentBox->save_value();
+ m_xLineDistAtMetricBox->save_value();
+ m_xRegisterCB->save_state();
+ m_xTopDist->save_value();
+ m_xBottomDist->save_value();
+ m_xContextualCB->save_state();
+ m_xAutoCB->save_state();
+}
+
+void SvxStdParagraphTabPage::EnableRelativeMode()
+{
+ DBG_ASSERT( GetItemSet().GetParent(), "RelativeMode, but no parent-set!" );
+
+ m_xLeftIndent->EnableRelativeMode( 0, 999 );
+ m_xFLineIndent->EnableRelativeMode( 0, 999 );
+ m_xRightIndent->EnableRelativeMode( 0, 999 );
+ m_xTopDist->EnableRelativeMode( 0, 999 );
+ m_xBottomDist->EnableRelativeMode( 0, 999 );
+ bRelativeMode = true;
+}
+
+void SvxStdParagraphTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState < SfxItemState::DEFAULT )
+ return;
+
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>( rSet.Get( _nWhich ) );
+ SvxAdjust eAdjust = rAdj.GetAdjust();
+ if ( eAdjust == SvxAdjust::Center || eAdjust == SvxAdjust::Block )
+ {
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ eItemState = rSet.GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet.Get( _nWhich ) );
+ SvxFrameDirection eFrameDirection = rFrameDirItem.GetValue();
+
+ m_aExampleWin.EnableRTL( SvxFrameDirection::Horizontal_RL_TB == eFrameDirection );
+
+ if ( eAdjust == SvxAdjust::Block )
+ m_aExampleWin.SetLastLine( rAdj.GetLastBlock() );
+ }
+ }
+ else
+ {
+ m_aExampleWin.EnableRTL( eAdjust == SvxAdjust::Right );
+ eAdjust = SvxAdjust::Left; //required for correct preview display
+ m_aExampleWin.SetLastLine( eAdjust );
+ }
+ m_aExampleWin.SetAdjust( eAdjust );
+
+ UpdateExample_Impl();
+}
+
+DeactivateRC SvxStdParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ ELRLoseFocus();
+
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+SvxStdParagraphTabPage::SvxStdParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paraindentspacing.ui", "ParaIndentSpacing", &rAttr)
+ , nWidth(11905 /*567 * 50*/)
+ , nMinFixDist(0)
+ , bRelativeMode(false)
+ , m_xLeftIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_LEFTINDENT", FieldUnit::CM)))
+ , m_xRightLabel(m_xBuilder->weld_label("labelFT_RIGHTINDENT"))
+ , m_xRightIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_RIGHTINDENT", FieldUnit::CM)))
+ , m_xFLineLabel(m_xBuilder->weld_label("labelFT_FLINEINDENT"))
+ , m_xFLineIndent(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_FLINEINDENT", FieldUnit::CM)))
+ , m_xAutoCB(m_xBuilder->weld_check_button("checkCB_AUTO"))
+ , m_xTopDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_TOPDIST", FieldUnit::CM)))
+ , m_xBottomDist(new SvxRelativeField(m_xBuilder->weld_metric_spin_button("spinED_BOTTOMDIST", FieldUnit::CM)))
+ , m_xContextualCB(m_xBuilder->weld_check_button("checkCB_CONTEXTUALSPACING"))
+ , m_xLineDist(m_xBuilder->weld_combo_box("comboLB_LINEDIST"))
+ , m_xLineDistAtPercentBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTPERCENT", FieldUnit::PERCENT))
+ , m_xLineDistAtMetricBox(m_xBuilder->weld_metric_spin_button("spinED_LINEDISTMETRIC", FieldUnit::CM))
+ , m_xLineDistAtLabel(m_xBuilder->weld_label("labelFT_LINEDIST"))
+ , m_xAbsDist(m_xBuilder->weld_label("labelST_LINEDIST_ABS"))
+ , m_xRegisterFL(m_xBuilder->weld_widget("frameFL_REGISTER"))
+ , m_xRegisterCB(m_xBuilder->weld_check_button("checkCB_REGISTER"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+{
+ sAbsDist = m_xAbsDist->get_label();
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xLineDistAtMetricBox->hide();
+
+ Init_Impl();
+ m_xFLineIndent->set_min(-9999, FieldUnit::NONE); // is set to 0 on default
+}
+
+SvxStdParagraphTabPage::~SvxStdParagraphTabPage()
+{
+}
+
+void SvxStdParagraphTabPage::EnableNegativeMode()
+{
+ m_xLeftIndent->set_min(-9999, FieldUnit::NONE);
+ m_xRightIndent->set_min(-9999, FieldUnit::NONE);
+ m_xRightIndent->EnableNegativeMode();
+ m_xLeftIndent->EnableNegativeMode();
+}
+
+void SvxStdParagraphTabPage::SetLineSpacing_Impl
+(
+ const SvxLineSpacingItem &rAttr
+)
+{
+ MapUnit eUnit = SfxViewFrame::Current()->GetPool().GetMetric( rAttr.Which() );
+
+ switch( rAttr.GetLineSpaceRule() )
+ {
+ case SvxLineSpaceRule::Auto:
+ {
+ SvxInterLineSpaceRule eInter = rAttr.GetInterLineSpaceRule();
+
+ switch( eInter )
+ {
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Off:
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+
+ // Default single line spacing
+ case SvxInterLineSpaceRule::Prop:
+ if ( 100 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_1 );
+ break;
+ }
+ // 1.15 line spacing
+ if ( 115 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_115 );
+ break;
+ }
+ // 1.5 line spacing
+ if ( 150 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_15 );
+ break;
+ }
+ // double line spacing
+ if ( 200 == rAttr.GetPropLineSpace() )
+ {
+ m_xLineDist->set_active( LLINESPACE_2 );
+ break;
+ }
+ // the set per cent value
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(rAttr.GetPropLineSpace()), FieldUnit::NONE);
+ m_xLineDist->set_active( LLINESPACE_PROP );
+ break;
+
+ case SvxInterLineSpaceRule::Fix:
+ SetMetricValue( *m_xLineDistAtMetricBox, rAttr.GetInterLineSpace(), eUnit );
+ m_xLineDist->set_active( LLINESPACE_DURCH );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ break;
+ case SvxLineSpaceRule::Fix:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_FIX );
+ break;
+
+ case SvxLineSpaceRule::Min:
+ SetMetricValue(*m_xLineDistAtMetricBox, rAttr.GetLineHeight(), eUnit);
+ m_xLineDist->set_active( LLINESPACE_MIN );
+ break;
+ default: ;//prevent warning
+ }
+ LineDistHdl_Impl( *m_xLineDist );
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, LineDistPopupHdl_Impl, weld::ComboBox&, void)
+{
+ m_bLineDistToggled = true;
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, LineDistHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ switch (rBox.get_active())
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ m_xLineDistAtLabel->set_sensitive(false);
+ m_xLineDistAtPercentBox->set_sensitive(false);
+ m_xLineDistAtPercentBox->set_text(OUString());
+ m_xLineDistAtMetricBox->set_sensitive(false);
+ m_xLineDistAtMetricBox->set_text(OUString());
+ break;
+
+ case LLINESPACE_DURCH:
+ // setting a sensible default?
+ // limit MS min(10, aPageSize)
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtMetricBox->get_text().isEmpty())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(1), FieldUnit::NONE);
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_MIN:
+ m_xLineDistAtMetricBox->set_min(0, FieldUnit::NONE);
+
+ if (m_xLineDistAtMetricBox->get_text().isEmpty())
+ m_xLineDistAtMetricBox->set_value(m_xLineDistAtMetricBox->normalize(10), FieldUnit::TWIP);
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+
+ case LLINESPACE_PROP:
+
+ if (m_xLineDistAtPercentBox->get_text().isEmpty())
+ m_xLineDistAtPercentBox->set_value(m_xLineDistAtPercentBox->normalize(100), FieldUnit::TWIP);
+ m_xLineDistAtMetricBox->hide();
+ m_xLineDistAtPercentBox->show();
+ m_xLineDistAtPercentBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ break;
+ case LLINESPACE_FIX:
+ {
+ auto nTemp = m_xLineDistAtMetricBox->get_value(FieldUnit::NONE);
+ m_xLineDistAtMetricBox->set_min(m_xLineDistAtMetricBox->normalize(nMinFixDist), FieldUnit::TWIP);
+
+ // if the value has been changed at SetMin,
+ // it is time for the default
+ if (m_xLineDistAtMetricBox->get_value(FieldUnit::NONE) != nTemp)
+ SetMetricValue( *m_xLineDistAtMetricBox, FIX_DIST_DEF, MapUnit::MapTwip ); // fix is only in Writer
+ m_xLineDistAtPercentBox->hide();
+ m_xLineDistAtMetricBox->show();
+ m_xLineDistAtMetricBox->set_sensitive(true);
+ m_xLineDistAtLabel->set_sensitive(true);
+ }
+ break;
+ }
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxStdParagraphTabPage, ModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxStdParagraphTabPage::Init_Impl()
+{
+ m_xLineDist->connect_popup_toggled(LINK(this, SvxStdParagraphTabPage, LineDistPopupHdl_Impl));
+ m_xLineDist->connect_changed(LINK(this, SvxStdParagraphTabPage, LineDistHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK(this, SvxStdParagraphTabPage, ELRLoseFocusHdl);
+ m_xFLineIndent->connect_value_changed(aLink2);
+ m_xLeftIndent->connect_value_changed(aLink2);
+ m_xRightIndent->connect_value_changed(aLink2);
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK(this, SvxStdParagraphTabPage, ModifyHdl_Impl);
+ m_xTopDist->connect_value_changed(aLink);
+ m_xBottomDist->connect_value_changed(aLink);
+
+ m_xAutoCB->connect_toggled(LINK(this, SvxStdParagraphTabPage, AutoHdl_Impl));
+ SfxItemPool* pPool = GetItemSet().GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ FieldUnit eUnit = MapToFieldUnit( pPool->GetMetric( GetWhich( SID_ATTR_LRSPACE ) ) );
+
+ m_xTopDist->set_max( m_xTopDist->normalize( MAX_DURCH ), eUnit );
+ m_xBottomDist->set_max( m_xBottomDist->normalize( MAX_DURCH ), eUnit );
+ m_xLineDistAtMetricBox->set_max( m_xLineDistAtMetricBox->normalize( MAX_DURCH ), eUnit );
+}
+
+void SvxStdParagraphTabPage::UpdateExample_Impl()
+{
+ m_aExampleWin.SetFirstLineOffset( static_cast<short>(m_xFLineIndent->denormalize( m_xFLineIndent->get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLeftMargin( static_cast<long>(m_xLeftIndent->denormalize( m_xLeftIndent->get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetRightMargin( static_cast<long>(m_xRightIndent->denormalize( m_xRightIndent->get_value( FieldUnit::TWIP ) ) ) );
+ m_aExampleWin.SetUpper( static_cast<sal_uInt16>(m_xTopDist->denormalize( m_xTopDist->get_value( FieldUnit::TWIP ) )) );
+ m_aExampleWin.SetLower( static_cast<sal_uInt16>(m_xBottomDist->denormalize( m_xBottomDist->get_value( FieldUnit::TWIP ) )) );
+
+ int nPos = m_xLineDist->get_active();
+
+ switch ( nPos )
+ {
+ case LLINESPACE_1:
+ case LLINESPACE_115:
+ case LLINESPACE_15:
+ case LLINESPACE_2:
+ case LLINESPACE_PROP:
+ case LLINESPACE_MIN:
+ case LLINESPACE_DURCH:
+ case LLINESPACE_FIX:
+ m_aExampleWin.SetLineSpace( static_cast<SvxPrevLineSpace>(nPos) );
+ break;
+ }
+ m_aExampleWin.Invalidate();
+}
+
+void SvxStdParagraphTabPage::EnableRegisterMode()
+{
+ m_xRegisterCB->show();
+ m_xRegisterFL->show();
+}
+
+void SvxStdParagraphTabPage::EnableContextualMode()
+{
+ m_xContextualCB->show();
+}
+
+IMPL_LINK(SvxStdParagraphTabPage, AutoHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ bool bEnable = !rBox.get_active();
+ m_xFLineLabel->set_sensitive(bEnable);
+ m_xFLineIndent->set_sensitive(bEnable);
+}
+
+void SvxStdParagraphTabPage::EnableAutoFirstLine()
+{
+ m_xAutoCB->show();
+}
+
+void SvxStdParagraphTabPage::EnableAbsLineDist(long nMinTwip)
+{
+ m_xLineDist->append_text(sAbsDist);
+ nMinFixDist = nMinTwip;
+}
+
+void SvxStdParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+
+/* different bit represent call to different method of SvxStdParagraphTabPage
+ 0x0001 --->EnableRelativeMode()
+ 0x0002 --->EnableRegisterMode()
+ 0x0004 --->EnableAutoFirstLine()
+ 0x0008 --->EnableNegativeMode()
+ 0x0010 --->EnableContextualMode()
+ */
+ const SfxUInt16Item* pPageWidthItem = aSet.GetItem<SfxUInt16Item>(SID_SVXSTDPARAGRAPHTABPAGE_PAGEWIDTH, false);
+ const SfxUInt32Item* pFlagSetItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_FLAGSET, false);
+ const SfxUInt32Item* pLineDistItem = aSet.GetItem<SfxUInt32Item>(SID_SVXSTDPARAGRAPHTABPAGE_ABSLINEDIST, false);
+
+ if (pPageWidthItem)
+ nWidth = pPageWidthItem->GetValue();
+
+ if (pFlagSetItem )
+ {
+ if (( 0x0001 & pFlagSetItem->GetValue())== 0x0001 )
+ EnableRelativeMode();
+
+ if (( 0x0002 & pFlagSetItem->GetValue())== 0x0002 )
+ EnableRegisterMode();
+
+ if ( ( 0x0004 & pFlagSetItem->GetValue())== 0x0004 )
+ EnableAutoFirstLine();
+ }
+
+ if(pLineDistItem)
+ EnableAbsLineDist(pLineDistItem->GetValue());
+
+ if (pFlagSetItem)
+ {
+ if (( 0x0008 & pFlagSetItem->GetValue()) == 0x0008 )
+ EnableNegativeMode();
+
+ if (( 0x0010 & pFlagSetItem->GetValue()) == 0x0010 )
+ EnableContextualMode();
+ }
+}
+
+#define LASTLINEPOS_DEFAULT 0
+#define LASTLINEPOS_LEFT 1
+
+#define LASTLINECOUNT_OLD 3
+#define LASTLINECOUNT_NEW 4
+
+SvxParaAlignTabPage::SvxParaAlignTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/paragalignpage.ui", "ParaAlignPage", &rSet)
+ , m_xLeft(m_xBuilder->weld_radio_button("radioBTN_LEFTALIGN"))
+ , m_xRight(m_xBuilder->weld_radio_button("radioBTN_RIGHTALIGN"))
+ , m_xCenter(m_xBuilder->weld_radio_button("radioBTN_CENTERALIGN"))
+ , m_xJustify(m_xBuilder->weld_radio_button("radioBTN_JUSTIFYALIGN"))
+ , m_xLeftBottom(m_xBuilder->weld_label("labelST_LEFTALIGN_ASIAN"))
+ , m_xRightTop(m_xBuilder->weld_label("labelST_RIGHTALIGN_ASIAN"))
+ , m_xLastLineFT(m_xBuilder->weld_label("labelLB_LASTLINE"))
+ , m_xLastLineLB(m_xBuilder->weld_combo_box("comboLB_LASTLINE"))
+ , m_xExpandCB(m_xBuilder->weld_check_button("checkCB_EXPAND"))
+ , m_xSnapToGridCB(m_xBuilder->weld_check_button("checkCB_SNAP"))
+ , m_xExampleWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWN_EXAMPLE", m_aExampleWin))
+ , m_xVertAlignFL(m_xBuilder->weld_widget("frameFL_VERTALIGN"))
+ , m_xVertAlignLB(m_xBuilder->weld_combo_box("comboLB_VERTALIGN"))
+ , m_xPropertiesFL(m_xBuilder->weld_widget("framePROPERTIES"))
+ , m_xTextDirectionLB(new svx::FrameDirectionListBox(m_xBuilder->weld_combo_box("comboLB_TEXTDIRECTION")))
+{
+ SetExchangeSupport();
+
+ SvtLanguageOptions aLangOptions;
+ sal_uInt16 nLastLinePos = LASTLINEPOS_DEFAULT;
+
+ if ( aLangOptions.IsAsianTypographyEnabled() )
+ {
+ m_xLeft->set_label(m_xLeftBottom->get_label());
+ m_xRight->set_label(m_xRightTop->get_label());
+
+ OUString sLeft(m_xLeft->get_label());
+ sLeft = MnemonicGenerator::EraseAllMnemonicChars( sLeft );
+
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_OLD)
+ {
+ m_xLastLineLB->remove(0);
+ m_xLastLineLB->insert_text(0, sLeft);
+ }
+ else
+ nLastLinePos = LASTLINEPOS_LEFT;
+ }
+
+ // remove "Default" or "Left" entry, depends on CJKOptions
+ if (m_xLastLineLB->get_count() == LASTLINECOUNT_NEW)
+ m_xLastLineLB->remove(nLastLinePos);
+
+ Link<weld::ToggleButton&, void> aLink = LINK( this, SvxParaAlignTabPage, AlignHdl_Impl );
+ m_xLeft->connect_toggled(aLink);
+ m_xRight->connect_toggled(aLink);
+ m_xCenter->connect_toggled(aLink);
+ m_xJustify->connect_toggled(aLink);
+ m_xLastLineLB->connect_changed(LINK(this, SvxParaAlignTabPage, LastLineHdl_Impl));
+ m_xTextDirectionLB->connect_changed(LINK(this, SvxParaAlignTabPage, TextDirectionHdl_Impl));
+
+ m_xTextDirectionLB->append(SvxFrameDirection::Environment, SvxResId(RID_SVXSTR_FRAMEDIR_SUPER));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_LR_TB, SvxResId(RID_SVXSTR_FRAMEDIR_LTR));
+ m_xTextDirectionLB->append(SvxFrameDirection::Horizontal_RL_TB, SvxResId(RID_SVXSTR_FRAMEDIR_RTL));
+}
+
+SvxParaAlignTabPage::~SvxParaAlignTabPage()
+{
+}
+
+DeactivateRC SvxParaAlignTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+std::unique_ptr<SfxTabPage> SvxParaAlignTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxParaAlignTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxParaAlignTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+
+ bool bAdj = false;
+ SvxAdjust eAdjust = SvxAdjust::Left;
+
+ if (m_xLeft->get_active())
+ {
+ eAdjust = SvxAdjust::Left;
+ bAdj = m_xLeft->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xRight->get_active())
+ {
+ eAdjust = SvxAdjust::Right;
+ bAdj = m_xRight->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xCenter->get_active())
+ {
+ eAdjust = SvxAdjust::Center;
+ bAdj = m_xCenter->get_saved_state() == TRISTATE_FALSE;
+ }
+ else if (m_xJustify->get_active())
+ {
+ eAdjust = SvxAdjust::Block;
+ bAdj = m_xJustify->get_saved_state() == TRISTATE_FALSE ||
+ m_xExpandCB->get_state_changed_from_saved() ||
+ m_xLastLineLB->get_value_changed_from_saved();
+ }
+
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+
+ if (bAdj)
+ {
+ SvxAdjust eOneWord = m_xExpandCB->get_active() ? SvxAdjust::Block : SvxAdjust::Left;
+
+ int nLBPos = m_xLastLineLB->get_active();
+ SvxAdjust eLastBlock = SvxAdjust::Left;
+ if ( 1 == nLBPos )
+ eLastBlock = SvxAdjust::Center;
+ else if ( 2 == nLBPos )
+ eLastBlock = SvxAdjust::Block;
+
+ SvxAdjustItem aAdj( static_cast<const SvxAdjustItem&>(GetItemSet().Get( _nWhich )) );
+ aAdj.SetAdjust( eAdjust );
+ aAdj.SetOneWord( eOneWord );
+ aAdj.SetLastBlock( eLastBlock );
+ rOutSet->Put( aAdj );
+ bModified = true;
+ }
+
+ if (m_xSnapToGridCB->get_state_changed_from_saved())
+ {
+ rOutSet->Put(SvxParaGridItem(m_xSnapToGridCB->get_active(), GetWhich( SID_ATTR_PARA_SNAPTOGRID )));
+ bModified = true;
+ }
+
+ if (m_xVertAlignLB->get_value_changed_from_saved())
+ {
+ rOutSet->Put(SvxParaVertAlignItem(static_cast<SvxParaVertAlignItem::Align>(m_xVertAlignLB->get_active()), GetWhich( SID_PARA_VERTALIGN )));
+ bModified = true;
+ }
+
+ if (m_xTextDirectionLB->get_visible())
+ {
+ if (m_xTextDirectionLB->get_value_changed_from_saved())
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ rOutSet->Put( SvxFrameDirectionItem( eDir, GetWhich( SID_ATTR_FRAMEDIRECTION ) ) );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+
+void SvxParaAlignTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ Reset( &rSet );
+}
+
+void SvxParaAlignTabPage::Reset( const SfxItemSet* rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_ADJUST );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ sal_Int32 nLBSelect = 0;
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxAdjustItem& rAdj = static_cast<const SvxAdjustItem&>(rSet->Get( _nWhich ));
+
+ switch ( rAdj.GetAdjust() /*!!! ask VB rAdj.GetLastBlock()*/ )
+ {
+ case SvxAdjust::Left: m_xLeft->set_active(true); break;
+
+ case SvxAdjust::Right: m_xRight->set_active(true); break;
+
+ case SvxAdjust::Center: m_xCenter->set_active(true); break;
+
+ case SvxAdjust::Block: m_xJustify->set_active(true); break;
+ default: ; //prevent warning
+ }
+ bool bEnable = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bEnable);
+ m_xLastLineLB->set_sensitive(bEnable);
+
+ switch(rAdj.GetLastBlock())
+ {
+ case SvxAdjust::Left: nLBSelect = 0; break;
+
+ case SvxAdjust::Center: nLBSelect = 1; break;
+
+ case SvxAdjust::Block: nLBSelect = 2; break;
+ default: ; //prevent warning
+ }
+ m_xExpandCB->set_sensitive(bEnable && nLBSelect == 2);
+ m_xExpandCB->set_active(SvxAdjust::Block == rAdj.GetOneWord());
+ }
+ else
+ {
+ m_xLeft->set_active(false);
+ m_xRight->set_active(false);
+ m_xCenter->set_active(false);
+ m_xJustify->set_active(false);
+ }
+ m_xLastLineLB->set_active(nLBSelect);
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl(*rSet);
+ if(nHtmlMode & HTMLMODE_ON)
+ {
+ m_xLastLineLB->hide();
+ m_xLastLineFT->hide();
+ m_xExpandCB->hide();
+ if(!(nHtmlMode & HTMLMODE_FULL_STYLES) )
+ m_xJustify->set_sensitive(false);
+ m_xSnapToGridCB->hide();
+ }
+ _nWhich = GetWhich(SID_ATTR_PARA_SNAPTOGRID);
+ eItemState = rSet->GetItemState( _nWhich );
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxParaGridItem& rSnap = static_cast<const SvxParaGridItem&>(rSet->Get( _nWhich ));
+ m_xSnapToGridCB->set_active(rSnap.GetValue());
+ }
+
+ _nWhich = GetWhich( SID_PARA_VERTALIGN );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ m_xVertAlignFL->show();
+
+ const SvxParaVertAlignItem& rAlign = static_cast<const SvxParaVertAlignItem&>(rSet->Get( _nWhich ));
+
+ m_xVertAlignLB->set_active(static_cast<sal_Int32>(rAlign.GetValue()));
+ }
+
+ _nWhich = GetWhich( SID_ATTR_FRAMEDIRECTION );
+ //text direction
+ if( SfxItemState::DEFAULT <= rSet->GetItemState( _nWhich ) )
+ {
+ const SvxFrameDirectionItem& rFrameDirItem = static_cast<const SvxFrameDirectionItem&>( rSet->Get( _nWhich ) );
+ m_xTextDirectionLB->set_active_id(rFrameDirItem.GetValue());
+ m_xTextDirectionLB->save_value();
+ }
+
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::ChangesApplied()
+{
+ m_xTextDirectionLB->save_value();
+ m_xSnapToGridCB->save_state();
+ m_xVertAlignLB->save_value();
+ m_xLeft->save_state();
+ m_xRight->save_state();
+ m_xCenter->save_state();
+ m_xJustify->save_state();
+ m_xLastLineLB->save_value();
+ m_xExpandCB->save_state();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, AlignHdl_Impl, weld::ToggleButton&, void)
+{
+ bool bJustify = m_xJustify->get_active();
+ m_xLastLineFT->set_sensitive(bJustify);
+ m_xLastLineLB->set_sensitive(bJustify);
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bJustify && bLastLineIsBlock);
+ //set last line listbox to entry position 0 if not enabled
+ if (!m_xLastLineLB->get_sensitive())
+ m_xLastLineLB->set_active(0);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, LastLineHdl_Impl, weld::ComboBox&, void)
+{
+ //fdo#41350 only enable 'Expand last word' if last line is also justified
+ bool bLastLineIsBlock = m_xLastLineLB->get_active() == 2;
+ m_xExpandCB->set_sensitive(bLastLineIsBlock);
+ //uncheck 'Expand ... word' when check box is not enabled
+ if (!m_xExpandCB->get_sensitive())
+ m_xExpandCB->set_active(false);
+ UpdateExample_Impl();
+}
+
+IMPL_LINK_NOARG(SvxParaAlignTabPage, TextDirectionHdl_Impl, weld::ComboBox&, void)
+{
+ UpdateExample_Impl();
+}
+
+void SvxParaAlignTabPage::UpdateExample_Impl()
+{
+ if (m_xLeft->get_active())
+ {
+ m_aExampleWin.EnableRTL(false);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else if (m_xRight->get_active())
+ {
+ m_aExampleWin.EnableRTL(true);
+ m_aExampleWin.SetAdjust(SvxAdjust::Left);
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ }
+ else
+ {
+ SvxFrameDirection eDir = m_xTextDirectionLB->get_active_id();
+ switch ( eDir )
+ {
+ case SvxFrameDirection::Environment :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( AllSettings::GetLayoutRTL() );
+ break;
+ case SvxFrameDirection::Horizontal_RL_TB :
+ if ( !m_xLeft->get_active() )
+ m_aExampleWin.EnableRTL( true );
+ break;
+ case SvxFrameDirection::Horizontal_LR_TB :
+ if ( !m_xRight->get_active() )
+ m_aExampleWin.EnableRTL( false );
+ break;
+ default: ; //prevent warning
+ }
+ if (m_xCenter->get_active())
+ m_aExampleWin.SetAdjust( SvxAdjust::Center );
+ else if (m_xJustify->get_active())
+ {
+ m_aExampleWin.SetAdjust( SvxAdjust::Block );
+ int nLBPos = m_xLastLineLB->get_active();
+ if (nLBPos == 0)
+ m_aExampleWin.SetLastLine(SvxAdjust::Left);
+ else if (nLBPos == 1)
+ m_aExampleWin.SetLastLine(SvxAdjust::Center);
+ else if (nLBPos == 2)
+ m_aExampleWin.SetLastLine(SvxAdjust::Block);
+ }
+ }
+
+ m_aExampleWin.Invalidate();
+}
+
+void SvxParaAlignTabPage::EnableJustifyExt()
+{
+ m_xLastLineFT->show();
+ m_xLastLineLB->show();
+ m_xExpandCB->show();
+ SvtLanguageOptions aCJKOptions;
+ if (aCJKOptions.IsAsianTypographyEnabled())
+ m_xSnapToGridCB->show();
+
+}
+
+void SvxParaAlignTabPage::PageCreated (const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pBoolItem = aSet.GetItem<SfxBoolItem>(SID_SVXPARAALIGNTABPAGE_ENABLEJUSTIFYEXT, false);
+ if (pBoolItem && pBoolItem->GetValue())
+ EnableJustifyExt();
+}
+
+std::unique_ptr<SfxTabPage> SvxExtParagraphTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxExtParagraphTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxExtParagraphTabPage::FillItemSet( SfxItemSet* rOutSet )
+{
+ bool bModified = false;
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ const TriState eHyphenState = m_xHyphenBox->get_state();
+ const SfxPoolItem* pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_HYPHENZONE );
+
+ if ( m_xHyphenBox->get_state_changed_from_saved() ||
+ m_xHyphenNoCapsBox->get_state_changed_from_saved() ||
+ m_xExtHyphenBeforeBox->get_value_changed_from_saved() ||
+ m_xExtHyphenAfterBox->get_value_changed_from_saved() ||
+ m_xMaxHyphenEdit->get_value_changed_from_saved() )
+ {
+ SvxHyphenZoneItem aHyphen(
+ static_cast<const SvxHyphenZoneItem&>(GetItemSet().Get( _nWhich )) );
+ aHyphen.SetHyphen( eHyphenState == TRISTATE_TRUE );
+ aHyphen.SetNoCapsHyphenation(m_xHyphenNoCapsBox->get_state() == TRISTATE_TRUE);
+
+ if ( eHyphenState == TRISTATE_TRUE )
+ {
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(m_xExtHyphenBeforeBox->get_value());
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(m_xExtHyphenAfterBox->get_value());
+ }
+ aHyphen.GetMaxHyphens() = static_cast<sal_uInt8>(m_xMaxHyphenEdit->get_value());
+
+ if ( !pOld ||
+ *static_cast<const SvxHyphenZoneItem*>(pOld) != aHyphen ||
+ m_xHyphenBox->get_state_changed_from_saved())
+ {
+ rOutSet->Put( aHyphen );
+ bModified = true;
+ }
+ }
+
+ if (m_xPageNumBox->get_sensitive()
+ && (m_xPageNumBox->get_state_changed_from_saved() || m_xPagenumEdit->get_value_changed_from_saved()))
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGENUM );
+
+ if (TRISTATE_TRUE == m_xPageNumBox->get_state()
+ && (!pOld || IsInvalidItem(pOld)
+ || static_cast<const SfxUInt16Item*>(pOld)->GetValue() != m_xPagenumEdit->get_value()))
+ {
+ SfxUInt16Item aPageNum(SID_ATTR_PARA_PAGENUM,
+ static_cast<sal_uInt16>(m_xPagenumEdit->get_value()));
+ rOutSet->Put( aPageNum );
+ bModified = true;
+ }
+ else if (TRISTATE_FALSE == m_xPageNumBox->get_state()
+ && (pOld || IsInvalidItem(pOld)))
+ {
+ // need to tell sw to remove the item
+ rOutSet->DisableItem(SID_ATTR_PARA_PAGENUM);
+ bModified = true;
+ }
+ }
+
+ // pagebreak
+
+ TriState eState = m_xApplyCollBtn->get_state();
+ bool bIsPageModel = false;
+
+ _nWhich = GetWhich( SID_ATTR_PARA_MODEL );
+ OUString sPage;
+ if ( m_xApplyCollBtn->get_state_changed_from_saved() ||
+ ( TRISTATE_TRUE == eState &&
+ m_xApplyCollBox->get_value_changed_from_saved() ) )
+ {
+ if ( eState == TRISTATE_TRUE )
+ {
+ sPage = m_xApplyCollBox->get_active_text();
+ bIsPageModel = !sPage.isEmpty();
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_MODEL );
+
+ if ( !pOld || static_cast<const SvxPageModelItem*>(pOld)->GetValue() != sPage )
+ {
+ rOutSet->Put( SvxPageModelItem( sPage, false, _nWhich ) );
+ bModified = true;
+ }
+ else
+ bIsPageModel = false;
+ }
+ else if(TRISTATE_TRUE == eState && m_xApplyCollBtn->get_sensitive())
+ bIsPageModel = true;
+ else
+ rOutSet->Put( SvxPageModelItem( sPage, false, _nWhich ) );
+
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+
+ if ( bIsPageModel )
+ // if PageModel is turned on, always turn off PageBreak
+ rOutSet->Put( SvxFormatBreakItem( SvxBreak::NONE, _nWhich ) );
+ else
+ {
+ eState = m_xPageBreakBox->get_state();
+ SfxItemState eModelState = GetItemSet().GetItemState(SID_ATTR_PARA_MODEL, false);
+
+ if ( (eModelState == SfxItemState::SET && TRISTATE_TRUE == m_xPageBreakBox->get_state()) ||
+ m_xPageBreakBox->get_state_changed_from_saved() ||
+ m_xBreakTypeLB->get_value_changed_from_saved() ||
+ m_xBreakPositionLB->get_value_changed_from_saved() )
+ {
+ const SvxFormatBreakItem rOldBreak(
+ static_cast<const SvxFormatBreakItem&>(GetItemSet().Get( _nWhich )));
+ SvxFormatBreakItem aBreak(rOldBreak.GetBreak(), rOldBreak.Which());
+
+ switch ( eState )
+ {
+ case TRISTATE_TRUE:
+ {
+ bool bBefore = m_xBreakPositionLB->get_active() == 0;
+
+ if (m_xBreakTypeLB->get_active() == 0)
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::PageBefore );
+ else
+ aBreak.SetValue( SvxBreak::PageAfter );
+ }
+ else
+ {
+ if ( bBefore )
+ aBreak.SetValue( SvxBreak::ColumnBefore );
+ else
+ aBreak.SetValue( SvxBreak::ColumnAfter );
+ }
+ break;
+ }
+
+ case TRISTATE_FALSE:
+ aBreak.SetValue( SvxBreak::NONE );
+ break;
+ default: ; //prevent warning
+ }
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_PAGEBREAK );
+
+ if ( eState != m_xPageBreakBox->get_saved_state() ||
+ !pOld || !( *static_cast<const SvxFormatBreakItem*>(pOld) == aBreak ) )
+ {
+ bModified = true;
+ rOutSet->Put( aBreak );
+ }
+ }
+ }
+
+ // paragraph split
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eState = m_xKeepTogetherBox->get_state();
+
+ if (m_xKeepTogetherBox->get_state_changed_from_saved())
+ {
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_SPLIT );
+
+ if ( !pOld || static_cast<const SvxFormatSplitItem*>(pOld)->GetValue() !=
+ ( eState == TRISTATE_FALSE ) )
+ {
+ rOutSet->Put( SvxFormatSplitItem( eState == TRISTATE_FALSE, _nWhich ) );
+ bModified = true;
+ }
+ }
+
+ // keep paragraphs
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eState = m_xKeepParaBox->get_state();
+
+ if (m_xKeepParaBox->get_state_changed_from_saved())
+ {
+ // if the status has changed, putting is necessary
+ rOutSet->Put( SvxFormatKeepItem( eState == TRISTATE_TRUE, _nWhich ) );
+ bModified = true;
+ }
+
+ // widows and orphans
+ _nWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ eState = m_xWidowBox->get_state();
+
+ if ( m_xWidowBox->get_state_changed_from_saved() ||
+ m_xWidowRowNo->get_value_changed_from_saved() )
+ {
+ SvxWidowsItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xWidowRowNo->get_value()) : 0, _nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_WIDOWS );
+
+ if ( m_xWidowBox->get_state_changed_from_saved() || !pOld || !( *static_cast<const SvxWidowsItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eState = m_xOrphanBox->get_state();
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ m_xOrphanRowNo->get_value_changed_from_saved() )
+ {
+ SvxOrphansItem rItem( eState == TRISTATE_TRUE ?
+ static_cast<sal_uInt8>(m_xOrphanRowNo->get_value()) : 0, _nWhich );
+ pOld = GetOldItem( *rOutSet, SID_ATTR_PARA_ORPHANS );
+
+ if ( m_xOrphanBox->get_state_changed_from_saved() ||
+ !pOld ||
+ !( *static_cast<const SvxOrphansItem*>(pOld) == rItem ) )
+ {
+ rOutSet->Put( rItem );
+ bModified = true;
+ }
+ }
+
+ return bModified;
+}
+void SvxExtParagraphTabPage::Reset( const SfxItemSet* rSet )
+{
+ sal_uInt16 _nWhich = GetWhich( SID_ATTR_PARA_HYPHENZONE );
+ SfxItemState eItemState = rSet->GetItemState( _nWhich );
+
+ bool bItemAvailable = eItemState >= SfxItemState::DEFAULT;
+ bool bIsHyphen = false;
+ if( !bHtmlMode && bItemAvailable )
+ {
+ const SvxHyphenZoneItem& rHyphen =
+ static_cast<const SvxHyphenZoneItem&>(rSet->Get( _nWhich ));
+ aHyphenState.bTriStateEnabled = false;
+
+ bIsHyphen = rHyphen.IsHyphen();
+ m_xHyphenBox->set_state(bIsHyphen ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xHyphenNoCapsBox->set_state(rHyphen.IsNoCapsHyphenation() ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xExtHyphenBeforeBox->set_value(rHyphen.GetMinLead());
+ m_xExtHyphenAfterBox->set_value(rHyphen.GetMinTrail());
+ m_xMaxHyphenEdit->set_value(rHyphen.GetMaxHyphens());
+ }
+ else
+ {
+ m_xHyphenBox->set_state(TRISTATE_INDET);
+ m_xHyphenNoCapsBox->set_state(TRISTATE_INDET);
+ }
+ bool bEnable = bItemAvailable && bIsHyphen;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGENUM );
+
+ switch (rSet->GetItemState(_nWhich))
+ {
+ case SfxItemState::SET:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_TRUE);
+ SfxUInt16Item const*const pItem(rSet->GetItem<SfxUInt16Item>(_nWhich));
+ const sal_uInt16 nPageNum(pItem->GetValue());
+ m_xPagenumEdit->set_value(nPageNum);
+ break;
+ }
+ case SfxItemState::DONTCARE:
+ {
+ aPageNumState.bTriStateEnabled = true;
+ m_xPageNumBox->set_state(TRISTATE_INDET);
+ break;
+ }
+ case SfxItemState::UNKNOWN:
+ case SfxItemState::DEFAULT:
+ case SfxItemState::DISABLED:
+ {
+ aPageNumState.bTriStateEnabled = false;
+ m_xPageNumBox->set_state(TRISTATE_FALSE);
+ break;
+ }
+ default:
+ assert(false); // unexpected
+ break;
+ }
+
+ if ( bPageBreak )
+ {
+ // first handle PageModel
+ _nWhich = GetWhich( SID_ATTR_PARA_MODEL );
+ bool bIsPageModel = false;
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::SET )
+ {
+ aApplyCollState.bTriStateEnabled = false;
+
+ const SvxPageModelItem& rModel =
+ static_cast<const SvxPageModelItem&>(rSet->Get( _nWhich ));
+ const OUString& aStr( rModel.GetValue() );
+
+ if (!aStr.isEmpty() && m_xApplyCollBox->find_text(aStr) != -1)
+ {
+ m_xApplyCollBox->set_active_text(aStr);
+ m_xApplyCollBtn->set_state(TRISTATE_TRUE);
+ bIsPageModel = true;
+
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ //select page break
+ m_xBreakTypeLB->set_active(0);
+ //select break before
+ m_xBreakPositionLB->set_active(0);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ {
+ aApplyCollState.bTriStateEnabled = true;
+ m_xApplyCollBtn->set_state(TRISTATE_INDET);
+ m_xApplyCollBox->set_active(-1);
+ }
+ else
+ {
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ }
+
+ if ( !bIsPageModel )
+ {
+ _nWhich = GetWhich( SID_ATTR_PARA_PAGEBREAK );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatBreakItem& rPageBreak =
+ static_cast<const SvxFormatBreakItem&>(rSet->Get( _nWhich ));
+
+ SvxBreak eBreak = rPageBreak.GetBreak();
+
+ // PageBreak not via CTRL-RETURN,
+ // then CheckBox can be freed
+ m_xPageBreakBox->set_sensitive(true);
+ aPageBreakState.bTriStateEnabled = false;
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ m_xPageBreakBox->set_state(TRISTATE_TRUE);
+
+ bool _bEnable = eBreak != SvxBreak::NONE &&
+ eBreak != SvxBreak::ColumnBefore &&
+ eBreak != SvxBreak::ColumnAfter;
+ m_xApplyCollBtn->set_sensitive(_bEnable);
+ if (!_bEnable)
+ {
+ m_xApplyCollBox->set_sensitive(_bEnable);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(_bEnable);
+ }
+
+ if ( eBreak == SvxBreak::NONE )
+ m_xPageBreakBox->set_state(TRISTATE_FALSE);
+
+ sal_Int32 nType = 0; // selection position in break type ListBox : Page
+ sal_Int32 nPosition = 0; // selection position in break position ListBox : Before
+ switch ( eBreak )
+ {
+ case SvxBreak::PageBefore:
+ break;
+ case SvxBreak::PageAfter:
+ nPosition = 1;
+ break;
+ case SvxBreak::ColumnBefore:
+ nType = 1;
+ break;
+ case SvxBreak::ColumnAfter:
+ nType = 1;
+ nPosition = 1;
+ break;
+ default: ;//prevent warning
+ }
+ m_xBreakTypeLB->set_active(nType);
+ m_xBreakPositionLB->set_active(nPosition);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xPageBreakBox->set_state(TRISTATE_INDET);
+ else
+ {
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ }
+ }
+
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+ PageBreakHdl();
+ }
+
+ _nWhich = GetWhich( SID_ATTR_PARA_KEEP );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ aKeepParaState.bTriStateEnabled = false;
+ const SvxFormatKeepItem& rKeep =
+ static_cast<const SvxFormatKeepItem&>(rSet->Get( _nWhich ));
+
+ if ( rKeep.GetValue() )
+ m_xKeepParaBox->set_state(TRISTATE_TRUE);
+ else
+ m_xKeepParaBox->set_state(TRISTATE_FALSE);
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xKeepParaBox->set_state(TRISTATE_INDET);
+ else
+ m_xKeepParaBox->set_sensitive(false);
+
+ _nWhich = GetWhich( SID_ATTR_PARA_SPLIT );
+ eItemState = rSet->GetItemState( _nWhich );
+
+ if ( eItemState >= SfxItemState::DEFAULT )
+ {
+ const SvxFormatSplitItem& rSplit =
+ static_cast<const SvxFormatSplitItem&>(rSet->Get( _nWhich ));
+ aKeepTogetherState.bTriStateEnabled = false;
+
+ if ( !rSplit.GetValue() )
+ m_xKeepTogetherBox->set_state(TRISTATE_TRUE);
+ else
+ {
+ m_xKeepTogetherBox->set_state(TRISTATE_FALSE);
+
+ // widows and orphans
+ m_xWidowBox->set_sensitive(true);
+ _nWhich = GetWhich( SID_ATTR_PARA_WIDOWS );
+ SfxItemState eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxWidowsItem& rWidow =
+ static_cast<const SvxWidowsItem&>(rSet->Get( _nWhich ));
+ aWidowState.bTriStateEnabled = false;
+ const sal_uInt16 nLines = rWidow.GetValue();
+
+ bool _bEnable = nLines > 0;
+ m_xWidowRowNo->set_value(m_xWidowRowNo->normalize(nLines));
+ m_xWidowBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xWidowRowNo->set_sensitive(_bEnable);
+ //m_xWidowRowLabel->set_sensitive(_bEnable);
+
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xWidowBox->set_state( TRISTATE_INDET );
+ else
+ m_xWidowBox->set_sensitive(false);
+
+ m_xOrphanBox->set_sensitive(true);
+ _nWhich = GetWhich( SID_ATTR_PARA_ORPHANS );
+ eTmpState = rSet->GetItemState( _nWhich );
+
+ if ( eTmpState >= SfxItemState::DEFAULT )
+ {
+ const SvxOrphansItem& rOrphan =
+ static_cast<const SvxOrphansItem&>(rSet->Get( _nWhich ));
+ const sal_uInt16 nLines = rOrphan.GetValue();
+ aOrphanState.bTriStateEnabled = false;
+
+ bool _bEnable = nLines > 0;
+ m_xOrphanBox->set_state(_bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xOrphanRowNo->set_value(m_xOrphanRowNo->normalize(nLines));
+ m_xOrphanRowNo->set_sensitive(_bEnable);
+ m_xOrphanRowLabel->set_sensitive(_bEnable);
+
+ }
+ else if ( SfxItemState::DONTCARE == eTmpState )
+ m_xOrphanBox->set_state(TRISTATE_INDET);
+ else
+ m_xOrphanBox->set_sensitive(false);
+ aOrphanState.eState = m_xOrphanBox->get_state();
+ }
+ }
+ else if ( SfxItemState::DONTCARE == eItemState )
+ m_xKeepTogetherBox->set_state(TRISTATE_INDET);
+ else
+ m_xKeepTogetherBox->set_sensitive(false);
+
+ // so that everything is enabled correctly
+ KeepTogetherHdl();
+ WidowHdl();
+ OrphanHdl();
+ ChangesApplied();
+}
+void SvxExtParagraphTabPage::ChangesApplied()
+{
+ m_xHyphenBox->save_state();
+ m_xHyphenNoCapsBox->save_state();
+ m_xExtHyphenBeforeBox->set_value(m_xExtHyphenBeforeBox->get_value());
+ m_xExtHyphenAfterBox->set_value(m_xExtHyphenAfterBox->get_value());
+ m_xMaxHyphenEdit->set_value(m_xMaxHyphenEdit->get_value());
+ m_xPageBreakBox->save_state();
+ m_xBreakPositionLB->save_value();
+ m_xBreakTypeLB->save_value();
+ m_xApplyCollBtn->save_state();
+ m_xApplyCollBox->save_value();
+ m_xPageNumBox->save_state();
+ m_xPagenumEdit->save_value();
+ m_xKeepTogetherBox->save_state();
+ m_xKeepParaBox->save_state();
+ m_xWidowBox->save_state();
+ m_xOrphanBox->save_state();
+ m_xOrphanRowNo->save_value();
+ m_xWidowRowNo->save_value();
+}
+
+DeactivateRC SvxExtParagraphTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxExtParagraphTabPage::DisablePageBreak()
+{
+ bPageBreak = false;
+ m_xPageBreakBox->set_sensitive(false);
+ m_xBreakTypeLB->remove(0);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+}
+
+SvxExtParagraphTabPage::SvxExtParagraphTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/textflowpage.ui", "TextFlowPage", &rAttr)
+ , bPageBreak(true)
+ , bHtmlMode(false)
+ , nStdPos(0)
+ // Hyphenation
+ , m_xHyphenBox(m_xBuilder->weld_check_button("checkAuto"))
+ , m_xHyphenNoCapsBox(m_xBuilder->weld_check_button("checkNoCaps"))
+ , m_xBeforeText(m_xBuilder->weld_label("labelLineBegin"))
+ , m_xExtHyphenBeforeBox(m_xBuilder->weld_spin_button("spinLineEnd"))
+ , m_xAfterText(m_xBuilder->weld_label("labelLineEnd"))
+ , m_xExtHyphenAfterBox(m_xBuilder->weld_spin_button("spinLineBegin"))
+ , m_xMaxHyphenLabel(m_xBuilder->weld_label("labelMaxNum"))
+ , m_xMaxHyphenEdit(m_xBuilder->weld_spin_button("spinMaxNum"))
+ //Page break
+ , m_xPageBreakBox(m_xBuilder->weld_check_button("checkInsert"))
+ , m_xBreakTypeFT(m_xBuilder->weld_label("labelType"))
+ , m_xBreakTypeLB(m_xBuilder->weld_combo_box("comboBreakType"))
+ , m_xBreakPositionFT(m_xBuilder->weld_label("labelPosition"))
+ , m_xBreakPositionLB(m_xBuilder->weld_combo_box("comboBreakPosition"))
+ , m_xApplyCollBtn(m_xBuilder->weld_check_button("checkPageStyle"))
+ , m_xApplyCollBox(m_xBuilder->weld_combo_box("comboPageStyle"))
+ , m_xPageNumBox(m_xBuilder->weld_check_button("labelPageNum"))
+ , m_xPagenumEdit(m_xBuilder->weld_spin_button("spinPageNumber"))
+ // Options
+ , m_xKeepTogetherBox(m_xBuilder->weld_check_button("checkSplitPara"))
+ , m_xKeepParaBox(m_xBuilder->weld_check_button("checkKeepPara"))
+ , m_xOrphanBox(m_xBuilder->weld_check_button("checkOrphan"))
+ , m_xOrphanRowNo(m_xBuilder->weld_spin_button("spinOrphan"))
+ , m_xOrphanRowLabel(m_xBuilder->weld_label("labelOrphan"))
+ , m_xWidowBox(m_xBuilder->weld_check_button("checkWidow"))
+ , m_xWidowRowNo(m_xBuilder->weld_spin_button("spinWidow"))
+ , m_xWidowRowLabel(m_xBuilder->weld_label("labelWidow"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ m_xHyphenBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, HyphenClickHdl_Impl));
+ m_xPageBreakBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageBreakHdl_Impl));
+ m_xKeepTogetherBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, KeepTogetherHdl_Impl));
+ m_xWidowBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, WidowHdl_Impl));
+ m_xOrphanBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, OrphanHdl_Impl));
+ m_xApplyCollBtn->connect_toggled(LINK(this, SvxExtParagraphTabPage, ApplyCollClickHdl_Impl));
+ m_xBreakTypeLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakTypeHdl_Impl));
+ m_xBreakPositionLB->connect_changed(LINK(this, SvxExtParagraphTabPage, PageBreakPosHdl_Impl));
+ m_xPageNumBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl));
+ m_xKeepParaBox->connect_toggled(LINK(this, SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl));
+
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+ if ( pSh )
+ {
+ SfxStyleSheetBasePool* pPool = pSh->GetStyleSheetPool();
+ SfxStyleSheetBase* pStyle = pPool->First(SfxStyleFamily::Page);
+ OUString aStdName;
+
+ while( pStyle )
+ {
+ if ( aStdName.isEmpty() )
+ // first style == standard style
+ aStdName = pStyle->GetName();
+ m_xApplyCollBox->append_text(pStyle->GetName());
+ pStyle = pPool->Next();
+ }
+ nStdPos = m_xApplyCollBox->find_text(aStdName);
+ }
+
+ sal_uInt16 nHtmlMode = GetHtmlMode_Impl( rAttr );
+ if ( !(nHtmlMode & HTMLMODE_ON) )
+ return;
+
+ bHtmlMode = true;
+ m_xHyphenBox->set_sensitive(false);
+ m_xHyphenNoCapsBox->set_sensitive(false);
+ m_xBeforeText->set_sensitive(false);
+ m_xExtHyphenBeforeBox->set_sensitive(false);
+ m_xAfterText->set_sensitive(false);
+ m_xExtHyphenAfterBox->set_sensitive(false);
+ m_xMaxHyphenLabel->set_sensitive(false);
+ m_xMaxHyphenEdit->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ // no column break in HTML
+ m_xBreakTypeLB->remove(1);
+}
+
+SvxExtParagraphTabPage::~SvxExtParagraphTabPage()
+{
+}
+
+void SvxExtParagraphTabPage::PageBreakHdl()
+{
+ switch (m_xPageBreakBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xBreakTypeFT->set_sensitive(true);
+ m_xBreakTypeLB->set_sensitive(true);
+ m_xBreakPositionFT->set_sensitive(true);
+ m_xBreakPositionLB->set_sensitive(true);
+
+ if (0 == m_xBreakTypeLB->get_active() && 0 == m_xBreakPositionLB->get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = TRISTATE_TRUE == m_xApplyCollBtn->get_state() &&
+ m_xApplyCollBox->get_count();
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if(!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ break;
+
+ case TRISTATE_FALSE:
+ case TRISTATE_INDET:
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ m_xBreakTypeFT->set_sensitive(false);
+ m_xBreakTypeLB->set_sensitive(false);
+ m_xBreakPositionFT->set_sensitive(false);
+ m_xBreakPositionLB->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aPageBreakState.ButtonToggled(rToggle);
+ PageBreakHdl();
+}
+
+void SvxExtParagraphTabPage::KeepTogetherHdl()
+{
+ bool bEnable = m_xKeepTogetherBox->get_state() == TRISTATE_FALSE;
+ m_xWidowBox->set_sensitive(bEnable);
+ m_xOrphanBox->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, KeepTogetherHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aKeepTogetherState.ButtonToggled(rToggle);
+ KeepTogetherHdl();
+}
+
+void SvxExtParagraphTabPage::WidowHdl()
+{
+ switch (m_xWidowBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xWidowRowNo->set_sensitive(true);
+ m_xWidowRowLabel->set_sensitive(true);
+ m_xKeepTogetherBox->set_sensitive(false);
+ break;
+ case TRISTATE_FALSE:
+ if (m_xOrphanBox->get_state() == TRISTATE_FALSE)
+ m_xKeepTogetherBox->set_sensitive(true);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xWidowRowNo->set_sensitive(false);
+ m_xWidowRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, WidowHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aWidowState.ButtonToggled(rToggle);
+ WidowHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, OrphanHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aOrphanState.ButtonToggled(rToggle);
+ OrphanHdl();
+}
+
+void SvxExtParagraphTabPage::OrphanHdl()
+{
+ switch (m_xOrphanBox->get_state())
+ {
+ case TRISTATE_TRUE:
+ m_xOrphanRowNo->set_sensitive(true);
+ m_xOrphanRowLabel->set_sensitive(true);
+ m_xKeepTogetherBox->set_sensitive(false);
+ break;
+
+ case TRISTATE_FALSE:
+ if (m_xWidowBox->get_state() == TRISTATE_FALSE)
+ m_xKeepTogetherBox->set_sensitive(true);
+ [[fallthrough]];
+ case TRISTATE_INDET:
+ m_xOrphanRowNo->set_sensitive(false);
+ m_xOrphanRowLabel->set_sensitive(false);
+ break;
+ }
+}
+
+void SvxExtParagraphTabPage::HyphenClickHdl()
+{
+ bool bEnable = m_xHyphenBox->get_state() == TRISTATE_TRUE;
+ m_xHyphenNoCapsBox->set_sensitive(bEnable);
+ m_xBeforeText->set_sensitive(bEnable);
+ m_xExtHyphenBeforeBox->set_sensitive(bEnable);
+ m_xAfterText->set_sensitive(bEnable);
+ m_xExtHyphenAfterBox->set_sensitive(bEnable);
+ m_xMaxHyphenLabel->set_sensitive(bEnable);
+ m_xMaxHyphenEdit->set_sensitive(bEnable);
+ m_xHyphenBox->set_state(bEnable ? TRISTATE_TRUE : TRISTATE_FALSE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, HyphenClickHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aHyphenState.ButtonToggled(rToggle);
+ HyphenClickHdl();
+}
+
+void SvxExtParagraphTabPage::ApplyCollClickHdl()
+{
+ bool bEnable = false;
+ if (m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count())
+ {
+ bEnable = true;
+ m_xApplyCollBox->set_active(nStdPos);
+ }
+ else
+ {
+ m_xApplyCollBox->set_active(-1);
+ }
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, ApplyCollClickHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aApplyCollState.ButtonToggled(rToggle);
+ ApplyCollClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakPosHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ if (0 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_sensitive(true);
+
+ bool bEnable = m_xApplyCollBtn->get_state() == TRISTATE_TRUE && m_xApplyCollBox->get_count();
+
+ m_xApplyCollBox->set_sensitive(bEnable);
+ if (!bHtmlMode)
+ {
+ m_xPageNumBox->set_sensitive(bEnable);
+ m_xPagenumEdit->set_sensitive(bEnable && m_xPageNumBox->get_state() == TRISTATE_TRUE);
+ }
+ }
+ else if (1 == rListBox.get_active())
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageBreakTypeHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ //column break or break after
+ int nBreakPos = m_xBreakPositionLB->get_active();
+ if (rListBox.get_active() == 1 || 1 == nBreakPos)
+ {
+ m_xApplyCollBtn->set_state(TRISTATE_FALSE);
+ m_xApplyCollBtn->set_sensitive(false);
+ m_xApplyCollBox->set_sensitive(false);
+ m_xPageNumBox->set_sensitive(false);
+ m_xPagenumEdit->set_sensitive(false);
+ }
+ else
+ PageBreakPosHdl_Impl(*m_xBreakPositionLB);
+}
+
+void SvxExtParagraphTabPage::PageNumBoxClickHdl()
+{
+ m_xPagenumEdit->set_sensitive(m_xPageNumBox->get_state() == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, PageNumBoxClickHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aPageNumState.ButtonToggled(rToggle);
+ PageNumBoxClickHdl();
+}
+
+IMPL_LINK(SvxExtParagraphTabPage, KeepParaBoxClickHdl_Impl, weld::ToggleButton&, rToggle, void)
+{
+ aKeepParaState.ButtonToggled(rToggle);
+}
+
+void SvxExtParagraphTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxBoolItem* pDisablePageBreakItem = aSet.GetItem<SfxBoolItem>(SID_DISABLE_SVXEXTPARAGRAPHTABPAGE_PAGEBREAK, false);
+
+ if (pDisablePageBreakItem)
+ if ( pDisablePageBreakItem->GetValue())
+ DisablePageBreak();
+}
+
+SvxAsianTabPage::SvxAsianTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/asiantypography.ui", "AsianTypography", &rSet)
+ , m_xForbiddenRulesCB(m_xBuilder->weld_check_button("checkForbidList"))
+ , m_xHangingPunctCB(m_xBuilder->weld_check_button("checkHangPunct"))
+ , m_xScriptSpaceCB(m_xBuilder->weld_check_button("checkApplySpacing"))
+{
+}
+
+SvxAsianTabPage::~SvxAsianTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAsianTabPage>(pPage, pController, *rSet);
+}
+
+const sal_uInt16* SvxAsianTabPage::GetRanges()
+{
+ static const sal_uInt16 pRanges[] =
+ {
+ SID_ATTR_PARA_SCRIPTSPACE, SID_ATTR_PARA_FORBIDDEN_RULES,
+ 0
+ };
+ return pRanges;
+}
+
+bool SvxAsianTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bRet = false;
+ SfxItemPool* pPool = rSet->GetPool();
+ if (m_xScriptSpaceCB->get_sensitive() && m_xScriptSpaceCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_SCRIPTSPACE)).Clone()));
+ pNewItem->SetValue(m_xScriptSpaceCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xHangingPunctCB->get_sensitive() && m_xHangingPunctCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_HANGPUNCTUATION)).Clone()));
+ pNewItem->SetValue(m_xHangingPunctCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ if (m_xForbiddenRulesCB->get_sensitive() && m_xForbiddenRulesCB->get_state_changed_from_saved())
+ {
+ std::unique_ptr<SfxBoolItem> pNewItem(static_cast<SfxBoolItem*>(rSet->Get(
+ pPool->GetWhich(SID_ATTR_PARA_FORBIDDEN_RULES)).Clone()));
+ pNewItem->SetValue(m_xForbiddenRulesCB->get_active());
+ rSet->Put(std::move(pNewItem));
+ bRet = true;
+ }
+ return bRet;
+}
+
+static void lcl_SetBox(const SfxItemSet& rSet, sal_uInt16 nSlotId, weld::CheckButton& rBox)
+{
+ sal_uInt16 _nWhich = rSet.GetPool()->GetWhich(nSlotId);
+ SfxItemState eState = rSet.GetItemState(_nWhich);
+ if( eState == SfxItemState::UNKNOWN || eState == SfxItemState::DISABLED )
+ rBox.set_sensitive(false);
+ else if(eState >= SfxItemState::DEFAULT)
+ rBox.set_active(static_cast<const SfxBoolItem&>(rSet.Get(_nWhich)).GetValue());
+ else
+ rBox.set_state(TRISTATE_INDET);
+ rBox.save_state();
+}
+
+void SvxAsianTabPage::Reset( const SfxItemSet* rSet )
+{
+ lcl_SetBox(*rSet, SID_ATTR_PARA_FORBIDDEN_RULES, *m_xForbiddenRulesCB );
+ lcl_SetBox(*rSet, SID_ATTR_PARA_HANGPUNCTUATION, *m_xHangingPunctCB );
+
+ //character distance not yet available
+ lcl_SetBox(*rSet, SID_ATTR_PARA_SCRIPTSPACE, *m_xScriptSpaceCB );
+}
+
+void SvxAsianTabPage::ChangesApplied()
+{
+ m_xForbiddenRulesCB->save_state();
+ m_xHangingPunctCB->save_state();
+ m_xScriptSpaceCB->save_state();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/swpossizetabpage.cxx b/cui/source/tabpages/swpossizetabpage.cxx
new file mode 100644
index 000000000..93644e7c3
--- /dev/null
+++ b/cui/source/tabpages/swpossizetabpage.cxx
@@ -0,0 +1,1891 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <cstddef>
+#include <swpossizetabpage.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/intitem.hxx>
+#include <svx/swframevalidation.hxx>
+#include <sfx2/htmlmode.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/swframeposstrings.hxx>
+#include <svx/rectenum.hxx>
+#include <sal/macros.h>
+#include <com/sun/star/text/HoriOrientation.hpp>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <com/sun/star/text/RelOrientation.hpp>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+
+using namespace ::com::sun::star::text;
+
+namespace {
+
+enum class LB;
+
+}
+
+struct FrmMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ short nAlign;
+ LB nLBRelations;
+};
+
+namespace {
+
+struct RelationMap
+{
+ SvxSwFramePosString::StringId eStrId;
+ SvxSwFramePosString::StringId eMirrorStrId;
+ LB nLBRelation;
+ short nRelation;
+};
+struct StringIdPair_Impl
+{
+ SvxSwFramePosString::StringId eHori;
+ SvxSwFramePosString::StringId eVert;
+};
+
+enum class LB {
+ NONE = 0x000000,
+ Frame = 0x000001, // paragraph text area
+ PrintArea = 0x000002, // paragraph text area + indents
+ VertFrame = 0x000004, // vertical paragraph text area
+ VertPrintArea = 0x000008, // vertical paragraph text area + indents
+ RelFrameLeft = 0x000010, // left paragraph margin
+ RelFrameRight = 0x000020, // right paragraph margin
+
+ RelPageLeft = 0x000040, // left page margin
+ RelPageRight = 0x000080, // right page margin
+ RelPageFrame = 0x000100, // complete page
+ RelPagePrintArea = 0x000200, // text area of page
+
+ FlyRelPageLeft = 0x000400, // left frame margin
+ FlyRelPageRight = 0x000800, // right frame margin
+ FlyRelPageFrame = 0x001000, // complete frame
+ FlyRelPagePrintArea = 0x002000, // frame interior
+
+ RelBase = 0x004000, // as char, relative to baseline
+ RelChar = 0x008000, // as char, relative to character
+ RelRow = 0x010000, // as char, relative to line
+
+// #i22305#
+ FlyVertFrame = 0x020000, // vertical entire frame
+ FlyVertPrintArea = 0x040000, // vertical frame text area
+
+// #i22341#
+ VertLine = 0x080000, // vertical text line
+
+ RelPagePrintAreaBottom = 0x100000, // bottom of text area of page
+
+ LAST = 0x200000
+};
+
+}
+
+namespace o3tl {
+ template<> struct typed_flags<LB> : is_typed_flags<LB, 0x3fffff> {};
+}
+
+static RelationMap const aRelationMap[] =
+{
+ {SvxSwFramePosString::FRAME, SvxSwFramePosString::FRAME, LB::Frame, RelOrientation::FRAME},
+ {SvxSwFramePosString::PRTAREA, SvxSwFramePosString::PRTAREA, LB::PrintArea, RelOrientation::PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::MIR_REL_PG_LEFT, LB::RelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::MIR_REL_PG_RIGHT, LB::RelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::MIR_REL_FRM_LEFT, LB::RelFrameLeft, RelOrientation::FRAME_LEFT},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::MIR_REL_FRM_RIGHT, LB::RelFrameRight, RelOrientation::FRAME_RIGHT},
+ {SvxSwFramePosString::REL_PG_FRAME, SvxSwFramePosString::REL_PG_FRAME, LB::RelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::REL_PG_PRTAREA,SvxSwFramePosString::REL_PG_PRTAREA, LB::RelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+ {SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM,SvxSwFramePosString::REL_PG_PRTAREA_BOTTOM, LB::RelPagePrintAreaBottom, RelOrientation::PAGE_PRINT_AREA_BOTTOM},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::CHAR},
+
+ {SvxSwFramePosString::FLY_REL_PG_LEFT, SvxSwFramePosString::FLY_MIR_REL_PG_LEFT, LB::FlyRelPageLeft, RelOrientation::PAGE_LEFT},
+ {SvxSwFramePosString::FLY_REL_PG_RIGHT, SvxSwFramePosString::FLY_MIR_REL_PG_RIGHT, LB::FlyRelPageRight, RelOrientation::PAGE_RIGHT},
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyRelPageFrame, RelOrientation::PAGE_FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyRelPagePrintArea, RelOrientation::PAGE_PRINT_AREA},
+
+ {SvxSwFramePosString::REL_BORDER, SvxSwFramePosString::REL_BORDER, LB::VertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_PRTAREA, SvxSwFramePosString::REL_PRTAREA, LB::VertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22305#
+ {SvxSwFramePosString::FLY_REL_PG_FRAME, SvxSwFramePosString::FLY_REL_PG_FRAME, LB::FlyVertFrame, RelOrientation::FRAME},
+ {SvxSwFramePosString::FLY_REL_PG_PRTAREA, SvxSwFramePosString::FLY_REL_PG_PRTAREA, LB::FlyVertPrintArea, RelOrientation::PRINT_AREA},
+
+ // #i22341#
+ {SvxSwFramePosString::REL_LINE, SvxSwFramePosString::REL_LINE, LB::VertLine, RelOrientation::TEXT_LINE}
+};
+
+static RelationMap const aAsCharRelationMap[] =
+{
+ {SvxSwFramePosString::REL_BASE, SvxSwFramePosString::REL_BASE, LB::RelBase, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_CHAR, SvxSwFramePosString::REL_CHAR, LB::RelChar, RelOrientation::FRAME},
+ {SvxSwFramePosString::REL_ROW, SvxSwFramePosString::REL_ROW, LB::RelRow, RelOrientation::FRAME}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at page
+ --------------------------------------------------------------------*/
+
+static constexpr auto HORI_PAGE_REL = LB::RelPageFrame|LB::RelPagePrintArea|LB::RelPageLeft|
+ LB::RelPageRight;
+
+static FrmMap const aHPageMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PAGE_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PAGE_REL},
+ {SvxSwFramePosString::CENTER_HORI,SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PAGE_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PAGE_REL}
+};
+
+static FrmMap const aHPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+#define VERT_PAGE_REL (LB::RelPageFrame|LB::RelPagePrintArea)
+
+static FrmMap const aVPageMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PAGE_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PAGE_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PAGE_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PAGE_REL}
+};
+
+static FrmMap const aVPageHtmlMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::RelPageFrame}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at frame
+ --------------------------------------------------------------------*/
+
+static constexpr auto HORI_FRAME_REL = LB::FlyRelPageFrame|LB::FlyRelPagePrintArea|
+ LB::FlyRelPageLeft|LB::FlyRelPageRight;
+
+static FrmMap const aHFrameMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_FRAME_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_FRAME_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_FRAME_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_FRAME_REL}
+};
+
+static FrmMap const aHFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::FlyRelPageFrame},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::FlyRelPageFrame}
+};
+
+// #i18732# - own vertical alignment map for to frame anchored objects
+// #i22305#
+#define VERT_FRAME_REL (LB::VertFrame|LB::FlyVertPrintArea)
+
+static FrmMap const aVFrameMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_FRAME_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_FRAME_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_FRAME_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_FRAME_REL}
+};
+
+static FrmMap const aVFlyHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::FlyVertFrame},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::FlyVertFrame}
+};
+
+static FrmMap const aVMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, LB::NONE}
+};
+static FrmMap const aHMultiSelectionMap[] =
+{
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::FROMLEFT, HoriOrientation::NONE, LB::NONE}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at paragraph
+ --------------------------------------------------------------------*/
+
+static constexpr auto HORI_PARA_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight;
+
+static FrmMap const aHParaMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_PARA_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_PARA_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_PARA_REL}
+};
+
+#define HTML_HORI_PARA_REL (LB::Frame|LB::PrintArea)
+
+static FrmMap const aHParaHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+static FrmMap const aHParaHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HTML_HORI_PARA_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HTML_HORI_PARA_REL}
+};
+
+
+static constexpr auto VERT_PARA_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea;
+
+static FrmMap const aVParaMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_PARA_REL},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_PARA_REL},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_PARA_REL},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_PARA_REL|LB::RelPagePrintAreaBottom}
+};
+
+static FrmMap const aVParaHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::VertPrintArea}
+};
+
+/*--------------------------------------------------------------------
+ Anchored at character
+ --------------------------------------------------------------------*/
+
+static constexpr auto HORI_CHAR_REL = LB::Frame|LB::PrintArea|LB::RelPageLeft|LB::RelPageRight|
+ LB::RelPageFrame|LB::RelPagePrintArea|LB::RelFrameLeft|
+ LB::RelFrameRight|LB::RelChar;
+
+static FrmMap aHCharMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, HORI_CHAR_REL},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_HORI, HoriOrientation::CENTER, HORI_CHAR_REL},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, HORI_CHAR_REL}
+};
+
+#define HTML_HORI_CHAR_REL (LB::Frame|LB::PrintArea|LB::RelChar)
+
+static FrmMap aHCharHtmlMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::LEFT, HoriOrientation::LEFT, HTML_HORI_CHAR_REL},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::RIGHT, HoriOrientation::RIGHT, HTML_HORI_CHAR_REL}
+};
+
+static FrmMap aHCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::MIR_LEFT, HoriOrientation::LEFT, LB::PrintArea|LB::RelChar},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::MIR_RIGHT, HoriOrientation::RIGHT, LB::PrintArea},
+ {SvxSwFramePosString::FROMLEFT, SvxSwFramePosString::MIR_FROMLEFT, HoriOrientation::NONE, LB::RelPageFrame}
+};
+
+// #i18732# - allow vertical alignment at page areas
+// #i22341# - handle <LB::RelChar> on its own
+static constexpr auto VERT_CHAR_REL = LB::VertFrame|LB::VertPrintArea|
+ LB::RelPageFrame|LB::RelPagePrintArea;
+
+static FrmMap aVCharMap[] =
+{
+ // #i22341#
+ // introduce mappings for new vertical alignment at top of line <LB::VertLine>
+ // and correct mapping for vertical alignment at character for position <FROM_BOTTOM>
+ // Note: because of these adjustments the map becomes ambiguous in its values
+ // <eStrId>/<eMirrorStrId> and <nAlign>. These ambiguities are considered
+ // in the methods <SwFrmPage::FillRelLB(..)>, <SwFrmPage::GetAlignment(..)>
+ // and <SwFrmPage::FillPosLB(..)>
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, VERT_CHAR_REL|LB::RelChar},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMTOP, VertOrientation::NONE, VERT_CHAR_REL|LB::RelPagePrintAreaBottom},
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelChar|LB::VertLine},
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::VertLine},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::VertLine},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::VertLine}
+};
+
+
+static FrmMap const aVCharHtmlMap[] =
+{
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+
+static FrmMap const aVCharHtmlAbsMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelChar},
+ {SvxSwFramePosString::BELOW, SvxSwFramePosString::BELOW, VertOrientation::CHAR_BOTTOM, LB::RelChar}
+};
+/*--------------------------------------------------------------------
+ anchored as character
+ --------------------------------------------------------------------*/
+
+static FrmMap const aVAsCharMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::BOTTOM, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::CHAR_BOTTOM, LB::RelChar},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CHAR_CENTER, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow},
+
+ {SvxSwFramePosString::FROMBOTTOM, SvxSwFramePosString::FROMBOTTOM, VertOrientation::NONE, LB::RelBase}
+};
+
+static FrmMap const aVAsCharHtmlMap[] =
+{
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::TOP, LB::RelBase},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::CENTER, LB::RelBase},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::CHAR_TOP, LB::RelChar},
+
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::TOP, VertOrientation::LINE_TOP, LB::RelRow},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::BOTTOM, VertOrientation::LINE_BOTTOM, LB::RelRow},
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_VERT, VertOrientation::LINE_CENTER, LB::RelRow}
+};
+
+static std::size_t lcl_GetFrmMapCount(const FrmMap* pMap)
+{
+ if( pMap )
+ {
+ if( pMap == aVParaHtmlMap )
+ return SAL_N_ELEMENTS(aVParaHtmlMap);
+ if( pMap == aVAsCharHtmlMap )
+ return SAL_N_ELEMENTS( aVAsCharHtmlMap );
+ if( pMap == aHParaHtmlMap )
+ return SAL_N_ELEMENTS( aHParaHtmlMap );
+ if( pMap == aHParaHtmlAbsMap )
+ return SAL_N_ELEMENTS( aHParaHtmlAbsMap );
+ if( pMap == aVPageMap )
+ return SAL_N_ELEMENTS( aVPageMap );
+ if( pMap == aVPageHtmlMap )
+ return SAL_N_ELEMENTS( aVPageHtmlMap );
+ if( pMap == aVAsCharMap )
+ return SAL_N_ELEMENTS( aVAsCharMap );
+ if( pMap == aVParaMap )
+ return SAL_N_ELEMENTS( aVParaMap );
+ if( pMap == aHParaMap )
+ return SAL_N_ELEMENTS( aHParaMap );
+ if( pMap == aHFrameMap )
+ return SAL_N_ELEMENTS( aHFrameMap );
+ if( pMap == aVFrameMap )
+ return SAL_N_ELEMENTS( aVFrameMap );
+ if( pMap == aHCharMap )
+ return SAL_N_ELEMENTS( aHCharMap );
+ if( pMap == aHCharHtmlMap )
+ return SAL_N_ELEMENTS( aHCharHtmlMap );
+ if( pMap == aHCharHtmlAbsMap )
+ return SAL_N_ELEMENTS( aHCharHtmlAbsMap );
+ if( pMap == aVCharMap )
+ return SAL_N_ELEMENTS( aVCharMap );
+ if( pMap == aVCharHtmlMap )
+ return SAL_N_ELEMENTS( aVCharHtmlMap );
+ if( pMap == aVCharHtmlAbsMap )
+ return SAL_N_ELEMENTS( aVCharHtmlAbsMap );
+ if( pMap == aHPageHtmlMap )
+ return SAL_N_ELEMENTS( aHPageHtmlMap );
+ if( pMap == aHFlyHtmlMap )
+ return SAL_N_ELEMENTS( aHFlyHtmlMap );
+ if( pMap == aVFlyHtmlMap )
+ return SAL_N_ELEMENTS( aVFlyHtmlMap );
+ if( pMap == aVMultiSelectionMap )
+ return SAL_N_ELEMENTS( aVMultiSelectionMap );
+ if( pMap == aHMultiSelectionMap )
+ return SAL_N_ELEMENTS( aHMultiSelectionMap );
+ return SAL_N_ELEMENTS(aHPageMap);
+ }
+ return 0;
+}
+
+static SvxSwFramePosString::StringId lcl_ChangeResIdToVerticalOrRTL(
+ SvxSwFramePosString::StringId eStringId, bool bVertical, bool bRTL)
+{
+ //special handling of STR_FROMLEFT
+ if(SvxSwFramePosString::FROMLEFT == eStringId)
+ {
+ eStringId = bVertical ?
+ bRTL ? SvxSwFramePosString::FROMBOTTOM : SvxSwFramePosString::FROMTOP :
+ bRTL ? SvxSwFramePosString::FROMRIGHT : SvxSwFramePosString::FROMLEFT;
+ return eStringId;
+ }
+ if(bVertical)
+ {
+ //exchange horizontal strings with vertical strings and vice versa
+ static const StringIdPair_Impl aHoriIds[] =
+ {
+ {SvxSwFramePosString::LEFT, SvxSwFramePosString::TOP},
+ {SvxSwFramePosString::RIGHT, SvxSwFramePosString::BOTTOM},
+ {SvxSwFramePosString::CENTER_HORI, SvxSwFramePosString::CENTER_VERT},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT},
+ {SvxSwFramePosString::REL_PG_LEFT, SvxSwFramePosString::REL_PG_TOP},
+ {SvxSwFramePosString::REL_PG_RIGHT, SvxSwFramePosString::REL_PG_BOTTOM} ,
+ {SvxSwFramePosString::REL_FRM_LEFT, SvxSwFramePosString::REL_FRM_TOP},
+ {SvxSwFramePosString::REL_FRM_RIGHT, SvxSwFramePosString::REL_FRM_BOTTOM}
+ };
+ static const StringIdPair_Impl aVertIds[] =
+ {
+ {SvxSwFramePosString::TOP, SvxSwFramePosString::RIGHT},
+ {SvxSwFramePosString::BOTTOM, SvxSwFramePosString::LEFT },
+ {SvxSwFramePosString::CENTER_VERT, SvxSwFramePosString::CENTER_HORI},
+ {SvxSwFramePosString::FROMTOP, SvxSwFramePosString::FROMRIGHT },
+ {SvxSwFramePosString::REL_PG_TOP, SvxSwFramePosString::REL_PG_LEFT },
+ {SvxSwFramePosString::REL_PG_BOTTOM, SvxSwFramePosString::REL_PG_RIGHT } ,
+ {SvxSwFramePosString::REL_FRM_TOP, SvxSwFramePosString::REL_FRM_LEFT },
+ {SvxSwFramePosString::REL_FRM_BOTTOM, SvxSwFramePosString::REL_FRM_RIGHT }
+ };
+ for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aHoriIds); ++nIndex)
+ {
+ if(aHoriIds[nIndex].eHori == eStringId)
+ {
+ eStringId = aHoriIds[nIndex].eVert;
+ return eStringId;
+ }
+ }
+ for(size_t nIndex = 0; nIndex < SAL_N_ELEMENTS(aVertIds); ++nIndex)
+ {
+ if(aVertIds[nIndex].eHori == eStringId)
+ {
+ eStringId = aVertIds[nIndex].eVert;
+ break;
+ }
+ }
+ }
+ return eStringId;
+}
+// #i22341# - helper method in order to determine all possible
+// listbox relations in a relation map for a given relation
+static LB lcl_GetLBRelationsForRelations( const sal_uInt16 _nRel )
+{
+ LB nLBRelations = LB::NONE;
+
+ for (RelationMap const & nRelMapPos : aRelationMap)
+ {
+ if ( nRelMapPos.nRelation == _nRel )
+ {
+ nLBRelations |= nRelMapPos.nLBRelation;
+ }
+ }
+
+ return nLBRelations;
+}
+
+// #i22341# - helper method on order to determine all possible
+// listbox relations in a relation map for a given string ID
+static LB lcl_GetLBRelationsForStrID(const FrmMap* _pMap,
+ const SvxSwFramePosString::StringId _eStrId,
+ const bool _bUseMirrorStr )
+{
+ LB nLBRelations = LB::NONE;
+
+ std::size_t nRelMapSize = lcl_GetFrmMapCount( _pMap );
+ for ( std::size_t nRelMapPos = 0; nRelMapPos < nRelMapSize; ++nRelMapPos )
+ {
+ if ( ( !_bUseMirrorStr && _pMap[nRelMapPos].eStrId == _eStrId ) ||
+ ( _bUseMirrorStr && _pMap[nRelMapPos].eMirrorStrId == _eStrId ) )
+ {
+ nLBRelations |= _pMap[nRelMapPos].nLBRelations;
+ }
+ }
+
+ return nLBRelations;
+}
+
+SvxSwPosSizeTabPage::SvxSwPosSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/swpossizepage.ui", "SwPosSizePage", &rInAttrs)
+ , m_pVMap(nullptr)
+ , m_pHMap(nullptr)
+ , m_pSdrView(nullptr)
+ , m_nOldH(HoriOrientation::CENTER)
+ , m_nOldHRel(RelOrientation::FRAME)
+ , m_nOldV(VertOrientation::TOP)
+ , m_nOldVRel(RelOrientation::PRINT_AREA)
+ , m_fWidthHeightRatio(1.0)
+ , m_bHtmlMode(false)
+ , m_bIsVerticalFrame(false)
+ , m_bPositioningDisabled(false)
+ , m_bIsMultiSelection(false)
+ , m_bIsInRightToLeft(false)
+ , m_nProtectSizeState(TRISTATE_FALSE)
+ , m_xWidthMF(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM))
+ , m_xHeightMF(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM))
+ , m_xKeepRatioCB(m_xBuilder->weld_check_button("ratio"))
+ , m_xToPageRB(m_xBuilder->weld_radio_button("topage"))
+ , m_xToParaRB(m_xBuilder->weld_radio_button("topara"))
+ , m_xToCharRB(m_xBuilder->weld_radio_button("tochar"))
+ , m_xAsCharRB(m_xBuilder->weld_radio_button("aschar"))
+ , m_xToFrameRB(m_xBuilder->weld_radio_button("toframe"))
+ , m_xPositionCB(m_xBuilder->weld_check_button("pos"))
+ , m_xSizeCB(m_xBuilder->weld_check_button("size"))
+ , m_xPosFrame(m_xBuilder->weld_widget("posframe"))
+ , m_xHoriFT(m_xBuilder->weld_label("horiposft"))
+ , m_xHoriLB(m_xBuilder->weld_combo_box("horipos"))
+ , m_xHoriByFT(m_xBuilder->weld_label("horibyft"))
+ , m_xHoriByMF(m_xBuilder->weld_metric_spin_button("byhori", FieldUnit::CM))
+ , m_xHoriToFT(m_xBuilder->weld_label("horitoft"))
+ , m_xHoriToLB(m_xBuilder->weld_combo_box("horianchor"))
+ , m_xHoriMirrorCB(m_xBuilder->weld_check_button("mirror"))
+ , m_xVertFT(m_xBuilder->weld_label("vertposft"))
+ , m_xVertLB(m_xBuilder->weld_combo_box("vertpos"))
+ , m_xVertByFT(m_xBuilder->weld_label("vertbyft"))
+ , m_xVertByMF(m_xBuilder->weld_metric_spin_button("byvert", FieldUnit::CM))
+ , m_xVertToFT(m_xBuilder->weld_label("verttoft"))
+ , m_xVertToLB(m_xBuilder->weld_combo_box("vertanchor"))
+ , m_xFollowCB(m_xBuilder->weld_check_button("followtextflow"))
+ , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
+{
+ setOptimalFrmWidth();
+ setOptimalRelWidth();
+
+ FieldUnit eDlgUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit(*m_xHoriByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xVertByMF, eDlgUnit, true);
+ SetFieldUnit(*m_xWidthMF , eDlgUnit, true);
+ SetFieldUnit(*m_xHeightMF, eDlgUnit, true);
+
+ SetExchangeSupport();
+
+ Link<weld::Widget&,void> aLk3 = LINK(this, SvxSwPosSizeTabPage, RangeModifyHdl);
+ m_xWidthMF->connect_focus_out(aLk3);
+ m_xHeightMF->connect_focus_out(aLk3);
+ m_xHoriByMF->connect_focus_out(aLk3);
+ m_xVertByMF->connect_focus_out(aLk3);
+ m_xFollowCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, RangeModifyClickHdl));
+
+ Link<weld::MetricSpinButton&,void> aLk = LINK(this, SvxSwPosSizeTabPage, ModifyHdl);
+ m_xWidthMF->connect_value_changed( aLk );
+ m_xHeightMF->connect_value_changed( aLk );
+ m_xHoriByMF->connect_value_changed( aLk );
+ m_xVertByMF->connect_value_changed( aLk );
+
+ Link<weld::ToggleButton&,void> aLk2 = LINK(this, SvxSwPosSizeTabPage, AnchorTypeHdl);
+ m_xToPageRB->connect_toggled( aLk2 );
+ m_xToParaRB->connect_toggled( aLk2 );
+ m_xToCharRB->connect_toggled( aLk2 );
+ m_xAsCharRB->connect_toggled( aLk2 );
+ m_xToFrameRB->connect_toggled( aLk2 );
+
+ m_xHoriLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+ m_xVertLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, PosHdl));
+
+ m_xHoriToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+ m_xVertToLB->connect_changed(LINK(this, SvxSwPosSizeTabPage, RelHdl));
+
+ m_xHoriMirrorCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, MirrorHdl));
+ m_xPositionCB->connect_toggled(LINK(this, SvxSwPosSizeTabPage, ProtectHdl));
+}
+
+SvxSwPosSizeTabPage::~SvxSwPosSizeTabPage()
+{
+ m_xWidthMF.reset();
+ m_xHeightMF.reset();
+ m_xHoriByMF.reset();
+ m_xVertByMF.reset();
+}
+
+namespace
+{
+ struct FrmMaps
+ {
+ FrmMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalFrmWidth()
+{
+ static const FrmMaps aMaps[] = {
+ { aHPageMap, SAL_N_ELEMENTS(aHPageMap) },
+ { aHPageHtmlMap, SAL_N_ELEMENTS(aHPageHtmlMap) },
+ { aVPageMap, SAL_N_ELEMENTS(aVPageMap) },
+ { aVPageHtmlMap, SAL_N_ELEMENTS(aVPageHtmlMap) },
+ { aHFrameMap, SAL_N_ELEMENTS(aHFrameMap) },
+ { aHFlyHtmlMap, SAL_N_ELEMENTS(aHFlyHtmlMap) },
+ { aVFrameMap, SAL_N_ELEMENTS(aVFrameMap) },
+ { aVFlyHtmlMap, SAL_N_ELEMENTS(aVFlyHtmlMap) },
+ { aHParaMap, SAL_N_ELEMENTS(aHParaMap) },
+ { aHParaHtmlMap, SAL_N_ELEMENTS(aHParaHtmlMap) },
+ { aHParaHtmlAbsMap, SAL_N_ELEMENTS(aHParaHtmlAbsMap) },
+ { aVParaMap, SAL_N_ELEMENTS(aVParaMap) },
+ { aVParaHtmlMap, SAL_N_ELEMENTS(aVParaHtmlMap) },
+ { aHCharMap, SAL_N_ELEMENTS(aHCharMap) },
+ { aHCharHtmlMap, SAL_N_ELEMENTS(aHCharHtmlMap) },
+ { aHCharHtmlAbsMap, SAL_N_ELEMENTS(aHCharHtmlAbsMap) },
+ { aVCharMap, SAL_N_ELEMENTS(aVCharMap) },
+ { aVCharHtmlMap, SAL_N_ELEMENTS(aVCharHtmlMap) },
+ { aVCharHtmlAbsMap, SAL_N_ELEMENTS(aVCharHtmlAbsMap) },
+ { aVAsCharMap, SAL_N_ELEMENTS(aVAsCharMap) },
+ { aVAsCharHtmlMap, SAL_N_ELEMENTS(aVAsCharHtmlMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aFrames;
+ for (const FrmMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aFrames.push_back(aMap.pMap[j].eStrId);
+ aFrames.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aFrames.begin(), aFrames.end());
+ aFrames.erase(std::unique(aFrames.begin(), aFrames.end()), aFrames.end());
+
+ for (auto const& frame : aFrames)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(frame));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+namespace
+{
+ struct RelationMaps
+ {
+ RelationMap const *pMap;
+ size_t nCount;
+ };
+}
+
+void SvxSwPosSizeTabPage::setOptimalRelWidth()
+{
+ static const RelationMaps aMaps[] = {
+ { aRelationMap, SAL_N_ELEMENTS(aRelationMap) },
+ { aAsCharRelationMap, SAL_N_ELEMENTS(aAsCharRelationMap) }
+ };
+
+ std::vector<SvxSwFramePosString::StringId> aRels;
+ for (const RelationMaps& aMap : aMaps)
+ {
+ for (size_t j = 0; j < aMap.nCount; ++j)
+ {
+ aRels.push_back(aMap.pMap[j].eStrId);
+ aRels.push_back(aMap.pMap[j].eMirrorStrId);
+ }
+ }
+
+ std::sort(aRels.begin(), aRels.end());
+ aRels.erase(std::unique(aRels.begin(), aRels.end()), aRels.end());
+
+ for (auto const& elem : aRels)
+ {
+ m_xHoriLB->append_text(SvxSwFramePosString::GetString(elem));
+ }
+
+ Size aBiggest(m_xHoriLB->get_preferred_size());
+ m_xHoriLB->set_size_request(aBiggest.Width(), -1);
+ m_xVertLB->set_size_request(aBiggest.Width(), -1);
+ m_xHoriLB->clear();
+}
+
+std::unique_ptr<SfxTabPage> SvxSwPosSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxSwPosSizeTabPage>(pPage, pController, *rSet);
+}
+
+const sal_uInt16* SvxSwPosSizeTabPage::GetRanges()
+{
+ static const sal_uInt16 pSwPosRanges[] =
+ {
+ SID_ATTR_TRANSFORM_POS_X,
+ SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_ANCHOR,
+ SID_ATTR_TRANSFORM_VERT_ORIENT,
+ SID_ATTR_TRANSFORM_WIDTH,
+ SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH,
+ SID_ATTR_TRANSFORM_VERT_ORIENT,
+ SID_HTML_MODE,
+ SID_HTML_MODE,
+ SID_SW_FOLLOW_TEXT_FLOW,
+ SID_SW_FOLLOW_TEXT_FLOW,
+ SID_ATTR_TRANSFORM_HORI_POSITION,
+ SID_ATTR_TRANSFORM_VERT_POSITION,
+ 0
+ };
+ return pSwPosRanges;
+}
+
+bool SvxSwPosSizeTabPage::FillItemSet( SfxItemSet* rSet)
+{
+ bool bAnchorChanged = false;
+ RndStdIds nAnchor = GetAnchorType(&bAnchorChanged);
+ bool bModified = false;
+ if(bAnchorChanged)
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_ANCHOR, static_cast<sal_Int16>(nAnchor)));
+ bModified = true;
+ }
+ if (m_xPositionCB->get_state_changed_from_saved())
+ {
+ if (m_xPositionCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ else
+ rSet->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
+ m_xPositionCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ if (m_xSizeCB->get_state_changed_from_saved())
+ {
+ if (m_xSizeCB->get_inconsistent())
+ rSet->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rSet->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
+ m_xSizeCB->get_state() == TRISTATE_TRUE ) );
+ bModified = true;
+ }
+
+ const SfxItemSet& rOldSet = GetItemSet();
+
+ if(!m_bPositioningDisabled)
+ {
+ //on multiple selections the positioning is set via SdrView
+ if (m_bIsMultiSelection)
+ {
+ if (m_xHoriByMF->get_value_changed_from_saved() || m_xVertByMF->get_value_changed_from_saved())
+ {
+ auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ // old rectangle with CoreUnit
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ nHoriByPos += m_aAnchorPos.X();
+ nVertByPos += m_aAnchorPos.Y();
+
+ rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_X ), nHoriByPos ) );
+ rSet->Put( SfxInt32Item( GetWhich( SID_ATTR_TRANSFORM_POS_Y ), nVertByPos ) );
+
+ bModified = true;
+ }
+ }
+ else
+ {
+ if ( m_pHMap )
+ {
+ const SfxInt16Item& rHoriOrient =
+ static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_ORIENT));
+ const SfxInt16Item& rHoriRelation =
+ static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_RELATION));
+ const SfxInt32Item& rHoriPosition =
+ static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_HORI_POSITION)) ;
+
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+ const auto nHoriByPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ if (
+ nAlign != rHoriOrient.GetValue() ||
+ nRel != rHoriRelation.GetValue() ||
+ (m_xHoriByMF->get_sensitive() && nHoriByPos != rHoriPosition.GetValue())
+ )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_HORI_RELATION, nRel));
+ if(m_xHoriByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_HORI_POSITION, nHoriByPos));
+ bModified = true;
+ }
+ }
+ if (m_xHoriMirrorCB->get_sensitive() && m_xHoriMirrorCB->get_state_changed_from_saved())
+ bModified |= nullptr != rSet->Put(SfxBoolItem(SID_ATTR_TRANSFORM_HORI_MIRROR, m_xHoriMirrorCB->get_active()));
+
+ if ( m_pVMap )
+ {
+ const SfxInt16Item& rVertOrient =
+ static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_ORIENT));
+ const SfxInt16Item& rVertRelation =
+ static_cast<const SfxInt16Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_RELATION));
+ const SfxInt32Item& rVertPosition =
+ static_cast<const SfxInt32Item&>(rOldSet.Get( SID_ATTR_TRANSFORM_VERT_POSITION));
+
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ short nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ short nRel = GetRelation(*m_xVertToLB);
+ // #i34055# - convert vertical position for
+ // as-character anchored objects
+ auto nVertByPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ if (GetAnchorType() == RndStdIds::FLY_AS_CHAR)
+ {
+ nVertByPos *= -1;
+ }
+ if ( nAlign != rVertOrient.GetValue() ||
+ nRel != rVertRelation.GetValue() ||
+ ( m_xVertByMF->get_sensitive() &&
+ nVertByPos != rVertPosition.GetValue() ) )
+ {
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_ORIENT, nAlign));
+ rSet->Put(SfxInt16Item(SID_ATTR_TRANSFORM_VERT_RELATION, nRel));
+ if(m_xVertByMF->get_sensitive())
+ rSet->Put(SfxInt32Item(SID_ATTR_TRANSFORM_VERT_POSITION, nVertByPos));
+ bModified = true;
+ }
+ }
+
+ // #i18732#
+ if (m_xFollowCB->get_state_changed_from_saved())
+ {
+ //Writer internal type - based on SfxBoolItem
+ const SfxPoolItem* pItem = GetItem( rOldSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ std::unique_ptr<SfxBoolItem> pFollow(static_cast<SfxBoolItem*>(pItem->Clone()));
+ pFollow->SetValue(m_xFollowCB->get_active());
+ bModified |= nullptr != rSet->Put(*pFollow);
+ }
+ }
+ }
+ }
+ if (m_xWidthMF->get_value_changed_from_saved() || m_xHeightMF->get_value_changed_from_saved())
+ {
+ sal_uInt32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_uInt32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), nWidth ) );
+ rSet->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), nHeight ) );
+ //this item is required by SdrEditView::SetGeoAttrToMarked()
+ rSet->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal_uInt16(RectPoint::LT) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxSwPosSizeTabPage::Reset( const SfxItemSet* rSet)
+{
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_ANCHOR );
+ bool bInvalidateAnchor = false;
+ RndStdIds nAnchorType = RndStdIds::FLY_AT_PARA;
+ if(pItem)
+ {
+ nAnchorType = static_cast<RndStdIds>(static_cast<const SfxInt16Item*>(pItem)->GetValue());
+ switch(nAnchorType)
+ {
+ case RndStdIds::FLY_AT_PAGE: m_xToPageRB->set_active(true); break;
+ case RndStdIds::FLY_AT_PARA: m_xToParaRB->set_active(true); break;
+ case RndStdIds::FLY_AT_CHAR: m_xToCharRB->set_active(true); break;
+ case RndStdIds::FLY_AS_CHAR: m_xAsCharRB->set_active(true); break;
+ case RndStdIds::FLY_AT_FLY: m_xToFrameRB->set_active(true); break;
+ default : bInvalidateAnchor = true;
+ }
+ m_xToPageRB->save_state();
+ m_xToParaRB->save_state();
+ m_xToCharRB->save_state();
+ m_xAsCharRB->save_state();
+ m_xToFrameRB->save_state();
+ }
+ if (bInvalidateAnchor)
+ {
+ m_xToPageRB->set_sensitive( false );
+ m_xToParaRB->set_sensitive( false );
+ m_xToCharRB->set_sensitive( false );
+ m_xAsCharRB->set_sensitive( false );
+ m_xToFrameRB->set_sensitive( false );
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if (pItem)
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xPositionCB->set_active(bProtected);
+ m_xSizeCB->set_sensitive(!bProtected);
+ }
+ else
+ {
+ m_xPositionCB->set_inconsistent(true);
+ }
+
+ m_xPositionCB->save_state();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+
+ if (pItem)
+ {
+ m_xSizeCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xSizeCB->set_inconsistent(true);
+ m_xSizeCB->save_state();
+
+ pItem = GetItem( *rSet, SID_HTML_MODE );
+ if(pItem)
+ {
+ m_bHtmlMode =
+ (static_cast<const SfxUInt16Item*>(pItem)->GetValue() & HTMLMODE_ON)
+ != 0;
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_VERTICAL_TEXT );
+ if(pItem && static_cast<const SfxBoolItem*>(pItem)->GetValue())
+ {
+ OUString sHLabel = m_xHoriFT->get_label();
+ m_xHoriFT->set_label(m_xVertFT->get_label());
+ m_xVertFT->set_label(sHLabel);
+ m_bIsVerticalFrame = true;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_IN_RTL_TEXT);
+ if(pItem)
+ m_bIsInRightToLeft = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+
+ pItem = GetItem( *rSet, SID_SW_FOLLOW_TEXT_FLOW);
+ if(pItem)
+ {
+ const bool bFollowTextFlow =
+ static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ m_xFollowCB->set_active(bFollowTextFlow);
+ }
+ m_xFollowCB->save_state();
+
+ if(m_bHtmlMode)
+ {
+ m_xHoriMirrorCB->hide();
+ m_xKeepRatioCB->set_sensitive(false);
+ // #i18732# - hide checkbox in HTML mode
+ m_xFollowCB->hide();
+ }
+ else
+ {
+ // #i18732# correct enable/disable of check box 'Mirror on..'
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable/disable check box 'Follow text flow'.
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() ||
+ m_xToCharRB->get_active());
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_WIDTH );
+ sal_Int32 nWidth = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ m_xWidthMF->save_value();
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HEIGHT );
+ sal_Int32 nHeight = std::max( pItem ? ( static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0, sal_uInt32(1) );
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ m_xHeightMF->save_value();
+ m_fWidthHeightRatio = double(nWidth) / double(nHeight);
+
+ if(m_bPositioningDisabled)
+ return;
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_ORIENT);
+ if(pItem)
+ {
+ short nHoriOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldH = nHoriOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_ORIENT);
+ if(pItem)
+ {
+ short nVertOrientation = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ m_nOldV = nVertOrientation;
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_RELATION);
+ if(pItem)
+ {
+ m_nOldHRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_RELATION);
+ if(pItem)
+ {
+ m_nOldVRel = static_cast< const SfxInt16Item*>(pItem)->GetValue();
+ }
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_MIRROR);
+ if(pItem)
+ m_xHoriMirrorCB->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ m_xHoriMirrorCB->save_state();
+
+ sal_Int32 nHoriPos = 0;
+ sal_Int32 nVertPos = 0;
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_HORI_POSITION);
+ if(pItem)
+ nHoriPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ pItem = GetItem( *rSet, SID_ATTR_TRANSFORM_VERT_POSITION);
+ if(pItem)
+ nVertPos = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+
+ InitPos(nAnchorType, m_nOldH, m_nOldHRel, m_nOldV, m_nOldVRel, nHoriPos, nVertPos);
+
+ m_xVertByMF->save_value();
+ m_xHoriByMF->save_value();
+ // #i18732#
+ m_xFollowCB->save_state();
+
+ RangeModifyHdl(m_xWidthMF->get_widget()); // initially set maximum values
+}
+
+DeactivateRC SvxSwPosSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
+ m_xPositionCB->get_active()));
+ _pSet->Put(SfxBoolItem(GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
+ m_xSizeCB->get_active()));
+ FillItemSet( _pSet );
+ }
+ return DeactivateRC::LeavePage;
+}
+
+void SvxSwPosSizeTabPage::EnableAnchorTypes(SvxAnchorIds nAnchorEnable)
+{
+ if (nAnchorEnable & SvxAnchorIds::Fly)
+ m_xToFrameRB->show();
+ if (!(nAnchorEnable & SvxAnchorIds::Page))
+ m_xToPageRB->set_sensitive(false);
+}
+
+RndStdIds SvxSwPosSizeTabPage::GetAnchorType(bool* pbHasChanged)
+{
+ RndStdIds nRet = RndStdIds::UNKNOWN;
+ weld::RadioButton* pCheckedButton = nullptr;
+ if(m_xToParaRB->get_sensitive())
+ {
+ if(m_xToPageRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PAGE;
+ pCheckedButton = m_xToPageRB.get();
+ }
+ else if(m_xToParaRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_PARA;
+ pCheckedButton = m_xToParaRB.get();
+ }
+ else if(m_xToCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_CHAR;
+ pCheckedButton = m_xToCharRB.get();
+ }
+ else if(m_xAsCharRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AS_CHAR;
+ pCheckedButton = m_xAsCharRB.get();
+ }
+ else if(m_xToFrameRB->get_active())
+ {
+ nRet = RndStdIds::FLY_AT_FLY;
+ pCheckedButton = m_xToFrameRB.get();
+ }
+ }
+ if(pbHasChanged)
+ {
+ if(pCheckedButton)
+ *pbHasChanged = pCheckedButton->get_state_changed_from_saved();
+ else
+ *pbHasChanged = false;
+ }
+ return nRet;
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyClickHdl, weld::ToggleButton&, void)
+{
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, RangeModifyHdl, weld::Widget&, void)
+{
+ if (m_bPositioningDisabled)
+ return;
+ SvxSwFrameValidation aVal;
+
+ aVal.nAnchorType = GetAnchorType();
+ aVal.bAutoHeight = false;
+ aVal.bMirror = m_xHoriMirrorCB->get_active();
+ // #i18732#
+ aVal.bFollowTextFlow = m_xFollowCB->get_active();
+
+ if ( m_pHMap )
+ {
+ // horizontal alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriToLB);
+ sal_uInt16 nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+
+ aVal.nHoriOrient = static_cast<short>(nAlign);
+ aVal.nHRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nHoriOrient = HoriOrientation::NONE;
+
+ if ( m_pVMap )
+ {
+ // vertical alignment
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ aVal.nVertOrient = static_cast<short>(nAlign);
+ aVal.nVRelOrient = static_cast<short>(nRel);
+ }
+ else
+ aVal.nVertOrient = VertOrientation::NONE;
+
+ const auto nAtHorzPosVal = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ const auto nAtVertPosVal = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+
+ aVal.nHPos = nAtHorzPosVal;
+ aVal.nVPos = nAtVertPosVal;
+
+ sal_Int32 nWidth = static_cast<sal_uInt32>(m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP)));
+ sal_Int32 nHeight = static_cast<sal_uInt32>(m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP)));
+ aVal.nWidth = nWidth;
+ aVal.nHeight = nHeight;
+
+ m_aValidateLink.Call(aVal);
+
+ // minimum width also for style
+ m_xHeightMF->set_min(m_xHeightMF->normalize(aVal.nMinHeight), FieldUnit::TWIP);
+ m_xWidthMF->set_min(m_xWidthMF->normalize(aVal.nMinWidth), FieldUnit::TWIP);
+
+ sal_Int32 nMaxWidth(aVal.nMaxWidth);
+ sal_Int32 nMaxHeight(aVal.nMaxHeight);
+
+ sal_Int64 nTmp = m_xHeightMF->normalize(nMaxHeight);
+ m_xHeightMF->set_max(nTmp, FieldUnit::TWIP);
+
+ nTmp = m_xWidthMF->normalize(nMaxWidth);
+ m_xWidthMF->set_max(nTmp, FieldUnit::TWIP);
+
+ m_xHoriByMF->set_range(m_xHoriByMF->normalize(aVal.nMinHPos),
+ m_xHoriByMF->normalize(aVal.nMaxHPos), FieldUnit::TWIP);
+ if ( aVal.nHPos != nAtHorzPosVal )
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(aVal.nHPos), FieldUnit::TWIP);
+
+ m_xVertByMF->set_range(m_xVertByMF->normalize(aVal.nMinVPos),
+ m_xVertByMF->normalize(aVal.nMaxVPos), FieldUnit::TWIP);
+ if ( aVal.nVPos != nAtVertPosVal )
+ m_xVertByMF->set_value(m_xVertByMF->normalize(aVal.nVPos), FieldUnit::TWIP);
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, AnchorTypeHdl, weld::ToggleButton&, void)
+{
+ m_xHoriMirrorCB->set_sensitive(!m_xAsCharRB->get_active() && !m_bIsMultiSelection);
+
+ // #i18732# - enable check box 'Follow text flow' for anchor
+ // type to-paragraph' and to-character
+ m_xFollowCB->set_sensitive(m_xToParaRB->get_active() || m_xToCharRB->get_active());
+
+ RndStdIds nId = GetAnchorType();
+
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ if(m_bHtmlMode)
+ {
+ PosHdl(*m_xHoriLB);
+ PosHdl(*m_xVertLB);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, MirrorHdl, weld::ToggleButton&, void)
+{
+ RndStdIds nId = GetAnchorType();
+ InitPos( nId, USHRT_MAX, 0, USHRT_MAX, 0, LONG_MAX, LONG_MAX);
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, RelHdl, weld::ComboBox&, rLB, void )
+{
+ bool bHori = &rLB == m_xHoriToLB.get();
+
+ UpdateExample();
+
+ if (m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()) // again special treatment
+ {
+ if(bHori)
+ {
+ sal_uInt16 nRel = GetRelation(*m_xHoriToLB);
+ if(RelOrientation::PRINT_AREA == nRel && 0 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(1);
+ }
+ else if(RelOrientation::CHAR == nRel && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ }
+ }
+ }
+ RangeModifyHdl(m_xWidthMF->get_widget());
+}
+
+IMPL_LINK(SvxSwPosSizeTabPage, PosHdl, weld::ComboBox&, rLB, void)
+{
+ bool bHori = &rLB == m_xHoriLB.get();
+ weld::ComboBox* pRelLB = bHori ? m_xHoriToLB.get() : m_xVertToLB.get();
+ weld::Label* pRelFT = bHori ? m_xHoriToFT.get() : m_xVertToFT.get();
+ FrmMap const *pMap = bHori ? m_pHMap : m_pVMap;
+
+
+ sal_uInt16 nMapPos = GetMapPos(pMap, rLB);
+ sal_uInt16 nAlign = GetAlignment(pMap, nMapPos, *pRelLB);
+
+ if (bHori)
+ {
+ bool bEnable = HoriOrientation::NONE == nAlign;
+ m_xHoriByMF->set_sensitive( bEnable );
+ m_xHoriByFT->set_sensitive( bEnable );
+ }
+ else
+ {
+ bool bEnable = VertOrientation::NONE == nAlign;
+ m_xVertByMF->set_sensitive( bEnable );
+ m_xVertByFT->set_sensitive( bEnable );
+ }
+
+ RangeModifyHdl(m_xWidthMF->get_widget());
+
+ short nRel = 0;
+ if (rLB.get_active() != -1)
+ {
+ if (pRelLB->get_active() != -1)
+ nRel = reinterpret_cast<RelationMap*>(pRelLB->get_active_id().toUInt64())->nRelation;
+
+ FillRelLB(pMap, nMapPos, nAlign, nRel, *pRelLB, *pRelFT);
+ }
+ else
+ pRelLB->clear();
+
+ UpdateExample();
+
+ // special treatment for HTML-Mode with horz-vert-dependencies
+ if (!(m_bHtmlMode && RndStdIds::FLY_AT_CHAR == GetAnchorType()))
+ return;
+
+ bool bSet = false;
+ if(bHori)
+ {
+ // on the right only below is allowed - from the left only at the top
+ // from the left at the character -> below
+ if((HoriOrientation::LEFT == nAlign || HoriOrientation::RIGHT == nAlign) &&
+ 0 == m_xVertLB->get_active())
+ {
+ if(RelOrientation::FRAME == nRel)
+ m_xVertLB->set_active(1);
+ else
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::LEFT == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ else if(HoriOrientation::NONE == nAlign && 1 == m_xVertLB->get_active())
+ {
+ m_xVertLB->set_active(0);
+ bSet = true;
+ }
+ if(bSet)
+ PosHdl(*m_xVertLB);
+ }
+ else
+ {
+ if(VertOrientation::TOP == nAlign)
+ {
+ if(1 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(1);
+ }
+ else if(VertOrientation::CHAR_BOTTOM == nAlign)
+ {
+ if(2 == m_xHoriLB->get_active())
+ {
+ m_xHoriLB->set_active(0);
+ bSet = true;
+ }
+ m_xHoriToLB->set_active(0) ;
+ }
+ if(bSet)
+ PosHdl(*m_xHoriLB);
+ }
+}
+
+IMPL_LINK( SvxSwPosSizeTabPage, ModifyHdl, weld::MetricSpinButton&, rEdit, void )
+{
+ auto nWidth = m_xWidthMF->denormalize(m_xWidthMF->get_value(FieldUnit::TWIP));
+ auto nHeight = m_xHeightMF->denormalize(m_xHeightMF->get_value(FieldUnit::TWIP));
+ if (m_xKeepRatioCB->get_active())
+ {
+ if ( &rEdit == m_xWidthMF.get() )
+ {
+ nHeight = int(static_cast<double>(nWidth) / m_fWidthHeightRatio);
+ m_xHeightMF->set_value(m_xHeightMF->normalize(nHeight), FieldUnit::TWIP);
+ }
+ else if(&rEdit == m_xHeightMF.get())
+ {
+ nWidth = int(static_cast<double>(nHeight) * m_fWidthHeightRatio);
+ m_xWidthMF->set_value(m_xWidthMF->normalize(nWidth), FieldUnit::TWIP);
+ }
+ }
+ m_fWidthHeightRatio = nHeight ? double(nWidth) / double(nHeight) : 1.0;
+ UpdateExample();
+}
+
+IMPL_LINK_NOARG(SvxSwPosSizeTabPage, ProtectHdl, weld::ToggleButton&, void)
+{
+ if (m_xSizeCB->get_sensitive())
+ {
+ m_nProtectSizeState = m_xSizeCB->get_state();
+ }
+
+ m_xSizeCB->set_state(m_xPositionCB->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : m_nProtectSizeState);
+ m_xSizeCB->set_sensitive(m_xPositionCB->get_sensitive() && !m_xPositionCB->get_active());
+}
+
+short SvxSwPosSizeTabPage::GetRelation(const weld::ComboBox& rRelationLB)
+{
+ short nRel = 0;
+ int nPos = rRelationLB.get_active();
+ if (nPos != -1)
+ {
+ RelationMap *pEntry = reinterpret_cast<RelationMap*>(rRelationLB.get_id(nPos).toUInt64());
+ nRel = pEntry->nRelation;
+ }
+
+ return nRel;
+}
+
+short SvxSwPosSizeTabPage::GetAlignment(FrmMap const *pMap, sal_uInt16 nMapPos, const weld::ComboBox& rRelationLB)
+{
+ short nAlign = 0;
+
+ // #i22341# - special handling also for map <aVCharMap>,
+ // because it contains ambiguous items for alignment
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap ||
+ pMap == aVCharMap )
+ {
+ if (rRelationLB.get_active() != -1)
+ {
+ LB nRel = reinterpret_cast<RelationMap*>(rRelationLB.get_active_id().toUInt64())->nLBRelation;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ if (pMap[i].eStrId == eStrId)
+ {
+ LB nLBRelations = pMap[i].nLBRelations;
+ if (nLBRelations & nRel)
+ {
+ nAlign = pMap[i].nAlign;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (pMap)
+ nAlign = pMap[nMapPos].nAlign;
+
+ return nAlign;
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::GetMapPos(FrmMap const *pMap, const weld::ComboBox& rAlignLB)
+{
+ sal_uInt16 nMapPos = 0;
+ int nLBSelPos = rAlignLB.get_active();
+
+ if (nLBSelPos != -1)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+ OUString sSelEntry(rAlignLB.get_active_text());
+
+ for (std::size_t i = 0; i < nMapCount; i++)
+ {
+ SvxSwFramePosString::StringId eResId = pMap[i].eStrId;
+
+ OUString sEntry = SvxSwFramePosString::GetString(eResId);
+
+ if (sEntry == sSelEntry)
+ {
+ nMapPos = sal::static_int_cast< sal_uInt16 >(i);
+ break;
+ }
+ }
+ }
+ else
+ nMapPos = nLBSelPos;
+ }
+
+ return nMapPos;
+}
+
+void SvxSwPosSizeTabPage::InitPos(RndStdIds nAnchor,
+ sal_uInt16 nH,
+ sal_uInt16 nHRel,
+ sal_uInt16 nV,
+ sal_uInt16 nVRel,
+ long nX,
+ long nY)
+{
+ int nPos = m_xVertLB->get_active();
+ if (nPos != -1 && m_pVMap)
+ {
+ m_nOldV = m_pVMap[nPos].nAlign;
+ nPos = m_xVertToLB->get_active();
+ if (nPos != -1)
+ m_nOldVRel = reinterpret_cast<RelationMap*>(m_xVertToLB->get_id(nPos).toUInt64())->nRelation;
+ }
+
+ nPos = m_xHoriLB->get_active();
+ if (nPos != -1 && m_pHMap)
+ {
+ m_nOldH = m_pHMap[nPos].nAlign;
+
+ nPos = m_xHoriToLB->get_active();
+ if (nPos != -1)
+ m_nOldHRel = reinterpret_cast<RelationMap*>(m_xHoriToLB->get_id(nPos).toUInt64())->nRelation;
+ }
+
+ bool bEnable = true;
+ if( m_bIsMultiSelection )
+ {
+ m_pVMap = aVMultiSelectionMap;
+ m_pHMap = aHMultiSelectionMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PAGE)
+ {
+ m_pVMap = m_bHtmlMode ? aVPageHtmlMap : aVPageMap;
+ m_pHMap = m_bHtmlMode ? aHPageHtmlMap : aHPageMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_FLY)
+ {
+ // #i18732# - own vertical alignment map for to frame
+ // anchored objects.
+ m_pVMap = m_bHtmlMode ? aVFlyHtmlMap : aVFrameMap;
+ m_pHMap = m_bHtmlMode ? aHFlyHtmlMap : aHFrameMap;
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_PARA)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVParaHtmlMap;
+ m_pHMap = aHParaHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVParaMap;
+ m_pHMap = aHParaMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AT_CHAR)
+ {
+ if(m_bHtmlMode)
+ {
+ m_pVMap = aVCharHtmlAbsMap;
+ m_pHMap = aHCharHtmlAbsMap;
+ }
+ else
+ {
+ m_pVMap = aVCharMap;
+ m_pHMap = aHCharMap;
+ }
+ }
+ else if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ m_pVMap = m_bHtmlMode ? aVAsCharHtmlMap : aVAsCharMap;
+ m_pHMap = nullptr;
+ bEnable = false;
+ }
+ m_xHoriLB->set_sensitive(bEnable);
+ m_xHoriFT->set_sensitive(bEnable);
+
+ // select current Pos
+ // horizontal
+ if ( nH == USHRT_MAX )
+ {
+ nH = m_nOldH;
+ nHRel = m_nOldHRel;
+ }
+ // #i22341# - pass <nHRel> as 3rd parameter to method <FillPosLB>
+ sal_uInt16 nMapPos = FillPosLB(m_pHMap, nH, nHRel, *m_xHoriLB);
+ FillRelLB(m_pHMap, nMapPos, nH, nHRel, *m_xHoriToLB, *m_xHoriToFT);
+
+ // vertical
+ if ( nV == USHRT_MAX )
+ {
+ nV = m_nOldV;
+ nVRel = m_nOldVRel;
+ }
+ // #i22341# - pass <nVRel> as 3rd parameter to method <FillPosLB>
+ nMapPos = FillPosLB(m_pVMap, nV, nVRel, *m_xVertLB);
+ FillRelLB(m_pVMap, nMapPos, nV, nVRel, *m_xVertToLB, *m_xVertToFT);
+
+ // Edits init
+ bEnable = nH == HoriOrientation::NONE && nAnchor != RndStdIds::FLY_AS_CHAR; //#61359# why not in formats&& !bFormat;
+ if (!bEnable)
+ {
+ m_xHoriByMF->set_value(0, FieldUnit::TWIP);
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(m_aRect.Left()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nX != LONG_MAX)
+ m_xHoriByMF->set_value(m_xHoriByMF->normalize(nX), FieldUnit::TWIP);
+ }
+ m_xHoriByFT->set_sensitive(bEnable);
+ m_xHoriByMF->set_sensitive(bEnable);
+
+ bEnable = nV == VertOrientation::NONE;
+ if ( !bEnable )
+ {
+ m_xVertByMF->set_value( 0, FieldUnit::TWIP );
+ }
+ else if(m_bIsMultiSelection)
+ {
+ m_xVertByMF->set_value(m_xVertByMF->normalize(m_aRect.Top()), FieldUnit::TWIP);
+ }
+ else
+ {
+ if (nAnchor == RndStdIds::FLY_AS_CHAR)
+ {
+ if ( nY == LONG_MAX )
+ nY = 0;
+ else
+ nY *= -1;
+ }
+ if ( nY != LONG_MAX )
+ m_xVertByMF->set_value( m_xVertByMF->normalize(nY), FieldUnit::TWIP );
+ }
+ m_xVertByFT->set_sensitive( bEnable );
+ m_xVertByMF->set_sensitive( bEnable );
+ UpdateExample();
+}
+
+void SvxSwPosSizeTabPage::UpdateExample()
+{
+ int nPos = m_xHoriLB->get_active();
+ if (m_pHMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pHMap, *m_xHoriLB);
+ short nAlign = GetAlignment(m_pHMap, nMapPos, *m_xHoriToLB);
+ short nRel = GetRelation(*m_xHoriToLB);
+
+ m_aExampleWN.SetHAlign(nAlign);
+ m_aExampleWN.SetHoriRel(nRel);
+ }
+
+ nPos = m_xVertLB->get_active();
+ if (m_pVMap && nPos != -1)
+ {
+ sal_uInt16 nMapPos = GetMapPos(m_pVMap, *m_xVertLB);
+ sal_uInt16 nAlign = GetAlignment(m_pVMap, nMapPos, *m_xVertToLB);
+ sal_uInt16 nRel = GetRelation(*m_xVertToLB);
+
+ m_aExampleWN.SetVAlign(nAlign);
+ m_aExampleWN.SetVertRel(nRel);
+ }
+
+ // Size
+ auto nXPos = m_xHoriByMF->denormalize(m_xHoriByMF->get_value(FieldUnit::TWIP));
+ auto nYPos = m_xVertByMF->denormalize(m_xVertByMF->get_value(FieldUnit::TWIP));
+ m_aExampleWN.SetRelPos(Point(nXPos, nYPos));
+
+ m_aExampleWN.SetAnchor( GetAnchorType() );
+ m_aExampleWN.Invalidate();
+}
+
+void SvxSwPosSizeTabPage::FillRelLB(FrmMap const *pMap, sal_uInt16 nMapPos, sal_uInt16 nAlign,
+ sal_uInt16 nRel, weld::ComboBox& rLB, weld::Label& rFT)
+{
+ OUString sSelEntry;
+ LB nLBRelations = LB::NONE;
+ std::size_t nMapCount = ::lcl_GetFrmMapCount(pMap);
+
+ rLB.clear();
+
+ if (nMapPos < nMapCount)
+ {
+ if (pMap == aVAsCharHtmlMap || pMap == aVAsCharMap)
+ {
+ OUString sOldEntry(rLB.get_active_text());
+ SvxSwFramePosString::StringId eStrId = pMap[nMapPos].eStrId;
+
+ for (std::size_t _nMapPos = 0; _nMapPos < nMapCount; _nMapPos++)
+ {
+ if (pMap[_nMapPos].eStrId == eStrId)
+ {
+ nLBRelations = pMap[_nMapPos].nLBRelations;
+ for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aAsCharRelationMap); nRelPos++)
+ {
+ if (nLBRelations & aAsCharRelationMap[nRelPos].nLBRelation)
+ {
+ SvxSwFramePosString::StringId sStrId1 = aAsCharRelationMap[nRelPos].eStrId;
+
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aAsCharRelationMap[nRelPos])), sEntry);
+ if (pMap[_nMapPos].nAlign == nAlign)
+ sSelEntry = sEntry;
+ break;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ rLB.set_active_text(sOldEntry);
+ if (rLB.get_active() == -1)
+ {
+ for (int i = 0; i < rLB.get_count(); i++)
+ {
+ RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
+ if (pEntry->nLBRelation == LB::RelChar) // Default
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ // #i22341# - special handling for map <aVCharMap>,
+ // because its ambiguous in its <eStrId>/<eMirrorStrId>.
+ if ( pMap == aVCharMap )
+ {
+ nLBRelations = ::lcl_GetLBRelationsForStrID( pMap,
+ ( m_xHoriMirrorCB->get_active()
+ ? pMap[nMapPos].eMirrorStrId
+ : pMap[nMapPos].eStrId ),
+ m_xHoriMirrorCB->get_active() );
+ }
+ else
+ {
+ nLBRelations = pMap[nMapPos].nLBRelations;
+ }
+
+ for (sal_uLong nBit = 1; nBit < sal_uLong(LB::LAST); nBit <<= 1)
+ {
+ if (nLBRelations & static_cast<LB>(nBit))
+ {
+ for (size_t nRelPos = 0; nRelPos < SAL_N_ELEMENTS(aRelationMap); nRelPos++)
+ {
+ if (aRelationMap[nRelPos].nLBRelation == static_cast<LB>(nBit))
+ {
+ SvxSwFramePosString::StringId sStrId1 = m_xHoriMirrorCB->get_active() ? aRelationMap[nRelPos].eMirrorStrId : aRelationMap[nRelPos].eStrId;
+ sStrId1 = lcl_ChangeResIdToVerticalOrRTL(sStrId1, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry = SvxSwFramePosString::GetString(sStrId1);
+ rLB.append(OUString::number(reinterpret_cast<sal_uInt64>(&aRelationMap[nRelPos])), sEntry);
+ if (sSelEntry.isEmpty() && aRelationMap[nRelPos].nRelation == nRel)
+ sSelEntry = sEntry;
+ }
+ }
+ }
+ }
+ if (!sSelEntry.isEmpty())
+ rLB.set_active_text(sSelEntry);
+ else
+ {
+ // Probably anchor change. So look for a similar relation.
+ switch (nRel)
+ {
+ case RelOrientation::FRAME: nRel = RelOrientation::PAGE_FRAME; break;
+ case RelOrientation::PRINT_AREA: nRel = RelOrientation::PAGE_PRINT_AREA; break;
+ case RelOrientation::PAGE_LEFT: nRel = RelOrientation::FRAME_LEFT; break;
+ case RelOrientation::PAGE_RIGHT: nRel = RelOrientation::FRAME_RIGHT; break;
+ case RelOrientation::FRAME_LEFT: nRel = RelOrientation::PAGE_LEFT; break;
+ case RelOrientation::FRAME_RIGHT: nRel = RelOrientation::PAGE_RIGHT; break;
+ case RelOrientation::PAGE_FRAME: nRel = RelOrientation::FRAME; break;
+ case RelOrientation::PAGE_PRINT_AREA: nRel = RelOrientation::PRINT_AREA; break;
+
+ default:
+ if (rLB.get_count())
+ {
+ RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(rLB.get_count() - 1).toUInt64());
+ nRel = pEntry->nRelation;
+ }
+ break;
+ }
+
+ for (int i = 0; i < rLB.get_count(); ++i)
+ {
+ RelationMap *pEntry = reinterpret_cast<RelationMap*>(rLB.get_id(i).toUInt64());
+ if (pEntry->nRelation == nRel)
+ {
+ rLB.set_active(i);
+ break;
+ }
+ }
+
+ if (rLB.get_active() == -1)
+ rLB.set_active(0);
+ }
+ }
+ }
+
+ rLB.set_sensitive(rLB.get_count() != 0);
+ rFT.set_sensitive(rLB.get_count() != 0);
+
+ RelHdl(rLB);
+}
+
+sal_uInt16 SvxSwPosSizeTabPage::FillPosLB(FrmMap const *_pMap,
+ sal_uInt16 _nAlign,
+ const sal_uInt16 _nRel,
+ weld::ComboBox& _rLB)
+{
+ OUString sSelEntry, sOldEntry;
+ sOldEntry = _rLB.get_active_text();
+
+ _rLB.clear();
+
+ // #i22341# - determine all possible listbox relations for
+ // given relation for map <aVCharMap>
+ const LB nLBRelations = (_pMap != aVCharMap)
+ ? LB::NONE
+ : ::lcl_GetLBRelationsForRelations( _nRel );
+
+ // fill listbox
+ std::size_t nCount = ::lcl_GetFrmMapCount(_pMap);
+ for (std::size_t i = 0; _pMap && i < nCount; ++i)
+ {
+ SvxSwFramePosString::StringId eStrId = m_xHoriMirrorCB->get_active() ? _pMap[i].eMirrorStrId : _pMap[i].eStrId;
+ eStrId = lcl_ChangeResIdToVerticalOrRTL(eStrId, m_bIsVerticalFrame, m_bIsInRightToLeft);
+ OUString sEntry(SvxSwFramePosString::GetString(eStrId));
+ if (_rLB.find_text(sEntry) == -1)
+ {
+ // don't insert duplicate entries at character wrapped borders
+ _rLB.append_text(sEntry);
+ }
+ // #i22341# - add condition to handle map <aVCharMap>
+ // that is ambiguous in the alignment.
+ if ( _pMap[i].nAlign == _nAlign &&
+ ( _pMap != aVCharMap || _pMap[i].nLBRelations & nLBRelations ) )
+ {
+ sSelEntry = sEntry;
+ }
+ }
+
+ _rLB.set_active_text(sSelEntry);
+ if (_rLB.get_active() == -1)
+ _rLB.set_active_text(sOldEntry);
+
+ if (_rLB.get_active() == -1)
+ _rLB.set_active(0);
+
+ PosHdl(_rLB);
+
+ return GetMapPos(_pMap, _rLB);
+}
+
+void SvxSwPosSizeTabPage::SetView( const SdrView* pSdrView )
+{
+ m_pSdrView = pSdrView;
+ if(!m_pSdrView)
+ {
+ OSL_FAIL("No SdrView* set");
+ return;
+ }
+
+ // setting of the rectangle and the working area
+ m_aRect = m_pSdrView->GetAllMarkedRect();
+ m_pSdrView->GetSdrPageView()->LogicToPagePos( m_aRect );
+
+ // get WorkArea
+ m_aWorkArea = m_pSdrView->GetWorkArea();
+
+ // consider anchor position (for Writer)
+ const SdrMarkList& rMarkList = m_pSdrView->GetMarkedObjectList();
+ if( rMarkList.GetMarkCount() > 0 )
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ m_aAnchorPos = pObj->GetAnchorPos();
+
+ if( m_aAnchorPos != Point(0,0) ) // -> Writer
+ {
+ for( size_t i = 1; i < rMarkList.GetMarkCount(); ++i )
+ {
+ pObj = rMarkList.GetMark( i )->GetMarkedSdrObj();
+ if( m_aAnchorPos != pObj->GetAnchorPos() )
+ {
+ // different anchor positions -> disable positioning
+ m_xPosFrame->set_sensitive(false);
+ m_bPositioningDisabled = true;
+ return;
+ }
+ }
+ }
+ Point aPt = m_aAnchorPos * -1;
+ Point aPt2 = aPt;
+
+ aPt += m_aWorkArea.TopLeft();
+ m_aWorkArea.SetPos( aPt );
+
+ aPt2 += m_aRect.TopLeft();
+ m_aRect.SetPos( aPt2 );
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if( rMarkList.GetMarkCount() != 1 )
+ m_bIsMultiSelection = true;
+#if OSL_DEBUG_LEVEL > 1
+ else
+ {
+ const SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
+ SdrObjKind eKind = (SdrObjKind) pObj->GetObjIdentifier();
+ if( ( pObj->GetObjInventor() == SdrInventor::Default ) &&
+ ( eKind==OBJ_TEXT || eKind==OBJ_TITLETEXT || eKind==OBJ_OUTLINETEXT) &&
+ pObj->HasText() )
+ {
+ OSL_FAIL("AutoWidth/AutoHeight should be enabled");
+ }
+ }
+#endif
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx
new file mode 100644
index 000000000..a400c0207
--- /dev/null
+++ b/cui/source/tabpages/tabarea.cxx
@@ -0,0 +1,248 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/objsh.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svx/svxids.hrc>
+
+#include <svx/xtable.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabarea.hxx>
+
+SvxAreaTabDialog::SvxAreaTabDialog
+(
+ weld::Window* pParent,
+ const SfxItemSet* pAttr,
+ SdrModel* pModel,
+ bool bShadow
+)
+ : SfxTabDialogController(pParent, "cui/ui/areadialog.ui", "AreaDialog", pAttr)
+ , mpDrawModel ( pModel ),
+ mpColorList ( pModel->GetColorList() ),
+ mpNewColorList ( pModel->GetColorList() ),
+ mpGradientList ( pModel->GetGradientList() ),
+ mpNewGradientList ( pModel->GetGradientList() ),
+ mpHatchingList ( pModel->GetHatchList() ),
+ mpNewHatchingList ( pModel->GetHatchList() ),
+ mpBitmapList ( pModel->GetBitmapList() ),
+ mpNewBitmapList ( pModel->GetBitmapList() ),
+ mpPatternList ( pModel->GetPatternList() ),
+ mpNewPatternList ( pModel->GetPatternList() ),
+
+ mnColorListState ( ChangeType::NONE ),
+ mnBitmapListState ( ChangeType::NONE ),
+ mnPatternListState ( ChangeType::NONE ),
+ mnGradientListState ( ChangeType::NONE ),
+ mnHatchingListState ( ChangeType::NONE )
+{
+ AddTabPage("RID_SVXPAGE_AREA", SvxAreaTabPage::Create, nullptr);
+
+ if (bShadow)
+ {
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ }
+ else
+ {
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+ }
+
+ AddTabPage( "RID_SVXPAGE_TRANSPARENCE", SvxTransparenceTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxAreaTabDialog, CancelHdlImpl));
+}
+
+void SvxAreaTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != mpDrawModel->GetColorList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ SvxColorListItem aColorListItem( mpNewColorList, SID_COLOR_TABLE );
+ if ( pShell )
+ pShell->PutItem( aColorListItem );
+ else
+ mpDrawModel->GetItemPool().Put(aColorListItem,SID_COLOR_TABLE);
+ mpColorList = mpDrawModel->GetColorList();
+ }
+ if( mpNewGradientList != mpDrawModel->GetGradientList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewGradientList.get()) );
+ SvxGradientListItem aItem( mpNewGradientList, SID_GRADIENT_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_GRADIENT_LIST);
+ mpGradientList = mpDrawModel->GetGradientList();
+ }
+ if( mpNewHatchingList != mpDrawModel->GetHatchList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewHatchingList.get()) );
+ SvxHatchListItem aItem( mpNewHatchingList, SID_HATCH_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_HATCH_LIST);
+ mpHatchingList = mpDrawModel->GetHatchList();
+ }
+ if( mpNewBitmapList != mpDrawModel->GetBitmapList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewBitmapList.get()) );
+ SvxBitmapListItem aItem( mpNewBitmapList, SID_BITMAP_LIST );
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_BITMAP_LIST);
+ mpBitmapList = mpDrawModel->GetBitmapList();
+ }
+ if( mpNewPatternList != mpDrawModel->GetPatternList() )
+ {
+ mpDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewPatternList.get()) );
+ SvxPatternListItem aItem( mpNewPatternList, SID_PATTERN_LIST );
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem,SID_PATTERN_LIST);
+ mpPatternList = mpDrawModel->GetPatternList();
+ }
+
+ // save the tables when they have been changed
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( mnHatchingListState & ChangeType::MODIFIED )
+ {
+ mpHatchingList->SetPath( aPath );
+ mpHatchingList->Save();
+
+ SvxHatchListItem aItem( mpHatchingList, SID_HATCH_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+
+ if( mnBitmapListState & ChangeType::MODIFIED )
+ {
+ mpBitmapList->SetPath( aPath );
+ mpBitmapList->Save();
+
+ SvxBitmapListItem aItem( mpBitmapList, SID_BITMAP_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+
+ if( mnPatternListState & ChangeType::MODIFIED )
+ {
+ mpPatternList->SetPath( aPath );
+ mpPatternList->Save();
+
+ SvxPatternListItem aItem( mpPatternList, SID_PATTERN_LIST );
+ // ToolBoxControls are informed:
+ if( pShell )
+ pShell->PutItem( aItem );
+ else
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+
+ if( mnGradientListState & ChangeType::MODIFIED )
+ {
+ mpGradientList->SetPath( aPath );
+ mpGradientList->Save();
+
+ SvxGradientListItem aItem( mpGradientList, SID_GRADIENT_LIST );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+
+ if (mnColorListState & ChangeType::MODIFIED && mpColorList.is())
+ {
+ SvxColorListItem aItem( mpColorList, SID_COLOR_TABLE );
+ // ToolBoxControls are informed:
+ if ( pShell )
+ pShell->PutItem( aItem );
+ else
+ {
+ mpDrawModel->GetItemPool().Put(aItem);
+ }
+ }
+}
+
+short SvxAreaTabDialog::Ok()
+{
+ SavePalettes();
+ // RET_OK is returned, if at least one
+ // TabPage returns sal_True in FillItemSet().
+ // This happens by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxAreaTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxAreaTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_AREA")
+ {
+ static_cast<SvxAreaTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGradientList( mpGradientList );
+ static_cast<SvxAreaTabPage&>(rPage).SetHatchingList( mpHatchingList );
+ static_cast<SvxAreaTabPage&>(rPage).SetBitmapList( mpBitmapList );
+ static_cast<SvxAreaTabPage&>(rPage).SetPatternList( mpPatternList );
+ static_cast<SvxAreaTabPage&>(rPage).SetGrdChgd( &mnGradientListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetHtchChgd( &mnHatchingListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetBmpChgd( &mnBitmapListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetPtrnChgd( &mnPatternListState );
+ static_cast<SvxAreaTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( mpColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_TRANSPARENCE")
+ {
+ static_cast<SvxTransparenceTabPage&>(rPage).SetPageType( PageType::Area );
+ static_cast<SvxTransparenceTabPage&>(rPage).SetDlgType( 0 );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabline.cxx b/cui/source/tabpages/tabline.cxx
new file mode 100644
index 000000000..f4e0a1268
--- /dev/null
+++ b/cui/source/tabpages/tabline.cxx
@@ -0,0 +1,207 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/pathoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <cuitabline.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+
+SvxLineTabDialog::SvxLineTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ SdrModel* pModel, const SdrObject* pSdrObj, bool bHasObj)
+ : SfxTabDialogController(pParent, "cui/ui/linedialog.ui", "LineDialog", pAttr)
+ , pDrawModel(pModel)
+ , pObj(pSdrObj)
+ , pColorList(pModel->GetColorList())
+ , mpNewColorList(pModel->GetColorList())
+ , pDashList(pModel->GetDashList())
+ , pNewDashList(pModel->GetDashList())
+ , pLineEndList(pModel->GetLineEndList())
+ , pNewLineEndList(pModel->GetLineEndList())
+ , bObjSelected(bHasObj)
+ , nLineEndListState(ChangeType::NONE)
+ , nDashListState(ChangeType::NONE)
+ , mnColorListState(ChangeType::NONE)
+ , nPageType(PageType::Area) // We use it here primarily to get the right attributes with FillItemSet
+ , nPosDashLb(0)
+ , nPosLineEndLb(0)
+{
+ bool bLineOnly = false;
+ if( pObj && pObj->GetObjInventor() == SdrInventor::Default )
+ {
+ switch( pObj->GetObjIdentifier() )
+ {
+ case OBJ_LINE:
+ case OBJ_PLIN:
+ case OBJ_PATHLINE:
+ case OBJ_FREELINE:
+ case OBJ_MEASURE:
+ case OBJ_EDGE:
+ bLineOnly = true;
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ AddTabPage("RID_SVXPAGE_LINE", SvxLineTabPage::Create, nullptr);
+ if( bLineOnly )
+ AddTabPage("RID_SVXPAGE_SHADOW", SvxShadowTabPage::Create, nullptr);
+ else
+ RemoveTabPage( "RID_SVXPAGE_SHADOW" );
+
+ AddTabPage("RID_SVXPAGE_LINE_DEF", SvxLineDefTabPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_LINEEND_DEF", SvxLineEndDefTabPage::Create, nullptr);
+
+ weld::Button& rBtnCancel = GetCancelButton();
+ rBtnCancel.connect_clicked(LINK(this, SvxLineTabDialog, CancelHdlImpl));
+}
+
+void SvxLineTabDialog::SavePalettes()
+{
+ SfxObjectShell* pShell = SfxObjectShell::Current();
+ if( mpNewColorList != pDrawModel->GetColorList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(mpNewColorList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( mpNewColorList, SID_COLOR_TABLE ) );
+ pColorList = pDrawModel->GetColorList();
+ }
+ if( pNewDashList != pDrawModel->GetDashList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewDashList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pNewDashList, SID_DASH_LIST ) );
+ pDashList = pDrawModel->GetDashList();
+ }
+ if( pNewLineEndList != pDrawModel->GetLineEndList() )
+ {
+ pDrawModel->SetPropertyList( static_cast<XPropertyList *>(pNewLineEndList.get()) );
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pNewLineEndList, SID_LINEEND_LIST ) );
+ pLineEndList = pDrawModel->GetLineEndList();
+ }
+
+ // Save the tables when they have been changed
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aPath;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aPath = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ if( nDashListState & ChangeType::MODIFIED )
+ {
+ pDashList->SetPath( aPath );
+ pDashList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxDashListItem( pDashList, SID_DASH_LIST ) );
+ }
+
+ if( nLineEndListState & ChangeType::MODIFIED )
+ {
+ pLineEndList->SetPath( aPath );
+ pLineEndList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxLineEndListItem( pLineEndList, SID_LINEEND_LIST ) );
+ }
+
+ if( mnColorListState & ChangeType::MODIFIED )
+ {
+ pColorList->SetPath( aPath );
+ pColorList->Save();
+
+ // Notify ToolBoxControls
+ if ( pShell )
+ pShell->PutItem( SvxColorListItem( pColorList, SID_COLOR_TABLE ) );
+ }
+}
+
+short SvxLineTabDialog::Ok()
+{
+ SavePalettes();
+
+ // We return RET_OK if at least one TabPage in FillItemSet() returns sal_True.
+ // We do this by default at the moment.
+ return SfxTabDialogController::Ok();
+}
+
+IMPL_LINK_NOARG(SvxLineTabDialog, CancelHdlImpl, weld::Button&, void)
+{
+ SavePalettes();
+
+ m_xDialog->response(RET_CANCEL);
+}
+
+void SvxLineTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_LINE")
+ {
+ static_cast<SvxLineTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxLineTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineTabPage&>(rPage).SetObjSelected( bObjSelected );
+ static_cast<SvxLineTabPage&>(rPage).Construct();
+ static_cast<SvxLineTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+ else if (rId == "RID_SVXPAGE_LINE_DEF")
+ {
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashList( pDashList );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineDefTabPage&>(rPage).SetPosDashLb( &nPosDashLb );
+ static_cast<SvxLineDefTabPage&>(rPage).SetDashChgd( &nDashListState );
+ static_cast<SvxLineDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_LINEEND_DEF")
+ {
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndList( pLineEndList );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPolyObj( pObj );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPageType( &nPageType );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetPosLineEndLb( &nPosLineEndLb );
+ static_cast<SvxLineEndDefTabPage&>(rPage).SetLineEndChgd( &nLineEndListState );
+ static_cast<SvxLineEndDefTabPage&>(rPage).Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SHADOW")
+ {
+ static_cast<SvxShadowTabPage&>(rPage).SetColorList( pColorList );
+ static_cast<SvxShadowTabPage&>(rPage).SetPageType( nPageType );
+ static_cast<SvxShadowTabPage&>(rPage).SetDlgType( 0 );
+ static_cast<SvxShadowTabPage&>(rPage).SetColorChgd( &mnColorListState );
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tabstpge.cxx b/cui/source/tabpages/tabstpge.cxx
new file mode 100644
index 000000000..939a51e41
--- /dev/null
+++ b/cui/source/tabpages/tabstpge.cxx
@@ -0,0 +1,667 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/ruler.hxx>
+#include <svtools/unitconv.hxx>
+#include <svx/svxids.hrc>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <editeng/lrspitem.hxx>
+#include <tabstpge.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/cjkoptions.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <svl/intitem.hxx>
+
+constexpr FieldUnit eDefUnit = FieldUnit::MM_100TH;
+
+const sal_uInt16 SvxTabulatorTabPage::pRanges[] =
+{
+ SID_ATTR_TABSTOP,
+ SID_ATTR_TABSTOP_OFFSET,
+ 0
+};
+
+static void FillUpWithDefTabs_Impl( long nDefDist, SvxTabStopItem& rTabs )
+{
+ if( rTabs.Count() )
+ return;
+ {
+ SvxTabStop aSwTabStop( nDefDist, SvxTabAdjust::Default );
+ rTabs.Insert( aSwTabStop );
+ }
+}
+
+void TabWin_Impl::Paint(vcl::RenderContext& rRenderContext, const ::tools::Rectangle&)
+{
+ // Paint tabulators
+ Point aPoint;
+ Size aSize(GetOutputSizePixel());
+ aPoint.setX( aSize.Width() / 2 );
+ aPoint.setY( aSize.Height() / 2 );
+ Ruler::DrawTab(rRenderContext, rRenderContext.GetSettings().GetStyleSettings().GetFontColor(), aPoint, nTabStyle);
+}
+
+SvxTabulatorTabPage::SvxTabulatorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rAttr)
+ : SfxTabPage(pPage, pController, "cui/ui/paratabspage.ui", "ParagraphTabsPage", &rAttr)
+ , aCurrentTab(0)
+ , aNewTabs(std::make_unique<SvxTabStopItem>(0, 0, SvxTabAdjust::Left, GetWhich(SID_ATTR_TABSTOP)))
+ , nDefDist(0)
+ , m_xTabSpin(m_xBuilder->weld_metric_spin_button("SP_TABPOS", FieldUnit::CM))
+ , m_xTabBox(m_xBuilder->weld_entry_tree_view("tabgrid", "ED_TABPOS", "LB_TABPOS"))
+ , m_xCenterTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_CENTER"))
+ , m_xDezTab(m_xBuilder->weld_radio_button("radiobuttonBTN_TABTYPE_DECIMAL"))
+ , m_xDezChar(m_xBuilder->weld_entry("entryED_TABTYPE_DECCHAR"))
+ , m_xDezCharLabel(m_xBuilder->weld_label("labelFT_TABTYPE_DECCHAR"))
+ // lower radio buttons
+ , m_xNoFillChar(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_NO"))
+ , m_xFillPoints(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_POINTS"))
+ , m_xFillDashLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_DASHLINE"))
+ , m_xFillSolidLine(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_UNDERSCORE"))
+ , m_xFillSpecial(m_xBuilder->weld_radio_button("radiobuttonBTN_FILLCHAR_OTHER"))
+ , m_xFillChar(m_xBuilder->weld_entry("entryED_FILLCHAR_OTHER"))
+ // button bar
+ , m_xNewBtn(m_xBuilder->weld_button("buttonBTN_NEW"))
+ , m_xDelAllBtn(m_xBuilder->weld_button("buttonBTN_DELALL"))
+ , m_xDelBtn(m_xBuilder->weld_button("buttonBTN_DEL"))
+ , m_xTypeFrame(m_xBuilder->weld_container("frameFL_TABTYPE"))
+ , m_xFillFrame(m_xBuilder->weld_container("frameFL_FILLCHAR"))
+ // the tab images
+ , m_xLeftWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABLEFT", m_aLeftWin))
+ , m_xRightWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABRIGHT", m_aRightWin))
+ , m_xCenterWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABCENTER", m_aCenterWin))
+ , m_xDezWin(new weld::CustomWeld(*m_xBuilder, "drawingareaWIN_TABDECIMAL", m_aDezWin))
+{
+ m_aLeftWin.SetTabStyle(sal_uInt16(RULER_TAB_LEFT|WB_HORZ));
+ m_aRightWin.SetTabStyle(sal_uInt16(RULER_TAB_RIGHT|WB_HORZ));
+ m_aCenterWin.SetTabStyle(sal_uInt16(RULER_TAB_CENTER|WB_HORZ));
+ m_aDezWin.SetTabStyle(sal_uInt16(RULER_TAB_DECIMAL|WB_HORZ));
+ //upper radiobuttons
+ SvtCJKOptions aCJKOptions;
+ m_xLeftTab = m_xBuilder->weld_radio_button(aCJKOptions.IsAsianTypographyEnabled() ? "radiobuttonST_LEFTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_LEFT");
+ m_xRightTab = m_xBuilder->weld_radio_button(aCJKOptions.IsAsianTypographyEnabled() ? "radiobuttonST_RIGHTTAB_ASIAN" : "radiobuttonBTN_TABTYPE_RIGHT");
+ m_xLeftTab->show();
+ m_xRightTab->show();
+
+ // This page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // Set metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rAttr );
+ SetFieldUnit(*m_xTabSpin, eFUnit);
+
+ // Initialize buttons
+ m_xNewBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, NewHdl_Impl));
+ m_xDelBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelHdl_Impl));
+ m_xDelAllBtn->connect_clicked(LINK(this,SvxTabulatorTabPage, DelAllHdl_Impl));
+
+ Link<weld::ToggleButton&,void> aLink = LINK(this, SvxTabulatorTabPage, TabTypeCheckHdl_Impl);
+ m_xLeftTab->connect_toggled(aLink);
+ m_xRightTab->connect_toggled(aLink);
+ m_xDezTab->connect_toggled(aLink);
+ m_xCenterTab->connect_toggled(aLink);
+
+ m_xDezChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetDezCharHdl_Impl));
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ aLink = LINK(this, SvxTabulatorTabPage, FillTypeCheckHdl_Impl);
+ m_xNoFillChar->connect_toggled(aLink);
+ m_xFillPoints->connect_toggled(aLink);
+ m_xFillDashLine->connect_toggled(aLink);
+ m_xFillSolidLine->connect_toggled(aLink);
+ m_xFillSpecial->connect_toggled(aLink);
+ m_xFillChar->connect_focus_out(LINK(this, SvxTabulatorTabPage, GetFillCharHdl_Impl));
+ m_xFillChar->set_sensitive(false);
+
+ m_xTabBox->connect_row_activated(LINK(this, SvxTabulatorTabPage, SelectHdl_Impl));
+ m_xTabBox->connect_changed(LINK(this, SvxTabulatorTabPage, ModifyHdl_Impl));
+ m_xTabBox->connect_focus_out(LINK(this, SvxTabulatorTabPage, ReformatHdl_Impl));
+
+ // Get the default decimal char from the system
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aCurrentTab.GetDecimal() = rLocaleWrapper.getNumDecimalSep()[0];
+}
+
+SvxTabulatorTabPage::~SvxTabulatorTabPage()
+{
+ m_xDezWin.reset();
+ m_xCenterWin.reset();
+ m_xRightWin.reset();
+ m_xLeftWin.reset();
+ m_xFillChar.reset();
+ m_xDezChar.reset();
+ m_xTabBox.reset();
+}
+
+bool SvxTabulatorTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ // Put the controls' values in here
+ if (m_xNewBtn->get_sensitive())
+ NewHdl_Impl(nullptr);
+
+ // Call the LoseFocus-Handler first
+ GetDezCharHdl_Impl(*m_xDezChar);
+ GetFillCharHdl_Impl(*m_xFillChar);
+
+ FillUpWithDefTabs_Impl(nDefDist, *aNewTabs);
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ const SfxPoolItem* pOld = GetOldItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ // If the ItemSet contains a LRSpaceItem with negative first line indent,
+ // the TabStopItem needs to have a DefTab at position 0.
+ const SfxPoolItem* pLRSpace;
+ // If not in the new set, then maybe in the old one
+ if (SfxItemState::SET != rSet->GetItemState(GetWhich(SID_ATTR_LRSPACE), true, &pLRSpace))
+ pLRSpace = GetOldItem(*rSet, SID_ATTR_LRSPACE);
+
+ if (pLRSpace && static_cast<const SvxLRSpaceItem*>(pLRSpace)->GetTextFirstLineOffset() < 0)
+ {
+ SvxTabStop aNull(0, SvxTabAdjust::Default);
+ aNewTabs->Insert(aNull);
+ }
+
+ std::unique_ptr<SvxTabStopItem> aTmp(aNewTabs->Clone());
+ aTmp->Remove(0, aTmp->Count());
+
+ for (sal_uInt16 i = 0; i < aNewTabs->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aNewTabs)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), MapUnit::Map100thMM, eUnit);
+ aTmp->Insert(aTmpStop);
+ }
+
+ if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aTmp)
+ {
+ rSet->Put(*aTmp);
+ bModified = true;
+ }
+ }
+ else if (!pOld || *static_cast<const SvxTabStopItem*>(pOld) != *aNewTabs)
+ {
+ rSet->Put(*aNewTabs);
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+std::unique_ptr<SfxTabPage> SvxTabulatorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxTabulatorTabPage>(pPage, pController, *rSet);
+}
+
+void SvxTabulatorTabPage::Reset(const SfxItemSet* rSet)
+{
+ SfxItemPool* pPool = rSet->GetPool();
+ MapUnit eUnit = pPool->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+
+ // Current tabs
+ const SfxPoolItem* pItem = GetItem(*rSet, SID_ATTR_TABSTOP);
+
+ if (pItem)
+ {
+ if (MapUnit::Map100thMM != eUnit)
+ {
+ std::unique_ptr<SvxTabStopItem> aTmp(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ aNewTabs->Remove(0, aNewTabs->Count());
+
+ for (sal_uInt16 i = 0; i < aTmp->Count(); ++i)
+ {
+ SvxTabStop aTmpStop = (*aTmp)[i];
+ aTmpStop.GetTabPos() = OutputDevice::LogicToLogic(aTmpStop.GetTabPos(), eUnit, MapUnit::Map100thMM);
+ aNewTabs->Insert(aTmpStop);
+ }
+ }
+ else
+ {
+ aNewTabs.reset(static_cast<SvxTabStopItem*>(pItem->Clone()));
+ }
+ }
+ else
+ {
+ aNewTabs->Remove(0, aNewTabs->Count());
+ }
+
+ // Default tab distance
+ nDefDist = SVX_TAB_DEFDIST;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_DEFAULTS);
+
+ if (pItem)
+ nDefDist = OutputDevice::LogicToLogic(long(static_cast<const SfxUInt16Item*>(pItem)->GetValue()), eUnit, MapUnit::Map100thMM);
+
+ // Tab pos currently selected
+ sal_uInt16 nTabPos = 0;
+ pItem = GetItem(*rSet, SID_ATTR_TABSTOP_POS);
+
+ if (pItem)
+ nTabPos = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
+
+ InitTabPos_Impl(nTabPos);
+}
+
+void SvxTabulatorTabPage::DisableControls(const TabulatorDisableFlags nFlag)
+{
+ if (TabulatorDisableFlags::TypeLeft & nFlag)
+ {
+ m_xLeftTab->set_sensitive(false);
+ m_xLeftWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeRight & nFlag)
+ {
+ m_xRightTab->set_sensitive(false);
+ m_xRightWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeCenter & nFlag)
+ {
+ m_xCenterTab->set_sensitive(false);
+ m_xCenterWin->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeDecimal & nFlag)
+ {
+ m_xDezTab->set_sensitive(false);
+ m_xDezWin->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::TypeMask & nFlag)
+ m_xTypeFrame->set_sensitive(false);
+ if (TabulatorDisableFlags::FillNone & nFlag)
+ m_xNoFillChar->set_sensitive(false);
+ if (TabulatorDisableFlags::FillPoint & nFlag)
+ m_xFillPoints->set_sensitive(false);
+ if (TabulatorDisableFlags::FillDashLine & nFlag)
+ m_xFillDashLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSolidLine & nFlag)
+ m_xFillSolidLine->set_sensitive(false);
+ if (TabulatorDisableFlags::FillSpecial & nFlag)
+ {
+ m_xFillSpecial->set_sensitive(false);
+ m_xFillChar->set_sensitive(false);
+ }
+ if (TabulatorDisableFlags::FillMask & nFlag)
+ m_xFillFrame->set_sensitive(false);
+}
+
+DeactivateRC SvxTabulatorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if ( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxTabulatorTabPage::InitTabPos_Impl( sal_uInt16 nTabPos )
+{
+ m_xTabBox->clear();
+
+ long nOffset = 0;
+ const SfxPoolItem* pItem = nullptr;
+ if (GetItemSet().GetItemState(SID_ATTR_TABSTOP_OFFSET, true, &pItem) == SfxItemState::SET)
+ {
+ nOffset = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric(GetWhich(SID_ATTR_TABSTOP));
+ nOffset = OutputDevice::LogicToLogic(nOffset, eUnit, MapUnit::Map100thMM);
+ }
+
+ // Correct current TabPos and default tabs
+ for ( sal_uInt16 i = 0; i < aNewTabs->Count(); i++ )
+ {
+ if ( (*aNewTabs)[i].GetAdjustment() != SvxTabAdjust::Default )
+ {
+ m_xTabSpin->set_value(m_xTabSpin->normalize((*aNewTabs)[i].GetTabPos() + nOffset ), eDefUnit);
+ m_xTabBox->append_text(m_xTabSpin->get_text());
+ }
+ else
+ {
+ aNewTabs->Remove( i-- );
+ }
+ }
+
+ // Select current tabulator
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nTabPos >= nSize )
+ nTabPos = 0;
+
+ // Switch off all RadioButtons for a start
+ m_xLeftTab->set_active(true);
+ m_xNoFillChar->set_active(true);
+
+ if (m_xTabBox->get_count() > 0)
+ {
+ m_xTabBox->set_active(nTabPos);
+ aCurrentTab = (*aNewTabs)[nTabPos];
+
+ SetFillAndTabType_Impl();
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ }
+ else
+ { // If no entry, 0 is the default value
+ m_xTabSpin->set_value(0, eDefUnit);
+ m_xTabBox->set_entry_text(m_xTabSpin->get_text());
+
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+ }
+}
+
+void SvxTabulatorTabPage::SetFillAndTabType_Impl()
+{
+ weld::RadioButton* pTypeBtn = nullptr;
+ weld::RadioButton* pFillBtn = nullptr;
+
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+
+ if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Left )
+ pTypeBtn = m_xLeftTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Right )
+ pTypeBtn = m_xRightTab.get();
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Decimal )
+ {
+ pTypeBtn = m_xDezTab.get();
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+ else if ( aCurrentTab.GetAdjustment() == SvxTabAdjust::Center )
+ pTypeBtn = m_xCenterTab.get();
+
+ if (pTypeBtn)
+ pTypeBtn->set_active(true);
+
+ m_xFillChar->set_sensitive(false);
+ m_xFillChar->set_text("");
+
+ if ( aCurrentTab.GetFill() == ' ' )
+ pFillBtn = m_xNoFillChar.get();
+ else if ( aCurrentTab.GetFill() == '-' )
+ pFillBtn = m_xFillDashLine.get();
+ else if ( aCurrentTab.GetFill() == '_' )
+ pFillBtn = m_xFillSolidLine.get();
+ else if ( aCurrentTab.GetFill() == '.' )
+ pFillBtn = m_xFillPoints.get();
+ else
+ {
+ pFillBtn = m_xFillSpecial.get();
+ m_xFillChar->set_sensitive(true);
+ m_xFillChar->set_text(OUString(aCurrentTab.GetFill()));
+ }
+ pFillBtn->set_active(true);
+}
+
+IMPL_LINK(SvxTabulatorTabPage, NewHdl_Impl, weld::Button&, rBtn, void)
+{
+ NewHdl_Impl(&rBtn);
+}
+
+void SvxTabulatorTabPage::NewHdl_Impl(const weld::Button* pBtn)
+{
+ // Add a new one and select it
+ // Get the value from the display
+ ReformatHdl_Impl(*m_xTabBox);
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ auto nVal = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+
+ // If the pBtn == 0 && the value == 0 then do not create a tab, because we create via OK
+ if (nVal == 0 && pBtn == nullptr)
+ return;
+
+ long nOffset = 0;
+ const SfxPoolItem* pItem = nullptr;
+
+ if ( GetItemSet().GetItemState( SID_ATTR_TABSTOP_OFFSET, true, &pItem ) ==
+ SfxItemState::SET )
+ {
+ nOffset = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+ MapUnit eUnit = GetItemSet().GetPool()->GetMetric( GetWhich( SID_ATTR_TABSTOP ) );
+ nOffset = OutputDevice::LogicToLogic( nOffset, eUnit, MapUnit::Map100thMM );
+ }
+ const long nReal = nVal - nOffset;
+ sal_Int32 nSize = m_xTabBox->get_count();
+
+ sal_Int32 i;
+ for( i = 0; i < nSize; i++ )
+ {
+ if ( nReal < (*aNewTabs)[i].GetTabPos() )
+ break;
+ }
+
+ // Make ListBox entry
+ m_xTabSpin->set_value(m_xTabSpin->normalize(nVal), eDefUnit);
+ m_xTabBox->insert_text(i, m_xTabSpin->get_text());
+
+ aCurrentTab.GetTabPos() = nReal;
+ SvxTabAdjust eAdj = SvxTabAdjust::Left;
+
+ if (m_xRightTab->get_active())
+ eAdj = SvxTabAdjust::Right;
+ else if (m_xCenterTab->get_active())
+ eAdj = SvxTabAdjust::Center;
+ else if (m_xDezTab->get_active())
+ eAdj = SvxTabAdjust::Decimal;
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ aNewTabs->Insert( aCurrentTab );
+
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+
+ // Set the selection into the position Edit
+ m_xTabBox->select_entry_region(0, -1);
+}
+
+int SvxTabulatorTabPage::FindCurrentTab()
+{
+ return m_xTabBox->find_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelHdl_Impl, weld::Button&, void)
+{
+ int nPos = FindCurrentTab();
+ if (nPos == -1)
+ return;
+
+ if (m_xTabBox->get_count() == 1)
+ {
+ DelAllHdl_Impl(*m_xDelAllBtn);
+ return;
+ }
+
+ // Delete Tab
+ m_xTabBox->remove(nPos);
+ aNewTabs->Remove( nPos );
+
+ // Reset aCurrentTab
+ const sal_uInt16 nSize = aNewTabs->Count();
+
+ if ( nSize > 0 )
+ {
+ // Correct Pos
+ nPos = ( ( nSize - 1 ) >= nPos) ? nPos : nPos - 1;
+ m_xTabBox->set_active(nPos);
+ aCurrentTab = (*aNewTabs)[nPos];
+ }
+
+ // If no Tabs Enable Disable Controls
+ if (m_xTabBox->get_count() == 0)
+ {
+ m_xDelBtn->set_sensitive(false);
+ m_xNewBtn->set_sensitive(true);
+ m_xTabBox->grab_focus();
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, DelAllHdl_Impl, weld::Button&, void)
+{
+ if ( aNewTabs->Count() )
+ {
+ aNewTabs = std::make_unique<SvxTabStopItem>(GetWhich(SID_ATTR_TABSTOP));
+ InitTabPos_Impl();
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, TabTypeCheckHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ SvxTabAdjust eAdj;
+ m_xDezChar->set_sensitive(false);
+ m_xDezCharLabel->set_sensitive(false);
+ m_xDezChar->set_text("");
+
+ if (&rBox == m_xLeftTab.get())
+ eAdj = SvxTabAdjust::Left;
+ else if (&rBox == m_xRightTab.get())
+ eAdj = SvxTabAdjust::Right;
+ else if (&rBox == m_xCenterTab.get())
+ eAdj = SvxTabAdjust::Center;
+ else
+ {
+ eAdj = SvxTabAdjust::Decimal;
+ m_xDezChar->set_sensitive(true);
+ m_xDezCharLabel->set_sensitive(true);
+ m_xDezChar->set_text(OUString(aCurrentTab.GetDecimal()));
+ }
+
+ aCurrentTab.GetAdjustment() = eAdj;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK(SvxTabulatorTabPage, FillTypeCheckHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ if (!rBox.get_active())
+ return;
+
+ sal_uInt8 cFill = ' ';
+ m_xFillChar->set_text( "" );
+ m_xFillChar->set_sensitive(false);
+
+ if (&rBox == m_xFillSpecial.get())
+ m_xFillChar->set_sensitive(true);
+ else if (&rBox == m_xNoFillChar.get())
+ cFill = ' ';
+ else if (&rBox == m_xFillSolidLine.get())
+ cFill = '_';
+ else if (&rBox == m_xFillPoints.get())
+ cFill = '.';
+ else if (&rBox == m_xFillDashLine.get())
+ cFill = '-';
+
+ aCurrentTab.GetFill() = cFill;
+ int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetFillCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xFillChar->get_text());
+ if ( !aChar.isEmpty() )
+ aCurrentTab.GetFill() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, GetDezCharHdl_Impl, weld::Widget&, void)
+{
+ OUString aChar(m_xDezChar->get_text());
+ if ( !aChar.isEmpty() && ( aChar[0] >= ' '))
+ aCurrentTab.GetDecimal() = aChar[0];
+
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aNewTabs->Remove( nPos );
+ aNewTabs->Insert( aCurrentTab );
+ }
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, SelectHdl_Impl, weld::TreeView&, bool)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ m_xNewBtn->set_sensitive(false);
+ SetFillAndTabType_Impl();
+ }
+ return true;
+}
+
+OUString SvxTabulatorTabPage::FormatTab()
+{
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ m_xTabSpin->reformat();
+ return m_xTabSpin->get_text();
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ReformatHdl_Impl, weld::Widget&, void)
+{
+ m_xTabBox->set_entry_text(FormatTab());
+}
+
+IMPL_LINK_NOARG(SvxTabulatorTabPage, ModifyHdl_Impl, weld::ComboBox&, void)
+{
+ const int nPos = FindCurrentTab();
+ if (nPos != -1)
+ {
+ aCurrentTab = (*aNewTabs)[nPos];
+ SetFillAndTabType_Impl();
+
+ m_xTabSpin->set_text(m_xTabBox->get_active_text());
+ aCurrentTab.GetTabPos() = m_xTabSpin->denormalize(m_xTabSpin->get_value(eDefUnit));
+ m_xNewBtn->set_sensitive(false);
+ m_xDelBtn->set_sensitive(true);
+ return;
+ }
+ m_xNewBtn->set_sensitive(true);
+ m_xDelBtn->set_sensitive(false);
+}
+
+void SvxTabulatorTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pControlItem = aSet.GetItem<SfxUInt16Item>(SID_SVXTABULATORTABPAGE_DISABLEFLAGS, false);
+ if (pControlItem)
+ DisableControls(static_cast<TabulatorDisableFlags>(pControlItem->GetValue()));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textanim.cxx b/cui/source/tabpages/textanim.cxx
new file mode 100644
index 000000000..ab5dc095b
--- /dev/null
+++ b/cui/source/tabpages/textanim.cxx
@@ -0,0 +1,536 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <textanim.hxx>
+#include <textattr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdview.hxx>
+#include <svx/sdtaaitm.hxx>
+#include <svx/sdtacitm.hxx>
+#include <svx/sdtaiitm.hxx>
+#include <svx/sdtayitm.hxx>
+#include <svtools/unitconv.hxx>
+
+const sal_uInt16 SvxTextAnimationPage::pRanges[] =
+{
+ SDRATTR_TEXT_ANIKIND,
+ SDRATTR_TEXT_ANIAMOUNT,
+ 0
+};
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds pages to the dialog
+|*
+\************************************************************************/
+
+SvxTextTabDialog::SvxTextTabDialog(weld::Window* pParent, const SfxItemSet* pAttr, const SdrView* pSdrView)
+ : SfxTabDialogController(pParent, "cui/ui/textdialog.ui", "TextDialog", pAttr)
+ , pView(pSdrView)
+{
+ AddTabPage("RID_SVXPAGE_TEXTATTR", SvxTextAttrPage::Create, nullptr);
+ AddTabPage("RID_SVXPAGE_TEXTANIMATION", SvxTextAnimationPage::Create, nullptr);
+}
+
+/*************************************************************************
+|*
+|* PageCreated()
+|*
+\************************************************************************/
+
+void SvxTextTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId != "RID_SVXPAGE_TEXTATTR")
+ return;
+
+ SdrObjKind eKind = OBJ_NONE;
+ if (pView)
+ {
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+ bool bHasMarked = rMarkList.GetMarkCount() > 0;
+ if (bHasMarked)
+ {
+ if (rMarkList.GetMarkCount() == 1)
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ eKind = static_cast<SdrObjKind>(pObj->GetObjIdentifier());
+ }
+ }
+ }
+ static_cast<SvxTextAttrPage&>(rPage).SetObjKind(eKind);
+ static_cast<SvxTextAttrPage&>(rPage).Construct();
+}
+
+/*************************************************************************
+|*
+|* Page
+|*
+\************************************************************************/
+SvxTextAnimationPage::SvxTextAnimationPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/textanimtabpage.ui", "TextAnimation", &rInAttrs)
+ , eAniKind(SdrTextAniKind::NONE)
+ , m_aUpState(TRISTATE_INDET)
+ , m_aLeftState(TRISTATE_INDET)
+ , m_aRightState(TRISTATE_INDET)
+ , m_aDownState(TRISTATE_INDET)
+ , m_xLbEffect(m_xBuilder->weld_combo_box("LB_EFFECT"))
+ , m_xBoxDirection(m_xBuilder->weld_widget("boxDIRECTION"))
+ , m_xBtnUp(m_xBuilder->weld_toggle_button("BTN_UP"))
+ , m_xBtnLeft(m_xBuilder->weld_toggle_button("BTN_LEFT"))
+ , m_xBtnRight(m_xBuilder->weld_toggle_button("BTN_RIGHT"))
+ , m_xBtnDown(m_xBuilder->weld_toggle_button("BTN_DOWN"))
+ , m_xFlProperties(m_xBuilder->weld_frame("FL_PROPERTIES"))
+ , m_xTsbStartInside(m_xBuilder->weld_check_button("TSB_START_INSIDE"))
+ , m_xTsbStopInside(m_xBuilder->weld_check_button("TSB_STOP_INSIDE"))
+ , m_xBoxCount(m_xBuilder->weld_widget("boxCOUNT"))
+ , m_xTsbEndless(m_xBuilder->weld_check_button("TSB_ENDLESS"))
+ , m_xNumFldCount(m_xBuilder->weld_spin_button("NUM_FLD_COUNT"))
+ , m_xTsbPixel(m_xBuilder->weld_check_button("TSB_PIXEL"))
+ , m_xMtrFldAmount(m_xBuilder->weld_metric_spin_button("MTR_FLD_AMOUNT", FieldUnit::PIXEL))
+ , m_xTsbAuto(m_xBuilder->weld_check_button("TSB_AUTO"))
+ , m_xMtrFldDelay(m_xBuilder->weld_metric_spin_button("MTR_FLD_DELAY", FieldUnit::MILLISECOND))
+{
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ m_xLbEffect->connect_changed( LINK( this, SvxTextAnimationPage, SelectEffectHdl_Impl ) );
+ m_xTsbEndless->connect_clicked( LINK( this, SvxTextAnimationPage, ClickEndlessHdl_Impl ) );
+ m_xTsbAuto->connect_clicked( LINK( this, SvxTextAnimationPage, ClickAutoHdl_Impl ) );
+ m_xTsbPixel->connect_clicked( LINK( this, SvxTextAnimationPage, ClickPixelHdl_Impl ) );
+
+ Link<weld::Button&,void> aLink( LINK( this, SvxTextAnimationPage, ClickDirectionHdl_Impl ) );
+ m_xBtnUp->connect_clicked( aLink );
+ m_xBtnLeft->connect_clicked( aLink );
+ m_xBtnRight->connect_clicked( aLink );
+ m_xBtnDown->connect_clicked( aLink );
+}
+
+SvxTextAnimationPage::~SvxTextAnimationPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAnimationPage::Reset( const SfxItemSet* rAttrs )
+{
+ const SfxItemPool* pPool = rAttrs->GetPool();
+
+ // animation type
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIKIND );
+
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIKIND );
+
+ eAniKind = static_cast<const SdrTextAniKindItem*>(pItem)->GetValue();
+ m_xLbEffect->set_active(sal::static_int_cast<sal_Int32>(eAniKind));
+ m_xLbEffect->save_value();
+
+ // animation direction
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDIRECTION );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDIRECTION );
+
+ SelectDirection(static_cast<const SdrTextAniDirectionItem*>(pItem)->GetValue());
+ m_aUpState = m_xBtnUp->get_state();
+ m_aLeftState = m_xBtnLeft->get_state();
+ m_aRightState = m_xBtnRight->get_state();
+ m_aDownState = m_xBtnDown->get_state();
+
+ // Start inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTARTINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTARTINSIDE );
+
+ if (static_cast<const SdrTextAniStartInsideItem*>(pItem)->GetValue())
+ m_xTsbStartInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStartInside->set_state(TRISTATE_FALSE);
+ m_xTsbStartInside->save_state();
+
+ // Stop inside
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANISTOPINSIDE );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANISTOPINSIDE );
+
+ if (static_cast<const SdrTextAniStopInsideItem*>(pItem)->GetValue())
+ m_xTsbStopInside->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbStopInside->set_state(TRISTATE_FALSE);
+ m_xTsbStopInside->save_state();
+
+ // quantity
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANICOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANICOUNT );
+
+ long nValue = static_cast<long>(static_cast<const SdrTextAniCountItem*>(pItem)->GetValue());
+ m_xNumFldCount->set_value(nValue);
+ if (nValue == 0)
+ {
+ if (eAniKind == SdrTextAniKind::Slide)
+ {
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->set_sensitive(false);
+ }
+ else
+ {
+ m_xTsbEndless->set_state(TRISTATE_TRUE);
+ m_xNumFldCount->set_text("");
+ }
+ }
+ else
+ m_xTsbEndless->set_state(TRISTATE_FALSE);
+ m_xTsbEndless->save_state();
+ m_xNumFldCount->save_value();
+
+ // delay
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIDELAY );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIDELAY );
+
+ nValue = static_cast<long>(static_cast<const SdrTextAniDelayItem*>(pItem)->GetValue());
+ m_xMtrFldDelay->set_value(nValue, FieldUnit::NONE);
+ if (nValue == 0)
+ {
+ m_xTsbAuto->set_state(TRISTATE_TRUE);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ m_xTsbAuto->set_state(TRISTATE_FALSE);
+ m_xTsbAuto->save_state();
+ m_xMtrFldDelay->save_value();
+
+ // step size
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_ANIAMOUNT );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_ANIAMOUNT );
+
+ nValue = static_cast<long>(static_cast<const SdrTextAniAmountItem*>(pItem)->GetValue());
+ if (nValue <= 0)
+ {
+ m_xTsbPixel->set_state(TRISTATE_TRUE);
+ nValue = -nValue;
+ if (nValue == 0)
+ nValue++;
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xTsbPixel->set_state(TRISTATE_FALSE);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ SetMetricValue(*m_xMtrFldAmount, nValue, eUnit);
+ }
+ m_xTsbPixel->save_state();
+ m_xMtrFldAmount->save_value();
+
+ SelectEffectHdl_Impl(*m_xLbEffect);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAnimationPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+ TriState eState;
+
+ // animation type
+ int nPos = m_xLbEffect->get_active();
+ if( nPos != -1 &&
+ m_xLbEffect->get_value_changed_from_saved() )
+ {
+ rAttrs->Put( SdrTextAniKindItem( static_cast<SdrTextAniKind>(nPos) ) );
+ bModified = true;
+ }
+
+ // animation direction
+ if (m_aUpState != m_xBtnUp->get_state() ||
+ m_aLeftState != m_xBtnLeft->get_state() ||
+ m_aRightState != m_xBtnRight->get_state() ||
+ m_aDownState != m_xBtnDown->get_state())
+ {
+ SdrTextAniDirection eValue = static_cast<SdrTextAniDirection>(GetSelectedDirection());
+ rAttrs->Put( SdrTextAniDirectionItem( eValue ) );
+ bModified = true;
+ }
+
+ // Start inside
+ eState = m_xTsbStartInside->get_state();
+ if (m_xTsbStartInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStartInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // Stop inside
+ eState = m_xTsbStopInside->get_state();
+ if (m_xTsbStopInside->get_state_changed_from_saved())
+ {
+ rAttrs->Put( SdrTextAniStopInsideItem( TRISTATE_TRUE == eState ) );
+ bModified = true;
+ }
+
+ // quantity
+ eState = m_xTsbEndless->get_state();
+ if (m_xTsbEndless->get_state_changed_from_saved() ||
+ m_xNumFldCount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE /*#89844#*/ && m_xTsbEndless->get_sensitive())
+ bModified = true;
+ else
+ {
+ if( m_xNumFldCount->get_value_changed_from_saved() )
+ {
+ nValue = m_xNumFldCount->get_value();
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniCountItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // delay
+ eState = m_xTsbAuto->get_state();
+ if (m_xTsbAuto->get_state_changed_from_saved() ||
+ m_xMtrFldDelay->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ bModified = true;
+ else
+ {
+ if( m_xMtrFldDelay->get_value_changed_from_saved() )
+ {
+ nValue = m_xMtrFldDelay->get_value(FieldUnit::NONE);
+ bModified = true;
+ }
+ }
+ if( bModified )
+ rAttrs->Put( SdrTextAniDelayItem( static_cast<sal_uInt16>(nValue) ) );
+ }
+
+ // step size
+ eState = m_xTsbPixel->get_state();
+ if (m_xTsbPixel->get_state_changed_from_saved() ||
+ m_xMtrFldAmount->get_value_changed_from_saved())
+ {
+ sal_Int64 nValue = 0;
+ if( eState == TRISTATE_TRUE )
+ {
+ nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE);
+ nValue = -nValue;
+ }
+ else
+ {
+ nValue = GetCoreValue( *m_xMtrFldAmount, eUnit );
+ }
+ rAttrs->Put( SdrTextAniAmountItem( static_cast<sal_Int16>(nValue) ) );
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+/*************************************************************************
+|*
+|* creates the page
+|*
+\************************************************************************/
+
+std::unique_ptr<SfxTabPage> SvxTextAnimationPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAnimationPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, SelectEffectHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xLbEffect->get_active();
+ if (nPos == -1)
+ return;
+
+ eAniKind = static_cast<SdrTextAniKind>(nPos);
+ switch( eAniKind )
+ {
+ case SdrTextAniKind::NONE:
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xFlProperties->set_sensitive(false);
+ }
+ break;
+
+ case SdrTextAniKind::Blink:
+ case SdrTextAniKind::Scroll:
+ case SdrTextAniKind::Alternate:
+ case SdrTextAniKind::Slide:
+ {
+ m_xFlProperties->set_sensitive(true);
+ if( eAniKind == SdrTextAniKind::Slide )
+ {
+ m_xTsbStartInside->set_sensitive(false);
+ m_xTsbStopInside->set_sensitive(false);
+ m_xTsbEndless->set_sensitive(false);
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+ else
+ {
+ m_xTsbStartInside->set_sensitive(true);
+ m_xTsbStopInside->set_sensitive(true);
+ m_xTsbEndless->set_sensitive(true);
+ ClickEndlessHdl_Impl(*m_xTsbEndless);
+ }
+
+ m_xTsbAuto->set_sensitive(true);
+ ClickAutoHdl_Impl(*m_xTsbAuto);
+
+ if( eAniKind == SdrTextAniKind::Blink )
+ {
+ m_xBoxDirection->set_sensitive(false);
+ m_xBoxCount->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxDirection->set_sensitive(true);
+ m_xBoxCount->set_sensitive(true);
+ }
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickEndlessHdl_Impl, weld::Button&, void)
+{
+ if( eAniKind == SdrTextAniKind::Slide )
+ return;
+
+ TriState eState = m_xTsbEndless->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xNumFldCount->set_sensitive(false);
+ m_xNumFldCount->set_text("");
+ }
+ else
+ {
+ m_xNumFldCount->set_sensitive(true);
+ m_xNumFldCount->set_value(m_xNumFldCount->get_value());
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickAutoHdl_Impl, weld::Button&, void)
+{
+ TriState eState = m_xTsbAuto->get_state();
+ if( eState != TRISTATE_FALSE )
+ {
+ m_xMtrFldDelay->set_sensitive(false);
+ m_xMtrFldDelay->set_text("");
+ }
+ else
+ {
+ m_xMtrFldDelay->set_sensitive(true);
+ m_xMtrFldDelay->set_value(m_xMtrFldDelay->get_value(FieldUnit::NONE), FieldUnit::NONE); //to-do
+ }
+}
+
+IMPL_LINK_NOARG(SvxTextAnimationPage, ClickPixelHdl_Impl, weld::Button&, void)
+{
+ TriState eState = m_xTsbPixel->get_state();
+ if (eState == TRISTATE_TRUE)
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) / 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(FieldUnit::CUSTOM);
+ m_xMtrFldAmount->set_digits(0);
+
+ m_xMtrFldAmount->set_increments(1, 10, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 100, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+ else if( eState == TRISTATE_FALSE )
+ {
+ int nValue = m_xMtrFldAmount->get_value(FieldUnit::NONE) * 10;
+ m_xMtrFldAmount->set_sensitive(true);
+ m_xMtrFldAmount->set_unit(eFUnit);
+ m_xMtrFldAmount->set_digits(2);
+
+ m_xMtrFldAmount->set_increments(10, 100, FieldUnit::NONE);
+ m_xMtrFldAmount->set_range(1, 10000, FieldUnit::NONE);
+
+ m_xMtrFldAmount->set_value(nValue, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK(SvxTextAnimationPage, ClickDirectionHdl_Impl, weld::Button&, rBtn, void)
+{
+ m_xBtnUp->set_active(&rBtn == m_xBtnUp.get());
+ m_xBtnLeft->set_active(&rBtn == m_xBtnLeft.get());
+ m_xBtnRight->set_active(&rBtn == m_xBtnRight.get());
+ m_xBtnDown->set_active(&rBtn == m_xBtnDown.get());
+}
+
+void SvxTextAnimationPage::SelectDirection( SdrTextAniDirection nValue )
+{
+ m_xBtnUp->set_active( nValue == SdrTextAniDirection::Up );
+ m_xBtnLeft->set_active( nValue == SdrTextAniDirection::Left );
+ m_xBtnRight->set_active( nValue == SdrTextAniDirection::Right );
+ m_xBtnDown->set_active( nValue == SdrTextAniDirection::Down );
+}
+
+sal_uInt16 SvxTextAnimationPage::GetSelectedDirection() const
+{
+ SdrTextAniDirection nValue = SdrTextAniDirection::Left;
+
+ if( m_xBtnUp->get_active() )
+ nValue = SdrTextAniDirection::Up;
+ else if( m_xBtnLeft->get_active() )
+ nValue = SdrTextAniDirection::Left;
+ else if( m_xBtnRight->get_active() )
+ nValue = SdrTextAniDirection::Right;
+ else if( m_xBtnDown->get_active() )
+ nValue = SdrTextAniDirection::Down;
+
+ return static_cast<sal_uInt16>(nValue);
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/textattr.cxx b/cui/source/tabpages/textattr.cxx
new file mode 100644
index 000000000..c9eaf461c
--- /dev/null
+++ b/cui/source/tabpages/textattr.cxx
@@ -0,0 +1,668 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svddef.hxx>
+#include <svx/sdasitm.hxx>
+#include <svx/sdtditm.hxx>
+#include <svx/sdtagitm.hxx>
+#include <svx/sdtaitm.hxx>
+#include <svx/sdtfsitm.hxx>
+#include <svx/sdtcfitm.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svxids.hrc>
+
+#include <textattr.hxx>
+#include <svx/dlgutil.hxx>
+#include <editeng/writingmodeitem.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace ::com::sun::star;
+
+const sal_uInt16 SvxTextAttrPage::pRanges[] =
+{
+ SDRATTR_MISC_FIRST
+ , SDRATTR_TEXT_HORZADJUST
+ , SDRATTR_TEXT_WORDWRAP
+ , SDRATTR_TEXT_WORDWRAP
+ , 0
+};
+
+/*************************************************************************
+|*
+|* dialog (page) for copying objects
+|*
+\************************************************************************/
+SvxTextAttrPage::SvxTextAttrPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/textattrtabpage.ui", "TextAttributesPage", rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , m_eObjKind(OBJ_NONE)
+ , bAutoGrowSizeEnabled(false)
+ , bContourEnabled(false)
+ , bAutoGrowWidthEnabled(false)
+ , bAutoGrowHeightEnabled(false)
+ , bWordWrapTextEnabled(false)
+ , bFitToSizeEnabled(false)
+ , m_aCtlPosition(this)
+ , m_xDrawingText(m_xBuilder->weld_widget("drawingtext"))
+ , m_xCustomShapeText(m_xBuilder->weld_widget("customshapetext"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+ , m_xTsbFitToSize(m_xBuilder->weld_check_button("TSB_FIT_TO_SIZE"))
+ , m_xTsbContour(m_xBuilder->weld_check_button("TSB_CONTOUR"))
+ , m_xTsbWordWrapText(m_xBuilder->weld_check_button("TSB_WORDWRAP_TEXT"))
+ , m_xTsbAutoGrowSize(m_xBuilder->weld_check_button("TSB_AUTOGROW_SIZE"))
+ , m_xFlDistance(m_xBuilder->weld_frame("FL_DISTANCE"))
+ , m_xMtrFldLeft(m_xBuilder->weld_metric_spin_button("MTR_FLD_LEFT", FieldUnit::CM))
+ , m_xMtrFldRight(m_xBuilder->weld_metric_spin_button("MTR_FLD_RIGHT", FieldUnit::CM))
+ , m_xMtrFldTop(m_xBuilder->weld_metric_spin_button("MTR_FLD_TOP", FieldUnit::CM))
+ , m_xMtrFldBottom(m_xBuilder->weld_metric_spin_button("MTR_FLD_BOTTOM", FieldUnit::CM))
+ , m_xFlPosition(m_xBuilder->weld_frame("FL_POSITION"))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xTsbFullWidth(m_xBuilder->weld_check_button("TSB_FULL_WIDTH"))
+{
+ m_aCtlPosition.SetControlSettings(RectPoint::MM, 240);
+
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xMtrFldLeft, eFUnit );
+ SetFieldUnit( *m_xMtrFldRight, eFUnit );
+ SetFieldUnit( *m_xMtrFldTop, eFUnit );
+ SetFieldUnit( *m_xMtrFldBottom, eFUnit );
+
+ Link<weld::Button&,void> aLink( LINK( this, SvxTextAttrPage, ClickHdl_Impl ) );
+ m_xTsbAutoGrowWidth->connect_clicked( aLink );
+ m_xTsbAutoGrowHeight->connect_clicked( aLink );
+ m_xTsbAutoGrowSize->connect_clicked( aLink );
+ m_xTsbFitToSize->connect_clicked( aLink );
+ m_xTsbContour->connect_clicked( aLink );
+
+ m_xTsbFullWidth->connect_clicked(LINK( this, SvxTextAttrPage, ClickFullWidthHdl_Impl ) );
+}
+
+SvxTextAttrPage::~SvxTextAttrPage()
+{
+}
+
+/*************************************************************************
+|*
+|* reads the passed item set
+|*
+\************************************************************************/
+
+void SvxTextAttrPage::Reset( const SfxItemSet* rAttrs )
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SDRATTR_TEXT_LEFTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LEFTDIST );
+
+ SetMetricValue(*m_xMtrFldLeft, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldLeft->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_RIGHTDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_RIGHTDIST );
+
+ SetMetricValue(*m_xMtrFldRight, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldRight->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_UPPERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_UPPERDIST );
+
+ SetMetricValue(*m_xMtrFldTop, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldTop->save_value();
+
+ pItem = GetItem( *rAttrs, SDRATTR_TEXT_LOWERDIST );
+ if( !pItem )
+ pItem = &pPool->GetDefaultItem( SDRATTR_TEXT_LOWERDIST );
+
+ SetMetricValue(*m_xMtrFldBottom, static_cast<const SdrMetricItem*>(pItem)->GetValue(), eUnit);
+ m_xMtrFldBottom->save_value();
+
+ // adjust to height and autogrowsize
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWHEIGHT ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowHeight->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+
+ m_xTsbAutoGrowSize->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWHEIGHT ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ {
+ m_xTsbAutoGrowHeight->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowSize->set_state( TRISTATE_INDET );
+ }
+ m_xTsbAutoGrowHeight->save_state();
+ m_xTsbAutoGrowSize->save_state();
+
+ // adjust to width
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_AUTOGROWWIDTH ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbAutoGrowWidth->set_state( rAttrs->Get( SDRATTR_TEXT_AUTOGROWWIDTH ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbAutoGrowWidth->set_state( TRISTATE_INDET );
+ m_xTsbAutoGrowWidth->save_state();
+
+ // wordwrap text
+ if ( rAttrs->GetItemState( SDRATTR_TEXT_WORDWRAP ) != SfxItemState::DONTCARE )
+ {
+ m_xTsbWordWrapText->set_state( rAttrs->Get( SDRATTR_TEXT_WORDWRAP ).
+ GetValue() ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbWordWrapText->set_state( TRISTATE_INDET );
+ m_xTsbWordWrapText->save_state();
+
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ // Setup center field and FullWidth
+ SfxItemState eVState = rAttrs->GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rAttrs->GetItemState( SDRATTR_TEXT_HORZADJUST );
+
+ if(SfxItemState::DONTCARE != eVState && SfxItemState::DONTCARE != eHState)
+ {
+ // VertAdjust and HorAdjust are unequivocal, thus
+ SdrTextVertAdjust eTVA = rAttrs->Get(SDRATTR_TEXT_VERTADJUST).GetValue();
+ SdrTextHorzAdjust eTHA = rAttrs->Get(SDRATTR_TEXT_HORZADJUST).GetValue();
+ RectPoint eRP = RectPoint::LB;
+
+ if (m_xTsbFullWidth->get_state() == TRISTATE_INDET)
+ m_xTsbFullWidth->set_state(TRISTATE_FALSE);
+
+ // Translate item values into local anchor position.
+ switch (eTVA)
+ {
+ case SDRTEXTVERTADJUST_TOP:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LT; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MT; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RT; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BLOCK:
+ case SDRTEXTVERTADJUST_CENTER:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LM; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MM; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RM; break;
+ }
+ break;
+ }
+ case SDRTEXTVERTADJUST_BOTTOM:
+ {
+ switch (eTHA)
+ {
+ case SDRTEXTHORZADJUST_LEFT: eRP = RectPoint::LB; break;
+ case SDRTEXTHORZADJUST_BLOCK:
+ case SDRTEXTHORZADJUST_CENTER: eRP = RectPoint::MB; break;
+ case SDRTEXTHORZADJUST_RIGHT: eRP = RectPoint::RB; break;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ // See if we have to check the "full width" check button.
+ bool bLeftToRight(IsTextDirectionLeftToRight());
+
+ if((bLeftToRight && (SDRTEXTHORZADJUST_BLOCK == eTHA)) || (!bLeftToRight && (SDRTEXTVERTADJUST_BLOCK == eTVA)))
+ {
+ // Move anchor to valid position.
+ ClickFullWidthHdl_Impl(*m_xTsbFullWidth);
+ m_xTsbFullWidth->set_state(TRISTATE_TRUE);
+ }
+
+ m_aCtlPosition.SetActualRP( eRP );
+ }
+ else
+ {
+ // VertAdjust or HorAdjust is not unequivocal
+ m_aCtlPosition.Reset();
+
+ m_aCtlPosition.SetState(CTL_STATE::NOVERT);
+ m_aCtlPosition.DoCompletelyDisable(true);
+
+ m_xTsbFullWidth->set_state(TRISTATE_INDET);
+ m_xFlPosition->set_sensitive( false );
+ }
+
+ // adjust to border
+ if (rAttrs->GetItemState(SDRATTR_TEXT_FITTOSIZE) != SfxItemState::DONTCARE)
+ {
+ drawing::TextFitToSizeType const eFTS =
+ rAttrs->Get( SDRATTR_TEXT_FITTOSIZE ).GetValue();
+ if (eFTS == drawing::TextFitToSizeType_AUTOFIT || eFTS == drawing::TextFitToSizeType_NONE)
+ m_xTsbFitToSize->set_state( TRISTATE_FALSE );
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_TRUE );
+ }
+ else
+ m_xTsbFitToSize->set_state( TRISTATE_INDET );
+ m_xTsbFitToSize->save_state();
+
+ if( rAttrs->GetItemState( SDRATTR_TEXT_CONTOURFRAME ) != SfxItemState::DONTCARE )
+ {
+ bool bContour = rAttrs->Get( SDRATTR_TEXT_CONTOURFRAME ).GetValue();
+ m_xTsbContour->set_state( bContour ? TRISTATE_TRUE : TRISTATE_FALSE );
+ }
+ else
+ m_xTsbContour->set_state( TRISTATE_INDET );
+ m_xTsbContour->save_state();
+
+ ClickHdl_Impl(*m_xTsbContour);
+}
+
+/*************************************************************************
+|*
+|* fills the passed item set with dialog box attributes
+|*
+\************************************************************************/
+
+bool SvxTextAttrPage::FillItemSet( SfxItemSet* rAttrs)
+{
+ SfxItemPool* pPool = rAttrs->GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ MapUnit eUnit = pPool->GetMetric( SDRATTR_TEXT_LEFTDIST );
+
+ sal_Int32 nValue;
+ TriState eState;
+
+ if( m_xMtrFldLeft->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldLeft, eUnit );
+ rAttrs->Put( makeSdrTextLeftDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldRight->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldRight, eUnit );
+ rAttrs->Put( makeSdrTextRightDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldTop->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldTop, eUnit );
+ rAttrs->Put( makeSdrTextUpperDistItem( nValue ) );
+ }
+
+ if( m_xMtrFldBottom->get_value_changed_from_saved() )
+ {
+ nValue = GetCoreValue( *m_xMtrFldBottom, eUnit );
+ rAttrs->Put( makeSdrTextLowerDistItem( nValue ) );
+ }
+
+ eState = m_xTsbAutoGrowHeight->get_state();
+ if( m_xTsbAutoGrowHeight->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowWidth->get_state();
+ if( m_xTsbAutoGrowWidth->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowWidthItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbAutoGrowSize->get_state();
+ if( m_xTsbAutoGrowSize->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextAutoGrowHeightItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbWordWrapText->get_state();
+ if( m_xTsbWordWrapText->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextWordWrapItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbContour->get_state();
+ if( m_xTsbContour->get_state_changed_from_saved() )
+ {
+ rAttrs->Put( makeSdrTextContourFrameItem( TRISTATE_TRUE == eState ) );
+ }
+
+ eState = m_xTsbFitToSize->get_state();
+ if( m_xTsbFitToSize->get_state_changed_from_saved() )
+ {
+ drawing::TextFitToSizeType eFTS;
+ switch( eState )
+ {
+ default: ; //prevent warning
+ OSL_FAIL( "svx::SvxTextAttrPage::FillItemSet(), unhandled state!" );
+ [[fallthrough]];
+ case TRISTATE_FALSE: eFTS = drawing::TextFitToSizeType_AUTOFIT; break;
+ case TRISTATE_TRUE: eFTS = drawing::TextFitToSizeType_PROPORTIONAL; break;
+ }
+ rAttrs->Put( SdrTextFitToSizeTypeItem( eFTS ) );
+ }
+
+ // centered
+ RectPoint eRP = m_aCtlPosition.GetActualRP();
+ SdrTextVertAdjust eTVA, eOldTVA;
+ SdrTextHorzAdjust eTHA, eOldTHA;
+
+ switch( eRP )
+ {
+ default:
+ case RectPoint::LT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::LB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_LEFT; break;
+ case RectPoint::MT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::MB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_CENTER; break;
+ case RectPoint::RT: eTVA = SDRTEXTVERTADJUST_TOP;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RM: eTVA = SDRTEXTVERTADJUST_CENTER;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ case RectPoint::RB: eTVA = SDRTEXTVERTADJUST_BOTTOM;
+ eTHA = SDRTEXTHORZADJUST_RIGHT; break;
+ }
+
+ // #103516# Do not change values if adjust controls were disabled.
+ bool bIsDisabled(m_aCtlPosition.IsCompletelyDisabled());
+
+ if(!bIsDisabled)
+ {
+ if( m_xTsbFullWidth->get_state() == TRISTATE_TRUE )
+ {
+ if (IsTextDirectionLeftToRight())
+ eTHA = SDRTEXTHORZADJUST_BLOCK;
+ else
+ eTVA = SDRTEXTVERTADJUST_BLOCK;
+ }
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST ) != SfxItemState::DONTCARE )
+ {
+ eOldTVA = rOutAttrs.Get( SDRATTR_TEXT_VERTADJUST ).GetValue();
+ if( eOldTVA != eTVA )
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+ }
+ else
+ rAttrs->Put( SdrTextVertAdjustItem( eTVA ) );
+
+ if ( rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST ) != SfxItemState::DONTCARE )
+ {
+ eOldTHA = rOutAttrs.Get( SDRATTR_TEXT_HORZADJUST ).GetValue();
+ if( eOldTHA != eTHA )
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+ }
+ else
+ rAttrs->Put( SdrTextHorzAdjustItem( eTHA ) );
+ }
+
+ return true;
+}
+
+void SvxTextAttrPage::Construct()
+{
+ switch (m_eObjKind)
+ {
+ case OBJ_NONE:
+ // indeterminate, show them all
+ bFitToSizeEnabled = bContourEnabled = bWordWrapTextEnabled =
+ bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->show();
+ m_xDrawingText->show();
+ break;
+ case OBJ_TEXT:
+ case OBJ_TITLETEXT:
+ case OBJ_OUTLINETEXT:
+ case OBJ_CAPTION:
+ // contour NOT possible for pure text objects
+ bContourEnabled = bWordWrapTextEnabled = bAutoGrowSizeEnabled = false;
+
+ // adjusting width and height is ONLY possible for pure text objects
+ bFitToSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = true;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ case OBJ_CUSTOMSHAPE:
+ bFitToSizeEnabled = bContourEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = true;
+ m_xDrawingText->hide();
+ m_xCustomShapeText->show();
+ break;
+ default:
+ bFitToSizeEnabled = bContourEnabled = true;
+ bWordWrapTextEnabled = bAutoGrowSizeEnabled = bAutoGrowWidthEnabled = bAutoGrowHeightEnabled = false;
+ m_xCustomShapeText->hide();
+ m_xDrawingText->show();
+ break;
+ }
+
+ m_xTsbAutoGrowHeight->set_visible( bAutoGrowHeightEnabled );
+ m_xTsbAutoGrowWidth->set_visible( bAutoGrowWidthEnabled );
+ m_xTsbFitToSize->set_visible( bFitToSizeEnabled );
+ m_xTsbContour->set_visible( bContourEnabled );
+ m_xTsbAutoGrowSize->set_visible( bAutoGrowSizeEnabled );
+ m_xTsbWordWrapText->set_visible( bWordWrapTextEnabled );
+}
+
+std::unique_ptr<SfxTabPage> SvxTextAttrPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTextAttrPage>(pPage, pController, *rAttrs);
+}
+
+/** Check whether we have to uncheck the "Full width" check box.
+*/
+void SvxTextAttrPage::PointChanged(weld::DrawingArea*, RectPoint eRP)
+{
+ if (m_xTsbFullWidth->get_state() != TRISTATE_TRUE)
+ return;
+
+ // Depending on write direction and currently checked anchor we have
+ // to uncheck the "full width" button.
+ if (IsTextDirectionLeftToRight())
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ case RectPoint::LM:
+ case RectPoint::LB:
+ case RectPoint::RT:
+ case RectPoint::RM:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+ else
+ switch (eRP)
+ {
+ case RectPoint::LT:
+ case RectPoint::MT:
+ case RectPoint::RT:
+ case RectPoint::LB:
+ case RectPoint::MB:
+ case RectPoint::RB:
+ m_xTsbFullWidth->set_state( TRISTATE_FALSE );
+ break;
+ default: ;//prevent warning
+ }
+}
+
+
+/*************************************************************************
+|*
+|* possibly changes the position of the position-control
+|*
+\************************************************************************/
+
+/** When switching the "full width" check button on the text anchor may have
+ to be moved to a valid and adjacent position. This position depends on
+ the current anchor position and the text writing direction.
+*/
+IMPL_LINK_NOARG(SvxTextAttrPage, ClickFullWidthHdl_Impl, weld::Button&, void)
+{
+ if( m_xTsbFullWidth->get_state() != TRISTATE_TRUE )
+ return;
+
+ if (IsTextDirectionLeftToRight())
+ {
+ // Move text anchor to horizontal middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::RT:
+ m_aCtlPosition.SetActualRP( RectPoint::MT );
+ break;
+
+ case RectPoint::LM:
+ case RectPoint::RM:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::LB:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::MB );
+ break;
+ default: ;//prevent warning
+ }
+ }
+ else
+ {
+ // Move text anchor to vertical middle axis.
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT:
+ case RectPoint::LB:
+ m_aCtlPosition.SetActualRP( RectPoint::LM );
+ break;
+
+ case RectPoint::MT:
+ case RectPoint::MB:
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ break;
+
+ case RectPoint::RT:
+ case RectPoint::RB:
+ m_aCtlPosition.SetActualRP( RectPoint::RM );
+ break;
+ default: ;//prevent warning
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* enables/disables "size at text" or "adjust to frame"
+|*
+\************************************************************************/
+
+IMPL_LINK(SvxTextAttrPage, ClickHdl_Impl, weld::Button&, rButton, void)
+{
+ if (&rButton == m_xTsbAutoGrowSize.get())
+ {
+ m_xTsbAutoGrowHeight->set_state(m_xTsbAutoGrowSize->get_state());
+ if (m_xTsbAutoGrowSize->get_state() == TRISTATE_TRUE)
+ {
+ m_xTsbFitToSize->set_state(TRISTATE_FALSE);
+ m_xTsbContour->set_state(TRISTATE_FALSE);
+ }
+ }
+ else if (&rButton == m_xTsbAutoGrowHeight.get())
+ m_xTsbAutoGrowSize->set_state(m_xTsbAutoGrowHeight->get_state());
+
+ bool bAutoGrowWidth = m_xTsbAutoGrowWidth->get_state() == TRISTATE_TRUE;
+ bool bAutoGrowHeight = m_xTsbAutoGrowHeight->get_state() == TRISTATE_TRUE;
+ bool bFitToSize = m_xTsbFitToSize->get_state() == TRISTATE_TRUE;
+ bool bContour = m_xTsbContour->get_state() == TRISTATE_TRUE;
+
+ m_xTsbContour->set_sensitive( !bFitToSize &&
+ !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ bContourEnabled );
+
+ m_xTsbAutoGrowWidth->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowWidthEnabled );
+
+ m_xTsbAutoGrowHeight->set_sensitive( !bFitToSize &&
+ !( bContour && bContourEnabled ) &&
+ bAutoGrowHeightEnabled );
+
+ m_xTsbFitToSize->set_sensitive( !( ( bAutoGrowWidth && bAutoGrowWidthEnabled ) || ( bAutoGrowHeight && bAutoGrowHeightEnabled ) ) &&
+ !( bContour && bContourEnabled ) &&
+ bFitToSizeEnabled );
+
+ // #101901# enable/disable metric fields and decorations dependent of contour
+ m_xFlDistance->set_sensitive(!bContour);
+
+ if( bContour && bContourEnabled )
+ {
+ m_xMtrFldLeft->set_value(0, FieldUnit::NONE);
+ m_xMtrFldRight->set_value(0, FieldUnit::NONE);
+ m_xMtrFldTop->set_value(0, FieldUnit::NONE);
+ m_xMtrFldBottom->set_value(0, FieldUnit::NONE);
+ }
+
+ // #103516# Do the setup based on states of hor/ver adjust
+ SfxItemState eVState = rOutAttrs.GetItemState( SDRATTR_TEXT_VERTADJUST );
+ SfxItemState eHState = rOutAttrs.GetItemState( SDRATTR_TEXT_HORZADJUST );
+ bool bHorAndVer(SfxItemState::DONTCARE == eVState || SfxItemState::DONTCARE == eHState);
+
+ // #83698# enable/disable text anchoring dependent of contour
+ m_xFlPosition->set_sensitive(!bContour && !bHorAndVer);
+}
+
+
+bool SvxTextAttrPage::IsTextDirectionLeftToRight() const
+{
+ // Determine the text writing direction with left to right as default.
+ bool bLeftToRightDirection = true;
+ SfxItemState eState = rOutAttrs.GetItemState(SDRATTR_TEXTDIRECTION);
+
+ if(SfxItemState::DONTCARE != eState)
+ {
+ const SvxWritingModeItem& rItem = rOutAttrs.Get(SDRATTR_TEXTDIRECTION);
+ if (rItem.GetValue() == css::text::WritingMode_TB_RL)
+ bLeftToRightDirection = false;
+ }
+ return bLeftToRightDirection;
+}
+
+void SvxTextAttrPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const CntUInt16Item* pObjTypeItem = aSet.GetItem<CntUInt16Item>(SID_SVXTEXTATTRPAGE_OBJKIND, false);
+
+ if (pObjTypeItem)
+ SetObjKind(static_cast<SdrObjKind>(pObjTypeItem->GetValue()));
+
+ Construct();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tparea.cxx b/cui/source/tabpages/tparea.cxx
new file mode 100644
index 000000000..079b717c3
--- /dev/null
+++ b/cui/source/tabpages/tparea.cxx
@@ -0,0 +1,465 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <cuitabarea.hxx>
+#include <sfx2/tabdlg.hxx>
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+namespace {
+
+enum FillType
+{
+ TRANSPARENT,
+ SOLID,
+ GRADIENT,
+ HATCH,
+ BITMAP,
+ PATTERN
+};
+
+}
+
+const sal_uInt16 SvxAreaTabPage::pAreaRanges[] =
+{
+ XATTR_GRADIENTSTEPCOUNT,
+ XATTR_GRADIENTSTEPCOUNT,
+ SID_ATTR_FILL_STYLE,
+ SID_ATTR_FILL_BITMAP,
+ 0
+};
+
+namespace
+{
+
+void lclExtendSize(Size& rSize, const Size& rInputSize)
+{
+ if (rSize.Width() < rInputSize.Width())
+ rSize.setWidth( rInputSize.Width() );
+ if (rSize.Height() < rInputSize.Height())
+ rSize.setHeight( rInputSize.Height() );
+}
+
+} // end anonymous namespace
+
+/*************************************************************************
+|*
+|* Dialog to modify fill-attributes
+|*
+\************************************************************************/
+
+SvxAreaTabPage::SvxAreaTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/areatabpage.ui", "AreaTabPage", &rInAttrs)
+ // local fixed not o be changed values for local pointers
+ , maFixed_ChangeType(ChangeType::NONE)
+ // init with pointers to fixed ChangeType
+ , m_pnColorListState(&maFixed_ChangeType)
+ , m_pnBitmapListState(&maFixed_ChangeType)
+ , m_pnPatternListState(&maFixed_ChangeType)
+ , m_pnGradientListState(&maFixed_ChangeType)
+ , m_pnHatchingListState(&maFixed_ChangeType)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xFillTab(m_xBuilder->weld_container("fillstylebox"))
+ , m_xBtnNone(m_xBuilder->weld_toggle_button("btnnone"))
+ , m_xBtnColor(m_xBuilder->weld_toggle_button("btncolor"))
+ , m_xBtnGradient(m_xBuilder->weld_toggle_button("btngradient"))
+ , m_xBtnHatch(m_xBuilder->weld_toggle_button("btnhatch"))
+ , m_xBtnBitmap(m_xBuilder->weld_toggle_button("btnbitmap"))
+ , m_xBtnPattern(m_xBuilder->weld_toggle_button("btnpattern"))
+{
+ maBox.AddButton(m_xBtnNone.get());
+ maBox.AddButton(m_xBtnColor.get());
+ maBox.AddButton(m_xBtnGradient.get());
+ maBox.AddButton(m_xBtnHatch.get());
+ maBox.AddButton(m_xBtnBitmap.get());
+ maBox.AddButton(m_xBtnPattern.get());
+ Link<weld::ToggleButton&, void> aLink = LINK(this, SvxAreaTabPage, SelectFillTypeHdl_Impl);
+ m_xBtnNone->connect_toggled(aLink);
+ m_xBtnColor->connect_toggled(aLink);
+ m_xBtnGradient->connect_toggled(aLink);
+ m_xBtnHatch->connect_toggled(aLink);
+ m_xBtnBitmap->connect_toggled(aLink);
+ m_xBtnPattern->connect_toggled(aLink);
+
+ SetExchangeSupport();
+}
+
+void SvxAreaTabPage::SetOptimalSize(weld::DialogController* pController)
+{
+ m_xFillTab->set_size_request(-1, -1);
+
+ // Calculate optimal size of all pages...
+ m_xFillTabPage = SvxColorTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aSize(m_xFillTab->get_preferred_size());
+
+ if (m_xBtnGradient->get_visible())
+ {
+ m_xFillTabPage = SvxGradientTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aGradientSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aGradientSize);
+ }
+ if (m_xBtnBitmap->get_visible())
+ {
+ m_xFillTabPage = SvxBitmapTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aBitmapSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aBitmapSize);
+ }
+ if (m_xBtnHatch->get_visible())
+ {
+ m_xFillTabPage = SvxHatchTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aHatchSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aHatchSize);
+ }
+ if (m_xBtnPattern->get_visible())
+ {
+ m_xFillTabPage = SvxPatternTabPage::Create(m_xFillTab.get(), pController, &m_rXFSet);
+ Size aPatternSize = m_xFillTab->get_preferred_size();
+ lclExtendSize(aSize, aPatternSize);
+ }
+ m_xFillTabPage.reset();
+
+ aSize.extendBy(10, 10); // apply a bit of margin
+
+ m_xFillTab->set_size_request(aSize.Width(), aSize.Height());
+}
+
+SvxAreaTabPage::~SvxAreaTabPage()
+{
+ m_xFillTabPage.reset();
+}
+
+void SvxAreaTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ drawing::FillStyle eXFS = drawing::FillStyle_NONE;
+ if( rSet.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ XFillStyleItem aFillStyleItem( static_cast<const XFillStyleItem&>( rSet.Get( GetWhich( XATTR_FILLSTYLE ) ) ) );
+ eXFS = aFillStyleItem.GetValue();
+ m_rXFSet.Put( aFillStyleItem );
+ }
+
+ switch(eXFS)
+ {
+ default:
+ case drawing::FillStyle_NONE:
+ {
+ SelectFillType(*m_xBtnNone);
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ m_rXFSet.Put( static_cast<const XFillColorItem&>( rSet.Get( GetWhich( XATTR_FILLCOLOR ) ) ) );
+ SelectFillType(*m_xBtnColor);
+ break;
+ }
+ case drawing::FillStyle_GRADIENT:
+ {
+ m_rXFSet.Put( static_cast<const XFillGradientItem&>( rSet.Get( GetWhich( XATTR_FILLGRADIENT ) ) ) );
+ SelectFillType(*m_xBtnGradient);
+ break;
+ }
+ case drawing::FillStyle_HATCH:
+ {
+ m_rXFSet.Put( rSet.Get(XATTR_FILLHATCH) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLBACKGROUND) );
+ m_rXFSet.Put( rSet.Get(XATTR_FILLCOLOR) );
+ SelectFillType(*m_xBtnHatch);
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ const bool bPattern
+ = rSet.Get(TypedWhichId<XFillBitmapItem>(GetWhich(XATTR_FILLBITMAP))).isPattern();
+ // pass full item set here, bitmap fill has many attributes (tiling, size, offset etc.)
+ m_rXFSet.Put( rSet );
+ if (!bPattern)
+ SelectFillType(*m_xBtnBitmap);
+ else
+ SelectFillType(*m_xBtnPattern);
+ break;
+ }
+ }
+}
+
+template< typename TTabPage >
+DeactivateRC SvxAreaTabPage::DeactivatePage_Impl( SfxItemSet* _pSet )
+{
+ return static_cast<TTabPage&>(*m_xFillTabPage).DeactivatePage(_pSet);
+}
+
+DeactivateRC SvxAreaTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ // Fill: None doesn't have its own tabpage and thus
+ // implementation of FillItemSet, so we supply it here
+ if ( m_bBtnClicked )
+ {
+ XFillStyleItem aStyleItem( drawing::FillStyle_NONE );
+ _pSet->Put( aStyleItem );
+ }
+ break;
+ }
+ case SOLID:
+ return DeactivatePage_Impl<SvxColorTabPage>(_pSet);
+ case GRADIENT:
+ return DeactivatePage_Impl<SvxGradientTabPage>(_pSet);
+ case HATCH:
+ return DeactivatePage_Impl<SvxHatchTabPage>(_pSet);
+ case BITMAP:
+ return DeactivatePage_Impl<SvxBitmapTabPage&>(_pSet);
+ case PATTERN:
+ return DeactivatePage_Impl<SvxPatternTabPage>(_pSet);
+ default:
+ break;
+ }
+ return DeactivateRC::LeavePage;
+}
+
+template< typename TTabPage >
+bool SvxAreaTabPage::FillItemSet_Impl( SfxItemSet* rAttrs)
+{
+ return static_cast<TTabPage&>( *m_xFillTabPage ).FillItemSet( rAttrs );
+}
+
+bool SvxAreaTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ switch( eFillType )
+ {
+ case TRANSPARENT:
+ {
+ rAttrs->Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+ return true;
+ }
+ case SOLID:
+ {
+ return FillItemSet_Impl<SvxColorTabPage>( rAttrs );
+ }
+ case GRADIENT:
+ {
+ return FillItemSet_Impl<SvxGradientTabPage>( rAttrs );
+ }
+ case HATCH:
+ {
+ return FillItemSet_Impl<SvxHatchTabPage>( rAttrs );
+ }
+ case BITMAP:
+ {
+ return FillItemSet_Impl<SvxBitmapTabPage>( rAttrs );
+ }
+ case PATTERN:
+ {
+ return FillItemSet_Impl<SvxPatternTabPage>( rAttrs );
+ }
+ default:
+ return false;
+ }
+}
+
+template< typename TTabPage >
+void SvxAreaTabPage::Reset_Impl( const SfxItemSet* rAttrs )
+{
+ static_cast<TTabPage&>( *m_xFillTabPage ).Reset( rAttrs );
+}
+
+void SvxAreaTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ m_bBtnClicked = false;
+ auto eFillType = maBox.GetCurrentButtonPos();
+ switch(eFillType)
+ {
+ case SOLID:
+ {
+ Reset_Impl<SvxColorTabPage>( rAttrs );
+ break;
+ }
+ case GRADIENT:
+ {
+ Reset_Impl<SvxGradientTabPage>( rAttrs );
+ break;
+ }
+ case HATCH:
+ {
+ Reset_Impl<SvxHatchTabPage>( rAttrs );
+ break;
+ }
+ case BITMAP:
+ {
+ Reset_Impl<SvxBitmapTabPage>( rAttrs );
+ break;
+ }
+ case PATTERN:
+ {
+ Reset_Impl<SvxPatternTabPage>( rAttrs );
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxAreaTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ auto xRet = std::make_unique<SvxAreaTabPage>(pPage, pController, *rAttrs);
+ xRet->SetOptimalSize(pController);
+ return xRet;
+}
+
+namespace {
+
+std::unique_ptr<SfxTabPage> lcl_CreateFillStyleTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case TRANSPARENT: fnCreate = nullptr; break;
+ case SOLID: fnCreate = &SvxColorTabPage::Create; break;
+ case GRADIENT: fnCreate = &SvxGradientTabPage::Create; break;
+ case HATCH: fnCreate = &SvxHatchTabPage::Create; break;
+ case BITMAP: fnCreate = &SvxBitmapTabPage::Create; break;
+ case PATTERN: fnCreate = &SvxPatternTabPage::Create; break;
+ }
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+}
+
+IMPL_LINK(SvxAreaTabPage, SelectFillTypeHdl_Impl, weld::ToggleButton&, rButton, void)
+{
+ //tdf#124549 - If the button is already active do not toggle it back.
+ if(!rButton.get_active())
+ rButton.set_active(true);
+
+ SelectFillType(rButton);
+ m_bBtnClicked = true;
+}
+
+void SvxAreaTabPage::SelectFillType(weld::ToggleButton& rButton, const SfxItemSet* _pSet)
+{
+ if (_pSet)
+ m_rXFSet.Set(*_pSet);
+
+ sal_Int32 nPos = maBox.GetButtonPos(&rButton);
+ if (nPos != -1 && (_pSet || nPos != maBox.GetCurrentButtonPos()))
+ {
+ maBox.SelectButton(&rButton);
+ FillType eFillType = static_cast<FillType>(maBox.GetCurrentButtonPos());
+ m_xFillTabPage = lcl_CreateFillStyleTabPage(eFillType, m_xFillTab.get(), GetDialogController(), m_rXFSet);
+ if (m_xFillTabPage)
+ m_xFillTabPage->SetDialogController(GetDialogController());
+ CreatePage(eFillType, m_xFillTabPage.get());
+ }
+}
+
+void SvxAreaTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SvxGradientListItem* pGradientListItem = aSet.GetItem<SvxGradientListItem>(SID_GRADIENT_LIST, false);
+ const SvxHatchListItem* pHatchingListItem = aSet.GetItem<SvxHatchListItem>(SID_HATCH_LIST, false);
+ const SvxBitmapListItem* pBitmapListItem = aSet.GetItem<SvxBitmapListItem>(SID_BITMAP_LIST, false);
+ const SvxPatternListItem* pPatternListItem = aSet.GetItem<SvxPatternListItem>(SID_PATTERN_LIST, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pGradientListItem)
+ SetGradientList(pGradientListItem->GetGradientList());
+ if (pHatchingListItem)
+ SetHatchingList(pHatchingListItem->GetHatchList());
+ if (pBitmapListItem)
+ SetBitmapList(pBitmapListItem->GetBitmapList());
+ if (pPatternListItem)
+ SetPatternList(pPatternListItem->GetPatternList());
+}
+
+void SvxAreaTabPage::CreatePage( sal_Int32 nId, SfxTabPage* pTab )
+{
+ if(nId == SOLID )
+ {
+ auto* pColorTab = static_cast<SvxColorTabPage*>(pTab);
+ pColorTab->SetColorList(m_pColorList);
+ pColorTab->SetColorChgd(m_pnColorListState);
+ pColorTab->Construct();
+ pColorTab->ActivatePage(m_rXFSet);
+ pColorTab->Reset(&m_rXFSet);
+ pColorTab->set_visible(true);
+ }
+ else if(nId == GRADIENT)
+ {
+ auto* pGradientTab = static_cast<SvxGradientTabPage*>(pTab);
+ pGradientTab->SetColorList(m_pColorList);
+ pGradientTab->SetGradientList(m_pGradientList);
+ pGradientTab->SetGrdChgd(m_pnGradientListState);
+ pGradientTab->SetColorChgd(m_pnColorListState);
+ pGradientTab->Construct();
+ pGradientTab->ActivatePage(m_rXFSet);
+ pGradientTab->Reset(&m_rXFSet);
+ pGradientTab->set_visible(true);
+ }
+ else if(nId == HATCH)
+ {
+ auto* pHatchTab = static_cast<SvxHatchTabPage*>(pTab);
+ pHatchTab->SetColorList(m_pColorList);
+ pHatchTab->SetHatchingList(m_pHatchingList);
+ pHatchTab->SetHtchChgd(m_pnHatchingListState);
+ pHatchTab->SetColorChgd(m_pnColorListState);
+ pHatchTab->Construct();
+ pHatchTab->ActivatePage(m_rXFSet);
+ pHatchTab->Reset(&m_rXFSet);
+ pHatchTab->set_visible(true);
+ }
+ else if(nId == BITMAP)
+ {
+ auto* pBitmapTab = static_cast<SvxBitmapTabPage*>(pTab);
+ pBitmapTab->SetBitmapList(m_pBitmapList);
+ pBitmapTab->SetBmpChgd(m_pnBitmapListState);
+ pBitmapTab->Construct();
+ pBitmapTab->ActivatePage(m_rXFSet);
+ pBitmapTab->Reset(&m_rXFSet);
+ pBitmapTab->set_visible(true);
+ }
+ else if(nId == PATTERN)
+ {
+ auto* pPatternTab = static_cast<SvxPatternTabPage*>(pTab);
+ pPatternTab->SetColorList(m_pColorList);
+ pPatternTab->SetPatternList(m_pPatternList);
+ pPatternTab->SetPtrnChgd(m_pnPatternListState);
+ pPatternTab->SetColorChgd(m_pnColorListState);
+ pPatternTab->Construct();
+ pPatternTab->ActivatePage(m_rXFSet);
+ pPatternTab->Reset(&m_rXFSet);
+ pPatternTab->set_visible(true);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpbitmap.cxx b/cui/source/tabpages/tpbitmap.cxx
new file mode 100644
index 000000000..87f22835a
--- /dev/null
+++ b/cui/source/tabpages/tpbitmap.cxx
@@ -0,0 +1,825 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <stdlib.h>
+#include <tools/urlobj.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/svxids.hrc>
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmsxy.hxx>
+#include <svx/xflbmtit.hxx>
+#include <svx/xflbstit.hxx>
+#include <svx/xflbmsli.hxx>
+#include <svx/xflbmpit.hxx>
+#include <svx/xflboxy.hxx>
+#include <svx/xflbtoxy.hxx>
+#include <cuitabarea.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svl/intitem.hxx>
+#include <sfx2/opengrf.hxx>
+#include <vcl/image.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <sal/log.hxx>
+#include <comphelper/lok.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+namespace {
+
+enum BitmapStyle
+{
+ CUSTOM,
+ TILED,
+ STRETCHED
+};
+
+enum TileOffset
+{
+ ROW,
+ COLUMN
+};
+
+}
+
+const sal_uInt16 SvxBitmapTabPage::pBitmapRanges[] =
+{
+ SID_ATTR_TRANSFORM_WIDTH,
+ SID_ATTR_TRANSFORM_HEIGHT,
+ 0
+};
+
+SvxBitmapTabPage::SvxBitmapTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/bitmaptabpage.ui", "BitmapTabPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnBitmapListState(nullptr)
+ , m_fObjectWidth(0.0)
+ , m_fObjectHeight(0.0)
+ , m_bLogicalSize(false)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , mpView(nullptr)
+ , m_xBitmapLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("bitmapwin")))
+ , m_xBitmapStyleLB(m_xBuilder->weld_combo_box("bitmapstyle"))
+ , m_xSizeBox(m_xBuilder->weld_container("sizebox"))
+ , m_xTsbScale(m_xBuilder->weld_check_button("scaletsb"))
+ , m_xBitmapWidth(m_xBuilder->weld_metric_spin_button("width", FieldUnit::PERCENT))
+ , m_xBitmapHeight(m_xBuilder->weld_metric_spin_button("height", FieldUnit::PERCENT))
+ , m_xPositionBox(m_xBuilder->weld_container("posbox"))
+ , m_xPositionLB(m_xBuilder->weld_combo_box("positionlb"))
+ , m_xPositionOffBox(m_xBuilder->weld_container("posoffbox"))
+ , m_xPositionOffX(m_xBuilder->weld_metric_spin_button("posoffx", FieldUnit::PERCENT))
+ , m_xPositionOffY(m_xBuilder->weld_metric_spin_button("posoffy", FieldUnit::PERCENT))
+ , m_xTileOffBox(m_xBuilder->weld_container("tileoffbox"))
+ , m_xTileOffLB(m_xBuilder->weld_combo_box("tileofflb"))
+ , m_xTileOffset(m_xBuilder->weld_metric_spin_button("tileoffmtr", FieldUnit::PERCENT))
+ , m_xBtnImport(m_xBuilder->weld_button("BTN_IMPORT"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_BITMAP_PREVIEW", m_aCtlBitmapPreview))
+ , m_xBitmapLBWin(new weld::CustomWeld(*m_xBuilder, "BITMAP", *m_xBitmapLB))
+{
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_xBitmapLB->SetSelectHdl( LINK(this, SvxBitmapTabPage, ModifyBitmapHdl) );
+ m_xBitmapLB->SetRenameHdl( LINK(this, SvxBitmapTabPage, ClickRenameHdl) );
+ m_xBitmapLB->SetDeleteHdl( LINK(this, SvxBitmapTabPage, ClickDeleteHdl) );
+ m_xBitmapStyleLB->connect_changed( LINK(this, SvxBitmapTabPage, ModifyBitmapStyleHdl) );
+ Link<weld::MetricSpinButton&, void> aLink1( LINK(this, SvxBitmapTabPage, ModifyBitmapSizeHdl) );
+ m_xBitmapWidth->connect_value_changed( aLink1 );
+ m_xBitmapHeight->connect_value_changed( aLink1 );
+ m_xTsbScale->connect_clicked(LINK(this, SvxBitmapTabPage, ClickScaleHdl));
+ m_xPositionLB->connect_changed( LINK( this, SvxBitmapTabPage, ModifyBitmapPositionHdl ) );
+ Link<weld::MetricSpinButton&, void> aLink( LINK( this, SvxBitmapTabPage, ModifyPositionOffsetHdl ) );
+ m_xPositionOffX->connect_value_changed(aLink);
+ m_xPositionOffY->connect_value_changed(aLink);
+ m_xTileOffset->connect_value_changed( LINK( this, SvxBitmapTabPage, ModifyTileOffsetHdl ) );
+ m_xBtnImport->connect_clicked( LINK(this, SvxBitmapTabPage, ClickImportHdl) );
+ if (comphelper::LibreOfficeKit::isActive())
+ m_xBtnImport->hide();
+
+ // Calculate size of display boxes
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlBitmapPreview.GetDrawingArea()->get_ref_device());
+ m_xBitmapLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlBitmapPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ SfxItemPool* pPool = m_rXFSet.GetPool();
+ mePoolUnit = pPool->GetMetric( XATTR_FILLBMP_SIZEX );
+ meFieldUnit = GetModuleFieldUnit( rInAttrs );
+ SetFieldUnit( *m_xBitmapWidth, meFieldUnit, true );
+ SetFieldUnit( *m_xBitmapHeight, meFieldUnit, true );
+
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+ if( pViewShell )
+ mpView = pViewShell->GetDrawView();
+ DBG_ASSERT( mpView, "no valid view (!)" );
+}
+
+SvxBitmapTabPage::~SvxBitmapTabPage()
+{
+ m_xBitmapLBWin.reset();
+ m_xBitmapLB.reset();
+ m_xCtlBitmapPreview.reset();
+}
+
+void SvxBitmapTabPage::Construct()
+{
+ m_xBitmapLB->FillPresetListBox( *m_pBitmapList );
+}
+
+void SvxBitmapTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ XFillBitmapItem aItem( rSet.Get(XATTR_FILLBITMAP) );
+
+ sal_Int32 nPos( 0 );
+ if ( !aItem.isPattern() )
+ {
+ nPos = SearchBitmapList( aItem.GetGraphicObject() );
+ if (nPos == -1)
+ return;
+ }
+ else
+ {
+ m_xBitmapWidth->set_value( 100, FieldUnit::NONE );
+ m_xBitmapHeight->set_value( 100, FieldUnit::NONE );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeXItem( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) ) );
+ const_cast<SfxItemSet&>(rSet).Put( XFillBmpSizeYItem( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) ) );
+ }
+
+ sal_uInt16 nId = m_xBitmapLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xBitmapLB->SelectItem( nId );
+}
+
+DeactivateRC SvxBitmapTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxBitmapTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ rAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pBitmapList->GetBitmap(nPos);
+ const OUString aString(m_xBitmapLB->GetItemText( m_xBitmapLB->GetSelectedItemId() ));
+ rAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ rAttrs->Put( XFillBmpTileItem(bIsTiled) );
+ rAttrs->Put( XFillBmpStretchItem(bIsStretched) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->get_value(FieldUnit::NONE);
+ sal_Int64 nHeightPercent = m_xBitmapHeight->get_value(FieldUnit::NONE);
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth( -nWidthPercent );
+ aSetBitmapSize.setHeight( -nHeightPercent );
+ }
+ else if (!m_bLogicalSize)
+ {
+ aSetBitmapSize.setWidth( GetCoreValue(*m_xBitmapWidth, mePoolUnit) );
+ aSetBitmapSize.setHeight( GetCoreValue(*m_xBitmapHeight, mePoolUnit) );
+ }
+ else
+ {
+ rAttrs->Put( XFillBmpSizeLogItem(true) );
+ aSetBitmapSize.setWidth( 0 );
+ aSetBitmapSize.setHeight( 0 );
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ rAttrs->Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ rAttrs->Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ if (m_xPositionLB->get_sensitive())
+ rAttrs->Put( XFillBmpPosItem( static_cast<RectPoint>( m_xPositionLB->get_active() ) ) );
+ if (m_xPositionOffX->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetXItem(m_xPositionOffX->get_value(FieldUnit::PERCENT)));
+ if (m_xPositionOffY->get_sensitive())
+ rAttrs->Put( XFillBmpPosOffsetYItem(m_xPositionOffY->get_value(FieldUnit::PERCENT)));
+ if (m_xTileOffBox->get_sensitive())
+ {
+ TileOffset eValue = static_cast<TileOffset>(m_xTileOffLB->get_active());
+ sal_uInt16 nOffsetValue = static_cast<sal_uInt16>(m_xTileOffset->get_value(FieldUnit::PERCENT));
+ sal_uInt16 nRowOff = (eValue == ROW) ? nOffsetValue : 0;
+ sal_uInt16 nColOff = (eValue == COLUMN) ? nOffsetValue : 0;
+ rAttrs->Put( XFillBmpTileOffsetXItem(nRowOff) );
+ rAttrs->Put( XFillBmpTileOffsetYItem(nColOff) );
+ }
+ return true;
+}
+
+
+void SvxBitmapTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ double transfWidth = 0.0;
+ double transfHeight = 0.0;
+ double fUIScale = 1.0;
+ if (mpView)
+ {
+ fUIScale = ( mpView->GetModel() ? double(mpView->GetModel()->GetUIScale()) : 1.0);
+
+
+ if (mpView->AreObjectsMarked())
+ {
+ SfxItemSet rGeoAttr(mpView->GetGeoAttrFromMarked());
+ transfWidth = static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_WIDTH )->GetValue());
+ transfHeight= static_cast<double>(GetItem( rGeoAttr, SID_ATTR_TRANSFORM_HEIGHT )->GetValue());
+ }
+ }
+ m_fObjectWidth = std::max( transfWidth, 1.0 );
+ m_fObjectHeight = std::max( transfHeight, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectWidth), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectWidth = fTmpWidth;
+
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(m_fObjectHeight), mePoolUnit, MapUnit::Map100thMM )) / fUIScale);
+ m_fObjectHeight = fTmpHeight;
+
+ XFillBitmapItem aItem( rAttrs->Get(XATTR_FILLBITMAP) );
+
+ if(!aItem.isPattern())
+ {
+ m_rXFSet.Put( aItem );
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ pGraphicObject.reset( new GraphicObject(aItem.GetGraphicObject()) );
+
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ rBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aTempBitmapSize, MapMode(MapUnit::Map100thMM));
+ CalculateBitmapPresetSize();
+
+ bool bTiled = false; bool bStretched = false;
+ if(rAttrs->GetItemState( XATTR_FILLBMP_TILE ) != SfxItemState::DONTCARE)
+ bTiled = rAttrs->Get( XATTR_FILLBMP_TILE ).GetValue();
+ if(rAttrs->GetItemState( XATTR_FILLBMP_STRETCH ) != SfxItemState::DONTCARE)
+ bStretched = rAttrs->Get( XATTR_FILLBMP_STRETCH ).GetValue();
+
+ if (bTiled)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(TILED));
+ else if (bStretched)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(STRETCHED));
+ else
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+
+ long nWidth = 0;
+ long nHeight = 0;
+
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZELOG) != SfxItemState::DONTCARE)
+ {
+ if (rAttrs->Get( XATTR_FILLBMP_SIZELOG ).GetValue())
+ {
+ m_xTsbScale->set_state(TRISTATE_FALSE);
+ m_bLogicalSize = true;
+ }
+ else
+ {
+ m_xTsbScale->set_state(TRISTATE_TRUE);
+ m_bLogicalSize = false;
+ }
+ }
+ else
+ m_xTsbScale->set_state(TRISTATE_INDET);
+
+ TriState eRelative = TRISTATE_FALSE;
+ if(rAttrs->GetItemState(XATTR_FILLBMP_SIZEX) != SfxItemState::DONTCARE)
+ {
+ nWidth = static_cast<const XFillBmpSizeXItem&>( rAttrs->Get( XATTR_FILLBMP_SIZEX ) ).GetValue();
+ if(nWidth == 0)
+ nWidth = rBitmapSize.Width();
+ else if(nWidth < 0)
+ {
+ eRelative = TRISTATE_TRUE;
+ nWidth = std::abs(nWidth);
+ }
+ }
+
+ if(rAttrs->GetItemState( XATTR_FILLBMP_SIZEY ) != SfxItemState::DONTCARE)
+ {
+ nHeight = rAttrs->Get( XATTR_FILLBMP_SIZEY ).GetValue();
+ if(nHeight == 0)
+ nHeight = rBitmapSize.Height();
+ else if(nHeight < 0)
+ {
+ eRelative = TRISTATE_TRUE;
+ nHeight = std::abs(nHeight);
+ }
+ }
+ m_xTsbScale->set_state(eRelative);
+ ClickScaleHdl(*m_xTsbScale);
+
+
+ if(!rBitmapSize.IsEmpty())
+ {
+ if (eRelative == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_value(nWidth, FieldUnit::NONE);
+ m_xBitmapHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ SetMetricValue(*m_xBitmapWidth, nWidth, mePoolUnit);
+ SetMetricValue(*m_xBitmapHeight, nHeight, mePoolUnit);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POS ) != SfxItemState::DONTCARE )
+ {
+ RectPoint eValue = rAttrs->Get( XATTR_FILLBMP_POS ).GetValue();
+ m_xPositionLB->set_active( static_cast< sal_Int32 >(eValue) );
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETX ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETX ).GetValue();
+ m_xPositionOffX->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffX->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_POSOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_POSOFFSETY ).GetValue();
+ m_xPositionOffY->set_value(nValue, FieldUnit::PERCENT);
+ }
+ else
+ m_xPositionOffY->set_text("");
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETX ) != SfxItemState::DONTCARE)
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETX ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(ROW));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ if( rAttrs->GetItemState( XATTR_FILLBMP_TILEOFFSETY ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nValue = rAttrs->Get( XATTR_FILLBMP_TILEOFFSETY ).GetValue();
+ if(nValue > 0)
+ {
+ m_xTileOffLB->set_active(static_cast<sal_Int32>(COLUMN));
+ m_xTileOffset->set_value(nValue, FieldUnit::PERCENT);
+ }
+ }
+
+ ClickBitmapHdl_Impl();
+}
+
+std::unique_ptr<SfxTabPage> SvxBitmapTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxBitmapTabPage>(pPage, pController, *rAttrs);
+}
+
+void SvxBitmapTabPage::ClickBitmapHdl_Impl()
+{
+ m_xBitmapLBWin->set_sensitive(true);
+ m_xCtlBitmapPreview->set_sensitive(true);
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+}
+
+void SvxBitmapTabPage::CalculateBitmapPresetSize()
+{
+ if(rBitmapSize.IsEmpty())
+ return;
+
+ long nObjectWidth = static_cast<long>(m_fObjectWidth);
+ long nObjectHeight = static_cast<long>(m_fObjectHeight);
+
+ if(std::abs(rBitmapSize.Width() - nObjectWidth) < std::abs(rBitmapSize.Height() - nObjectHeight))
+ {
+ rFilledSize.setWidth( nObjectWidth );
+ rFilledSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ rZoomedSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rZoomedSize.setHeight( nObjectHeight );
+ }
+ else
+ {
+ rFilledSize.setWidth( rBitmapSize.Width()*nObjectHeight/rBitmapSize.Height() );
+ rFilledSize.setHeight( nObjectHeight );
+ rZoomedSize.setWidth( nObjectWidth );
+ rZoomedSize.setHeight( rBitmapSize.Height()*nObjectWidth/rBitmapSize.Width() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapHdl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ const SfxPoolItem* pPoolItem = nullptr;
+
+ if(SfxItemState::SET == m_rOutAttrs.GetItemState(GetWhich(XATTR_FILLSTYLE), true, &pPoolItem))
+ {
+ const drawing::FillStyle eXFS(static_cast<const XFillStyleItem*>(pPoolItem)->GetValue());
+
+ if((drawing::FillStyle_BITMAP == eXFS) && (SfxItemState::SET == m_rOutAttrs.GetItemState(GetWhich(XATTR_FILLBITMAP), true, &pPoolItem)))
+ {
+ pGraphicObject.reset(new GraphicObject(static_cast<const XFillBitmapItem*>(pPoolItem)->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nId = m_xBitmapLB->GetItemId(0);
+ m_xBitmapLB->SelectItem(nId);
+
+ if(0 != nId)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pBitmapList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(pGraphicObject)
+ {
+ BitmapEx aBmpEx(pGraphicObject->GetGraphic().GetBitmapEx());
+ Size aTempBitmapSize = aBmpEx.GetSizePixel();
+ const double fUIScale = ( (mpView && mpView->GetModel()) ? double(mpView->GetModel()->GetUIScale()) : 1.0);
+
+ rBitmapSize.setWidth( (OutputDevice::LogicToLogic(static_cast<sal_Int32>(aTempBitmapSize.Width()),MapUnit::MapPixel, MapUnit::Map100thMM )) / fUIScale );
+ rBitmapSize.setHeight( (OutputDevice::LogicToLogic(static_cast<sal_Int32>(aTempBitmapSize.Height()),MapUnit::MapPixel, MapUnit::Map100thMM )) / fUIScale );
+ CalculateBitmapPresetSize();
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+ ModifyBitmapPositionHdl( *m_xPositionLB );
+
+ m_rXFSet.ClearItem(XATTR_FILLBITMAP);
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), *pGraphicObject));
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+ }
+ else
+ {
+ SAL_WARN("cui.tabpages", "SvxBitmapTabPage::ModifyBitmapHdl(): null pGraphicObject");
+ }
+
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickRenameHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_NEW_BITMAP ) );
+ OUString aName( m_pBitmapList->GetBitmap( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nBitmapPos = SearchBitmapList( aName );
+ bool bValidBitmapName = (nBitmapPos == static_cast<sal_Int32>(nPos) ) || (nBitmapPos == -1);
+
+ if(bValidBitmapName)
+ {
+ bLoop = false;
+ m_pBitmapList->GetBitmap(nPos)->SetName(aName);
+
+ m_xBitmapLB->SetItemText(nId, aName);
+ m_xBitmapLB->SelectItem( nId );
+
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickDeleteHdl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xBitmapLB->GetSelectedItemId();
+ size_t nPos = m_xBitmapLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pBitmapList->Remove( static_cast<sal_uInt16>(nPos) );
+ m_xBitmapLB->RemoveItem( nId );
+ nId = m_xBitmapLB->GetItemId(0);
+ m_xBitmapLB->SelectItem( nId );
+
+ m_aCtlBitmapPreview.Invalidate();
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+ }
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapSizeHdl, weld::MetricSpinButton&, void )
+{
+ m_bLogicalSize = false;
+ if (m_xTsbScale->get_state() != TRISTATE_TRUE && static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active()) != TILED)
+ {
+ sal_Int64 nWidthPercent = m_xBitmapWidth->denormalize(m_xBitmapWidth->get_value(FieldUnit::NONE));
+ sal_Int64 nHeightPercent = m_xBitmapHeight->denormalize(m_xBitmapHeight->get_value(FieldUnit::NONE));
+ if (nWidthPercent == 100 && nHeightPercent == 100)
+ m_xBitmapStyleLB->set_active(static_cast<sal_Int32>(CUSTOM));
+ }
+ ModifyBitmapStyleHdl(*m_xBitmapStyleLB);
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ClickScaleHdl, weld::Button&, void )
+{
+ if (m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ m_xBitmapWidth->set_digits( 0 );
+ m_xBitmapWidth->set_unit(FieldUnit::PERCENT);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 100, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 0 );
+ m_xBitmapHeight->set_unit(FieldUnit::PERCENT);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 100, FieldUnit::NONE);
+ }
+ else
+ {
+ m_xBitmapWidth->set_digits( 2 );
+ m_xBitmapWidth->set_unit(meFieldUnit);
+ m_xBitmapWidth->set_value(100, FieldUnit::NONE);
+ m_xBitmapWidth->set_range(0, 999900, FieldUnit::NONE);
+
+ m_xBitmapHeight->set_digits( 2 );
+ m_xBitmapHeight->set_unit(meFieldUnit);
+ m_xBitmapHeight->set_value(100, FieldUnit::NONE);
+ m_xBitmapHeight->set_range(0, 999900, FieldUnit::NONE);
+ }
+
+ ModifyBitmapStyleHdl( *m_xBitmapStyleLB );
+}
+
+IMPL_LINK_NOARG( SvxBitmapTabPage, ModifyBitmapStyleHdl, weld::ComboBox&, void )
+{
+ BitmapStyle eStylePos = static_cast<BitmapStyle>(m_xBitmapStyleLB->get_active());
+ bool bIsStretched( eStylePos == STRETCHED );
+ bool bIsTiled( eStylePos == TILED );
+
+ m_xSizeBox->set_sensitive( !bIsStretched );
+ m_xPositionBox->set_sensitive( !bIsStretched );
+ m_xPositionOffBox->set_sensitive( bIsTiled );
+ m_xTileOffBox->set_sensitive( bIsTiled );
+
+ m_rXFSet.Put( XFillBmpTileItem( bIsTiled ) );
+ m_rXFSet.Put( XFillBmpStretchItem( bIsStretched ) );
+
+ if(!bIsStretched)
+ {
+ Size aSetBitmapSize;
+ switch(eStylePos)
+ {
+ case CUSTOM:
+ case TILED:
+ {
+ if (m_xTsbScale->get_sensitive() && m_xTsbScale->get_state() == TRISTATE_TRUE)
+ {
+ aSetBitmapSize.setWidth(-m_xBitmapWidth->get_value(FieldUnit::NONE));
+ aSetBitmapSize.setHeight(-m_xBitmapHeight->get_value(FieldUnit::NONE));
+ }
+ else
+ {
+ aSetBitmapSize.setWidth( GetCoreValue( *m_xBitmapWidth, mePoolUnit ) );
+ aSetBitmapSize.setHeight( GetCoreValue( *m_xBitmapHeight, mePoolUnit ) );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+
+ m_rXFSet.Put( XFillBmpSizeXItem( aSetBitmapSize.Width() ) );
+ m_rXFSet.Put( XFillBmpSizeYItem( aSetBitmapSize.Height() ) );
+ }
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyBitmapPositionHdl, weld::ComboBox&, void)
+{
+ if (m_xPositionLB->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosItem( static_cast< RectPoint >( m_xPositionLB->get_active() ) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyPositionOffsetHdl, weld::MetricSpinButton&, void)
+{
+ if (m_xPositionOffX->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetXItem( m_xPositionOffX->get_value(FieldUnit::PERCENT) ) );
+
+ if (m_xPositionOffY->get_sensitive())
+ m_rXFSet.Put( XFillBmpPosOffsetYItem( m_xPositionOffY->get_value(FieldUnit::PERCENT) ) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ModifyTileOffsetHdl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nTileXOff = 0;
+ sal_uInt16 nTileYOff = 0;
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(ROW))
+ nTileXOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ if(m_xTileOffLB->get_active() == static_cast<sal_Int32>(COLUMN))
+ nTileYOff = m_xTileOffset->get_value(FieldUnit::PERCENT);
+
+ m_rXFSet.Put( XFillBmpTileOffsetXItem(nTileXOff) );
+ m_rXFSet.Put( XFillBmpTileOffsetYItem(nTileYOff) );
+
+ m_aCtlBitmapPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxBitmapTabPage, ClickImportHdl, weld::Button&, void)
+{
+ weld::Window* pDialogFrameWeld = GetFrameWeld();
+
+ SvxOpenGraphicDialog aDlg(CuiResId(RID_SVXSTR_ADD_IMAGE), pDialogFrameWeld);
+ aDlg.EnableLink(false);
+ long nCount = m_pBitmapList->Count();
+
+ if( aDlg.Execute() )
+ return;
+
+ Graphic aGraphic;
+
+ std::unique_ptr<weld::WaitObject> xWait(new weld::WaitObject(pDialogFrameWeld));
+ ErrCode nError = aDlg.GetGraphic( aGraphic );
+ xWait.reset();
+
+ if( !nError )
+ {
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_EXT_BITMAP));
+
+ // convert file URL to UI name
+ OUString aName;
+ INetURLObject aURL( aDlg.GetPath() );
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(
+ pDialogFrameWeld, aURL.GetLastName().getToken(0, '.'), aDesc));
+ nError = ErrCode(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bool bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ if( aName == m_pBitmapList->GetBitmap( i )->GetName() )
+ bDifferent = false;
+
+ if( bDifferent ) {
+ nError = ERRCODE_NONE;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ m_pBitmapList->Insert(std::make_unique<XBitmapEntry>(aGraphic, aName), nCount);
+
+ sal_Int32 nId = m_xBitmapLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pBitmapList->GetBitmapForPreview( nCount, m_xBitmapLB->GetIconSize() );
+
+ m_xBitmapLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xBitmapLB->SelectItem( nId + 1 );
+ *m_pnBitmapListState |= ChangeType::MODIFIED;
+
+ ModifyBitmapHdl(m_xBitmapLB.get());
+ }
+ }
+ else
+ {
+ // graphic couldn't be loaded
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pDialogFrameWeld, "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(const GraphicObject& rGraphicObject)
+{
+ long nCount = m_pBitmapList->Count();
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount;i++)
+ {
+ if(rGraphicObject.GetUniqueID() == m_pBitmapList->GetBitmap( i )->GetGraphicObject().GetUniqueID())
+ {
+ nPos = i;
+ break;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxBitmapTabPage::SearchBitmapList(const OUString& rBitmapName)
+{
+ long nCount = m_pBitmapList->Count();
+ bool bValidBitmapName = true;
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount && bValidBitmapName;i++)
+ {
+ if(rBitmapName == m_pBitmapList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidBitmapName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpcolor.cxx b/cui/source/tabpages/tpcolor.cxx
new file mode 100644
index 000000000..5933985a9
--- /dev/null
+++ b/cui/source/tabpages/tpcolor.cxx
@@ -0,0 +1,747 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <i18nutil/unicode.hxx>
+#include <svtools/colrdlg.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xtable.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <cuitabline.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <officecfg/Office/Common.hxx>
+
+using namespace com::sun::star;
+
+SvxColorTabPage::SvxColorTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/colorpage.ui", "ColorPage", &rInAttrs)
+ , rOutAttrs ( rInAttrs )
+ // All the horrific pointers we store and should not
+ , pnColorListState( nullptr )
+ , aXFillAttr( rInAttrs.GetPool() )
+ , rXFSet( aXFillAttr.GetItemSet() )
+ , eCM( ColorModel::RGB )
+ , m_context(comphelper::getProcessComponentContext())
+ , m_xValSetColorList(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("colorsetwin")))
+ , m_xValSetRecentList(new SvxColorValueSet(nullptr))
+ , m_xSelectPalette(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xRbRGB(m_xBuilder->weld_radio_button("RGB"))
+ , m_xRbCMYK(m_xBuilder->weld_radio_button("CMYK"))
+ , m_xRGBcustom(m_xBuilder->weld_widget("rgbcustom"))
+ , m_xRGBpreset(m_xBuilder->weld_widget("rgbpreset"))
+ , m_xRpreset(m_xBuilder->weld_entry("R_preset"))
+ , m_xGpreset(m_xBuilder->weld_entry("G_preset"))
+ , m_xBpreset(m_xBuilder->weld_entry("B_preset"))
+ , m_xRcustom(m_xBuilder->weld_spin_button("R_custom"))
+ , m_xGcustom(m_xBuilder->weld_spin_button("G_custom"))
+ , m_xBcustom(m_xBuilder->weld_spin_button("B_custom"))
+ , m_xHexpreset(new weld::HexColorControl(m_xBuilder->weld_entry("hex_preset")))
+ , m_xHexcustom(new weld::HexColorControl(m_xBuilder->weld_entry("hex_custom")))
+ , m_xCMYKcustom(m_xBuilder->weld_widget("cmykcustom"))
+ , m_xCMYKpreset(m_xBuilder->weld_widget("cmykpreset"))
+ , m_xCpreset(m_xBuilder->weld_entry("C_preset"))
+ , m_xYpreset(m_xBuilder->weld_entry("Y_preset"))
+ , m_xMpreset(m_xBuilder->weld_entry("M_preset"))
+ , m_xKpreset(m_xBuilder->weld_entry("K_preset"))
+ , m_xCcustom(m_xBuilder->weld_metric_spin_button("C_custom", FieldUnit::PERCENT))
+ , m_xYcustom(m_xBuilder->weld_metric_spin_button("Y_custom", FieldUnit::PERCENT))
+ , m_xMcustom(m_xBuilder->weld_metric_spin_button("M_custom", FieldUnit::PERCENT))
+ , m_xKcustom(m_xBuilder->weld_metric_spin_button("K_custom", FieldUnit::PERCENT))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnDelete(m_xBuilder->weld_button("delete"))
+ , m_xBtnWorkOn(m_xBuilder->weld_button("edit"))
+ , m_xCtlPreviewOld(new weld::CustomWeld(*m_xBuilder, "oldpreview", m_aCtlPreviewOld))
+ , m_xCtlPreviewNew(new weld::CustomWeld(*m_xBuilder, "newpreview", m_aCtlPreviewNew))
+ , m_xValSetColorListWin(new weld::CustomWeld(*m_xBuilder, "colorset", *m_xValSetColorList))
+ , m_xValSetRecentListWin(new weld::CustomWeld(*m_xBuilder, "recentcolorset", *m_xValSetRecentList))
+{
+ Size aSize(m_xBtnWorkOn->get_approximate_digit_width() * 25,
+ m_xBtnWorkOn->get_text_height() * 10);
+ m_xValSetColorList->set_size_request(aSize.Width(), aSize.Height());
+ aSize = Size(m_xBtnWorkOn->get_approximate_digit_width() * 8,
+ m_xBtnWorkOn->get_text_height() * 3);
+ m_aCtlPreviewOld.set_size_request(aSize.Width(), aSize.Height());
+ m_aCtlPreviewNew.set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ rXFSet.Put( XFillStyleItem(drawing::FillStyle_SOLID) );
+ rXFSet.Put( XFillColorItem(OUString(), COL_BLACK) );
+ m_aCtlPreviewOld.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ // set handler
+ m_xSelectPalette->connect_changed(LINK(this, SvxColorTabPage, SelectPaletteLBHdl));
+ Link<ValueSet*, void> aValSelectLink = LINK(this, SvxColorTabPage, SelectValSetHdl_Impl);
+ m_xValSetColorList->SetSelectHdl(aValSelectLink);
+ m_xValSetRecentList->SetSelectHdl(aValSelectLink);
+
+ Link<weld::SpinButton&,void> aSpinLink = LINK(this, SvxColorTabPage, SpinValueHdl_Impl);
+ m_xRcustom->connect_value_changed(aSpinLink);
+ m_xGcustom->connect_value_changed(aSpinLink);
+ m_xBcustom->connect_value_changed(aSpinLink);
+ Link<weld::Entry&,void> aEntryLink = LINK(this, SvxColorTabPage, ModifiedHdl_Impl);
+ m_xHexcustom->connect_changed(aEntryLink);
+ Link<weld::MetricSpinButton&,void> aMetricSpinLink = LINK(this, SvxColorTabPage, MetricSpinValueHdl_Impl);
+ m_xCcustom->connect_value_changed(aMetricSpinLink);
+ m_xYcustom->connect_value_changed(aMetricSpinLink);
+ m_xMcustom->connect_value_changed(aMetricSpinLink);
+ m_xKcustom->connect_value_changed(aMetricSpinLink);
+
+ Link<weld::ToggleButton&,void> aLink2 = LINK( this, SvxColorTabPage, SelectColorModeHdl_Impl );
+ m_xRbRGB->connect_toggled(aLink2);
+ m_xRbCMYK->connect_toggled(aLink2);
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxColorTabPage, ClickAddHdl_Impl ) );
+ m_xBtnWorkOn->connect_clicked( LINK( this, SvxColorTabPage, ClickWorkOnHdl_Impl ) );
+ m_xBtnDelete->connect_clicked( LINK( this, SvxColorTabPage, ClickDeleteHdl_Impl ) );
+ // disable modify buttons
+ // Color palettes can't be modified
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR1) );
+
+ // disable preset color values
+ m_xRGBpreset->set_sensitive(false);
+ m_xCMYKpreset->set_sensitive(false);
+
+ // ValueSet
+ m_xValSetColorList->SetStyle(m_xValSetColorList->GetStyle() | WB_ITEMBORDER);
+ m_xValSetColorList->Show();
+
+ m_xValSetRecentList->SetStyle(m_xValSetRecentList->GetStyle() | WB_ITEMBORDER);
+ m_xValSetRecentList->Show();
+
+ maPaletteManager.ReloadRecentColorSet(*m_xValSetRecentList);
+ aSize = m_xValSetRecentList->layoutAllVisible(maPaletteManager.GetRecentColorCount());
+ m_xValSetRecentList->set_size_request(aSize.Width(), aSize.Height());
+}
+
+SvxColorTabPage::~SvxColorTabPage()
+{
+ m_xValSetRecentListWin.reset();
+ m_xValSetRecentList.reset();
+ m_xValSetColorListWin.reset();
+ m_xValSetColorList.reset();
+}
+
+void SvxColorTabPage::ImpColorCountChanged()
+{
+ if (!pColorList.is())
+ return;
+ m_xValSetColorList->SetColCount(SvxColorValueSet::getColumnCount());
+ m_xValSetRecentList->SetColCount(SvxColorValueSet::getColumnCount());
+}
+
+void SvxColorTabPage::FillPaletteLB()
+{
+ m_xSelectPalette->clear();
+ std::vector<OUString> aPaletteList = maPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ {
+ m_xSelectPalette->append_text(palette);
+ }
+ OUString aPaletteName( officecfg::Office::Common::UserColors::PaletteName::get() );
+ m_xSelectPalette->set_active_text(aPaletteName);
+ if (m_xSelectPalette->get_active() != -1)
+ {
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ }
+}
+
+void SvxColorTabPage::Construct()
+{
+ if (pColorList.is())
+ {
+ FillPaletteLB();
+ ImpColorCountChanged();
+ }
+}
+
+void SvxColorTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( !pColorList.is() )
+ return;
+
+ const SfxPoolItem* pPoolItem = nullptr;
+ if( SfxItemState::SET == rOutAttrs.GetItemState( GetWhich( XATTR_FILLCOLOR ), true, &pPoolItem ) )
+ {
+ SetColorModel( ColorModel::RGB );
+ ChangeColorModel();
+
+ const Color aColor = static_cast<const XFillColorItem*>(pPoolItem)->GetColorValue();
+ ChangeColor( aColor );
+ sal_Int32 nPos = FindInPalette( aColor );
+
+ if ( nPos != -1 )
+ m_xValSetColorList->SelectItem(m_xValSetColorList->GetItemId(nPos));
+ // else search in other palettes?
+
+ }
+
+ m_aCtlPreviewOld.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewOld.Invalidate();
+
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+}
+
+DeactivateRC SvxColorTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxColorTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ Color aColor = m_xValSetColorList->GetItemColor( m_xValSetColorList->GetSelectedItemId() );
+ OUString sColorName;
+ if ( aCurrentColor == aColor )
+ sColorName = m_xValSetColorList->GetItemText( m_xValSetColorList->GetSelectedItemId() );
+ else
+ sColorName = "#" + aCurrentColor.AsRGBHexString().toAsciiUpperCase();
+ maPaletteManager.AddRecentColor( aCurrentColor, sColorName );
+ rSet->Put( XFillColorItem( sColorName, aCurrentColor ) );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
+ return true;
+}
+
+void SvxColorTabPage::UpdateModified()
+{
+ bool bEnable = pColorList.is() && pColorList->Count();
+ m_xBtnWorkOn->set_sensitive(bEnable);
+}
+
+void SvxColorTabPage::Reset( const SfxItemSet* rSet )
+{
+ SfxItemState nState = rSet->GetItemState( XATTR_FILLCOLOR );
+
+ Color aNewColor;
+
+ if ( nState >= SfxItemState::DEFAULT )
+ {
+ XFillColorItem aColorItem( rSet->Get( XATTR_FILLCOLOR ) );
+ aPreviousColor = aColorItem.GetColorValue();
+ aNewColor = aColorItem.GetColorValue();
+ }
+
+ // set color model
+ OUString aStr = GetUserData();
+ eCM = static_cast<ColorModel>(aStr.toInt32());
+ SetColorModel( eCM );
+ ChangeColorModel();
+
+ ChangeColor(aNewColor);
+
+ UpdateModified();
+}
+
+std::unique_ptr<SfxTabPage> SvxColorTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxColorTabPage>(pPage, pController, *rOutAttrs);
+}
+
+// is called when the content of the MtrFields is changed for color values
+IMPL_LINK_NOARG(SvxColorTabPage, SpinValueHdl_Impl, weld::SpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ aCurrentColor = Color(static_cast<sal_uInt8>(PercentToColor_Impl(m_xRcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xGcustom->get_value())),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xBcustom->get_value())));
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, MetricSpinValueHdl_Impl, weld::MetricSpinButton&, void)
+{
+ // read current MtrFields, if cmyk, then k-value as transparency
+ aCurrentColor = Color(static_cast<sal_uInt8>(PercentToColor_Impl(m_xKcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xCcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xYcustom->get_value(FieldUnit::NONE))),
+ static_cast<sal_uInt8>(PercentToColor_Impl(m_xMcustom->get_value(FieldUnit::NONE))));
+ ConvertColorValues (aCurrentColor, ColorModel::RGB);
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ModifiedHdl_Impl, weld::Entry&, void)
+{
+ aCurrentColor = m_xHexcustom->GetColor();
+ UpdateColorValues();
+
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_COLOR ) );
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_COLOR ) );
+ OUString aName;
+
+ long j = 1;
+ bool bValidColorName = false;
+ // check if name is already existing
+ while (!bValidColorName)
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidColorName = (FindInCustomColors(aName) == -1);
+ if (bValidColorName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if (!nError)
+ {
+ m_xSelectPalette->set_active(0);
+ SelectPaletteLBHdl(*m_xSelectPalette);
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(m_context));
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ sal_Int32 nSize = aCustomColorList.getLength();
+ aCustomColorList.realloc( nSize + 1 );
+ aCustomColorNameList.realloc( nSize + 1 );
+ aCustomColorList[nSize] = sal_Int32(aCurrentColor);
+ aCustomColorNameList[nSize] = aName;
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ sal_uInt16 nId = m_xValSetColorList->GetItemId(nSize - 1);
+ m_xValSetColorList->InsertItem( nId + 1 , aCurrentColor, aName );
+ m_xValSetColorList->SelectItem( nId + 1 );
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR2) );
+ ImpColorCountChanged();
+ }
+
+ UpdateModified();
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickWorkOnHdl_Impl, weld::Button&, void)
+{
+ SvColorDialog aColorDlg;
+
+ aColorDlg.SetColor (aCurrentColor);
+ aColorDlg.SetMode( svtools::ColorPickerMode::Modify );
+
+ if (aColorDlg.Execute(GetFrameWeld()) == RET_OK)
+ {
+ Color aPreviewColor = aColorDlg.GetColor();
+ aCurrentColor = aPreviewColor;
+ UpdateColorValues( false );
+ // fill ItemSet and pass it on to XOut
+ rXFSet.Put( XFillColorItem( OUString(), aPreviewColor ) );
+ //m_aCtlPreviewOld.SetAttributes( aXFillAttr );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+
+ m_aCtlPreviewNew.Invalidate();
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xValSetColorList->GetSelectedItemId();
+ size_t nPos = m_xValSetColorList->GetSelectItemPos();
+ if (!(m_xSelectPalette->get_active() == 0 && nPos != VALUESET_ITEM_NOTFOUND) )
+ return;
+
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create(m_context));
+ css::uno::Sequence< sal_Int32 > aCustomColorList(officecfg::Office::Common::UserColors::CustomColor::get());
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ sal_Int32 nSize = aCustomColorList.getLength() - 1;
+ for(sal_Int32 nIndex = static_cast<sal_Int32>(nPos);nIndex < nSize;nIndex++)
+ {
+ aCustomColorList[nIndex] = aCustomColorList[nIndex+1];
+ aCustomColorNameList[nIndex] = aCustomColorNameList[nIndex+1];
+ }
+ aCustomColorList.realloc(nSize);
+ aCustomColorNameList.realloc(nSize);
+ officecfg::Office::Common::UserColors::CustomColor::set(aCustomColorList, batch);
+ officecfg::Office::Common::UserColors::CustomColorName::set(aCustomColorNameList, batch);
+ batch->commit();
+ m_xValSetColorList->RemoveItem(nId);
+ if (m_xValSetColorList->GetItemCount() != 0)
+ {
+ nId = m_xValSetColorList->GetItemId(0);
+ m_xValSetColorList->SelectItem(nId);
+ SelectValSetHdl_Impl(m_xValSetColorList.get());
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR2) );
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectPaletteLBHdl, weld::ComboBox&, void)
+{
+ m_xValSetColorList->Clear();
+ sal_Int32 nPos = m_xSelectPalette->get_active();
+ maPaletteManager.SetPalette( nPos );
+ maPaletteManager.ReloadColorSet(*m_xValSetColorList);
+
+ if(nPos != maPaletteManager.GetPaletteCount() - 1 && nPos != 0)
+ {
+ XColorListRef pList = XPropertyList::AsColorList(
+ XPropertyList::CreatePropertyListFromURL(
+ XPropertyListType::Color, maPaletteManager.GetSelectedPalettePath()));
+ pList->SetName(maPaletteManager.GetPaletteName());
+ if(pList->Load())
+ {
+ SfxOkDialogController* pController = GetDialogController();
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(pController);
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(pController);
+ pColorList = pList;
+ if( pArea )
+ pArea->SetNewColorList(pList);
+ else if( pLine )
+ pLine->SetNewColorList(pList);
+ else
+ SetColorList(pList);
+ *pnColorListState |= ChangeType::CHANGED;
+ *pnColorListState &= ~ChangeType::MODIFIED;
+ }
+ }
+ if (nPos != 0)
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR1) );
+ }
+
+ m_xValSetColorList->Resize();
+}
+
+IMPL_LINK(SvxColorTabPage, SelectValSetHdl_Impl, ValueSet*, pValSet, void)
+{
+ sal_Int32 nPos = pValSet->GetSelectedItemId();
+ if( nPos == 0 )
+ return;
+
+ Color aColor = pValSet->GetItemColor( nPos );
+
+ rXFSet.Put( XFillColorItem( OUString(), aColor ) );
+ m_aCtlPreviewNew.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlPreviewNew.Invalidate();
+ ChangeColor(aColor, false);
+
+ if (pValSet == m_xValSetColorList.get())
+ {
+ m_xValSetRecentList->SetNoSelection();
+ if (m_xSelectPalette->get_active() == 0 && m_xValSetColorList->GetSelectedItemId() != 0)
+ {
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnDelete->set_tooltip_text("");
+ }
+ else
+ {
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR1) );
+ }
+ }
+ if (pValSet == m_xValSetRecentList.get())
+ {
+ m_xValSetColorList->SetNoSelection();
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnDelete->set_tooltip_text( SvxResId(RID_SVXSTR_DELETEUSERCOLOR2) );
+ }
+}
+
+void SvxColorTabPage::ConvertColorValues (Color& rColor, ColorModel eModell)
+{
+ switch (eModell)
+ {
+ case ColorModel::RGB:
+ {
+ CmykToRgb_Impl (rColor, static_cast<sal_uInt16>(rColor.GetTransparency()) );
+ rColor.SetTransparency (sal_uInt8(0));
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ sal_uInt16 nK;
+ RgbToCmyk_Impl (rColor, nK );
+ rColor.SetTransparency (static_cast<sal_uInt8>(nK));
+ }
+ break;
+ }
+}
+
+IMPL_LINK_NOARG(SvxColorTabPage, SelectColorModeHdl_Impl, weld::ToggleButton&, void)
+{
+ if (m_xRbRGB->get_active())
+ eCM = ColorModel::RGB;
+ else if (m_xRbCMYK->get_active())
+ eCM = ColorModel::CMYK;
+ ChangeColorModel();
+ UpdateColorValues();
+}
+
+void SvxColorTabPage::ChangeColor(const Color &rNewColor, bool bUpdatePreset )
+{
+ aPreviousColor = rNewColor;
+ aCurrentColor = rNewColor;
+ UpdateColorValues( bUpdatePreset );
+ // fill ItemSet and pass it on to XOut
+ rXFSet.Put( XFillColorItem( OUString(), aCurrentColor ) );
+ m_aCtlPreviewNew.SetAttributes(aXFillAttr.GetItemSet());
+ m_aCtlPreviewNew.Invalidate();
+}
+
+void SvxColorTabPage::SetColorModel( ColorModel eModel )
+{
+ if (eModel == ColorModel::RGB)
+ m_xRbRGB->set_active(true);
+ else if (eModel == ColorModel::CMYK)
+ m_xRbCMYK->set_active(true);
+}
+
+void SvxColorTabPage::ChangeColorModel()
+{
+ switch( eCM )
+ {
+ case ColorModel::RGB:
+ {
+ m_xRGBcustom->show();
+ m_xRGBpreset->show();
+ m_xCMYKcustom->hide();
+ m_xCMYKpreset->hide();
+ }
+ break;
+
+ case ColorModel::CMYK:
+ {
+ m_xCMYKcustom->show();
+ m_xCMYKpreset->show();
+ m_xRGBcustom->hide();
+ m_xRGBpreset->hide();
+ }
+ break;
+ }
+}
+
+void SvxColorTabPage::UpdateColorValues( bool bUpdatePreset )
+{
+ if (eCM != ColorModel::RGB)
+ {
+ ConvertColorValues (aPreviousColor, eCM );
+ ConvertColorValues (aCurrentColor, eCM);
+
+ m_xCcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetRed() ), FieldUnit::PERCENT );
+ m_xMcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetBlue() ), FieldUnit::PERCENT );
+ m_xYcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetGreen() ), FieldUnit::PERCENT );
+ m_xKcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetTransparency() ), FieldUnit::PERCENT );
+
+ if( bUpdatePreset )
+ {
+ m_xCpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetRed()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xMpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetBlue()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xYpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetGreen()),
+ Application::GetSettings().GetUILanguageTag()));
+ m_xKpreset->set_text(unicode::formatPercent(ColorToPercent_Impl(aPreviousColor.GetTransparency()),
+ Application::GetSettings().GetUILanguageTag()));
+ }
+
+ ConvertColorValues (aPreviousColor, ColorModel::RGB);
+ ConvertColorValues (aCurrentColor, ColorModel::RGB);
+ }
+ else
+ {
+ m_xRcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetRed() ) );
+ m_xGcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetGreen() ) );
+ m_xBcustom->set_value( ColorToPercent_Impl( aCurrentColor.GetBlue() ) );
+ m_xHexcustom->SetColor( aCurrentColor );
+
+ if( bUpdatePreset )
+ {
+ m_xRpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetRed())));
+ m_xGpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetGreen())));
+ m_xBpreset->set_text(OUString::number(ColorToPercent_Impl(aPreviousColor.GetBlue())));
+ m_xHexpreset->SetColor( aPreviousColor );
+ }
+ }
+}
+
+sal_Int32 SvxColorTabPage::FindInCustomColors(OUString const & aColorName)
+{
+ css::uno::Sequence< OUString > aCustomColorNameList(officecfg::Office::Common::UserColors::CustomColorName::get());
+ long nCount = aCustomColorNameList.getLength();
+ bool bValidColorName = true;
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount && bValidColorName;i++)
+ {
+ if(aColorName == aCustomColorNameList[i])
+ {
+ nPos = i;
+ bValidColorName = false;
+ }
+ }
+ return nPos;
+}
+
+sal_Int32 SvxColorTabPage::FindInPalette( const Color& rColor )
+{
+ return pColorList->GetIndexOfColor(rColor);
+}
+
+// A RGB value is converted to a CMYK value - not in an ideal way as
+// R is converted into C, G into M and B into Y. The K value is held in an
+// extra variable. For further color models one should develop own
+// classes which should contain the respective casts.
+
+void SvxColorTabPage::RgbToCmyk_Impl( Color& rColor, sal_uInt16& rK )
+{
+ sal_uInt16 const nColor1 = 255 - rColor.GetRed();
+ sal_uInt16 const nColor2 = 255 - rColor.GetGreen();
+ sal_uInt16 const nColor3 = 255 - rColor.GetBlue();
+
+ rK = std::min( std::min( nColor1, nColor2 ), nColor3 );
+
+ rColor.SetRed( sal::static_int_cast< sal_uInt8 >( nColor1 - rK ) );
+ rColor.SetGreen( sal::static_int_cast< sal_uInt8 >( nColor2 - rK ) );
+ rColor.SetBlue( sal::static_int_cast< sal_uInt8 >( nColor3 - rK ) );
+}
+
+
+// reverse case to RgbToCmyk_Impl (see above)
+
+void SvxColorTabPage::CmykToRgb_Impl( Color& rColor, const sal_uInt16 nK )
+{
+ long lTemp;
+
+ lTemp = 255 - ( rColor.GetRed() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetRed( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetGreen() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetGreen( static_cast<sal_uInt8>(lTemp) );
+
+ lTemp = 255 - ( rColor.GetBlue() + nK );
+
+ if( lTemp < 0 )
+ lTemp = 0;
+ rColor.SetBlue( static_cast<sal_uInt8>(lTemp) );
+}
+
+
+sal_uInt16 SvxColorTabPage::ColorToPercent_Impl( sal_uInt16 nColor )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nColor;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nColor) * 100.0 / 255.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+sal_uInt16 SvxColorTabPage::PercentToColor_Impl( sal_uInt16 nPercent )
+{
+ sal_uInt16 nValue = 0;
+
+ switch (eCM)
+ {
+ case ColorModel::RGB :
+ nValue = nPercent;
+ break;
+
+ case ColorModel::CMYK:
+ nValue = static_cast<sal_uInt16>( static_cast<double>(nPercent) * 255.0 / 100.0 + 0.5 );
+ break;
+ }
+
+ return nValue;
+}
+
+
+void SvxColorTabPage::FillUserData()
+{
+ // the color model is saved in the Ini-file
+ SetUserData( OUString::number( static_cast<int>(eCM) ) );
+}
+
+
+void SvxColorTabPage::SetPropertyList( XPropertyListType t, const XPropertyListRef &xRef )
+{
+ OSL_ASSERT( t == XPropertyListType::Color );
+ pColorList = XColorListRef( static_cast<XColorList *>(xRef.get() ) );
+}
+
+void SvxColorTabPage::SetColorList( const XColorListRef& pColList )
+{
+ SetPropertyList( XPropertyListType::Color, XPropertyListRef( ( pColList.get() ) ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx
new file mode 100644
index 000000000..628c042ee
--- /dev/null
+++ b/cui/source/tabpages/tpgradnt.cxx
@@ -0,0 +1,630 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xgrscit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <sal/log.hxx>
+
+#define DEFAULT_GRADIENTSTEP 64
+
+using namespace com::sun::star;
+
+SvxGradientTabPage::SvxGradientTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/gradientpage.ui", "GradientPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnGradientListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xLbGradientType(m_xBuilder->weld_combo_box("gradienttypelb"))
+ , m_xFtCenter(m_xBuilder->weld_label("centerft"))
+ , m_xMtrCenterX(m_xBuilder->weld_metric_spin_button("centerxmtr", FieldUnit::PERCENT))
+ , m_xMtrCenterY(m_xBuilder->weld_metric_spin_button("centerymtr", FieldUnit::PERCENT))
+ , m_xFtAngle(m_xBuilder->weld_label("angleft"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xMtrBorder(m_xBuilder->weld_metric_spin_button("bordermtr", FieldUnit::PERCENT))
+ , m_xSliderBorder(m_xBuilder->weld_scale("borderslider"))
+ , m_xLbColorFrom(new ColorListBox(m_xBuilder->weld_menu_button("colorfromlb"), pController->getDialog()))
+ , m_xMtrColorFrom(m_xBuilder->weld_metric_spin_button("colorfrommtr", FieldUnit::PERCENT))
+ , m_xLbColorTo(new ColorListBox(m_xBuilder->weld_menu_button("colortolb"), pController->getDialog()))
+ , m_xMtrColorTo(m_xBuilder->weld_metric_spin_button("colortomtr", FieldUnit::PERCENT))
+ , m_xGradientLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("gradientpresetlistwin")))
+ , m_xMtrIncrement(m_xBuilder->weld_spin_button("incrementmtr"))
+ , m_xCbIncrement(m_xBuilder->weld_check_button("autoincrement"))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+ , m_xGradientLBWin(new weld::CustomWeld(*m_xBuilder, "gradientpresetlist", *m_xGradientLB))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xGradientLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // as long as NOT supported by the item
+
+ m_xMtrColorTo->set_value(100, FieldUnit::PERCENT);
+ m_xMtrColorFrom->set_value(100, FieldUnit::PERCENT);
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
+ m_rXFSet.Put( XFillGradientItem(OUString(), XGradient( COL_BLACK, COL_WHITE )) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ // set handler
+ m_xGradientLB->SetSelectHdl( LINK( this, SvxGradientTabPage, ChangeGradientHdl ) );
+ m_xGradientLB->SetRenameHdl( LINK( this, SvxGradientTabPage, ClickRenameHdl_Impl ) );
+ m_xGradientLB->SetDeleteHdl( LINK( this, SvxGradientTabPage, ClickDeleteHdl_Impl ) );
+ m_xBtnAdd->connect_clicked(LINK(this, SvxGradientTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxGradientTabPage, ClickModifyHdl_Impl));
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxGradientTabPage, ModifiedMetricHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxGradientTabPage, ModifiedListBoxHdl_Impl );
+ m_xLbGradientType->connect_changed( aLink2 );
+ m_xCbIncrement->connect_toggled(LINK(this, SvxGradientTabPage, ChangeAutoStepHdl_Impl));
+ m_xMtrIncrement->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedEditHdl_Impl));
+ m_xMtrCenterX->connect_value_changed( aLink );
+ m_xMtrCenterY->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrBorder->connect_value_changed( aLink );
+ m_xSliderBorder->connect_value_changed(LINK(this, SvxGradientTabPage, ModifiedSliderHdl_Impl));
+ m_xMtrColorFrom->connect_value_changed( aLink );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxGradientTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbColorFrom->SetSelectHdl( aLink3 );
+ m_xMtrColorTo->connect_value_changed( aLink );
+ m_xLbColorTo->SetSelectHdl( aLink3 );
+
+ // #i76307# always paint the preview in LTR, because this is what the document does
+ m_aCtlPreview.EnableRTL(false);
+}
+
+SvxGradientTabPage::~SvxGradientTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xGradientLBWin.reset();
+ m_xGradientLB.reset();
+ m_xLbColorTo.reset();
+ m_xLbColorFrom.reset();
+}
+
+void SvxGradientTabPage::Construct()
+{
+ m_xGradientLB->FillPresetListBox( *m_pGradientList );
+}
+
+void SvxGradientTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (and possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_SVXSTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pGradientList->GetPath() );
+
+ aURL.Append( m_pGradientList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += aURL.getBase().copy( 0, 15 ) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchGradientList( rSet.Get(XATTR_FILLGRADIENT).GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xGradientLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xGradientLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeGradientHdl_Impl();
+}
+
+
+DeactivateRC SvxGradientTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+bool SvxGradientTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<XGradient> pXGradient;
+ OUString aString;
+ size_t nPos = m_xGradientLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xGradientLB->GetSelectItemPos();
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pXGradient.reset(new XGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetGradient() ));
+ aString = m_xGradientLB->GetItemText( m_xGradientLB->GetSelectedItemId() );
+ rSet->Put( XFillGradientItem( aString, *pXGradient ) );
+ }
+ else
+ // gradient was passed (unidentified)
+ {
+ pXGradient.reset(new XGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) ));
+ rSet->Put( XFillGradientItem( OUString(), *pXGradient ) );
+ }
+
+ sal_uInt16 nValue = 0;
+ if (!m_xCbIncrement->get_active())
+ nValue = m_xMtrIncrement->get_value();
+
+ assert( pXGradient && "XGradient could not be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_GRADIENT ) );
+ rSet->Put( XGradientStepCountItem( nValue ) );
+ return true;
+}
+
+void SvxGradientTabPage::Reset( const SfxItemSet* )
+{
+ m_xMtrIncrement->set_value(DEFAULT_GRADIENTSTEP);
+ ChangeGradientHdl_Impl();
+
+ // determine state of the buttons
+ if( m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(true);
+ else
+ m_xBtnModify->set_sensitive(false);
+}
+
+std::unique_ptr<SfxTabPage> SvxGradientTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxGradientTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // gradient params changed, it is no longer one of the presets
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedEditHdl_Impl, weld::SpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedMetricHdl_Impl, weld::MetricSpinButton&, rBox, void )
+{
+ ModifiedHdl_Impl(&rBox);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxGradientTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xGradientLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxGradientTabPage, ChangeAutoStepHdl_Impl, weld::ToggleButton&, void )
+{
+ if (m_xCbIncrement->get_active())
+ {
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xMtrIncrement->set_sensitive(true);
+ }
+ ModifiedHdl_Impl(m_xMtrIncrement.get());
+}
+
+void SvxGradientTabPage::ModifiedHdl_Impl( void const * pControl )
+{
+ if (pControl == m_xMtrBorder.get())
+ m_xSliderBorder->set_value(m_xMtrBorder->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderBorder.get())
+ m_xMtrBorder->set_value(m_xSliderBorder->get_value(), FieldUnit::NONE);
+ if (pControl == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+ if (pControl == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active());
+
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ eXGS,
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ // enable/disable controls
+ if (pControl == m_xLbGradientType.get() || pControl == this)
+ SetControlState_Impl( eXGS );
+
+ sal_uInt16 nValue = 0;
+ if (!m_xCbIncrement->get_active())
+ nValue = static_cast<sal_uInt16>(m_xMtrIncrement->get_value());
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+
+ // displaying in XOutDev
+ m_rXFSet.Put( XFillGradientItem( OUString(), aXGradient ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_GRADIENT ) );
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_GRADIENT ) );
+ OUString aName;
+
+ long nCount = m_pGradientList->Count();
+ long j = 1;
+ bool bValidGradientName = false;
+
+ while( !bValidGradientName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidGradientName = (SearchGradientList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName( aName );
+
+ bValidGradientName = (SearchGradientList(aName) == -1);
+
+ if (bValidGradientName)
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ m_pGradientList->Insert(std::make_unique<XGradientEntry>(aXGradient, aName), nCount);
+
+ sal_Int32 nId = m_xGradientLB->GetItemId(nCount - 1); //calculate the last ID
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( nCount, m_xGradientLB->GetIconSize() );
+ m_xGradientLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xGradientLB->SelectItem( nId + 1 );
+ m_xGradientLB->Resize();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+
+ ChangeGradientHdl_Impl();
+ }
+
+ // determine button state
+ if (m_pGradientList->Count())
+ m_xBtnModify->set_sensitive(true);
+}
+
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
+ m_xLbColorTo->GetSelectEntryColor(),
+ static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10), // should be changed in resource
+ static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrCenterY->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrBorder->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorFrom->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrColorTo->get_value(FieldUnit::NONE)),
+ static_cast<sal_uInt16>(m_xMtrIncrement->get_value()) );
+
+ m_pGradientList->Replace(std::make_unique<XGradientEntry>(aXGradient, aName), nPos);
+
+ BitmapEx aBitmap = m_pGradientList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xGradientLB->GetIconSize() );
+ m_xGradientLB->RemoveItem( nId );
+ m_xGradientLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletegradientdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelGradientDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pGradientList->Remove(nPos);
+ m_xGradientLB->RemoveItem( nId );
+ nId = m_xGradientLB->GetItemId( 0 );
+ m_xGradientLB->SelectItem( nId );
+ m_xGradientLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeGradientHdl_Impl();
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pGradientList->Count() )
+ m_xBtnModify->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xGradientLB->GetSelectedItemId();
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_GRADIENT ) );
+ OUString aName( m_pGradientList->GetGradient( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nGradientPos = SearchGradientList(aName);
+ bool bValidGradientName = (nGradientPos == static_cast<sal_Int32>(nPos) ) || (nGradientPos == -1);
+
+ if( bValidGradientName )
+ {
+ bLoop = false;
+ m_pGradientList->GetGradient(nPos)->SetName(aName);
+
+ m_xGradientLB->SetItemText( nId, aName );
+ m_xGradientLB->SelectItem( nId );
+
+ *m_pnGradientListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxGradientTabPage, ChangeGradientHdl, ValueSet*, void)
+{
+ ChangeGradientHdl_Impl();
+}
+
+void SvxGradientTabPage::ChangeGradientHdl_Impl()
+{
+ std::unique_ptr<XGradient> pGradient;
+ size_t nPos = m_xGradientLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pGradient.reset(new XGradient( m_pGradientList->GetGradient( static_cast<sal_uInt16>( nPos ) )->GetGradient() ));
+ else
+ {
+ const SfxPoolItem* pPoolItem = nullptr;
+ if( SfxItemState::SET == m_rOutAttrs.GetItemState( GetWhich( XATTR_FILLSTYLE ), true, &pPoolItem ) )
+ {
+ if( ( drawing::FillStyle_GRADIENT == static_cast<const XFillStyleItem*>( pPoolItem )->GetValue() ) &&
+ ( SfxItemState::SET == m_rOutAttrs.GetItemState( GetWhich( XATTR_FILLGRADIENT ), true, &pPoolItem ) ) )
+ {
+ pGradient.reset(new XGradient( static_cast<const XFillGradientItem*>( pPoolItem )->GetGradientValue() ));
+ }
+ }
+ if( !pGradient )
+ {
+ sal_uInt16 nPosition = m_xGradientLB->GetItemId(0);
+ m_xGradientLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pGradient.reset(new XGradient( m_pGradientList->GetGradient( 0 )->GetGradient() ));
+ }
+ }
+
+ if( !pGradient )
+ return;
+
+ css::awt::GradientStyle eXGS = pGradient->GetGradientStyle();
+ sal_uInt16 nValue = pGradient->GetSteps();
+ if( nValue == 0 )
+ {
+ m_xCbIncrement->set_state(TRISTATE_TRUE);
+ m_xMtrIncrement->set_sensitive(false);
+ }
+ else
+ {
+ m_xCbIncrement->set_state(TRISTATE_FALSE);
+ m_xMtrIncrement->set_sensitive(true);
+ m_xMtrIncrement->set_value( nValue );
+ }
+ m_xLbGradientType->set_active(
+ sal::static_int_cast< sal_Int32 >( eXGS ) );
+ // if the entry is not in the listbox,
+ // colors are added temporarily
+ m_xLbColorFrom->SetNoSelection();
+ m_xLbColorFrom->SelectEntry( pGradient->GetStartColor() );
+
+ m_xLbColorTo->SetNoSelection();
+ m_xLbColorTo->SelectEntry( pGradient->GetEndColor() );
+
+ m_xMtrAngle->set_value(pGradient->GetAngle() / 10, FieldUnit::NONE); // should be changed in resource
+ m_xSliderAngle->set_value(pGradient->GetAngle() / 10);
+ m_xMtrBorder->set_value(pGradient->GetBorder(), FieldUnit::NONE);
+ m_xSliderBorder->set_value(pGradient->GetBorder());
+ m_xMtrCenterX->set_value(pGradient->GetXOffset(), FieldUnit::NONE);
+ m_xMtrCenterY->set_value(pGradient->GetYOffset(), FieldUnit::NONE);
+ m_xMtrColorFrom->set_value(pGradient->GetStartIntens(), FieldUnit::NONE);
+ m_xMtrColorTo->set_value(pGradient->GetEndIntens(), FieldUnit::NONE);
+
+ // disable/enable controls
+ SetControlState_Impl( eXGS );
+
+ // fill ItemSet and pass it on to aCtlPreview
+ m_rXFSet.Put( XFillGradientItem( OUString(), *pGradient ) );
+ m_rXFSet.Put( XGradientStepCountItem( nValue ) );
+ m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxGradientTabPage::SetControlState_Impl( css::awt::GradientStyle eXGS )
+{
+ switch( eXGS )
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtCenter->set_sensitive(false);
+ m_xMtrCenterX->set_sensitive(false);
+ m_xMtrCenterY->set_sensitive(false);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(false);
+ m_xMtrAngle->set_sensitive(false);
+ m_xSliderAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtCenter->set_sensitive(true);
+ m_xMtrCenterX->set_sensitive(true);
+ m_xMtrCenterY->set_sensitive(true);
+ m_xFtAngle->set_sensitive(true);
+ m_xMtrAngle->set_sensitive(true);
+ m_xSliderAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+sal_Int32 SvxGradientTabPage::SearchGradientList(const OUString& rGradientName)
+{
+ long nCount = m_pGradientList->Count();
+ bool bValidGradientName = true;
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount && bValidGradientName;i++)
+ {
+ if(rGradientName == m_pGradientList->GetGradient( i )->GetName())
+ {
+ nPos = i;
+ bValidGradientName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tphatch.cxx b/cui/source/tabpages/tphatch.cxx
new file mode 100644
index 000000000..d1dbbc79a
--- /dev/null
+++ b/cui/source/tabpages/tphatch.cxx
@@ -0,0 +1,558 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/dialoghelper.hxx>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbckit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <sal/log.hxx>
+#include <svtools/unitconv.hxx>
+
+using namespace com::sun::star;
+
+SvxHatchTabPage::SvxHatchTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/hatchpage.ui", "HatchPage", &rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnHatchingListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("distancemtr", FieldUnit::MM))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("anglemtr", FieldUnit::DEGREE))
+ , m_xSliderAngle(m_xBuilder->weld_scale("angleslider"))
+ , m_xLbLineType(m_xBuilder->weld_combo_box("linetypelb"))
+ , m_xLbLineColor(new ColorListBox(m_xBuilder->weld_menu_button("linecolorlb"), pController->getDialog()))
+ , m_xCbBackgroundColor(m_xBuilder->weld_check_button("backgroundcolor"))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("backgroundcolorlb"), pController->getDialog()))
+ , m_xHatchLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("hatchpresetlistwin")))
+ , m_xBtnAdd(m_xBuilder->weld_button("add"))
+ , m_xBtnModify(m_xBuilder->weld_button("modify"))
+ , m_xHatchLBWin(new weld::CustomWeld(*m_xBuilder, "hatchpresetlist", *m_xHatchLB))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "previewctl", m_aCtlPreview))
+{
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xHatchLBWin->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ assert( pPool && "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_FILL_HATCH );
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_HATCH) );
+ m_rXFSet.Put( XFillHatchItem(OUString(), XHatch()) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_xHatchLB->SetSelectHdl( LINK( this, SvxHatchTabPage, ChangeHatchHdl ) );
+ m_xHatchLB->SetRenameHdl( LINK( this, SvxHatchTabPage, ClickRenameHdl_Impl ) );
+ m_xHatchLB->SetDeleteHdl( LINK( this, SvxHatchTabPage, ClickDeleteHdl_Impl ) );
+
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxHatchTabPage, ModifiedEditHdl_Impl );
+ Link<weld::ComboBox&,void> aLink2 = LINK( this, SvxHatchTabPage, ModifiedListBoxHdl_Impl );
+ m_xMtrDistance->connect_value_changed( aLink );
+ m_xMtrAngle->connect_value_changed( aLink );
+ m_xSliderAngle->connect_value_changed(LINK(this, SvxHatchTabPage, ModifiedSliderHdl_Impl));
+ m_xLbLineType->connect_changed( aLink2 );
+ Link<ColorListBox&,void> aLink3 = LINK( this, SvxHatchTabPage, ModifiedColorListBoxHdl_Impl );
+ m_xLbLineColor->SetSelectHdl( aLink3 );
+ m_xCbBackgroundColor->connect_toggled( LINK( this, SvxHatchTabPage, ToggleHatchBackgroundColor_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxHatchTabPage, ModifiedBackgroundHdl_Impl ) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxHatchTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxHatchTabPage, ClickModifyHdl_Impl ) );
+
+ m_aCtlPreview.SetDrawMode(Application::GetSettings().GetStyleSettings().GetHighContrastMode() ? OUTPUT_DRAWMODE_CONTRAST : OUTPUT_DRAWMODE_COLOR);
+}
+
+SvxHatchTabPage::~SvxHatchTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xHatchLBWin.reset();
+ m_xHatchLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbLineColor.reset();
+}
+
+void SvxHatchTabPage::Construct()
+{
+ m_xHatchLB->FillPresetListBox(*m_pHatchingList);
+}
+
+void SvxHatchTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( m_pColorList.is() )
+ {
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+
+ ModifiedHdl_Impl( this );
+ }
+
+ // determining (possibly cutting) the name
+ // and displaying it in the GroupBox
+ OUString aString = CuiResId( RID_SVXSTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pHatchingList->GetPath() );
+
+ aURL.Append( m_pHatchingList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if ( aURL.getBase().getLength() > 18 )
+ {
+ aString += aURL.getBase().copy( 0, 15 ) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ sal_Int32 nPos = SearchHatchList( rSet.Get(XATTR_FILLHATCH).GetName() );
+ if( nPos != -1)
+ {
+ sal_uInt16 nId = m_xHatchLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xHatchLB->SelectItem( nId );
+ }
+ // colors could have been deleted
+ ChangeHatchHdl_Impl();
+ }
+
+ XFillBackgroundItem aBckItem( rSet.Get(XATTR_FILLBACKGROUND));
+ m_rXFSet.Put( aBckItem );
+
+ if (aBckItem.GetValue())
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ XFillColorItem aColorItem( rSet.Get(XATTR_FILLCOLOR) );
+ Color aColor(aColorItem.GetColorValue());
+ m_xLbBackgroundColor->SelectEntry(aColor);
+ m_xLbBackgroundColor->set_sensitive(true);
+ m_rXFSet.Put( aColorItem );
+ }
+ else
+ {
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_xLbBackgroundColor->SelectEntry(COL_AUTO);
+ m_xLbBackgroundColor->set_sensitive(false);
+ }
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+DeactivateRC SvxHatchTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+sal_Int32 SvxHatchTabPage::SearchHatchList(const OUString& rHatchName)
+{
+ long nCount = m_pHatchingList->Count();
+ bool bValidHatchName = true;
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount && bValidHatchName;i++)
+ {
+ if(rHatchName == m_pHatchingList->GetHatch( i )->GetName())
+ {
+ nPos = i;
+ bValidHatchName = false;
+ }
+ }
+ return nPos;
+}
+
+bool SvxHatchTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ std::unique_ptr<XHatch> pXHatch;
+ OUString aString;
+ size_t nPos = m_xHatchLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xHatchLB->GetSelectItemPos();
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ pXHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ aString = m_xHatchLB->GetItemText( m_xHatchLB->GetSelectedItemId() );
+ }
+ // unidentified hatch has been passed
+ else
+ {
+ pXHatch.reset(new XHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10) ));
+ }
+ assert( pXHatch && "XHatch couldn't be created" );
+ rSet->Put( XFillStyleItem( drawing::FillStyle_HATCH ) );
+ rSet->Put( XFillHatchItem( aString, *pXHatch ) );
+ rSet->Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ if (m_xCbBackgroundColor->get_active())
+ {
+ NamedColor aColor = m_xLbBackgroundColor->GetSelectedEntry();
+ rSet->Put(XFillColorItem(aColor.second, aColor.first));
+ }
+ return true;
+}
+
+void SvxHatchTabPage::Reset( const SfxItemSet* rSet )
+{
+ ChangeHatchHdl_Impl();
+
+ XFillColorItem aColItem( rSet->Get(XATTR_FILLCOLOR) );
+ m_xLbBackgroundColor->SelectEntry(aColItem.GetColorValue());
+ m_rXFSet.Put( aColItem );
+
+ XFillBackgroundItem aBckItem( rSet->Get(XATTR_FILLBACKGROUND) );
+ if(aBckItem.GetValue())
+ m_xCbBackgroundColor->set_state(TRISTATE_TRUE);
+ else
+ m_xCbBackgroundColor->set_state(TRISTATE_FALSE);
+ m_rXFSet.Put( aBckItem );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+std::unique_ptr<SfxTabPage> SvxHatchTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxHatchTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ // hatch params have changed, it is no longer one of the presets
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedColorListBoxHdl_Impl, ColorListBox&, rListBox, void )
+{
+ ModifiedHdl_Impl(&rListBox);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ToggleHatchBackgroundColor_Impl, weld::ToggleButton&, void )
+{
+ if (m_xCbBackgroundColor->get_active())
+ m_xLbBackgroundColor->set_sensitive(true);
+ else
+ m_xLbBackgroundColor->set_sensitive(false);
+ m_rXFSet.Put( XFillBackgroundItem( m_xCbBackgroundColor->get_active() ) );
+ ModifiedBackgroundHdl_Impl(*m_xLbBackgroundColor);
+}
+
+IMPL_LINK_NOARG( SvxHatchTabPage, ModifiedBackgroundHdl_Impl, ColorListBox&, void )
+{
+ Color aColor(COL_TRANSPARENT);
+ if (m_xCbBackgroundColor->get_active())
+ {
+ aColor = m_xLbBackgroundColor->GetSelectEntryColor();
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ m_rXFSet.Put(XFillColorItem( OUString(), aColor ));
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedEditHdl_Impl, weld::MetricSpinButton&, rEdit, void )
+{
+ ModifiedHdl_Impl(&rEdit);
+ m_xHatchLB->SetNoSelection();
+}
+
+IMPL_LINK( SvxHatchTabPage, ModifiedSliderHdl_Impl, weld::Scale&, rSlider, void )
+{
+ ModifiedHdl_Impl(&rSlider);
+ m_xHatchLB->SetNoSelection();
+}
+
+void SvxHatchTabPage::ModifiedHdl_Impl( void const * p )
+{
+ if (p == m_xMtrAngle.get())
+ m_xSliderAngle->set_value(m_xMtrAngle->get_value(FieldUnit::NONE));
+
+ if (p == m_xSliderAngle.get())
+ m_xMtrAngle->set_value(m_xSliderAngle->get_value(), FieldUnit::NONE);
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10) );
+
+ m_rXFSet.Put( XFillHatchItem( OUString(), aXHatch ) );
+
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ChangeHatchHdl, ValueSet*, void)
+{
+ ChangeHatchHdl_Impl();
+}
+
+void SvxHatchTabPage::ChangeHatchHdl_Impl()
+{
+ std::unique_ptr<XHatch> pHatch;
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ pHatch.reset(new XHatch( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetHatch() ));
+ else
+ {
+ const SfxPoolItem* pPoolItem = nullptr;
+ if( SfxItemState::SET == m_rOutAttrs.GetItemState( GetWhich( XATTR_FILLSTYLE ), true, &pPoolItem ) )
+ {
+ if( ( drawing::FillStyle_HATCH == static_cast<const XFillStyleItem*>( pPoolItem )->GetValue() ) &&
+ ( SfxItemState::SET == m_rOutAttrs.GetItemState( GetWhich( XATTR_FILLHATCH ), true, &pPoolItem ) ) )
+ {
+ pHatch.reset(new XHatch( static_cast<const XFillHatchItem*>( pPoolItem )->GetHatchValue() ));
+ }
+ }
+ if( !pHatch )
+ {
+ sal_uInt16 nPosition = m_xHatchLB->GetItemId( 0 );
+ m_xHatchLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ pHatch.reset( new XHatch( m_pHatchingList->GetHatch( 0 )->GetHatch() ) );
+ }
+ }
+ if( pHatch )
+ {
+ m_xLbLineType->set_active(
+ sal::static_int_cast< sal_Int32 >( pHatch->GetHatchStyle() ) );
+ m_xLbLineColor->SetNoSelection();
+ m_xLbLineColor->SelectEntry( pHatch->GetColor() );
+ SetMetricValue( *m_xMtrDistance, pHatch->GetDistance(), m_ePoolUnit );
+ long nHatchAngle = pHatch->GetAngle() / 10;
+ m_xMtrAngle->set_value(nHatchAngle, FieldUnit::NONE);
+ m_xSliderAngle->set_value(nHatchAngle);
+
+ // fill ItemSet and pass it on to m_aCtlPreview
+ m_rXFSet.Put( XFillHatchItem( OUString(), *pHatch ) );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+
+ m_aCtlPreview.Invalidate();
+ pHatch.reset();
+ }
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName( SvxResId( RID_SVXSTR_HATCH ) );
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_HATCH ) );
+ OUString aName;
+
+ long nCount = m_pHatchingList->Count();
+ long j = 1;
+ bool bValidHatchName = false;
+
+ while( !bValidHatchName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError = 1;
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidHatchName = (SearchHatchList(aName) == -1);
+ if( bValidHatchName )
+ {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+ pDlg.disposeAndClear();
+
+ if( nError )
+ return;
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10) );
+
+ m_pHatchingList->Insert(std::make_unique<XHatchEntry>(aXHatch, aName), nCount);
+
+ sal_Int32 nId = m_xHatchLB->GetItemId(nCount - 1); // calculate the last ID
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( nCount, m_xHatchLB->GetIconSize() );
+ // Insert the new entry at the next ID
+ m_xHatchLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xHatchLB->SelectItem( nId + 1 );
+ m_xHatchLB->Resize();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+
+ ChangeHatchHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pHatchingList->GetHatch( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ XHatch aXHatch( m_xLbLineColor->GetSelectEntryColor(),
+ static_cast<css::drawing::HatchStyle>(m_xLbLineType->get_active()),
+ GetCoreValue( *m_xMtrDistance, m_ePoolUnit ),
+ static_cast<long>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10) );
+
+ m_pHatchingList->Replace(std::make_unique<XHatchEntry>(aXHatch, aName), nPos);
+
+ BitmapEx aBitmap = m_pHatchingList->GetBitmapForPreview( static_cast<sal_uInt16>(nPos), m_xHatchLB->GetIconSize() );
+ m_xHatchLB->RemoveItem( nId );
+ m_xHatchLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xHatchLB->SelectItem( nId );
+
+ // save values for changes recognition (-> method)
+ m_xMtrDistance->save_value();
+ m_xMtrAngle->save_value();
+ m_xLbLineType->save_value();
+ m_xLbLineColor->SaveValue();
+ m_xLbBackgroundColor->SaveValue();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletehatchdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelHatchDialog"));
+ if (xQueryBox->run() != RET_YES)
+ return;
+
+ m_pHatchingList->Remove(nPos);
+ m_xHatchLB->RemoveItem( nId );
+ nId = m_xHatchLB->GetItemId(0);
+ m_xHatchLB->SelectItem( nId );
+ m_xHatchLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+
+ ChangeHatchHdl_Impl();
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+}
+
+IMPL_LINK_NOARG(SvxHatchTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void )
+{
+ sal_uInt16 nId = m_xHatchLB->GetSelectedItemId();
+ size_t nPos = m_xHatchLB->GetSelectItemPos();
+
+ if( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_HATCH ) );
+ OUString aName( m_pHatchingList->GetHatch( nPos )->GetName() );
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nHatchPos = SearchHatchList( aName );
+ bool bValidHatchName = (nHatchPos == static_cast<sal_Int32>(nPos) ) || (nHatchPos == -1);
+
+ if(bValidHatchName)
+ {
+ bLoop = false;
+ m_pHatchingList->GetHatch(nPos)->SetName(aName);
+
+ m_xHatchLB->SetItemText(nId, aName);
+ m_xHatchLB->SelectItem( nId );
+
+ *m_pnHatchingListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpline.cxx b/cui/source/tabpages/tpline.cxx
new file mode 100644
index 000000000..6079adcd5
--- /dev/null
+++ b/cui/source/tabpages/tpline.cxx
@@ -0,0 +1,1689 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <editeng/sizeitem.hxx>
+#include <osl/file.hxx>
+#include <tools/urlobj.hxx>
+
+#include <strings.hrc>
+#include <svx/colorbox.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlinjoit.hxx>
+#include <svx/xlncapit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <svx/xlnstcit.hxx>
+#include <svx/xlnedcit.hxx>
+
+
+#include <svx/tabline.hxx>
+#include <svx/xtable.hxx>
+#include <svx/drawitem.hxx>
+#include <cuitabline.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/svxgrahicitem.hxx>
+#include <svx/ofaitem.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/xlntrit.hxx>
+#include <svx/xfltrit.hxx>
+#include <editeng/numitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <svx/gallery.hxx>
+#include <sfx2/opengrf.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/svxids.hrc>
+#include <svx/strings.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+#include <comphelper/lok.hxx>
+
+#define MAX_BMP_WIDTH 16
+#define MAX_BMP_HEIGHT 16
+
+using namespace com::sun::star;
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxLineTabPage::pLineRanges[] =
+{
+ XATTR_LINETRANSPARENCE,
+ XATTR_LINETRANSPARENCE,
+ SID_ATTR_LINE_STYLE,
+ SID_ATTR_LINE_ENDCENTER,
+ 0
+};
+
+SvxLineTabPage::SvxLineTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linetabpage.ui", "LineTabPage", &rInAttrs)
+ , m_pSymbolList(nullptr)
+ , m_bNewSize(false)
+ , m_nSymbolType(SVX_SYMBOLTYPE_UNKNOWN) // unknown respectively unchanged
+ , m_pSymbolAttr(nullptr)
+ , m_bLastWidthModified(false)
+ , m_aSymbolLastSize(Size(0,0))
+ , m_bSymbols(false)
+ , m_rOutAttrs(rInAttrs)
+ , m_bObjSelected(false)
+ , m_aXLineAttr(rInAttrs.GetPool())
+ , m_rXLSet(m_aXLineAttr.GetItemSet())
+ , m_pnLineEndListState(nullptr)
+ , m_pnDashListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_pPosDashLb(nullptr)
+ , m_pPosLineEndLb(nullptr)
+ , m_xBoxColor(m_xBuilder->weld_widget("boxCOLOR"))
+ , m_xLbLineStyle(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINE_STYLE")))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"), pController->getDialog()))
+ , m_xBoxWidth(m_xBuilder->weld_widget("boxWIDTH"))
+ , m_xMtrLineWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_LINE_WIDTH", FieldUnit::CM))
+ , m_xBoxTransparency(m_xBuilder->weld_widget("boxTRANSPARENCY"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_LINE_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xFlLineEnds(m_xBuilder->weld_widget("FL_LINE_ENDS"))
+ , m_xBoxArrowStyles(m_xBuilder->weld_widget("boxARROW_STYLES"))
+ , m_xLbStartStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_START_STYLE")))
+ , m_xBoxStart(m_xBuilder->weld_widget("boxSTART"))
+ , m_xMtrStartWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_START_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterStart(m_xBuilder->weld_check_button("TSB_CENTER_START"))
+ , m_xBoxEnd(m_xBuilder->weld_widget("boxEND"))
+ , m_xLbEndStyle(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_END_STYLE")))
+ , m_xMtrEndWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_END_WIDTH", FieldUnit::CM))
+ , m_xTsbCenterEnd(m_xBuilder->weld_check_button("TSB_CENTER_END"))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xFLEdgeStyle(m_xBuilder->weld_widget("FL_EDGE_STYLE"))
+ , m_xGridEdgeCaps(m_xBuilder->weld_widget("gridEDGE_CAPS"))
+ , m_xLBEdgeStyle(m_xBuilder->weld_combo_box("LB_EDGE_STYLE"))
+ , m_xLBCapStyle(m_xBuilder->weld_combo_box("LB_CAP_STYLE")) // LineCaps
+ , m_xFlSymbol(m_xBuilder->weld_widget("FL_SYMBOL_FORMAT")) //#58425# Symbols on a line (e.g. StarChart)
+ , m_xGridIconSize(m_xBuilder->weld_widget("gridICON_SIZE"))
+ , m_xSymbolMB(m_xBuilder->weld_menu_button("MB_SYMBOL_BITMAP"))
+ , m_xSymbolWidthMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_WIDTH", FieldUnit::CM))
+ , m_xSymbolHeightMF(m_xBuilder->weld_metric_spin_button("MF_SYMBOL_HEIGHT", FieldUnit::CM))
+ , m_xSymbolRatioCB(m_xBuilder->weld_check_button("CB_SYMBOL_RATIO"))
+{
+ // This Page requires ExchangeSupport
+ SetExchangeSupport();
+
+ // Metric set
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ [[fallthrough]]; // we now have mm
+ case FieldUnit::MM:
+ m_xMtrLineWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(50, 500, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(50, 500, FieldUnit::NONE);
+ break;
+
+ case FieldUnit::INCH:
+ m_xMtrLineWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrStartWidth->set_increments(2, 20, FieldUnit::NONE);
+ m_xMtrEndWidth->set_increments(2, 20, FieldUnit::NONE);
+ break;
+ default: ;// prevent warning
+ }
+ SetFieldUnit( *m_xMtrLineWidth, eFUnit );
+ SetFieldUnit( *m_xMtrStartWidth, eFUnit );
+ SetFieldUnit( *m_xMtrEndWidth, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ m_xLbLineStyle->connect_changed(LINK(this, SvxLineTabPage, ClickInvisibleHdl_Impl));
+ m_xLbColor->SetSelectHdl( LINK( this, SvxLineTabPage, ChangePreviewListBoxHdl_Impl ) );
+ m_xMtrLineWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangePreviewModifyHdl_Impl));
+ m_xMtrTransparent->connect_value_changed(LINK( this, SvxLineTabPage, ChangeTransparentHdl_Impl));
+
+ m_xLbStartStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeStartListBoxHdl_Impl));
+ m_xLbEndStyle->connect_changed(LINK(this, SvxLineTabPage, ChangeEndListBoxHdl_Impl));
+ m_xMtrStartWidth->connect_value_changed(LINK(this, SvxLineTabPage, ChangeStartModifyHdl_Impl));
+ m_xMtrEndWidth->connect_value_changed(LINK( this, SvxLineTabPage, ChangeEndModifyHdl_Impl));
+ m_xTsbCenterStart->connect_clicked(LINK(this, SvxLineTabPage, ChangeStartClickHdl_Impl));
+ m_xTsbCenterEnd->connect_clicked(LINK(this, SvxLineTabPage, ChangeEndClickHdl_Impl));
+
+ Link<weld::ComboBox&,void> aEdgeStyle = LINK(this, SvxLineTabPage, ChangeEdgeStyleHdl_Impl);
+ m_xLBEdgeStyle->connect_changed(aEdgeStyle);
+
+ // LineCaps
+ Link<weld::ComboBox&,void> aCapStyle = LINK(this, SvxLineTabPage, ChangeCapStyleHdl_Impl);
+ m_xLBCapStyle->connect_changed(aCapStyle);
+
+ // Symbols on a line (eg star charts), MB-handler set
+ m_xSymbolMB->connect_selected(LINK(this, SvxLineTabPage, GraphicHdl_Impl));
+ m_xSymbolMB->connect_toggled(LINK(this, SvxLineTabPage, MenuCreateHdl_Impl));
+ m_xSymbolWidthMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolHeightMF->connect_value_changed(LINK(this, SvxLineTabPage, SizeHdl_Impl));
+ m_xSymbolRatioCB->connect_toggled(LINK(this, SvxLineTabPage, RatioHdl_Impl));
+
+ m_xSymbolRatioCB->set_active(true);
+ ShowSymbolControls(false);
+
+ m_nActLineWidth = -1;
+}
+
+void SvxLineTabPage::ShowSymbolControls(bool bOn)
+{
+ // Symbols on a line (e.g. StarCharts), symbol-enable controls
+
+ m_bSymbols=bOn;
+ m_xFlSymbol->set_visible(bOn);
+ m_aCtlPreview.ShowSymbol(bOn);
+}
+
+SvxLineTabPage::~SvxLineTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbEndStyle.reset();
+ m_xLbStartStyle.reset();
+ m_xLbColor.reset();
+ m_xLbLineStyle.reset();
+ m_aGalleryBrushItems.clear();
+ m_aSymbolBrushItems.clear();
+}
+
+void SvxLineTabPage::Construct()
+{
+ FillListboxes();
+}
+
+void SvxLineTabPage::FillListboxes()
+{
+ // Line styles
+ auto nOldSelect = m_xLbLineStyle->get_active();
+ // aLbLineStyle.FillStyles();
+ m_xLbLineStyle->Fill( m_pDashList );
+ m_xLbLineStyle->set_active( nOldSelect );
+
+ // Line end style
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+ nOldSelect = m_xLbStartStyle->get_active();
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+ m_xLbStartStyle->Fill(m_pLineEndList);
+ m_xLbStartStyle->set_active(nOldSelect);
+ nOldSelect = m_xLbEndStyle->get_active();
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+ m_xLbEndStyle->Fill(m_pLineEndList, false);
+ m_xLbEndStyle->set_active(nOldSelect);
+}
+
+void SvxLineTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if( m_nDlgType == 0 && m_pDashList.is() )
+ {
+ sal_Int32 nPos;
+ sal_Int32 nCount;
+
+ // Dash list
+ if( ( *m_pnDashListState & ChangeType::MODIFIED ) ||
+ ( *m_pnDashListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnDashListState & ChangeType::CHANGED )
+ m_pDashList = static_cast<SvxLineTabDialog*>(GetDialogController() )->GetNewDashList();
+
+ *m_pnDashListState = ChangeType::NONE;
+
+ // Style list
+ nPos = m_xLbLineStyle->get_active();
+
+ m_xLbLineStyle->clear();
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_INVISIBLE));
+ m_xLbLineStyle->append_text(SvxResId(RID_SVXSTR_SOLID));
+ m_xLbLineStyle->Fill(m_pDashList);
+ nCount = m_xLbLineStyle->get_count();
+
+ if ( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbLineStyle->set_active(0);
+ else
+ m_xLbLineStyle->set_active(nPos);
+ }
+
+ INetURLObject aDashURL( m_pDashList->GetPath() );
+
+ aDashURL.Append( m_pDashList->GetName() );
+ DBG_ASSERT( aDashURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // LineEnd list
+ if( ( *m_pnLineEndListState & ChangeType::MODIFIED ) || ( *m_pnLineEndListState & ChangeType::CHANGED ) )
+ {
+ if( *m_pnLineEndListState & ChangeType::CHANGED )
+ m_pLineEndList = static_cast<SvxLineTabDialog*>(GetDialogController())->GetNewLineEndList();
+
+ *m_pnLineEndListState = ChangeType::NONE;
+
+ nPos = m_xLbLineStyle->get_active();
+ OUString sNone( comphelper::LibreOfficeKit::isActive() ? SvxResId( RID_SVXSTR_INVISIBLE )
+ : SvxResId( RID_SVXSTR_NONE ) );
+
+ m_xLbStartStyle->clear();
+ m_xLbStartStyle->append_text(sNone);
+
+ m_xLbStartStyle->Fill( m_pLineEndList );
+ nCount = m_xLbStartStyle->get_count();
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbStartStyle->set_active(0);
+ else
+ m_xLbStartStyle->set_active(nPos);
+
+ m_xLbEndStyle->clear();
+ m_xLbEndStyle->append_text(sNone);
+
+ m_xLbEndStyle->Fill( m_pLineEndList, false );
+ nCount = m_xLbEndStyle->get_count();
+
+ if( nCount == 0 )
+ ; // This case should never occur
+ else if( nCount <= nPos )
+ m_xLbEndStyle->set_active(0);
+ else
+ m_xLbEndStyle->set_active(nPos);
+ }
+ INetURLObject aLineURL( m_pLineEndList->GetPath() );
+
+ aLineURL.Append( m_pLineEndList->GetName() );
+ DBG_ASSERT( aLineURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ // Evaluate if another TabPage set another fill type
+ if( m_xLbLineStyle->get_active() != 0 )
+ {
+ if( m_nPageType == PageType::Hatch ) // 1
+ {
+ m_xLbLineStyle->set_active(*m_pPosDashLb + 2); // +2 due to SOLID and INVISIBLE
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ if( m_nPageType == PageType::Bitmap )
+ {
+ m_xLbStartStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ m_xLbEndStyle->set_active(*m_pPosLineEndLb + 1);// +1 due to SOLID
+ ChangePreviewHdl_Impl( nullptr );
+ }
+ }
+
+ // ColorList
+ if( *m_pnColorListState != ChangeType::NONE )
+ {
+ ChangePreviewHdl_Impl( nullptr );
+ }
+
+ m_nPageType = PageType::Area;
+ }
+ // Page does not yet exist in the ctor, that's why we do it here!
+
+ else if (m_nDlgType == 1101) // nNoArrowNoShadowDlg from chart2/source/controller/dialogs/dlg_ObjectProperties.cxx
+ {
+ m_xFlLineEnds->hide();
+ m_xFLEdgeStyle->hide();
+ }
+}
+
+
+DeactivateRC SvxLineTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( m_nDlgType == 0 ) // Line dialog
+ {
+ m_nPageType = PageType::Gradient; // possibly for extensions
+ *m_pPosDashLb = m_xLbLineStyle->get_active() - 2;// First entry SOLID!!!
+ sal_Int32 nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ nPos--;
+ *m_pPosLineEndLb = nPos;
+ }
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxLineTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ const SfxPoolItem* pOld = nullptr;
+ sal_Int32 nPos;
+ bool bModified = false;
+
+ // To prevent modifications to the list, we do not set other page's items.
+ if( m_nDlgType != 0 || m_nPageType != PageType::Hatch )
+ {
+ nPos = m_xLbLineStyle->get_active();
+ if( nPos != -1 &&
+ m_xLbLineStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStyleItem> pStyleItem;
+
+ if( nPos == 0 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_NONE ));
+ else if( nPos == 1 )
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_SOLID ));
+ else
+ {
+ pStyleItem.reset(new XLineStyleItem( drawing::LineStyle_DASH ));
+
+ // For added security
+ if( m_pDashList->Count() > static_cast<long>( nPos - 2 ) )
+ {
+ XLineDashItem aDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEDASH );
+ if ( !pOld || !( *static_cast<const XLineDashItem*>(pOld) == aDashItem ) )
+ {
+ rAttrs->Put( aDashItem );
+ bModified = true;
+ }
+ }
+ }
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTYLE );
+ if ( !pOld || !( *static_cast<const XLineStyleItem*>(pOld) == *pStyleItem ) )
+ {
+ rAttrs->Put( *pStyleItem );
+ bModified = true;
+ }
+ }
+ }
+ // Line width
+ // GetSavedValue() returns OUString!
+ if( m_xMtrLineWidth->get_value_changed_from_saved() )
+ {
+ XLineWidthItem aItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEWIDTH );
+ if ( !pOld || !( *static_cast<const XLineWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line start
+ if( m_xMtrStartWidth->get_value_changed_from_saved() )
+ {
+ XLineStartWidthItem aItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTWIDTH );
+ if ( !pOld || !( *static_cast<const XLineStartWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ // Width line end
+ if( m_xMtrEndWidth->get_value_changed_from_saved() )
+ {
+ XLineEndWidthItem aItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDWIDTH );
+ if ( !pOld || !( *static_cast<const XLineEndWidthItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Line color
+ if (m_xLbColor->IsValueChangedFromSaved())
+ {
+ NamedColor aColor = m_xLbColor->GetSelectedEntry();
+ XLineColorItem aItem(aColor.second, aColor.first);
+ pOld = GetOldItem( *rAttrs, XATTR_LINECOLOR );
+ if ( !pOld || !( *static_cast<const XLineColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ if( m_nDlgType != 0 || m_nPageType != PageType::Bitmap )
+ {
+ // Line start
+ nPos = m_xLbStartStyle->get_active();
+ if( nPos != -1 && m_xLbStartStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineStartItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineStartItem());
+ else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
+ pItem.reset(new XLineStartItem( m_xLbStartStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTART );
+ if( pItem && ( !pOld || *pOld != *pItem ) )
+ {
+ rAttrs->Put( *pItem );
+ bModified = true;
+ }
+ }
+ // Line end
+ nPos = m_xLbEndStyle->get_active();
+ if( nPos != -1 && m_xLbEndStyle->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<XLineEndItem> pItem;
+ if( nPos == 0 )
+ pItem.reset(new XLineEndItem());
+ else if( m_pLineEndList->Count() > static_cast<long>( nPos - 1 ) )
+ pItem.reset(new XLineEndItem( m_xLbEndStyle->get_active_text(), m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ));
+ pOld = GetOldItem( *rAttrs, XATTR_LINEEND );
+ if( pItem &&
+ ( !pOld || !( *static_cast<const XLineEndItem*>(pOld) == *pItem ) ) )
+ {
+ rAttrs->Put( *pItem );
+ bModified = true;
+ }
+ }
+ }
+
+ // Centered line end
+ TriState eState = m_xTsbCenterStart->get_state();
+ if( m_xTsbCenterStart->get_state_changed_from_saved() )
+ {
+ XLineStartCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINESTARTCENTER );
+ if ( !pOld || !( *static_cast<const XLineStartCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+ eState = m_xTsbCenterEnd->get_state();
+ if( m_xTsbCenterEnd->get_state_changed_from_saved() )
+ {
+ XLineEndCenterItem aItem( eState != TRISTATE_FALSE );
+ pOld = GetOldItem( *rAttrs, XATTR_LINEENDCENTER );
+ if ( !pOld || !( *static_cast<const XLineEndCenterItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if( m_xMtrTransparent->get_value_changed_from_saved() )
+ {
+ XLineTransparenceItem aItem( nVal );
+ pOld = GetOldItem( *rAttrs, XATTR_LINETRANSPARENCE );
+ if ( !pOld || !( *static_cast<const XLineTransparenceItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1 && m_xLBEdgeStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineJointItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ pNew.reset(new XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINEJOINT );
+
+ if(!pOld || !(*static_cast<const XLineJointItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( *pNew );
+ bModified = true;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1 && m_xLBCapStyle->get_value_changed_from_saved())
+ {
+ std::unique_ptr<XLineCapItem> pNew;
+
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ pNew.reset(new XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+
+ if(pNew)
+ {
+ pOld = GetOldItem( *rAttrs, XATTR_LINECAP );
+
+ if(!pOld || !(*static_cast<const XLineCapItem*>(pOld) == *pNew))
+ {
+ rAttrs->Put( *pNew );
+ bModified = true;
+ }
+ }
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_UNKNOWN || m_bNewSize)
+ {
+ // Was set by selection or the size is different
+ SvxSizeItem aSItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),m_aSymbolSize);
+ const SfxPoolItem* pSOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE) );
+ m_bNewSize = pSOld ? *static_cast<const SvxSizeItem *>(pSOld) != aSItem : m_bNewSize ;
+ if(m_bNewSize)
+ {
+ rAttrs->Put(aSItem);
+ bModified=true;
+ }
+
+ SfxInt32Item aTItem(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),m_nSymbolType);
+ const SfxPoolItem* pTOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE) );
+ bool bNewType = pTOld == nullptr || *static_cast<const SfxInt32Item*>(pTOld) != aTItem;
+ if(bNewType && m_nSymbolType==SVX_SYMBOLTYPE_UNKNOWN)
+ bNewType=false; // a small fix, type wasn't set -> don't create a type item after all!
+ if(bNewType)
+ {
+ rAttrs->Put(aTItem);
+ bModified=true;
+ }
+
+ if(m_nSymbolType!=SVX_SYMBOLTYPE_NONE)
+ {
+ SvxBrushItem aBItem(m_aSymbolGraphic,GPOS_MM,rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH));
+ const SfxPoolItem* pBOld = GetOldItem( *rAttrs, rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH) );
+ bool bNewBrush =
+ pBOld == nullptr || *static_cast<const SvxBrushItem*>(pBOld) != aBItem;
+ if(bNewBrush)
+ {
+ rAttrs->Put(aBItem);
+ bModified=true;
+ }
+ }
+ }
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+ return bModified;
+}
+
+
+void SvxLineTabPage::FillXLSet_Impl()
+{
+ sal_Int32 nPos;
+
+ if (m_xLbLineStyle->get_active() == -1)
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ }
+ else if (m_xLbLineStyle->get_active() == 0)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
+ else if (m_xLbLineStyle->get_active() == 1)
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
+ else
+ {
+ m_rXLSet.Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+
+ nPos = m_xLbLineStyle->get_active();
+ if (nPos != -1)
+ {
+ m_rXLSet.Put( XLineDashItem( m_xLbLineStyle->get_active_text(),
+ m_pDashList->GetDash( nPos - 2 )->GetDash() ) );
+ }
+ }
+
+ nPos = m_xLbStartStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineStartItem() );
+ else
+ m_rXLSet.Put( XLineStartItem( m_xLbStartStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+ nPos = m_xLbEndStyle->get_active();
+ if (nPos != -1)
+ {
+ if( nPos == 0 )
+ m_rXLSet.Put( XLineEndItem() );
+ else
+ m_rXLSet.Put( XLineEndItem( m_xLbEndStyle->get_active_text(),
+ m_pLineEndList->GetLineEnd( nPos - 1 )->GetLineEnd() ) );
+ }
+
+ nPos = m_xLBEdgeStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Rounded, default
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_ROUND));
+ break;
+ }
+ case 1: // - none -
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_NONE));
+ break;
+ }
+ case 2: // Miter
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_MITER));
+ break;
+ }
+ case 3: // Bevel
+ {
+ m_rXLSet.Put(XLineJointItem(css::drawing::LineJoint_BEVEL));
+ break;
+ }
+ }
+ }
+
+ // LineCaps
+ nPos = m_xLBCapStyle->get_active();
+ if (nPos != -1)
+ {
+ switch(nPos)
+ {
+ case 0: // Butt (=Flat), default
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_BUTT));
+ break;
+ }
+ case 1: // Round
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_ROUND));
+ break;
+ }
+ case 2: // Square
+ {
+ m_rXLSet.Put(XLineCapItem(css::drawing::LineCap_SQUARE));
+ break;
+ }
+ }
+ }
+
+ m_rXLSet.Put( XLineStartWidthItem( GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit ) ) );
+ m_rXLSet.Put( XLineEndWidthItem( GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit ) ) );
+
+ m_rXLSet.Put( XLineWidthItem( GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit ) ) );
+ NamedColor aColor = m_xLbColor->GetSelectedEntry();
+ m_rXLSet.Put(XLineColorItem(aColor.second, aColor.first));
+
+ // Centered line end
+ if( m_xTsbCenterStart->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineStartCenterItem( true ) );
+ else if( m_xTsbCenterStart->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineStartCenterItem( false ) );
+
+ if( m_xTsbCenterEnd->get_state() == TRISTATE_TRUE )
+ m_rXLSet.Put( XLineEndCenterItem( true ) );
+ else if( m_xTsbCenterEnd->get_state() == TRISTATE_FALSE )
+ m_rXLSet.Put( XLineEndCenterItem( false ) );
+
+ // Transparency
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ m_rXLSet.Put( XLineTransparenceItem( nVal ) );
+
+ m_aCtlPreview.SetLineAttributes(m_aXLineAttr.GetItemSet());
+}
+
+
+void SvxLineTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ drawing::LineStyle eXLS; // drawing::LineStyle_NONE, drawing::LineStyle_SOLID, drawing::LineStyle_DASH
+
+ // Line style
+ const SfxPoolItem *pPoolItem;
+ long nSymType=SVX_SYMBOLTYPE_UNKNOWN;
+ bool bPrevSym=false;
+ bool bEnable=true;
+ bool bIgnoreGraphic=false;
+ bool bIgnoreSize=false;
+ if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLTYPE),true,&pPoolItem) == SfxItemState::SET)
+ {
+ nSymType=static_cast<const SfxInt32Item *>(pPoolItem)->GetValue();
+ }
+
+ if(nSymType == SVX_SYMBOLTYPE_AUTO)
+ {
+ m_aSymbolGraphic=m_aAutoSymbolGraphic;
+ m_aSymbolSize=m_aSymbolLastSize=m_aAutoSymbolGraphic.GetPrefSize();
+ bPrevSym=true;
+ }
+ else if(nSymType == SVX_SYMBOLTYPE_NONE)
+ {
+ bEnable=false;
+ bIgnoreGraphic=true;
+ bIgnoreSize=true;
+ }
+ else if(nSymType >= 0)
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ SdrPage* pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage, 0 );
+ {
+ std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
+ pView->hideMarkHandles();
+ pView->ShowSdrPage(pPage);
+ SdrObject *pObj=nullptr;
+ size_t nSymTmp = static_cast<size_t>(nSymType);
+ if(m_pSymbolList)
+ {
+ if(m_pSymbolList->GetObjCount())
+ {
+ nSymTmp %= m_pSymbolList->GetObjCount(); // Treat list as cyclic!
+ pObj=m_pSymbolList->GetObj(nSymTmp);
+ if(pObj)
+ {
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ if(m_pSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_pSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+
+ pPage->NbcInsertObject(pObj);
+
+ // Generate invisible square to give all symbol types a
+ // bitmap size, which is independent from specific glyph
+ SdrObject* pInvisibleSquare(m_pSymbolList->GetObj(0));
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare);
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ pView->MarkAll();
+ GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
+
+ m_aSymbolGraphic=Graphic(aMeta);
+ m_aSymbolSize=pObj->GetSnapRect().GetSize();
+ m_aSymbolGraphic.SetPrefSize(pInvisibleSquare->GetSnapRect().GetSize());
+ m_aSymbolGraphic.SetPrefMapMode(MapMode(MapUnit::Map100thMM));
+ bPrevSym=true;
+ bEnable=true;
+ bIgnoreGraphic=true;
+
+ pView->UnmarkAll();
+ pInvisibleSquare=pPage->RemoveObject(1);
+ SdrObject::Free( pInvisibleSquare);
+ pObj=pPage->RemoveObject(0);
+ SdrObject::Free( pObj );
+ }
+ }
+ }
+ }
+ }
+ if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_BRUSH),true,&pPoolItem) == SfxItemState::SET)
+ {
+ const Graphic* pGraphic = static_cast<const SvxBrushItem *>(pPoolItem)->GetGraphic();
+ if( pGraphic )
+ {
+ if(!bIgnoreGraphic)
+ {
+ m_aSymbolGraphic=*pGraphic;
+ }
+ if(!bIgnoreSize)
+ {
+ m_aSymbolSize=OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
+ pGraphic->GetPrefMapMode(),
+ MapMode(MapUnit::Map100thMM));
+ }
+ bPrevSym=true;
+ }
+ }
+
+ if(rAttrs->GetItemState(rAttrs->GetPool()->GetWhich(SID_ATTR_SYMBOLSIZE),true,&pPoolItem) == SfxItemState::SET)
+ {
+ m_aSymbolSize = static_cast<const SvxSizeItem *>(pPoolItem)->GetSize();
+ }
+
+ m_xGridIconSize->set_sensitive(bEnable);
+
+ if(bPrevSym)
+ {
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(),m_ePoolUnit);
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+ }
+
+ if( rAttrs->GetItemState( XATTR_LINESTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXLS = rAttrs->Get( XATTR_LINESTYLE ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ m_xLbLineStyle->set_active(0);
+ break;
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyle->set_active(1);
+ break;
+
+ case drawing::LineStyle_DASH:
+ m_xLbLineStyle->set_active(-1);
+ m_xLbLineStyle->set_active_text(rAttrs->Get( XATTR_LINEDASH ).GetName());
+ break;
+
+ default:
+ break;
+ }
+ }
+ else
+ {
+ m_xLbLineStyle->set_active(-1);
+ }
+
+ // Line strength
+ if( rAttrs->GetItemState( XATTR_LINEWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrLineWidth, rAttrs->Get( XATTR_LINEWIDTH ).GetValue(), m_ePoolUnit );
+ }
+ else
+ m_xMtrLineWidth->set_text("");
+
+ // Line color
+ m_xLbColor->SetNoSelection();
+
+ if ( rAttrs->GetItemState( XATTR_LINECOLOR ) != SfxItemState::DONTCARE )
+ {
+ Color aCol = rAttrs->Get( XATTR_LINECOLOR ).GetColorValue();
+ m_xLbColor->SelectEntry( aCol );
+ }
+
+ // Line start
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTART ) == SfxItemState::DEFAULT )
+ {
+ m_xLbStartStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTART ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINESTART).GetLineStartValue();
+
+ for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbStartStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbStartStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbStartStyle->set_active(-1);
+ }
+
+ // Line end
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEEND ) == SfxItemState::DEFAULT )
+ {
+ m_xLbEndStyle->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEEND ) != SfxItemState::DONTCARE )
+ {
+ // #86265# select entry using list and polygon, not string
+ bool bSelected(false);
+ const basegfx::B2DPolyPolygon& rItemPolygon = rAttrs->Get(XATTR_LINEEND).GetLineEndValue();
+
+ for(long a(0);!bSelected && a < m_pLineEndList->Count(); a++)
+ {
+ const XLineEndEntry* pEntry = m_pLineEndList->GetLineEnd(a);
+ const basegfx::B2DPolyPolygon& rEntryPolygon = pEntry->GetLineEnd();
+
+ if(rItemPolygon == rEntryPolygon)
+ {
+ // select this entry
+ m_xLbEndStyle->set_active(a + 1);
+ bSelected = true;
+ }
+ }
+
+ if(!bSelected)
+ m_xLbEndStyle->set_active(0);
+ }
+ else
+ {
+ m_xLbEndStyle->set_active(-1);
+ }
+
+ // Line start strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrStartWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrStartWidth,
+ rAttrs->Get( XATTR_LINESTARTWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrStartWidth->set_text( "" );
+
+ // Line end strength
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDWIDTH ) == SfxItemState::DEFAULT )
+ {
+ m_xMtrEndWidth->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDWIDTH ) != SfxItemState::DONTCARE )
+ {
+ SetMetricValue( *m_xMtrEndWidth,
+ rAttrs->Get( XATTR_LINEENDWIDTH ).GetValue(),
+ m_ePoolUnit );
+ }
+ else
+ m_xMtrEndWidth->set_text("");
+
+ // Centered line end (start)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINESTARTCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterStart->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINESTARTCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINESTARTCENTER ).GetValue() )
+ m_xTsbCenterStart->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterStart->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterStart->set_state(TRISTATE_INDET);
+ }
+
+ // Centered line end (end)
+ if( m_bObjSelected && rAttrs->GetItemState( XATTR_LINEENDCENTER ) == SfxItemState::DEFAULT )
+ {
+ m_xTsbCenterEnd->set_sensitive(false);
+ }
+ else if( rAttrs->GetItemState( XATTR_LINEENDCENTER ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( XATTR_LINEENDCENTER ).GetValue() )
+ m_xTsbCenterEnd->set_state(TRISTATE_TRUE);
+ else
+ m_xTsbCenterEnd->set_state(TRISTATE_FALSE);
+ }
+ else
+ {
+ m_xTsbCenterEnd->set_state(TRISTATE_INDET);
+ }
+
+ // Transparency
+ if( rAttrs->GetItemState( XATTR_LINETRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( XATTR_LINETRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ ChangeTransparentHdl_Impl(*m_xMtrTransparent);
+ }
+ else
+ m_xMtrTransparent->set_text( "" );
+
+ if( !m_xLbStartStyle->get_sensitive() &&
+ !m_xLbEndStyle->get_sensitive() &&
+ !m_xMtrStartWidth->get_sensitive() &&
+ !m_xMtrEndWidth->get_sensitive() &&
+ !m_xTsbCenterStart->get_sensitive()&&
+ !m_xTsbCenterEnd->get_sensitive() )
+ {
+ m_xCbxSynchronize->set_sensitive(false);
+ m_xFlLineEnds->set_sensitive(false);
+ }
+
+ // Synchronize
+ // We get the value from the INI file now
+ OUString aStr = GetUserData();
+ m_xCbxSynchronize->set_active(aStr.toInt32() != 0);
+
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+// maFTEdgeStyle.set_sensitive(false);
+ m_xLBEdgeStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINEJOINT))
+ {
+ const css::drawing::LineJoint eLineJoint = rAttrs->Get(XATTR_LINEJOINT).GetValue();
+
+ switch(eLineJoint)
+ {
+ case css::drawing::LineJoint::LineJoint_MAKE_FIXED_SIZE: // fallback to round, unused value
+ case css::drawing::LineJoint_ROUND : m_xLBEdgeStyle->set_active(0); break;
+ case css::drawing::LineJoint_NONE : m_xLBEdgeStyle->set_active(1); break;
+ case css::drawing::LineJoint_MIDDLE : // fallback to mitre, unused value
+ case css::drawing::LineJoint_MITER : m_xLBEdgeStyle->set_active(2); break;
+ case css::drawing::LineJoint_BEVEL : m_xLBEdgeStyle->set_active(3); break;
+ }
+ }
+ else
+ {
+ m_xLBEdgeStyle->set_active(-1);
+ }
+
+ // fdo#43209
+ if(m_bObjSelected && SfxItemState::DEFAULT == rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ m_xLBCapStyle->set_sensitive(false);
+ }
+ else if(SfxItemState::DONTCARE != rAttrs->GetItemState(XATTR_LINECAP))
+ {
+ const css::drawing::LineCap eLineCap(rAttrs->Get(XATTR_LINECAP).GetValue());
+
+ switch(eLineCap)
+ {
+ case css::drawing::LineCap_ROUND: m_xLBCapStyle->set_active(1); break;
+ case css::drawing::LineCap_SQUARE : m_xLBCapStyle->set_active(2); break;
+ default /*css::drawing::LineCap_BUTT*/: m_xLBCapStyle->set_active(0); break;
+ }
+ }
+ else
+ {
+ m_xLBCapStyle->set_active(-1);
+ }
+
+ // Save values
+ m_xLbLineStyle->save_value();
+ m_xMtrLineWidth->save_value();
+ m_xLbColor->SaveValue();
+ m_xLbStartStyle->save_value();
+ m_xLbEndStyle->save_value();
+ m_xMtrStartWidth->save_value();
+ m_xMtrEndWidth->save_value();
+ m_xTsbCenterStart->save_state();
+ m_xTsbCenterEnd->save_state();
+ m_xMtrTransparent->save_value();
+
+ m_xLBEdgeStyle->save_value();
+
+ // LineCaps
+ m_xLBCapStyle->save_value();
+
+ ClickInvisibleHdl_Impl();
+
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+std::unique_ptr<SfxTabPage> SvxLineTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxLineTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangePreviewListBoxHdl_Impl, ColorListBox&, void)
+{
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK(SvxLineTabPage, ChangePreviewModifyHdl_Impl, weld::MetricSpinButton&, rEdit, void)
+{
+ ChangePreviewHdl_Impl(&rEdit);
+}
+
+void SvxLineTabPage::ChangePreviewHdl_Impl(const weld::MetricSpinButton* pCntrl)
+{
+ if (pCntrl == m_xMtrLineWidth.get())
+ {
+ // Line width and start end width
+ sal_Int32 nNewLineWidth = GetCoreValue( *m_xMtrLineWidth, m_ePoolUnit );
+ if(m_nActLineWidth == -1)
+ {
+ // Don't initialize yet, get the start value
+ const SfxPoolItem* pOld = GetOldItem( m_rXLSet, XATTR_LINEWIDTH );
+ sal_Int32 nStartLineWidth = 0;
+ if(pOld)
+ nStartLineWidth = static_cast<const XLineWidthItem *>(pOld)->GetValue();
+ m_nActLineWidth = nStartLineWidth;
+ }
+
+ if(m_nActLineWidth != nNewLineWidth)
+ {
+ // Adapt start/end width
+ sal_Int32 nValAct = GetCoreValue( *m_xMtrStartWidth, m_ePoolUnit );
+ sal_Int32 nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrStartWidth, nValNew, m_ePoolUnit );
+
+ nValAct = GetCoreValue( *m_xMtrEndWidth, m_ePoolUnit );
+ nValNew = nValAct + (((nNewLineWidth - m_nActLineWidth) * 15) / 10);
+ if(nValNew < 0)
+ nValNew = 0;
+ SetMetricValue( *m_xMtrEndWidth, nValNew, m_ePoolUnit );
+ }
+
+ // Remember current value
+ m_nActLineWidth = nNewLineWidth;
+ }
+
+ FillXLSet_Impl();
+ m_aCtlPreview.Invalidate();
+
+ // Make transparency accessible accordingly
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ m_xBoxTransparency->set_sensitive(false);
+ }
+ else
+ {
+ m_xBoxTransparency->set_sensitive(true);
+ }
+
+ const bool bHasLineStyle = m_xLbLineStyle->get_active() !=0;
+ const bool bHasLineStart = m_xLbStartStyle->get_active() != 0;
+
+ m_xBoxStart->set_sensitive(bHasLineStart && bHasLineStyle);
+
+ const bool bHasLineEnd = m_xLbEndStyle->get_active() != 0;
+
+ m_xBoxEnd->set_sensitive(bHasLineEnd && bHasLineStyle);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartClickHdl_Impl, weld::Button&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterEnd->set_state(m_xTsbCenterStart->get_state());
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbEndStyle->set_active(m_xLbStartStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeStartModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrEndWidth->set_value(m_xMtrStartWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEdgeStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+// fdo#43209
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeCapStyleHdl_Impl, weld::ComboBox&, void)
+{
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ClickInvisibleHdl_Impl, weld::ComboBox&, void)
+{
+ ClickInvisibleHdl_Impl();
+}
+
+void SvxLineTabPage::ClickInvisibleHdl_Impl()
+{
+ if( m_xLbLineStyle->get_active() == 0 ) // invisible
+ {
+ if(!m_bSymbols)
+ m_xBoxColor->set_sensitive(false);
+
+ m_xBoxWidth->set_sensitive(false);
+
+ if( m_xFlLineEnds->get_sensitive() )
+ {
+ m_xBoxStart->set_sensitive(false);
+ m_xBoxArrowStyles->set_sensitive(false);
+ m_xGridEdgeCaps->set_sensitive(false);
+ }
+ }
+ else
+ {
+ m_xBoxColor->set_sensitive(true);
+ m_xBoxWidth->set_sensitive(true);
+
+ if (m_xFlLineEnds->get_sensitive())
+ {
+ m_xBoxArrowStyles->set_sensitive(true);
+ m_xGridEdgeCaps->set_sensitive(true);
+ }
+ }
+ ChangePreviewHdl_Impl( nullptr );
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndClickHdl_Impl, weld::Button&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xTsbCenterStart->set_state(m_xTsbCenterEnd->get_state());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xLbStartStyle->set_active(m_xLbEndStyle->get_active());
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeEndModifyHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xCbxSynchronize->get_active())
+ m_xMtrStartWidth->set_value(m_xMtrEndWidth->get_value(FieldUnit::NONE), FieldUnit::NONE);
+
+ ChangePreviewHdl_Impl(nullptr);
+}
+
+IMPL_LINK_NOARG(SvxLineTabPage, ChangeTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nVal = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+
+ m_rXLSet.Put(XLineTransparenceItem(nVal));
+
+ FillXLSet_Impl();
+
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxLineTabPage::FillUserData()
+{
+ // Write the synched value to the INI file
+ OUString aStrUserData = OUString::boolean(m_xCbxSynchronize->get_active());
+ SetUserData( aStrUserData );
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for the symbol selection's popup menu (NumMenueButton)
+// The following link originates from SvxNumOptionsTabPage
+IMPL_LINK_NOARG(SvxLineTabPage, MenuCreateHdl_Impl, weld::ToggleButton&, void)
+{
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+
+ // Initialize popup
+ if (!m_xGalleryMenu)
+ {
+ m_xGalleryMenu = m_xBuilder->weld_menu("gallerysubmenu");
+ weld::WaitObject aWait(GetFrameWeld());
+ // Get gallery entries
+ GalleryExplorer::FillObjList(GALLERY_THEME_BULLETS, m_aGrfNames);
+
+ sal_uInt32 i = 0;
+ for (auto const& grfName : m_aGrfNames)
+ {
+ const OUString *pUIName = &grfName;
+
+ // Convert URL encodings to UI characters (e.g. %20 for spaces)
+ OUString aPhysicalName;
+ if (osl::FileBase::getSystemPathFromFileURL(grfName, aPhysicalName)
+ == osl::FileBase::E_None)
+ {
+ pUIName = &aPhysicalName;
+ }
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(grfName, "", GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "gallery" + OUString::number(i);
+ m_aGalleryBrushItems.emplace_back(pInfo);
+ const Graphic* pGraphic = pInfo->pBrushItem->GetGraphic();
+
+ if(pGraphic)
+ {
+ BitmapEx aBitmap(pGraphic->GetBitmapEx());
+ Size aSize(aBitmap.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmap.Scale(nScale, nScale);
+
+ }
+ pVD->SetOutputSizePixel(aBitmap.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmap);
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName, *pVD);
+ }
+ else
+ {
+ m_xGalleryMenu->append(pInfo->sItemId, *pUIName);
+ }
+ ++i;
+ }
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("gallery", false);
+ }
+
+ if (!(!m_xSymbolsMenu && m_pSymbolList))
+ return;
+
+ m_xSymbolsMenu = m_xBuilder->weld_menu("symbolssubmenu");
+ ScopedVclPtrInstance< VirtualDevice > pVDev;
+ pVDev->SetMapMode(MapMode(MapUnit::Map100thMM));
+ std::unique_ptr<SdrModel> pModel(
+ new SdrModel(nullptr, nullptr, true));
+ pModel->GetItemPool().FreezeIdRanges();
+ // Page
+ SdrPage* pPage = new SdrPage( *pModel, false );
+ pPage->SetSize(Size(1000,1000));
+ pModel->InsertPage( pPage, 0 );
+ {
+ // 3D View
+ std::unique_ptr<SdrView> pView(new SdrView( *pModel, pVDev ));
+ pView->hideMarkHandles();
+ pView->ShowSdrPage(pPage);
+
+ // Generate invisible square to give all symbols a
+ // bitmap size, which is independent from specific glyph
+ SdrObject *pInvisibleSquare=m_pSymbolList->GetObj(0);
+
+ // directly clone to target SdrModel
+ pInvisibleSquare = pInvisibleSquare->CloneSdrObject(*pModel);
+
+ pPage->NbcInsertObject(pInvisibleSquare);
+ pInvisibleSquare->SetMergedItem(XFillTransparenceItem(100));
+ pInvisibleSquare->SetMergedItem(XLineTransparenceItem(100));
+
+ for(size_t i=0; i < m_pSymbolList->GetObjCount(); ++i)
+ {
+ SdrObject *pObj=m_pSymbolList->GetObj(i);
+ assert(pObj);
+
+ // directly clone to target SdrModel
+ pObj = pObj->CloneSdrObject(*pModel);
+
+ m_aGrfNames.emplace_back("");
+ pPage->NbcInsertObject(pObj);
+ if(m_pSymbolAttr)
+ {
+ pObj->SetMergedItemSet(*m_pSymbolAttr);
+ }
+ else
+ {
+ pObj->SetMergedItemSet(m_rOutAttrs);
+ }
+ pView->MarkAll();
+ BitmapEx aBitmapEx(pView->GetMarkedObjBitmapEx());
+ GDIMetaFile aMeta(pView->GetMarkedObjMetaFile());
+ pView->UnmarkAll();
+ pObj=pPage->RemoveObject(1);
+ SdrObject::Free(pObj);
+
+ SvxBmpItemInfo* pInfo = new SvxBmpItemInfo;
+ pInfo->pBrushItem.reset(new SvxBrushItem(Graphic(aMeta), GPOS_AREA, SID_ATTR_BRUSH));
+ pInfo->sItemId = "symbol" + OUString::number(i);
+ m_aSymbolBrushItems.emplace_back(pInfo);
+
+ Size aSize(aBitmapEx.GetSizePixel());
+ if(aSize.Width() > MAX_BMP_WIDTH || aSize.Height() > MAX_BMP_HEIGHT)
+ {
+ bool bWidth = aSize.Width() > aSize.Height();
+ double nScale = bWidth ?
+ double(MAX_BMP_WIDTH) / static_cast<double>(aSize.Width()):
+ double(MAX_BMP_HEIGHT) / static_cast<double>(aSize.Height());
+ aBitmapEx.Scale(nScale, nScale);
+ }
+ pVD->SetOutputSizePixel(aBitmapEx.GetSizePixel());
+ pVD->DrawBitmapEx(Point(), aBitmapEx);
+ m_xSymbolsMenu->append(pInfo->sItemId, "", *pVD);
+ }
+ pInvisibleSquare=pPage->RemoveObject(0);
+ SdrObject::Free(pInvisibleSquare);
+
+ if (m_aGrfNames.empty())
+ m_xSymbolMB->set_item_sensitive("symbols", false);
+ }
+}
+
+// #58425# Symbols on a list (e.g. StarChart)
+// Handler for menu button
+IMPL_LINK(SvxLineTabPage, GraphicHdl_Impl, const OString&, rIdent, void)
+{
+ const Graphic* pGraphic = nullptr;
+ Graphic aGraphic;
+ bool bResetSize = false;
+ bool bEnable = true;
+ long nPreviousSymbolType = m_nSymbolType;
+
+ OString sNumber;
+ if (rIdent.startsWith("gallery", &sNumber))
+ {
+ SvxBmpItemInfo* pInfo = m_aGalleryBrushItems[sNumber.toUInt32()].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ m_nSymbolType = SVX_SYMBOLTYPE_BRUSHITEM;
+ }
+ else if (rIdent.startsWith("symbol", &sNumber))
+ {
+ m_nSymbolType = sNumber.toUInt32();
+ SvxBmpItemInfo* pInfo = m_aSymbolBrushItems[m_nSymbolType].get();
+ pGraphic = pInfo->pBrushItem->GetGraphic();
+ }
+ else if (rIdent == "automatic")
+ {
+ pGraphic=&m_aAutoSymbolGraphic;
+ m_aAutoSymbolGraphic.SetPrefSize( Size(253,253) );
+ m_nSymbolType=SVX_SYMBOLTYPE_AUTO;
+ }
+ else if (rIdent == "none")
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_NONE;
+ pGraphic=nullptr;
+ bEnable = false;
+ }
+ else if (rIdent == "file")
+ {
+ SvxOpenGraphicDialog aGrfDlg(CuiResId(RID_SVXSTR_EDIT_GRAPHIC), GetFrameWeld());
+ aGrfDlg.EnableLink(false);
+ aGrfDlg.AsLink(false);
+ if( !aGrfDlg.Execute() )
+ {
+ // Remember selected filters
+ if( !aGrfDlg.GetGraphic(aGraphic) )
+ {
+ m_nSymbolType=SVX_SYMBOLTYPE_BRUSHITEM;
+ pGraphic = &aGraphic;
+ bResetSize = true;
+ }
+ }
+ if( !pGraphic )
+ return;
+ }
+
+ if (pGraphic)
+ {
+ Size aSize = SvxNumberFormat::GetGraphicSizeMM100(pGraphic);
+ aSize = OutputDevice::LogicToLogic(aSize, MapMode(MapUnit::Map100thMM), MapMode(m_ePoolUnit));
+ m_aSymbolGraphic=*pGraphic;
+ if( bResetSize )
+ {
+ m_aSymbolSize=aSize;
+ }
+ else if( nPreviousSymbolType == SVX_SYMBOLTYPE_BRUSHITEM )
+ { //#i31097# Data Point Symbol size changes when a different symbol is chosen(maoyg)
+ if( m_aSymbolSize.Width() != m_aSymbolSize.Height() )
+ {
+ aSize.setWidth( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ aSize.setHeight( static_cast<long>( m_aSymbolSize.Width() + m_aSymbolSize.Height() )/2 );
+ m_aSymbolSize = aSize;
+ }
+ }
+ m_aCtlPreview.SetSymbol(&m_aSymbolGraphic,m_aSymbolSize);
+ }
+ else
+ {
+ m_aSymbolGraphic=Graphic();
+ m_aCtlPreview.SetSymbol(nullptr,m_aSymbolSize);
+ bEnable = false;
+ }
+ m_aSymbolLastSize=m_aSymbolSize;
+ SetMetricValue(*m_xSymbolWidthMF, m_aSymbolSize.Width(), m_ePoolUnit);
+ SetMetricValue(*m_xSymbolHeightMF, m_aSymbolSize.Height(), m_ePoolUnit);
+
+ m_xGridIconSize->set_sensitive(bEnable);
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK( SvxLineTabPage, SizeHdl_Impl, weld::MetricSpinButton&, rField, void)
+{
+ m_bNewSize = true;
+ bool bWidth = &rField == m_xSymbolWidthMF.get();
+ m_bLastWidthModified = bWidth;
+ bool bRatio = m_xSymbolRatioCB->get_active();
+ long nWidthVal = static_cast<long>(m_xSymbolWidthMF->denormalize(m_xSymbolWidthMF->get_value(FieldUnit::MM_100TH)));
+ long nHeightVal= static_cast<long>(m_xSymbolHeightMF->denormalize(m_xSymbolHeightMF->get_value(FieldUnit::MM_100TH)));
+ nWidthVal = OutputDevice::LogicToLogic(nWidthVal,MapUnit::Map100thMM, m_ePoolUnit );
+ nHeightVal = OutputDevice::LogicToLogic(nHeightVal,MapUnit::Map100thMM, m_ePoolUnit);
+ m_aSymbolSize = Size(nWidthVal,nHeightVal);
+ double fSizeRatio = double(1);
+
+ if(bRatio)
+ {
+ if (m_aSymbolLastSize.Height() && m_aSymbolLastSize.Width())
+ fSizeRatio = static_cast<double>(m_aSymbolLastSize.Width()) / m_aSymbolLastSize.Height();
+ }
+
+ if (bWidth)
+ {
+ long nDelta = nWidthVal - m_aSymbolLastSize.Width();
+ m_aSymbolSize.setWidth( nWidthVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setHeight( m_aSymbolLastSize.Height() + static_cast<long>(static_cast<double>(nDelta) / fSizeRatio) );
+ m_aSymbolSize.setHeight( OutputDevice::LogicToLogic( m_aSymbolSize.Height(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolHeightMF->SetUserValue(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ m_xSymbolHeightMF->set_value(m_xSymbolHeightMF->normalize(m_aSymbolSize.Height()), FieldUnit::MM_100TH);
+ }
+ }
+ else
+ {
+ long nDelta = nHeightVal - m_aSymbolLastSize.Height();
+ m_aSymbolSize.setHeight( nHeightVal );
+ if (bRatio)
+ {
+ m_aSymbolSize.setWidth( m_aSymbolLastSize.Width() + static_cast<long>(static_cast<double>(nDelta) * fSizeRatio) );
+ m_aSymbolSize.setWidth( OutputDevice::LogicToLogic( m_aSymbolSize.Width(), m_ePoolUnit, MapUnit::Map100thMM ) );
+//TODO m_xSymbolWidthMF->SetUserValue(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ m_xSymbolWidthMF->set_value(m_xSymbolWidthMF->normalize(m_aSymbolSize.Width()), FieldUnit::MM_100TH);
+ }
+ }
+ m_aCtlPreview.ResizeSymbol(m_aSymbolSize);
+ m_aSymbolLastSize=m_aSymbolSize;
+}
+
+IMPL_LINK(SvxLineTabPage, RatioHdl_Impl, weld::ToggleButton&, rBox, void)
+{
+ if (rBox.get_active())
+ {
+ if (m_bLastWidthModified)
+ SizeHdl_Impl(*m_xSymbolWidthMF);
+ else
+ SizeHdl_Impl(*m_xSymbolHeightMF);
+ }
+}
+
+void SvxLineTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxDashListItem* pDashListItem = aSet.GetItem<SvxDashListItem>(SID_DASH_LIST, false);
+ const SvxLineEndListItem* pLineEndListItem = aSet.GetItem<SvxLineEndListItem>(SID_LINEEND_LIST, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+ const OfaPtrItem* pSdrObjListItem = aSet.GetItem<OfaPtrItem>(SID_OBJECT_LIST, false);
+ const SfxTabDialogItem* pSymbolAttrItem = aSet.GetItem<SfxTabDialogItem>(SID_ATTR_SET, false);
+ const SvxGraphicItem* pGraphicItem = aSet.GetItem<SvxGraphicItem>(SID_GRAPHIC, false);
+
+ if (pDashListItem)
+ SetDashList(pDashListItem->GetDashList());
+ if (pLineEndListItem)
+ SetLineEndList(pLineEndListItem->GetLineEndList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+ Construct();
+
+ if(pSdrObjListItem) //symbols
+ {
+ ShowSymbolControls(true);
+ m_pSymbolList = static_cast<SdrObjList*>(pSdrObjListItem->GetValue());
+ if (pSymbolAttrItem)
+ m_pSymbolAttr = new SfxItemSet(pSymbolAttrItem->GetItemSet());
+ if(pGraphicItem)
+ m_aAutoSymbolGraphic = pGraphicItem->GetGraphic();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplnedef.cxx b/cui/source/tabpages/tplnedef.cxx
new file mode 100644
index 000000000..2cef64e0e
--- /dev/null
+++ b/cui/source/tabpages/tplnedef.cxx
@@ -0,0 +1,839 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlndsit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xtable.hxx>
+
+#include <svx/dlgctrl.hxx>
+#include <cuitabline.hxx>
+#include <defdlgname.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/dialmgr.hxx>
+#include <svx/strings.hrc>
+#include <svx/svxids.hrc>
+#include <cuitabarea.hxx>
+#include <svtools/unitconv.hxx>
+
+#define XOUT_WIDTH 150
+
+using namespace com::sun::star;
+
+
+SvxLineDefTabPage::SvxLineDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/linestyletabpage.ui", "LineStylePage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnDashListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosDashLb(nullptr)
+ , m_xLbLineStyles(new SvxLineLB(m_xBuilder->weld_combo_box("LB_LINESTYLES")))
+ , m_xLbType1(m_xBuilder->weld_combo_box("LB_TYPE_1"))
+ , m_xLbType2(m_xBuilder->weld_combo_box("LB_TYPE_2"))
+ , m_xNumFldNumber1(m_xBuilder->weld_spin_button("NUM_FLD_1"))
+ , m_xNumFldNumber2(m_xBuilder->weld_spin_button("NUM_FLD_2"))
+ , m_xMtrLength1(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_1", FieldUnit::CM))
+ , m_xMtrLength2(m_xBuilder->weld_metric_spin_button("MTR_FLD_LENGTH_2", FieldUnit::CM))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xCbxSynchronize(m_xBuilder->weld_check_button("CBX_SYNCHRONIZE"))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ; //prevent warning
+ }
+ SetFieldUnit(*m_xMtrDistance, eFUnit);
+ SetFieldUnit(*m_xMtrLength1, eFUnit);
+ SetFieldUnit(*m_xMtrLength2, eFUnit);
+
+ // determine PoolUnit
+ SfxItemPool* pPool = rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ ePoolUnit = pPool->GetMetric( SID_ATTR_LINE_WIDTH );
+
+ rXLSet.Put( XLineStyleItem(drawing::LineStyle_DASH) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT, 3, 7, 2, 40, 15 ) ) );
+ rXLSet.Put( XLineColorItem(OUString(), COL_BLACK) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK(this, SvxLineDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK(this, SvxLineDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK(this, SvxLineDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK(this, SvxLineDefTabPage, ClickSaveHdl_Impl));
+
+ m_xNumFldNumber1->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber1Hdl_Impl));
+ m_xNumFldNumber2->connect_value_changed(LINK(this, SvxLineDefTabPage, ChangeNumber2Hdl_Impl));
+ m_xLbLineStyles->connect_changed(LINK(this, SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl));
+
+ // #i122042# switch off default adding of 'none' and 'solid' entries
+ // for this ListBox; we want to select only editable/dashed styles
+ m_xLbLineStyles->setAddStandardFields(false);
+
+ // absolute (in mm) or relative (in %)
+ m_xCbxSynchronize->connect_toggled(LINK(this, SvxLineDefTabPage, ChangeMetricHdl_Impl));
+
+ // preview must be updated when there's something changed
+ Link<weld::ComboBox&, void> aLink = LINK(this, SvxLineDefTabPage, SelectTypeListBoxHdl_Impl);
+ m_xLbType1->connect_changed(aLink);
+ m_xLbType2->connect_changed(aLink);
+ Link<weld::MetricSpinButton&,void> aLink2 = LINK( this, SvxLineDefTabPage, ChangePreviewHdl_Impl );
+ m_xMtrLength1->connect_value_changed(aLink2);
+ m_xMtrLength2->connect_value_changed(aLink2);
+ m_xMtrDistance->connect_value_changed(aLink2);
+
+ pDashList = nullptr;
+}
+
+SvxLineDefTabPage::~SvxLineDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineStyles.reset();
+}
+
+void SvxLineDefTabPage::Construct()
+{
+ // Line style fill; do *not* add default fields here
+ m_xLbLineStyles->Fill( pDashList );
+}
+
+void SvxLineDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pDashList.is() )
+ return;
+
+ if (*pPageType == PageType::Gradient &&
+ *pPosDashLb != -1)
+ {
+ m_xLbLineStyles->set_active(*pPosDashLb);
+ }
+ // so that a possibly existing line style is discarded
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determining (and possibly cutting) the name
+ // and displaying it in the GroupBox
+// OUString aString( CuiResId( RID_SVXSTR_TABLE ) );
+// aString += ": ";
+ INetURLObject aURL( pDashList->GetPath() );
+
+ aURL.Append( pDashList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ *pPageType = PageType::Area; // 2
+ *pPosDashLb = -1;
+}
+
+
+DeactivateRC SvxLineDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxLineDefTabPage::CheckChanges_Impl()
+{
+ // is here used to NOT lose changes
+ //css::drawing::DashStyle eXDS;
+
+ if( m_xNumFldNumber1->get_value_changed_from_saved() ||
+ m_xMtrLength1->get_value_changed_from_saved() ||
+ m_xLbType1->get_value_changed_from_saved() ||
+ m_xNumFldNumber2->get_value_changed_from_saved() ||
+ m_xMtrLength2->get_value_changed_from_saved() ||
+ m_xLbType2->get_value_changed_from_saved() ||
+ m_xMtrDistance->get_value_changed_from_saved() )
+ {
+ std::unique_ptr<weld::MessageDialog> xMessDlg(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Cancel,
+ CuiResId(RID_SVXSTR_ASK_CHANGE_LINESTYLE)));
+ xMessDlg->set_title(SvxResId(RID_SVXSTR_LINESTYLE));
+ xMessDlg->add_button(CuiResId(RID_SVXSTR_CHANGE), RET_BTN_1);
+ xMessDlg->add_button(CuiResId(RID_SVXSTR_ADD), RET_BTN_2);
+
+ short nRet = xMessDlg->run();
+
+ switch( nRet )
+ {
+ case RET_BTN_1:
+ {
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ break;
+
+ case RET_BTN_2:
+ {
+ ClickAddHdl_Impl(*m_xBtnAdd);
+ }
+ break;
+
+ case RET_CANCEL:
+ break;
+ }
+ }
+
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ *pPosDashLb = nPos;
+ }
+}
+
+
+bool SvxLineDefTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Hatch )
+ {
+ FillDash_Impl();
+
+ OUString aString(m_xLbLineStyles->get_active_text());
+ rAttrs->Put( XLineStyleItem( drawing::LineStyle_DASH ) );
+ rAttrs->Put( XLineDashItem( aString, aDash ) );
+ }
+ }
+ return true;
+}
+
+
+void SvxLineDefTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ if( rAttrs->GetItemState( GetWhich( XATTR_LINESTYLE ) ) != SfxItemState::DONTCARE )
+ {
+ drawing::LineStyle eXLS = static_cast<const XLineStyleItem&>( rAttrs->Get( GetWhich( XATTR_LINESTYLE ) ) ).GetValue();
+
+ switch( eXLS )
+ {
+ case drawing::LineStyle_NONE:
+ case drawing::LineStyle_SOLID:
+ m_xLbLineStyles->set_active(0);
+ break;
+ case drawing::LineStyle_DASH:
+ {
+ const XLineDashItem& rDashItem = rAttrs->Get( XATTR_LINEDASH );
+ aDash = rDashItem.GetDashValue();
+
+ m_xLbLineStyles->set_active(-1);
+ m_xLbLineStyles->set_active_text(rDashItem.GetName());
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ SelectLinestyleHdl_Impl( nullptr );
+
+ // determine button state
+ if( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs )
+{
+ return std::make_unique<SvxLineDefTabPage>(pPage, pController, *rOutAttrs);
+}
+
+IMPL_LINK(SvxLineDefTabPage, SelectLinestyleListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ SelectLinestyleHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectLinestyleHdl_Impl(const weld::ComboBox* p)
+{
+ if(!pDashList->Count())
+ return;
+
+ int nTmp = m_xLbLineStyles->get_active();
+ if (nTmp == -1)
+ {
+ OSL_ENSURE(false, "OOps, non-existent LineDash selected (!)");
+ nTmp = 1;
+ }
+
+ aDash = pDashList->GetDash( nTmp )->GetDash();
+
+ FillDialog_Impl();
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to take the new style
+ // only if there was an entry selected in the ListBox.
+ // If it was called via Reset(), then p is == NULL
+ if( p )
+ *pPageType = PageType::Hatch;
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangePreviewHdl_Impl, weld::MetricSpinButton&, void)
+{
+ FillDash_Impl();
+ m_aCtlPreview.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber1Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber1->get_value() == 0)
+ {
+ m_xNumFldNumber2->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber2->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ChangeNumber2Hdl_Impl, weld::SpinButton&, void)
+{
+ if (m_xNumFldNumber2->get_value() == 0)
+ {
+ m_xNumFldNumber1->set_min(1);
+ }
+ else
+ {
+ m_xNumFldNumber1->set_min(0);
+ }
+
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK( SvxLineDefTabPage, ChangeMetricHdl_Impl, weld::ToggleButton&, r, void)
+{
+ ChangeMetricHdl_Impl(&r);
+}
+
+void SvxLineDefTabPage::ChangeMetricHdl_Impl(const weld::ToggleButton* p)
+{
+ if( !m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != eFUnit )
+ {
+ long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * XOUT_WIDTH / 100;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * XOUT_WIDTH / 100;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+ m_xMtrLength1->set_digits(2);
+ m_xMtrLength2->set_digits(2);
+ m_xMtrDistance->set_digits(2);
+
+ // adjust metric
+ m_xMtrLength1->set_unit(eFUnit);
+ m_xMtrLength2->set_unit(eFUnit);
+ m_xMtrDistance->set_unit(eFUnit);
+
+ // tdf#126736 max 5cm
+ m_xMtrLength1->set_range(0, 500, FieldUnit::CM);
+ m_xMtrLength2->set_range(0, 500, FieldUnit::CM);
+ m_xMtrDistance->set_range(0, 500, FieldUnit::CM);
+
+ SetMetricValue( *m_xMtrLength1, nTmp1, ePoolUnit );
+ SetMetricValue( *m_xMtrLength2, nTmp2, ePoolUnit );
+ SetMetricValue( *m_xMtrDistance, nTmp3, ePoolUnit );
+ }
+ else if( m_xCbxSynchronize->get_active() && m_xMtrLength1->get_unit() != FieldUnit::PERCENT )
+ {
+ long nTmp1, nTmp2, nTmp3;
+
+ // was changed with Control
+ if( p )
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit ) * 100 / XOUT_WIDTH;
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit ) * 100 / XOUT_WIDTH;
+ }
+ else
+ {
+ nTmp1 = GetCoreValue( *m_xMtrLength1, ePoolUnit );
+ nTmp2 = GetCoreValue( *m_xMtrLength2, ePoolUnit );
+ nTmp3 = GetCoreValue( *m_xMtrDistance, ePoolUnit );
+ }
+
+ m_xMtrLength1->set_digits(0);
+ m_xMtrLength2->set_digits(0);
+ m_xMtrDistance->set_digits(0);
+
+ m_xMtrLength1->set_unit(FieldUnit::PERCENT);
+ m_xMtrLength2->set_unit(FieldUnit::PERCENT);
+ m_xMtrDistance->set_unit(FieldUnit::PERCENT);
+
+ // tdf#126736 800%
+ m_xMtrLength1->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrLength2->set_range(0, 800, FieldUnit::PERCENT);
+ m_xMtrDistance->set_range(0, 800, FieldUnit::PERCENT);
+
+ m_xMtrLength1->set_value(nTmp1, FieldUnit::PERCENT);
+ m_xMtrLength2->set_value(nTmp2, FieldUnit::PERCENT);
+ m_xMtrDistance->set_value(nTmp3, FieldUnit::PERCENT);
+ }
+ SelectTypeHdl_Impl( nullptr );
+}
+
+IMPL_LINK( SvxLineDefTabPage, SelectTypeListBoxHdl_Impl, weld::ComboBox&, rListBox, void )
+{
+ SelectTypeHdl_Impl(&rListBox);
+}
+
+void SvxLineDefTabPage::SelectTypeHdl_Impl(const weld::ComboBox* p)
+{
+ if (p == m_xLbType1.get() || !p)
+ {
+ if (m_xLbType1->get_active() == 0)
+ {
+ m_xMtrLength1->set_sensitive(false);
+ m_xMtrLength1->set_text("");
+ }
+ else if (!m_xMtrLength1->get_sensitive())
+ {
+ m_xMtrLength1->set_sensitive(true);
+ m_xMtrLength1->reformat();
+ }
+ }
+
+ if (p == m_xLbType2.get() || !p)
+ {
+ if (m_xLbType2->get_active() == 0)
+ {
+ m_xMtrLength2->set_sensitive(false);
+ m_xMtrLength2->set_text("");
+ }
+ else if (!m_xMtrLength2->get_sensitive())
+ {
+ m_xMtrLength2->set_sensitive(true);
+ m_xMtrLength2->reformat();
+ }
+ }
+ ChangePreviewHdl_Impl(*m_xMtrLength1);
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ OUString aNewName(SvxResId(RID_SVXSTR_LINESTYLE));
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINESTYLE));
+ OUString aName;
+
+ long nCount = pDashList->Count();
+ long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for ( long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ long nDashCount = pDashList->Count();
+ pDashList->Insert( std::make_unique<XDashEntry>(aDash, aName), nDashCount );
+ m_xLbLineStyles->Append( *pDashList->GetDash(nDashCount), pDashList->GetUiBitmap(nDashCount) );
+
+ m_xLbLineStyles->set_active(m_xLbLineStyles->get_count() - 1);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+ pDlg.disposeAndClear();
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINESTYLE));
+ OUString aName( pDashList->GetDash( nPos )->GetName() );
+ OUString aOldName = aName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ long nCount = pDashList->Count();
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bool bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pDashList->GetDash( i )->GetName() &&
+ aName != aOldName )
+ bDifferent = false;
+ }
+
+ if ( bDifferent )
+ {
+ bLoop = false;
+ FillDash_Impl();
+
+ pDashList->Replace(std::make_unique<XDashEntry>(aDash, aName), nPos);
+ m_xLbLineStyles->Modify(*pDashList->GetDash(nPos), nPos, pDashList->GetUiBitmap(nPos));
+
+ m_xLbLineStyles->set_active(nPos);
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Hatch;
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineStyles->get_active();
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelinestyledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineStyleDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ pDashList->Remove(nPos);
+ m_xLbLineStyles->remove(nPos);
+ m_xLbLineStyles->set_active(0);
+
+ SelectLinestyleHdl_Impl( nullptr );
+ *pPageType = PageType::Area; // style should not be taken
+
+ *pnDashListState |= ChangeType::MODIFIED;
+
+ ChangePreviewHdl_Impl( *m_xMtrLength1 );
+ }
+ }
+
+ // determine button state
+ if ( !pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnDashListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pDashList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XDashListRef pDshLst = XPropertyList::AsDashList(XPropertyList::CreatePropertyList( XPropertyListType::Dash, aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), "" ));
+ pDshLst->SetName( aURL.getName() );
+
+ if( pDshLst->Load() )
+ {
+ pDashList = pDshLst;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewDashList( pDashList );
+
+ m_xLbLineStyles->clear();
+ m_xLbLineStyles->Fill( pDashList );
+ Reset( &rOutAttrs );
+
+ pDashList->SetName( aURL.getName() );
+
+ *pnDashListState |= ChangeType::CHANGED;
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pDashList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.sod" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pDashList->GetName().isEmpty() )
+ {
+ aFile.Append( pDashList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( "sod" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pDashList->SetName( aURL.getName() );
+ pDashList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pDashList->Save() )
+ {
+ *pnDashListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+void SvxLineDefTabPage::FillDash_Impl()
+{
+ css::drawing::DashStyle eXDS;
+
+ if (m_xCbxSynchronize->get_active())
+ eXDS = css::drawing::DashStyle_RECTRELATIVE;
+ else
+ eXDS = css::drawing::DashStyle_RECT;
+
+ aDash.SetDashStyle( eXDS );
+ aDash.SetDots( static_cast<sal_uInt8>(m_xNumFldNumber1->get_value()) );
+ aDash.SetDotLen( m_xLbType1->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength1, ePoolUnit ) );
+ aDash.SetDashes( static_cast<sal_uInt8>(m_xNumFldNumber2->get_value()) );
+ aDash.SetDashLen( m_xLbType2->get_active() == 0 ? 0 : GetCoreValue( *m_xMtrLength2, ePoolUnit ) );
+ aDash.SetDistance( GetCoreValue( *m_xMtrDistance, ePoolUnit ) );
+
+ rXLSet.Put( XLineDashItem( OUString(), aDash ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+}
+
+void SvxLineDefTabPage::FillDialog_Impl()
+{
+ css::drawing::DashStyle eXDS = aDash.GetDashStyle(); // css::drawing::DashStyle_RECT, css::drawing::DashStyle_ROUND
+ if( eXDS == css::drawing::DashStyle_RECTRELATIVE )
+ m_xCbxSynchronize->set_active(true);
+ else
+ m_xCbxSynchronize->set_active(false);
+
+ m_xNumFldNumber1->set_value(aDash.GetDots());
+ SetMetricValue( *m_xMtrLength1, aDash.GetDotLen(), ePoolUnit );
+ m_xLbType1->set_active(aDash.GetDotLen() == 0 ? 0 : 1);
+ m_xNumFldNumber2->set_value(aDash.GetDashes());
+ SetMetricValue( *m_xMtrLength2, aDash.GetDashLen(), ePoolUnit );
+ m_xLbType2->set_active(aDash.GetDashLen() == 0 ? 0 : 1);
+ SetMetricValue( *m_xMtrDistance, aDash.GetDistance(), ePoolUnit );
+
+ ChangeMetricHdl_Impl(nullptr);
+
+ // save values for changes recognition (-> method)
+ m_xNumFldNumber1->save_value();
+ m_xMtrLength1->save_value();
+ m_xLbType1->save_value();
+ m_xNumFldNumber2->save_value();
+ m_xMtrLength2->save_value();
+ m_xLbType2->save_value();
+ m_xMtrDistance->save_value();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tplneend.cxx b/cui/source/tabpages/tplneend.cxx
new file mode 100644
index 000000000..a9db979bc
--- /dev/null
+++ b/cui/source/tabpages/tplneend.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 <tools/urlobj.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+
+#include <strings.hrc>
+#include <svx/dialmgr.hxx>
+#include <svx/dlgctrl.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnedwit.hxx>
+#include <svx/xlnstit.hxx>
+#include <svx/xlnedit.hxx>
+#include <cuitabline.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <svx/strings.hrc>
+
+#define XOUT_WIDTH 150
+
+SvxLineEndDefTabPage::SvxLineEndDefTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/lineendstabpage.ui", "LineEndPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , pPolyObj(nullptr)
+ , aXLineAttr(rInAttrs.GetPool())
+ , rXLSet(aXLineAttr.GetItemSet())
+ , pnLineEndListState(nullptr)
+ , pPageType(nullptr)
+ , nDlgType(0)
+ , pPosLineEndLb(nullptr)
+ , m_xEdtName(m_xBuilder->weld_entry("EDT_NAME"))
+ , m_xLbLineEnds(new SvxLineEndLB(m_xBuilder->weld_combo_box("LB_LINEENDS")))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xBtnDelete(m_xBuilder->weld_button("BTN_DELETE"))
+ , m_xBtnLoad(m_xBuilder->weld_button("BTN_LOAD"))
+ , m_xBtnSave(m_xBuilder->weld_button("BTN_SAVE"))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ rXLSet.Put( XLineStyleItem(css::drawing::LineStyle_SOLID) );
+ rXLSet.Put( XLineWidthItem(XOUT_WIDTH) );
+ rXLSet.Put( XLineColorItem( OUString(), COL_BLACK ) );
+ rXLSet.Put( XLineStartWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+ rXLSet.Put( XLineEndWidthItem( m_aCtlPreview.GetOutputSize().Height() / 2 ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+
+ m_xBtnAdd->connect_clicked(LINK(this, SvxLineEndDefTabPage, ClickAddHdl_Impl));
+ m_xBtnModify->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickModifyHdl_Impl));
+ m_xBtnDelete->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickDeleteHdl_Impl));
+ m_xBtnLoad->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickLoadHdl_Impl));
+ m_xBtnSave->connect_clicked(LINK( this, SvxLineEndDefTabPage, ClickSaveHdl_Impl));
+
+ m_xLbLineEnds->connect_changed(LINK(this, SvxLineEndDefTabPage, SelectLineEndHdl_Impl));
+}
+
+SvxLineEndDefTabPage::~SvxLineEndDefTabPage()
+{
+ m_xCtlPreview.reset();
+ m_xLbLineEnds.reset();
+}
+
+void SvxLineEndDefTabPage::Construct()
+{
+ m_xLbLineEnds->Fill( pLineEndList );
+
+ bool bCreateArrowPossible = true;
+
+ if( !pPolyObj )
+ {
+ bCreateArrowPossible = false;
+ }
+ else if( nullptr == dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+ SdrObjectUniquePtr pNewObj;
+ if( aInfoRec.bCanConvToPath )
+ pNewObj = pPolyObj->ConvertToPolyObj( true, false );
+
+ bCreateArrowPossible = nullptr != dynamic_cast<const SdrPathObj*>( pNewObj.get());
+ }
+
+ if( !bCreateArrowPossible )
+ m_xBtnAdd->set_sensitive(false);
+}
+
+void SvxLineEndDefTabPage::ActivatePage( const SfxItemSet& )
+{
+ if( nDlgType != 0 ) // area dialog
+ return;
+
+ // ActivatePage() is called before the dialog receives PageCreated() !!!
+ if( !pLineEndList.is() )
+ return;
+
+ if( *pPosLineEndLb != -1)
+ {
+ m_xLbLineEnds->set_active(*pPosLineEndLb);
+ SelectLineEndHdl_Impl();
+ }
+ INetURLObject aURL( pLineEndList->GetPath() );
+
+ aURL.Append( pLineEndList->GetName() );
+ DBG_ASSERT( aURL.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+ *pPageType = PageType::Area; // 3
+ *pPosLineEndLb = -1;
+}
+
+
+DeactivateRC SvxLineEndDefTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ CheckChanges_Impl();
+
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+void SvxLineEndDefTabPage::CheckChanges_Impl()
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ OUString aString = m_xEdtName->get_text();
+
+ if( aString != m_xLbLineEnds->get_active_text() )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querychangelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskChangeLineEndDialog"));
+ if (xQueryBox->run() == RET_YES)
+ ClickModifyHdl_Impl(*m_xBtnModify);
+ }
+ }
+ nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ *pPosLineEndLb = nPos;
+}
+
+
+bool SvxLineEndDefTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ if( nDlgType == 0 ) // line dialog
+ {
+ if( *pPageType == PageType::Bitmap )
+ {
+ CheckChanges_Impl();
+
+ int nPos = m_xLbLineEnds->get_active();
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ rSet->Put( XLineStartItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ rSet->Put( XLineEndItem( pEntry->GetName(), pEntry->GetLineEnd() ) );
+ }
+ }
+ return true;
+}
+
+void SvxLineEndDefTabPage::Reset( const SfxItemSet* )
+{
+ m_xLbLineEnds->set_active(0);
+
+ // Update lineend
+ if( pLineEndList->Count() > 0 )
+ {
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+ }
+
+ // determine button state
+ if( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxLineEndDefTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxLineEndDefTabPage>(pPage, pController, *rSet );
+}
+
+void SvxLineEndDefTabPage::SelectLineEndHdl_Impl()
+{
+ if( pLineEndList->Count() <= 0 )
+ return;
+
+ int nPos = m_xLbLineEnds->get_active();
+
+ const XLineEndEntry* pEntry = pLineEndList->GetLineEnd(nPos);
+
+ m_xEdtName->set_text(m_xLbLineEnds->get_active_text());
+
+ rXLSet.Put( XLineStartItem( OUString(), pEntry->GetLineEnd() ) );
+ rXLSet.Put( XLineEndItem( OUString(), pEntry->GetLineEnd() ) );
+
+ // #i34740#
+ m_aCtlPreview.SetLineAttributes(aXLineAttr.GetItemSet());
+ m_aCtlPreview.Invalidate();
+
+ // Is not set before, in order to only take the new style,
+ // if there is an entry selected in the ListBox
+ *pPageType = PageType::Bitmap;
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, SelectLineEndHdl_Impl, weld::ComboBox&, void)
+{
+ SelectLineEndHdl_Impl();
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+ if (nPos == -1)
+ return;
+
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINEEND));
+ OUString aName(m_xEdtName->get_text());
+ long nCount = pLineEndList->Count();
+ bool bDifferent = true;
+
+ // check whether the name is existing already
+ for ( long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+
+ // if yes, repeat and demand a new name
+ if ( !bDifferent )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ bool bLoop = true;
+
+ while( !bDifferent && bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ bLoop = false;
+ else
+ xWarningBox->run();
+ }
+ }
+
+ // if not existing, enter the entry
+ if( !bDifferent )
+ return;
+
+ const XLineEndEntry* pOldEntry = pLineEndList->GetLineEnd(nPos);
+
+ if(pOldEntry)
+ {
+ // #123497# Need to replace the existing entry with a new one
+ pLineEndList->Replace(std::make_unique<XLineEndEntry>(pOldEntry->GetLineEnd(), aName), nPos);
+
+ m_xEdtName->set_text(aName);
+
+ m_xLbLineEnds->Modify(*pLineEndList->GetLineEnd(nPos), nPos, pLineEndList->GetUiBitmap(nPos));
+ m_xLbLineEnds->set_active(nPos);
+
+ // set flag for modified
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ *pPageType = PageType::Bitmap;
+ }
+ else
+ {
+ OSL_ENSURE(false, "LineEnd to be modified not existing (!)");
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+ if( pPolyObj )
+ {
+ const SdrObject* pNewObj;
+ SdrObjectUniquePtr pConvPolyObj;
+
+ if( nullptr != dynamic_cast<const SdrPathObj*>( pPolyObj) )
+ {
+ pNewObj = pPolyObj;
+ }
+ else
+ {
+ SdrObjTransformInfoRec aInfoRec;
+ pPolyObj->TakeObjInfo( aInfoRec );
+
+ if( aInfoRec.bCanConvToPath )
+ {
+ pConvPolyObj = pPolyObj->ConvertToPolyObj( true, false );
+ pNewObj = pConvPolyObj.get();
+
+ if( !pNewObj || nullptr == dynamic_cast<const SdrPathObj*>( pNewObj) )
+ return; // cancel, additional safety, which
+ // has no use for group objects though.
+ }
+ else return; // cancel
+ }
+
+ basegfx::B2DPolyPolygon aNewPolyPolygon(static_cast<const SdrPathObj*>(pNewObj)->GetPathPoly());
+ basegfx::B2DRange aNewRange(basegfx::utils::getRange(aNewPolyPolygon));
+
+ // normalize
+ aNewPolyPolygon.transform(basegfx::utils::createTranslateB2DHomMatrix( -aNewRange.getMinX(), -aNewRange.getMinY()));
+
+ pConvPolyObj.reset();
+
+ OUString aNewName(SvxResId(RID_SVXSTR_LINEEND));
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_LINEEND));
+ OUString aName;
+
+ long nCount = pLineEndList->Count();
+ long j = 1;
+ bool bDifferent = false;
+
+ while ( !bDifferent )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ if ( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc ));
+ bool bLoop = true;
+
+ while ( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ bDifferent = true;
+
+ for( long i = 0; i < nCount && bDifferent; i++ )
+ {
+ if( aName == pLineEndList->GetLineEnd( i )->GetName() )
+ bDifferent = false;
+ }
+
+ if( bDifferent )
+ {
+ bLoop = false;
+
+ auto nLineEndCount = pLineEndList->Count();
+ pLineEndList->Insert(std::make_unique<XLineEndEntry>(aNewPolyPolygon, aName), nLineEndCount);
+
+ // add to the ListBox
+ m_xLbLineEnds->Append(*pLineEndList->GetLineEnd(nLineEndCount), pLineEndList->GetUiBitmap(nLineEndCount));
+ m_xLbLineEnds->set_active(m_xLbLineEnds->get_count() - 1);
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ SelectLineEndHdl_Impl();
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarningBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarningBox->run();
+ }
+ }
+ }
+ else
+ m_xBtnAdd->set_sensitive(false);
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickDeleteHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xLbLineEnds->get_active();
+
+ if (nPos != -1)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletelineenddialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelLineEndDialog"));
+
+ if (xQueryBox->run() == RET_YES)
+ {
+ pLineEndList->Remove(nPos);
+ m_xLbLineEnds->remove(nPos);
+ m_xLbLineEnds->set_active(0);
+
+ SelectLineEndHdl_Impl();
+ *pPageType = PageType::Area; // LineEnd shall not be taken over
+
+ *pnLineEndListState |= ChangeType::MODIFIED;
+
+ m_aCtlPreview.Invalidate();
+ }
+ }
+ // determine button state
+ if( !pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickLoadHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nReturn = RET_YES;
+
+ if ( *pnLineEndListState & ChangeType::MODIFIED )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querysavelistdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("AskSaveList"));
+
+ nReturn = xBox->run();
+
+ if ( nReturn == RET_YES )
+ pLineEndList->Save();
+ }
+
+ if ( nReturn != RET_CANCEL )
+ {
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
+ FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( aDlg.Execute() == ERRCODE_NONE )
+ {
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ XLineEndListRef pLeList = XPropertyList::AsLineEndList(
+ XPropertyList::CreatePropertyList(
+ XPropertyListType::LineEnd,
+ aPathURL.GetMainURL(INetURLObject::DecodeMechanism::NONE), ""));
+ pLeList->SetName( aURL.getName() );
+ if( pLeList->Load() )
+ {
+ pLineEndList = pLeList;
+ static_cast<SvxLineTabDialog*>(GetDialogController())->SetNewLineEndList( pLineEndList );
+ m_xLbLineEnds->clear();
+ m_xLbLineEnds->Fill( pLineEndList );
+ Reset( &rOutAttrs );
+
+ pLineEndList->SetName( aURL.getName() );
+
+ *pnLineEndListState |= ChangeType::CHANGED;
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynoloadedfiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoLoadedFileDialog"));
+ xBox->run();
+ }
+ }
+ }
+
+ // determine button state
+ if ( pLineEndList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnDelete->set_sensitive(true);
+ m_xBtnSave->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnDelete->set_sensitive(false);
+ m_xBtnSave->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxLineEndDefTabPage, ClickSaveHdl_Impl, weld::Button&, void)
+{
+ ::sfx2::FileDialogHelper aDlg(css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString aStrFilterType( "*.soe" );
+ aDlg.AddFilter( aStrFilterType, aStrFilterType );
+
+ OUString aPalettePath(SvtPathOptions().GetPalettePath());
+ OUString aLastDir;
+ sal_Int32 nIndex = 0;
+ do
+ {
+ aLastDir = aPalettePath.getToken(0, ';', nIndex);
+ }
+ while (nIndex >= 0);
+
+ INetURLObject aFile(aLastDir);
+ DBG_ASSERT( aFile.GetProtocol() != INetProtocol::NotValid, "invalid URL" );
+
+ if( !pLineEndList->GetName().isEmpty() )
+ {
+ aFile.Append( pLineEndList->GetName() );
+
+ if( aFile.getExtension().isEmpty() )
+ aFile.SetExtension( "soe" );
+ }
+
+ aDlg.SetDisplayDirectory( aFile.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ if ( aDlg.Execute() != ERRCODE_NONE )
+ return;
+
+ INetURLObject aURL( aDlg.GetPath() );
+ INetURLObject aPathURL( aURL );
+
+ aPathURL.removeSegment();
+ aPathURL.removeFinalSlash();
+
+ pLineEndList->SetName( aURL.getName() );
+ pLineEndList->SetPath( aPathURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ if( pLineEndList->Save() )
+ {
+ *pnLineEndListState &= ~ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querynosavefiledialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xBox(xBuilder->weld_message_dialog("NoSaveFileDialog"));
+ xBox->run();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tppattern.cxx b/cui/source/tabpages/tppattern.cxx
new file mode 100644
index 000000000..a22197d77
--- /dev/null
+++ b/cui/source/tabpages/tppattern.cxx
@@ -0,0 +1,554 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <tools/urlobj.hxx>
+#include <sfx2/dialoghelper.hxx>
+#include <svx/colorbox.hxx>
+#include <svx/dialmgr.hxx>
+#include <vcl/BitmapTools.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/strings.hrc>
+
+#include <strings.hrc>
+#include <svx/xfillit0.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xtable.hxx>
+#include <svx/xflbmtit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/svxdlg.hxx>
+#include <dialmgr.hxx>
+#include <sal/log.hxx>
+
+using namespace com::sun::star;
+
+/*************************************************************************
+|* Preview control for the display of bitmaps
+\************************************************************************/
+
+class SvxBitmapCtl
+{
+private:
+ Color aPixelColor, aBackgroundColor;
+ std::array<sal_uInt8,64> const * pBmpArray;
+
+public:
+ // Constructor: BitmapCtl for SvxPixelCtl
+ SvxBitmapCtl()
+ : pBmpArray(nullptr)
+ {
+ }
+
+ // BitmapCtl: Returns the Bitmap
+ BitmapEx GetBitmapEx() const
+ {
+ if (!pBmpArray)
+ return BitmapEx();
+ return vcl::bitmap::createHistorical8x8FromArray(*pBmpArray, aPixelColor, aBackgroundColor);
+ }
+
+ void SetBmpArray( std::array<sal_uInt8,64> const & pPixel ) { pBmpArray = &pPixel; }
+ void SetPixelColor( Color aColor ) { aPixelColor = aColor; }
+ void SetBackgroundColor( Color aColor ) { aBackgroundColor = aColor; }
+};
+
+SvxPatternTabPage::SvxPatternTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/patterntabpage.ui", "PatternTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnPatternListState(nullptr)
+ , m_pnColorListState(nullptr)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_xCtlPixel(new SvxPixelCtl(this))
+ , m_xLbColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_COLOR"), pController->getDialog()))
+ , m_xLbBackgroundColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_BACKGROUND_COLOR"), pController->getDialog()))
+ , m_xPatternLB(new SvxPresetListBox(m_xBuilder->weld_scrolled_window("patternpresetlistwin")))
+ , m_xBtnAdd(m_xBuilder->weld_button("BTN_ADD"))
+ , m_xBtnModify(m_xBuilder->weld_button("BTN_MODIFY"))
+ , m_xCtlPixelWin(new weld::CustomWeld(*m_xBuilder, "CTL_PIXEL", *m_xCtlPixel))
+ , m_xCtlPreview(new weld::CustomWeld(*m_xBuilder, "CTL_PREVIEW", m_aCtlPreview))
+ , m_xPatternLBWin(new weld::CustomWeld(*m_xBuilder, "patternpresetlist", *m_xPatternLB))
+{
+ // size of the bitmap display
+ Size aSize = getDrawPreviewOptimalSize(m_aCtlPreview.GetDrawingArea()->get_ref_device());
+ m_xPatternLB->set_size_request(aSize.Width(), aSize.Height());
+ m_xCtlPreview->set_size_request(aSize.Width(), aSize.Height());
+
+ m_xBitmapCtl.reset(new SvxBitmapCtl);
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // setting the output device
+ m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_BITMAP) );
+ m_rXFSet.Put( XFillBitmapItem(OUString(), Graphic()) );
+
+ m_xBtnAdd->connect_clicked( LINK( this, SvxPatternTabPage, ClickAddHdl_Impl ) );
+ m_xBtnModify->connect_clicked( LINK( this, SvxPatternTabPage, ClickModifyHdl_Impl ) );
+
+ m_xPatternLB->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangePatternHdl_Impl ) );
+ m_xPatternLB->SetRenameHdl( LINK( this, SvxPatternTabPage, ClickRenameHdl_Impl ) );
+ m_xPatternLB->SetDeleteHdl( LINK( this, SvxPatternTabPage, ClickDeleteHdl_Impl ) );
+ m_xLbColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+ m_xLbBackgroundColor->SetSelectHdl( LINK( this, SvxPatternTabPage, ChangeColorHdl_Impl ) );
+}
+
+SvxPatternTabPage::~SvxPatternTabPage()
+{
+ m_xPatternLBWin.reset();
+ m_xCtlPreview.reset();
+ m_xCtlPixelWin.reset();
+ m_xPatternLB.reset();
+ m_xLbBackgroundColor.reset();
+ m_xLbColor.reset();
+ m_xCtlPixel.reset();
+}
+
+void SvxPatternTabPage::Construct()
+{
+ m_xPatternLB->FillPresetListBox( *m_pPatternList );
+}
+
+void SvxPatternTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ SvxAreaTabDialog* pArea = (*m_pnColorListState & ChangeType::CHANGED) ?
+ dynamic_cast<SvxAreaTabDialog*>(GetDialogController()) : nullptr;
+ if (pArea)
+ m_pColorList = pArea->GetNewColorList();
+ }
+
+ // determining (possibly cutting) the name and
+ // displaying it in the GroupBox
+ OUString aString = CuiResId( RID_SVXSTR_TABLE ) + ": ";
+ INetURLObject aURL( m_pPatternList->GetPath() );
+
+ aURL.Append( m_pPatternList->GetName() );
+ SAL_WARN_IF( aURL.GetProtocol() == INetProtocol::NotValid, "cui.tabpages", "invalid URL" );
+
+ if( aURL.getBase().getLength() > 18 )
+ {
+ aString += aURL.getBase().copy( 0, 15 ) + "...";
+ }
+ else
+ aString += aURL.getBase();
+
+ XFillBitmapItem aItem( rSet.Get( XATTR_FILLBITMAP ) );
+
+ if ( aItem.isPattern() )
+ {
+ sal_Int32 nPos = SearchPatternList( aItem.GetName() );
+ if ( nPos != -1)
+ {
+ sal_uInt16 nId = m_xPatternLB->GetItemId( static_cast<size_t>( nPos ) );
+ m_xPatternLB->SelectItem( nId );
+ }
+ }
+ else
+ m_xPatternLB->SelectItem( m_xPatternLB->GetItemId( static_cast<size_t>( 0 ) ) );
+}
+
+
+DeactivateRC SvxPatternTabPage::DeactivatePage( SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxPatternTabPage::FillItemSet( SfxItemSet* _rOutAttrs )
+{
+ _rOutAttrs->Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ size_t nPos = m_xPatternLB->IsNoSelection() ? VALUESET_ITEM_NOTFOUND : m_xPatternLB->GetSelectItemPos();
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ const XBitmapEntry* pXBitmapEntry = m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) );
+ const OUString aString( m_xPatternLB->GetItemText( m_xPatternLB->GetSelectedItemId() ) );
+
+ _rOutAttrs->Put(XFillBitmapItem(aString, pXBitmapEntry->GetGraphicObject()));
+ }
+ else
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ _rOutAttrs->Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
+ }
+ _rOutAttrs->Put(XFillBmpTileItem(true));
+ return true;
+}
+
+
+void SvxPatternTabPage::Reset( const SfxItemSet* )
+{
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBmpArray( m_xCtlPixel->GetBitmapPixelPtr() );
+
+ // get bitmap and display it
+ const XFillBitmapItem aBmpItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx()));
+ if(aBmpItem.isPattern())
+ {
+ m_rXFSet.Put( aBmpItem );
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ // determine button state
+ if( m_pPatternList.is() && m_pPatternList->Count() )
+ {
+ m_xBtnAdd->set_sensitive(true);
+ m_xBtnModify->set_sensitive(true);
+ }
+ else
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxPatternTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rSet )
+{
+ return std::make_unique<SvxPatternTabPage>(pPage, pController, *rSet);
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangePatternHdl_Impl, ValueSet*, void)
+{
+ std::unique_ptr<GraphicObject> pGraphicObject;
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if(VALUESET_ITEM_NOTFOUND != nPos)
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetGraphicObject()));
+ }
+ else
+ {
+ const SfxPoolItem* pPoolItem = nullptr;
+
+ if(SfxItemState::SET == m_rOutAttrs.GetItemState(GetWhich(XATTR_FILLSTYLE), true, &pPoolItem))
+ {
+ const drawing::FillStyle eXFS(static_cast<const XFillStyleItem*>(pPoolItem)->GetValue());
+
+ if((drawing::FillStyle_BITMAP == eXFS) && (SfxItemState::SET == m_rOutAttrs.GetItemState(GetWhich(XATTR_FILLBITMAP), true, &pPoolItem)))
+ {
+ pGraphicObject.reset(new GraphicObject(static_cast<const XFillBitmapItem*>(pPoolItem)->GetGraphicObject()));
+ }
+ }
+
+ if(!pGraphicObject)
+ {
+ sal_uInt16 nPosition = m_xPatternLB->GetItemId( 0 );
+ m_xPatternLB->SelectItem( nPosition );
+ if( nPosition != 0 )
+ {
+ pGraphicObject.reset(new GraphicObject(m_pPatternList->GetBitmap(0)->GetGraphicObject()));
+ }
+ }
+ }
+
+ if(!pGraphicObject)
+ return;
+
+ Color aBackColor;
+ Color aPixelColor;
+ bool bIs8x8(vcl::bitmap::isHistorical8x8(pGraphicObject->GetGraphic().GetBitmapEx(), aBackColor, aPixelColor));
+
+ m_xLbColor->SetNoSelection();
+ m_xLbBackgroundColor->SetNoSelection();
+
+ if(bIs8x8)
+ {
+ m_xCtlPixel->SetPaintable( true );
+ m_xBtnModify->set_sensitive(true);
+ m_xBtnAdd->set_sensitive(true);
+
+ // setting the pixel control
+
+ m_xCtlPixel->SetXBitmap(pGraphicObject->GetGraphic().GetBitmapEx());
+
+ m_xLbColor->SelectEntry( aPixelColor );
+ m_xLbBackgroundColor->SelectEntry( aBackColor );
+
+ // update m_xBitmapCtl, rXFSet and m_aCtlPreview
+ m_xBitmapCtl->SetPixelColor( aPixelColor );
+ m_xBitmapCtl->SetBackgroundColor( aBackColor );
+ m_rXFSet.ClearItem();
+ m_rXFSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+ else
+ {
+ m_xCtlPixel->Reset();
+ m_xCtlPixel->SetPaintable( false );
+ m_xBtnModify->set_sensitive(false);
+ m_xBtnAdd->set_sensitive(false);
+ }
+
+ m_xCtlPixel->Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickAddHdl_Impl, weld::Button&, void)
+{
+
+ OUString aNewName( SvxResId( RID_SVXSTR_PATTERN_UNTITLED ) );
+ OUString aDesc( CuiResId( RID_SVXSTR_DESC_NEW_PATTERN ) );
+ OUString aName;
+
+ long nCount = m_pPatternList->Count();
+ long j = 1;
+ bool bValidPatternName = false;
+
+ while( !bValidPatternName )
+ {
+ aName = aNewName + " " + OUString::number( j++ );
+ bValidPatternName = (SearchPatternList(aName) == -1);
+ }
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+ sal_uInt16 nError(1);
+
+ while( pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+
+ bValidPatternName = (SearchPatternList(aName) == -1);
+
+ if( bValidPatternName ) {
+ nError = 0;
+ break;
+ }
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ if (xWarnBox->run() != RET_OK)
+ break;
+ }
+
+ pDlg.disposeAndClear();
+
+ if( !nError )
+ {
+ std::unique_ptr<XBitmapEntry> pEntry;
+ if( m_xCtlPixel->IsEnabled() )
+ {
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ pEntry.reset(new XBitmapEntry(Graphic(aBitmapEx), aName));
+ }
+ else // it must be a not existing imported bitmap
+ {
+ const SfxPoolItem* pPoolItem = nullptr;
+
+ if(SfxItemState::SET == m_rOutAttrs.GetItemState(XATTR_FILLBITMAP, true, &pPoolItem))
+ {
+ auto pFillBmpItem = dynamic_cast<const XFillBitmapItem*>(pPoolItem);
+ assert(pFillBmpItem);
+ pEntry.reset(new XBitmapEntry(pFillBmpItem->GetGraphicObject(), aName));
+ }
+ else
+ assert(!"SvxPatternTabPage::ClickAddHdl_Impl(), XBitmapEntry* pEntry == nullptr ?");
+ }
+
+ if( pEntry )
+ {
+ m_pPatternList->Insert(std::move(pEntry), nCount);
+ sal_Int32 nId = m_xPatternLB->GetItemId( nCount - 1 );
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( nCount, m_xPatternLB->GetIconSize() );
+ m_xPatternLB->InsertItem( nId + 1, Image(aBitmap), aName );
+ m_xPatternLB->SelectItem( nId + 1 );
+ m_xPatternLB->Resize();
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+ }
+ }
+
+ // determine button state
+ if( m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(true);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickModifyHdl_Impl, weld::Button&, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aName( m_pPatternList->GetBitmap( static_cast<sal_uInt16>(nPos) )->GetName() );
+
+ const BitmapEx aBitmapEx(m_xBitmapCtl->GetBitmapEx());
+
+ // #i123497# Need to replace the existing entry with a new one (old returned needs to be deleted)
+ m_pPatternList->Replace(std::make_unique<XBitmapEntry>(Graphic(aBitmapEx), aName), nPos);
+
+ BitmapEx aBitmap = m_pPatternList->GetBitmapForPreview( static_cast<sal_uInt16>( nPos ), m_xPatternLB->GetIconSize() );
+ m_xPatternLB->RemoveItem(nId);
+ m_xPatternLB->InsertItem( nId, Image(aBitmap), aName, static_cast<sal_uInt16>(nPos) );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+}
+
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickRenameHdl_Impl, SvxPresetListBox*, void)
+{
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+ sal_Int32 nId = m_xPatternLB->GetSelectedItemId();
+
+ if ( nPos == VALUESET_ITEM_NOTFOUND )
+ return;
+
+ OUString aDesc(CuiResId(RID_SVXSTR_DESC_NEW_PATTERN));
+ OUString aName(m_pPatternList->GetBitmap(nPos)->GetName());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(pFact->CreateSvxNameDialog(GetFrameWeld(), aName, aDesc));
+
+ bool bLoop = true;
+
+ while( bLoop && pDlg->Execute() == RET_OK )
+ {
+ pDlg->GetName( aName );
+ sal_Int32 nPatternPos = SearchPatternList(aName);
+ bool bValidPatternName = (nPatternPos == static_cast<sal_Int32>(nPos) ) || (nPatternPos == -1);
+
+ if( bValidPatternName )
+ {
+ bLoop = false;
+
+ m_pPatternList->GetBitmap(nPos)->SetName(aName);
+
+ m_xPatternLB->SetItemText( nId, aName );
+ m_xPatternLB->SelectItem( nId );
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ else
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/queryduplicatedialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xWarnBox(xBuilder->weld_message_dialog("DuplicateNameDialog"));
+ xWarnBox->run();
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ClickDeleteHdl_Impl, SvxPresetListBox*, void)
+{
+ sal_uInt16 nId = m_xPatternLB->GetSelectedItemId();
+ size_t nPos = m_xPatternLB->GetSelectItemPos();
+
+ if( nPos != VALUESET_ITEM_NOTFOUND )
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletebitmapdialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQueryBox(xBuilder->weld_message_dialog("AskDelBitmapDialog"));
+ if (xQueryBox->run() == RET_YES)
+ {
+ m_pPatternList->Remove(nPos);
+ m_xPatternLB->RemoveItem( nId );
+ nId = m_xPatternLB->GetItemId(0);
+ m_xPatternLB->SelectItem( nId );
+ m_xPatternLB->Resize();
+
+ m_aCtlPreview.Invalidate();
+ m_xCtlPixel->Invalidate();
+
+ ChangePatternHdl_Impl(m_xPatternLB.get());
+
+ *m_pnPatternListState |= ChangeType::MODIFIED;
+ }
+ }
+ // determine button state
+ if( !m_pPatternList->Count() )
+ {
+ m_xBtnModify->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPatternTabPage, ChangeColorHdl_Impl, ColorListBox&, void)
+{
+ ChangeColor_Impl();
+ m_xPatternLB->SetNoSelection();
+}
+
+void SvxPatternTabPage::ChangeColor_Impl()
+{
+ m_xCtlPixel->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xCtlPixel->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+ m_xCtlPixel->Invalidate();
+
+ m_xBitmapCtl->SetPixelColor( m_xLbColor->GetSelectEntryColor() );
+ m_xBitmapCtl->SetBackgroundColor( m_xLbBackgroundColor->GetSelectEntryColor() );
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+}
+
+void SvxPatternTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint)
+{
+ if (pDrawingArea == m_xCtlPixel->GetDrawingArea())
+ {
+ m_xBitmapCtl->SetBmpArray(m_xCtlPixel->GetBitmapPixelPtr());
+
+ // get bitmap and display it
+ m_rXFSet.Put(XFillBitmapItem(OUString(), Graphic(m_xBitmapCtl->GetBitmapEx())));
+ m_aCtlPreview.SetAttributes( m_aXFillAttr.GetItemSet() );
+ m_aCtlPreview.Invalidate();
+ }
+
+ m_xPatternLB->SetNoSelection();
+}
+
+sal_Int32 SvxPatternTabPage::SearchPatternList(const OUString& rPatternName)
+{
+ long nCount = m_pPatternList->Count();
+ bool bValidPatternName = true;
+ sal_Int32 nPos = -1;
+
+ for(long i = 0;i < nCount && bValidPatternName;i++)
+ {
+ if(rPatternName == m_pPatternList->GetBitmap( i )->GetName())
+ {
+ nPos = i;
+ bValidPatternName = false;
+ }
+ }
+ return nPos;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tpshadow.cxx b/cui/source/tabpages/tpshadow.cxx
new file mode 100644
index 000000000..de448b197
--- /dev/null
+++ b/cui/source/tabpages/tpshadow.cxx
@@ -0,0 +1,495 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/colorbox.hxx>
+#include <svx/svxids.hrc>
+#include <svtools/unitconv.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/sdmetitm.hxx>
+#include <svx/sdooitm.hxx>
+#include <svx/sdprcitm.hxx>
+#include <svx/sdshcitm.hxx>
+#include <svx/sdshitm.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/sdsxyitm.hxx>
+#include <svx/drawitem.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svx/dlgutil.hxx>
+#include <cuitabline.hxx>
+
+using namespace com::sun::star;
+
+const sal_uInt16 SvxShadowTabPage::pShadowRanges[] =
+{
+ SDRATTR_SHADOWCOLOR,
+ SDRATTR_SHADOWTRANSPARENCE,
+ SID_ATTR_FILL_SHADOW,
+ SID_ATTR_FILL_SHADOW,
+ SID_ATTR_SHADOW_TRANSPARENCE,
+ SID_ATTR_SHADOW_YDISTANCE,
+ 0
+};
+
+SvxShadowTabPage::SvxShadowTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/shadowtabpage.ui", "ShadowTabPage", rInAttrs)
+ , m_rOutAttrs(rInAttrs)
+ , m_pnColorListState(nullptr)
+ , m_nPageType(PageType::Area)
+ , m_nDlgType(0)
+ , m_aXFillAttr(rInAttrs.GetPool())
+ , m_rXFSet(m_aXFillAttr.GetItemSet())
+ , m_aCtlPosition(this)
+ , m_xTsbShowShadow(m_xBuilder->weld_check_button("TSB_SHOW_SHADOW"))
+ , m_xGridShadow(m_xBuilder->weld_widget("gridSHADOW"))
+ , m_xMtrDistance(m_xBuilder->weld_metric_spin_button("MTR_FLD_DISTANCE", FieldUnit::CM))
+ , m_xLbShadowColor(new ColorListBox(m_xBuilder->weld_menu_button("LB_SHADOW_COLOR"), pController->getDialog()))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_SHADOW_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xCtlPosition(new weld::CustomWeld(*m_xBuilder, "CTL_POSITION", m_aCtlPosition))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_COLOR_PREVIEW", m_aCtlXRectPreview))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // adjust metric
+ FieldUnit eFUnit = GetModuleFieldUnit( rInAttrs );
+
+ switch ( eFUnit )
+ {
+ case FieldUnit::M:
+ case FieldUnit::KM:
+ eFUnit = FieldUnit::MM;
+ break;
+ default: ;//prevent warning
+ }
+ SetFieldUnit( *m_xMtrDistance, eFUnit );
+
+ // determine PoolUnit
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "Where is the pool?" );
+ m_ePoolUnit = pPool->GetMetric( SDRATTR_SHADOWXDIST );
+
+ // setting the output device
+ drawing::FillStyle eXFS = drawing::FillStyle_SOLID;
+ if( m_rOutAttrs.GetItemState( XATTR_FILLSTYLE ) != SfxItemState::DONTCARE )
+ {
+ eXFS = static_cast<const XFillStyleItem&>( m_rOutAttrs.
+ Get( GetWhich( XATTR_FILLSTYLE ) ) ).GetValue();
+ switch( eXFS )
+ {
+ case drawing::FillStyle_SOLID:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLCOLOR ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLCOLOR ) );
+ }
+ break;
+
+ case drawing::FillStyle_GRADIENT:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLGRADIENT ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLGRADIENT ) );
+ }
+ break;
+
+ case drawing::FillStyle_HATCH:
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLHATCH ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLHATCH ) );
+ }
+ break;
+
+ case drawing::FillStyle_BITMAP:
+ {
+ if( SfxItemState::DONTCARE != m_rOutAttrs.GetItemState( XATTR_FILLBITMAP ) )
+ {
+ m_rXFSet.Put( m_rOutAttrs.Get( XATTR_FILLBITMAP ) );
+ }
+ }
+ break;
+ case drawing::FillStyle_NONE : break;
+ default: break;
+ }
+ }
+ else
+ {
+ m_rXFSet.Put( XFillColorItem( OUString(), COL_LIGHTRED ) );
+ }
+
+ if(drawing::FillStyle_NONE == eXFS)
+ {
+ // #i96350#
+ // fallback to solid fillmode when no fill mode is provided to have
+ // a reasonable shadow preview. The used color will be a set one or
+ // the default (currently blue8)
+ eXFS = drawing::FillStyle_SOLID;
+ }
+
+ m_rXFSet.Put( XFillStyleItem( eXFS ) );
+ m_aCtlXRectPreview.SetRectangleAttributes(m_aXFillAttr.GetItemSet());
+
+ m_xTsbShowShadow->connect_toggled(LINK( this, SvxShadowTabPage, ClickShadowHdl_Impl));
+ m_xLbShadowColor->SetSelectHdl( LINK( this, SvxShadowTabPage, SelectShadowHdl_Impl ) );
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxShadowTabPage, ModifyShadowHdl_Impl );
+ m_xMtrTransparent->connect_value_changed(aLink);
+ m_xMtrDistance->connect_value_changed(aLink);
+}
+
+SvxShadowTabPage::~SvxShadowTabPage()
+{
+ m_xCtlXRectPreview.reset();
+ m_xLbShadowColor.reset();
+ m_xCtlPosition.reset();
+}
+
+void SvxShadowTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ const SfxUInt16Item* pPageTypeItem = rSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if( m_nDlgType != 0 )
+ return;
+
+ if( !m_pColorList.is() )
+ return;
+
+ // ColorList
+ if( *m_pnColorListState & ChangeType::CHANGED ||
+ *m_pnColorListState & ChangeType::MODIFIED )
+ {
+ if( *m_pnColorListState & ChangeType::CHANGED )
+ {
+ SvxAreaTabDialog* pArea = dynamic_cast<SvxAreaTabDialog*>(GetDialogController());
+ if( pArea )
+ {
+ m_pColorList = pArea->GetNewColorList();
+ }
+ else
+ {
+ SvxLineTabDialog* pLine = dynamic_cast<SvxLineTabDialog*>(GetDialogController());
+ if( pLine )
+ m_pColorList = pLine->GetNewColorList();
+ }
+ }
+
+ SfxItemSet rAttribs( rSet );
+ // rSet contains shadow attributes too, but we want
+ // to use it for updating rectangle attributes only,
+ // so set the shadow to none here
+ SdrOnOffItem aItem( makeSdrShadowItem( false ));
+ rAttribs.Put( aItem );
+
+ m_aCtlXRectPreview.SetRectangleAttributes( rAttribs );
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+ }
+ m_nPageType = PageType::Shadow;
+}
+
+
+DeactivateRC SvxShadowTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+
+ return DeactivateRC::LeavePage;
+}
+
+
+bool SvxShadowTabPage::FillItemSet( SfxItemSet* rAttrs )
+{
+ bool bModified = false;
+
+ const SfxPoolItem* pOld = nullptr;
+
+ if (m_xTsbShowShadow->get_state_changed_from_saved())
+ {
+ TriState eState = m_xTsbShowShadow->get_state();
+ assert(eState != TRISTATE_INDET);
+ // given how m_xTsbShowShadow is set up and saved in Reset(),
+ // eState == TRISTATE_INDET would imply
+ // !IsValueChangedFromSaved()
+ SdrOnOffItem aItem( makeSdrShadowItem(eState == TRISTATE_TRUE) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOW );
+ if ( !pOld || !( *static_cast<const SdrOnOffItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // shadow removal
+ // a bit intricate inquiry whether there was something changed,
+ // as the items can't be displayed directly on controls
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+
+ switch (m_aCtlPosition.GetActualRP())
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ // If the values of the shadow distances==SfxItemState::DONTCARE and the displayed
+ // string in the respective MetricField=="", then the comparison of the old
+ // and the new distance values would return a wrong result because in such a
+ // case the new distance values would match the default values of the MetricField !!!!
+ if ( !m_xMtrDistance->get_text().isEmpty() ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE ||
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nOldX = 9876543; // impossible value, so DontCare
+ sal_Int32 nOldY = 9876543;
+ if( m_rOutAttrs.GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ m_rOutAttrs.GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ nOldX = m_rOutAttrs.Get( SDRATTR_SHADOWXDIST ).GetValue();
+ nOldY = m_rOutAttrs.Get( SDRATTR_SHADOWYDIST ).GetValue();
+ }
+ SdrMetricItem aXItem( makeSdrShadowXDistItem(nX) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWXDIST );
+ if ( nX != nOldX &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aXItem ) ) )
+ {
+ rAttrs->Put( aXItem );
+ bModified = true;
+ }
+ SdrMetricItem aYItem( makeSdrShadowYDistItem(nY) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWYDIST );
+ if ( nY != nOldY &&
+ ( !pOld || !( *static_cast<const SdrMetricItem*>(pOld) == aYItem ) ) )
+ {
+ rAttrs->Put( aYItem );
+ bModified = true;
+ }
+ }
+
+ // ShadowColor
+ {
+ XColorItem aItem(makeSdrShadowColorItem(m_xLbShadowColor->GetSelectEntryColor()));
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWCOLOR );
+ if ( !pOld || !( *static_cast<const XColorItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ // transparency
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ if (m_xMtrTransparent->get_value_changed_from_saved())
+ {
+ SdrPercentItem aItem( makeSdrShadowTransparenceItem(nVal) );
+ pOld = GetOldItem( *rAttrs, SDRATTR_SHADOWTRANSPARENCE );
+ if ( !pOld || !( *static_cast<const SdrPercentItem*>(pOld) == aItem ) )
+ {
+ rAttrs->Put( aItem );
+ bModified = true;
+ }
+ }
+
+ rAttrs->Put (CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(m_nPageType)));
+
+ return bModified;
+}
+
+
+void SvxShadowTabPage::Reset( const SfxItemSet* rAttrs )
+{
+ // all objects can have a shadow
+ // at the moment there are only 8 possible positions where a shadow can be set
+
+ // has a shadow been set?
+ if( rAttrs->GetItemState( SDRATTR_SHADOW ) != SfxItemState::DONTCARE )
+ {
+ if( rAttrs->Get( SDRATTR_SHADOW ).GetValue() )
+ m_xTsbShowShadow->set_state(TRISTATE_TRUE);
+ else
+ {
+ m_xTsbShowShadow->set_state(TRISTATE_FALSE);
+ }
+ }
+ else
+ m_xTsbShowShadow->set_state(TRISTATE_INDET);
+
+ // distance (only 8 possible positions),
+ // so there is only one item evaluated
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWXDIST ) != SfxItemState::DONTCARE &&
+ rAttrs->GetItemState( SDRATTR_SHADOWYDIST ) != SfxItemState::DONTCARE )
+ {
+ sal_Int32 nX = rAttrs->Get( SDRATTR_SHADOWXDIST ).GetValue();
+ sal_Int32 nY = rAttrs->Get( SDRATTR_SHADOWYDIST ).GetValue();
+
+ if( nX != 0 )
+ SetMetricValue( *m_xMtrDistance, nX < 0 ? -nX : nX, m_ePoolUnit );
+ else
+ SetMetricValue( *m_xMtrDistance, nY < 0 ? -nY : nY, m_ePoolUnit );
+
+ // setting the shadow control
+ if ( nX < 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::LT );
+ else if( nX == 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::MT );
+ else if( nX > 0 && nY < 0 ) m_aCtlPosition.SetActualRP( RectPoint::RT );
+ else if( nX < 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::LM );
+ // there's no center point anymore
+ else if( nX == 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ else if( nX > 0 && nY == 0 ) m_aCtlPosition.SetActualRP( RectPoint::RM );
+ else if( nX < 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::LB );
+ else if( nX == 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::MB );
+ else if( nX > 0 && nY > 0 ) m_aCtlPosition.SetActualRP( RectPoint::RB );
+ }
+ else
+ {
+ // determine default-distance
+ SfxItemPool* pPool = m_rOutAttrs.GetPool();
+ {
+ sal_Int32 n = pPool->GetDefaultItem(SDRATTR_SHADOWXDIST).GetValue();
+ if (n == 0)
+ n = pPool->GetDefaultItem(SDRATTR_SHADOWYDIST).GetValue();
+ SetMetricValue(*m_xMtrDistance, std::abs(n), m_ePoolUnit);
+ }
+
+ // Tristate, e. g. multiple objects have been marked of which some have a shadow and some don't.
+ // The text (which shall be displayed) of the MetricFields is set to "" and serves as an
+ // identification in the method FillItemSet for the fact that the distance value was NOT changed !!!!
+ m_xMtrDistance->set_text( "" );
+ m_aCtlPosition.SetActualRP( RectPoint::MM );
+ }
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWCOLOR ) != SfxItemState::DONTCARE )
+ {
+ m_xLbShadowColor->SelectEntry( rAttrs->Get( SDRATTR_SHADOWCOLOR ).GetColorValue() );
+ }
+ else
+ m_xLbShadowColor->SetNoSelection();
+
+ if( rAttrs->GetItemState( SDRATTR_SHADOWTRANSPARENCE ) != SfxItemState::DONTCARE )
+ {
+ sal_uInt16 nTransp = rAttrs->Get( SDRATTR_SHADOWTRANSPARENCE ).GetValue();
+ m_xMtrTransparent->set_value(nTransp, FieldUnit::PERCENT);
+ }
+ else
+ m_xMtrTransparent->set_text("");
+
+ //aCtlPosition
+ m_xMtrDistance->save_value();
+ m_xLbShadowColor->SaveValue();
+ m_xTsbShowShadow->save_state();
+
+ // #66832# This field was not saved, but used to determine changes.
+ // Why? Seems to be the error.
+ // It IS the error.
+ m_xMtrTransparent->save_value();
+
+ ClickShadowHdl_Impl(*m_xTsbShowShadow);
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+std::unique_ptr<SfxTabPage> SvxShadowTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxShadowTabPage>(pPage, pController, *rAttrs);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ClickShadowHdl_Impl, weld::ToggleButton&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_FALSE)
+ {
+ m_xGridShadow->set_sensitive(false);
+ m_xCtlPosition->set_sensitive(false);
+ }
+ else
+ {
+ m_xGridShadow->set_sensitive(true);
+ m_xCtlPosition->set_sensitive(true);
+ }
+ m_aCtlPosition.Invalidate();
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, SelectShadowHdl_Impl, ColorListBox&, void)
+{
+ ModifyShadowHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxShadowTabPage, ModifyShadowHdl_Impl, weld::MetricSpinButton&, void)
+{
+ if (m_xTsbShowShadow->get_state() == TRISTATE_TRUE)
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
+ else
+ m_rXFSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
+
+ m_rXFSet.Put( XFillColorItem( OUString(), m_xLbShadowColor->GetSelectEntryColor() ) );
+ sal_uInt16 nVal = static_cast<sal_uInt16>(m_xMtrTransparent->get_value(FieldUnit::PERCENT));
+ m_rXFSet.Put( XFillTransparenceItem( nVal ) );
+
+ // shadow removal
+ sal_Int32 nX = 0, nY = 0;
+ sal_Int32 nXY = GetCoreValue( *m_xMtrDistance, m_ePoolUnit );
+ switch( m_aCtlPosition.GetActualRP() )
+ {
+ case RectPoint::LT: nX = nY = -nXY; break;
+ case RectPoint::MT: nY = -nXY; break;
+ case RectPoint::RT: nX = nXY; nY = -nXY; break;
+ case RectPoint::LM: nX = -nXY; break;
+ case RectPoint::RM: nX = nXY; break;
+ case RectPoint::LB: nX = -nXY; nY = nXY; break;
+ case RectPoint::MB: nY = nXY; break;
+ case RectPoint::RB: nX = nY = nXY; break;
+ case RectPoint::MM: break;
+ }
+
+ m_aCtlXRectPreview.SetShadowPosition(Point(nX, nY));
+
+ m_aCtlXRectPreview.SetShadowAttributes(m_aXFillAttr.GetItemSet());
+ m_aCtlXRectPreview.Invalidate();
+}
+
+void SvxShadowTabPage::PointChanged( weld::DrawingArea*, RectPoint )
+{
+ // repaint shadow
+ ModifyShadowHdl_Impl( *m_xMtrTransparent );
+}
+
+void SvxShadowTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SvxColorListItem* pColorListItem = aSet.GetItem<SvxColorListItem>(SID_COLOR_TABLE, false);
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pColorListItem)
+ SetColorList(pColorListItem->GetColorList());
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/tptrans.cxx b/cui/source/tabpages/tptrans.cxx
new file mode 100644
index 000000000..ac950ceb3
--- /dev/null
+++ b/cui/source/tabpages/tptrans.cxx
@@ -0,0 +1,524 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxids.hrc>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflftrit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <svx/xflbckit.hxx>
+#include <svx/sdshtitm.hxx>
+#include <svx/xfltrit.hxx>
+#include <cuitabarea.hxx>
+#include <svl/intitem.hxx>
+
+using namespace com::sun::star;
+
+const sal_uInt16 SvxTransparenceTabPage::pTransparenceRanges[] =
+{
+ XATTR_FILLTRANSPARENCE,
+ XATTR_FILLTRANSPARENCE,
+ SDRATTR_SHADOWTRANSPARENCE,
+ SDRATTR_SHADOWTRANSPARENCE,
+ XATTR_FILLFLOATTRANSPARENCE,
+ XATTR_FILLFLOATTRANSPARENCE,
+ 0
+};
+
+/*************************************************************************
+|*
+|* Dialog for transparence
+|*
+\************************************************************************/
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransOffHdl_Impl, weld::ToggleButton&, void)
+{
+ // disable all other controls
+ ActivateLinear(false);
+ ActivateGradient(false);
+
+ // Preview
+ rXFSet.ClearItem(XATTR_FILLTRANSPARENCE);
+ rXFSet.ClearItem(XATTR_FILLFLOATTRANSPARENCE);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ InvalidatePreview(false);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransLinearHdl_Impl, weld::ToggleButton&, void)
+{
+ // enable linear, disable other
+ ActivateLinear(true);
+ ActivateGradient(false);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLFLOATTRANSPARENCE);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ClickTransGradientHdl_Impl, weld::ToggleButton&, void)
+{
+ // enable gradient, disable other
+ ActivateLinear(false);
+ ActivateGradient(true);
+
+ // preview
+ rXFSet.ClearItem (XATTR_FILLTRANSPARENCE);
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+SvxTransparenceTabPage::~SvxTransparenceTabPage()
+{
+}
+
+void SvxTransparenceTabPage::ActivateLinear(bool bActivate)
+{
+ m_xMtrTransparent->set_sensitive(bActivate);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifyTransparentHdl_Impl, weld::MetricSpinButton&, void)
+{
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ rXFSet.Put(XFillTransparenceItem(nPos));
+
+ // preview
+ InvalidatePreview();
+}
+
+IMPL_LINK(SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl, weld::ComboBox&, rListBox, void)
+{
+ ModifiedTrgrHdl_Impl(&rListBox);
+}
+
+IMPL_LINK_NOARG(SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl, weld::MetricSpinButton&, void)
+{
+ ModifiedTrgrHdl_Impl(nullptr);
+}
+
+void SvxTransparenceTabPage::ModifiedTrgrHdl_Impl(const weld::ComboBox* pControl)
+{
+ if (pControl == m_xLbTrgrGradientType.get())
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+
+ // preview
+ sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ XGradient aTmpGradient(
+ Color(nStartCol, nStartCol, nStartCol),
+ Color(nEndCol, nEndCol, nEndCol),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ static_cast<sal_uInt16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10,
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem( aTmpGradient);
+ rXFSet.Put ( aItem );
+
+ InvalidatePreview();
+}
+
+void SvxTransparenceTabPage::ActivateGradient(bool bActivate)
+{
+ m_xGridGradient->set_sensitive(bActivate);
+
+ if (bActivate)
+ {
+ css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active());
+ SetControlState_Impl( eXGS );
+ }
+}
+
+void SvxTransparenceTabPage::SetControlState_Impl(css::awt::GradientStyle eXGS)
+{
+ switch(eXGS)
+ {
+ case css::awt::GradientStyle_LINEAR:
+ case css::awt::GradientStyle_AXIAL:
+ m_xFtTrgrCenterX->set_sensitive(false);
+ m_xMtrTrgrCenterX->set_sensitive(false);
+ m_xFtTrgrCenterY->set_sensitive(false);
+ m_xMtrTrgrCenterY->set_sensitive(false);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+
+ case css::awt::GradientStyle_RADIAL:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(false);
+ m_xMtrTrgrAngle->set_sensitive(false);
+ break;
+
+ case css::awt::GradientStyle_ELLIPTICAL:
+ case css::awt::GradientStyle_SQUARE:
+ case css::awt::GradientStyle_RECT:
+ m_xFtTrgrCenterX->set_sensitive(true);
+ m_xMtrTrgrCenterX->set_sensitive(true);
+ m_xFtTrgrCenterY->set_sensitive(true);
+ m_xMtrTrgrCenterY->set_sensitive(true);
+ m_xFtTrgrAngle->set_sensitive(true);
+ m_xMtrTrgrAngle->set_sensitive(true);
+ break;
+ default:
+ break;
+ }
+}
+
+SvxTransparenceTabPage::SvxTransparenceTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/transparencytabpage.ui", "TransparencyTabPage", &rInAttrs)
+ , rOutAttrs(rInAttrs)
+ , nPageType(PageType::Area)
+ , nDlgType(0)
+ , bBitmap(false)
+ , aXFillAttr(rInAttrs.GetPool())
+ , rXFSet(aXFillAttr.GetItemSet())
+ , m_xRbtTransOff(m_xBuilder->weld_radio_button("RBT_TRANS_OFF"))
+ , m_xRbtTransLinear(m_xBuilder->weld_radio_button("RBT_TRANS_LINEAR"))
+ , m_xRbtTransGradient(m_xBuilder->weld_radio_button("RBT_TRANS_GRADIENT"))
+ , m_xMtrTransparent(m_xBuilder->weld_metric_spin_button("MTR_TRANSPARENT", FieldUnit::PERCENT))
+ , m_xGridGradient(m_xBuilder->weld_widget("gridGradient"))
+ , m_xLbTrgrGradientType(m_xBuilder->weld_combo_box("LB_TRGR_GRADIENT_TYPES"))
+ , m_xFtTrgrCenterX(m_xBuilder->weld_label("FT_TRGR_CENTER_X"))
+ , m_xMtrTrgrCenterX(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_X", FieldUnit::PERCENT))
+ , m_xFtTrgrCenterY(m_xBuilder->weld_label("FT_TRGR_CENTER_Y"))
+ , m_xMtrTrgrCenterY(m_xBuilder->weld_metric_spin_button("MTR_TRGR_CENTER_Y", FieldUnit::PERCENT))
+ , m_xFtTrgrAngle(m_xBuilder->weld_label("FT_TRGR_ANGLE"))
+ , m_xMtrTrgrAngle(m_xBuilder->weld_metric_spin_button("MTR_TRGR_ANGLE", FieldUnit::DEGREE))
+ , m_xMtrTrgrBorder(m_xBuilder->weld_metric_spin_button("MTR_TRGR_BORDER", FieldUnit::PERCENT))
+ , m_xMtrTrgrStartValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_START_VALUE", FieldUnit::PERCENT))
+ , m_xMtrTrgrEndValue(m_xBuilder->weld_metric_spin_button("MTR_TRGR_END_VALUE", FieldUnit::PERCENT))
+ , m_xCtlBitmapBorder(m_xBuilder->weld_widget("bitmap_border"))
+ , m_xCtlXRectBorder(m_xBuilder->weld_widget("trans_border"))
+ , m_xCtlBitmapPreview(new weld::CustomWeld(*m_xBuilder, "CTL_BITMAP_PREVIEW", m_aCtlBitmapPreview))
+ , m_xCtlXRectPreview(new weld::CustomWeld(*m_xBuilder, "CTL_TRANS_PREVIEW", m_aCtlXRectPreview))
+{
+ // main selection
+ m_xRbtTransOff->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransOffHdl_Impl));
+ m_xRbtTransLinear->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransLinearHdl_Impl));
+ m_xRbtTransGradient->connect_toggled(LINK(this, SvxTransparenceTabPage, ClickTransGradientHdl_Impl));
+
+ // linear transparency
+ m_xMtrTransparent->set_value(50, FieldUnit::PERCENT);
+ m_xMtrTransparent->connect_value_changed(LINK(this, SvxTransparenceTabPage, ModifyTransparentHdl_Impl));
+
+ // gradient transparency
+ m_xMtrTrgrEndValue->set_value(100, FieldUnit::PERCENT);
+ m_xMtrTrgrStartValue->set_value(0, FieldUnit::PERCENT);
+ Link<weld::MetricSpinButton&,void> aLink = LINK( this, SvxTransparenceTabPage, ModifiedTrgrEditHdl_Impl);
+ m_xLbTrgrGradientType->connect_changed(LINK(this, SvxTransparenceTabPage, ModifiedTrgrListBoxHdl_Impl));
+ m_xMtrTrgrCenterX->connect_value_changed( aLink );
+ m_xMtrTrgrCenterY->connect_value_changed( aLink );
+ m_xMtrTrgrAngle->connect_value_changed( aLink );
+ m_xMtrTrgrBorder->connect_value_changed( aLink );
+ m_xMtrTrgrStartValue->connect_value_changed( aLink );
+ m_xMtrTrgrEndValue->connect_value_changed( aLink );
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+}
+
+std::unique_ptr<SfxTabPage> SvxTransparenceTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs)
+{
+ return std::make_unique<SvxTransparenceTabPage>(pPage, pController, *rAttrs);
+}
+
+bool SvxTransparenceTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ const SfxPoolItem* pGradientItem = nullptr;
+ const SfxPoolItem* pLinearItem = nullptr;
+ SfxItemState eStateGradient(rOutAttrs.GetItemState(XATTR_FILLFLOATTRANSPARENCE, true, &pGradientItem));
+ SfxItemState eStateLinear(rOutAttrs.GetItemState(XATTR_FILLTRANSPARENCE, true, &pLinearItem));
+ bool bGradActive = (eStateGradient == SfxItemState::SET && static_cast<const XFillFloatTransparenceItem*>(pGradientItem)->IsEnabled());
+ bool bLinearActive = (eStateLinear == SfxItemState::SET && static_cast<const XFillTransparenceItem*>(pLinearItem)->GetValue() != 0);
+
+ bool bGradUsed = (eStateGradient == SfxItemState::DONTCARE);
+ bool bLinearUsed = (eStateLinear == SfxItemState::DONTCARE);
+
+ bool bModified(false);
+ bool bSwitchOffLinear(false);
+ bool bSwitchOffGradient(false);
+
+ if (m_xMtrTransparent->get_sensitive())
+ {
+ // linear transparence
+ sal_uInt16 nPos = m_xMtrTransparent->get_value(FieldUnit::PERCENT);
+ if (m_xMtrTransparent->get_value_changed_from_saved() || !bLinearActive)
+ {
+ XFillTransparenceItem aItem(nPos);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(nPos));
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLTRANSPARENCE);
+ if(!pOld || !(*static_cast<const XFillTransparenceItem*>(pOld) == aItem) || !bLinearActive)
+ {
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ bSwitchOffGradient = true;
+ }
+ }
+ }
+ else if (m_xGridGradient->get_sensitive())
+ {
+ // transparence gradient, fill ItemSet from values
+ if (!bGradActive
+ || m_xLbTrgrGradientType->get_value_changed_from_saved()
+ || m_xMtrTrgrAngle->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterX->get_value_changed_from_saved()
+ || m_xMtrTrgrCenterY->get_value_changed_from_saved()
+ || m_xMtrTrgrBorder->get_value_changed_from_saved()
+ || m_xMtrTrgrStartValue->get_value_changed_from_saved()
+ || m_xMtrTrgrEndValue->get_value_changed_from_saved())
+ {
+ sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
+ XGradient aTmpGradient(
+ Color(nStartCol, nStartCol, nStartCol),
+ Color(nEndCol, nEndCol, nEndCol),
+ static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
+ static_cast<sal_uInt16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10,
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrCenterY->get_value(FieldUnit::PERCENT)),
+ static_cast<sal_uInt16>(m_xMtrTrgrBorder->get_value(FieldUnit::PERCENT)),
+ 100, 100);
+
+ XFillFloatTransparenceItem aItem(aTmpGradient);
+ const SfxPoolItem* pOld = GetOldItem(*rAttrs, XATTR_FILLFLOATTRANSPARENCE);
+
+ if(!pOld || !(*static_cast<const XFillFloatTransparenceItem*>(pOld) == aItem) || !bGradActive)
+ {
+ rAttrs->Put(aItem);
+ bModified = true;
+ bSwitchOffLinear = true;
+ }
+ }
+ }
+ else
+ {
+ // no transparence
+ bSwitchOffGradient = true;
+ bSwitchOffLinear = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffGradient && (bGradActive || bGradUsed))
+ {
+ XGradient aGrad(COL_BLACK, COL_WHITE);
+ aGrad.SetStartIntens(100);
+ aGrad.SetEndIntens(100);
+ XFillFloatTransparenceItem aItem(aGrad);
+ aItem.SetEnabled(false);
+ rAttrs->Put(aItem);
+ bModified = true;
+ }
+
+ // disable unused XFillFloatTransparenceItem
+ if(bSwitchOffLinear && (bLinearActive || bLinearUsed))
+ {
+ XFillTransparenceItem aItem(0);
+ SdrPercentItem aShadowItem(makeSdrShadowTransparenceItem(0));
+ rAttrs->Put(aItem);
+ rAttrs->Put(aShadowItem);
+ bModified = true;
+ }
+ rAttrs->Put(CntUInt16Item(SID_PAGE_TYPE, static_cast<sal_uInt16>(nPageType)));
+ return bModified;
+}
+
+void SvxTransparenceTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const SfxPoolItem* pGradientItem = nullptr;
+ SfxItemState eStateGradient(rAttrs->GetItemState(XATTR_FILLFLOATTRANSPARENCE, true, &pGradientItem));
+ if(!pGradientItem)
+ pGradientItem = &rAttrs->Get(XATTR_FILLFLOATTRANSPARENCE);
+ bool bGradActive = (eStateGradient == SfxItemState::SET && static_cast<const XFillFloatTransparenceItem*>(pGradientItem)->IsEnabled());
+
+ const SfxPoolItem* pLinearItem = nullptr;
+ SfxItemState eStateLinear(rAttrs->GetItemState(XATTR_FILLTRANSPARENCE, true, &pLinearItem));
+ if(!pLinearItem)
+ pLinearItem = &rAttrs->Get(XATTR_FILLTRANSPARENCE);
+ bool bLinearActive = (eStateLinear == SfxItemState::SET && static_cast<const XFillTransparenceItem*>(pLinearItem)->GetValue() != 0);
+
+ // transparence gradient
+ const XGradient& rGradient = static_cast<const XFillFloatTransparenceItem*>(pGradientItem)->GetGradientValue();
+ css::awt::GradientStyle eXGS(rGradient.GetGradientStyle());
+ m_xLbTrgrGradientType->set_active(sal::static_int_cast< sal_Int32 >(eXGS));
+ m_xMtrTrgrAngle->set_value(rGradient.GetAngle() / 10, FieldUnit::DEGREE);
+ m_xMtrTrgrBorder->set_value(rGradient.GetBorder(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterX->set_value(rGradient.GetXOffset(), FieldUnit::PERCENT);
+ m_xMtrTrgrCenterY->set_value(rGradient.GetYOffset(), FieldUnit::PERCENT);
+ m_xMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetStartColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+ m_xMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetEndColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
+
+ // linear transparence
+ sal_uInt16 nTransp = static_cast<const XFillTransparenceItem*>(pLinearItem)->GetValue();
+ m_xMtrTransparent->set_value(bLinearActive ? nTransp : 50, FieldUnit::PERCENT);
+ ModifyTransparentHdl_Impl(*m_xMtrTransparent);
+
+ // select the correct radio button
+ if(bGradActive)
+ {
+ // transparence gradient, set controls appropriate to item
+ m_xRbtTransGradient->set_active(true);
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+ else if(bLinearActive)
+ {
+ // linear transparence
+ m_xRbtTransLinear->set_active(true);
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else
+ {
+ // no transparence
+ m_xRbtTransOff->set_active(true);
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ ModifiedTrgrHdl_Impl(nullptr);
+ }
+
+ // save values
+ ChangesApplied();
+ bool bActive = InitPreview ( *rAttrs );
+ InvalidatePreview ( bActive );
+}
+
+void SvxTransparenceTabPage::ChangesApplied()
+{
+ m_xMtrTransparent->save_value();
+ m_xLbTrgrGradientType->save_value();
+ m_xMtrTrgrCenterX->save_value();
+ m_xMtrTrgrCenterY->save_value();
+ m_xMtrTrgrAngle->save_value();
+ m_xMtrTrgrBorder->save_value();
+ m_xMtrTrgrStartValue->save_value();
+ m_xMtrTrgrEndValue->save_value();
+}
+
+void SvxTransparenceTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ const CntUInt16Item* pPageTypeItem = rSet.GetItem<CntUInt16Item>(SID_PAGE_TYPE, false);
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+
+ if(nDlgType == 0) // area dialog
+ nPageType = PageType::Transparence;
+
+ InitPreview ( rSet );
+}
+
+DeactivateRC SvxTransparenceTabPage::DeactivatePage(SfxItemSet* _pSet)
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+// Preview-Methods
+
+bool SvxTransparenceTabPage::InitPreview(const SfxItemSet& rSet)
+{
+ // set transparencetype for preview
+ if (m_xRbtTransOff->get_active())
+ {
+ ClickTransOffHdl_Impl(*m_xRbtTransOff);
+ }
+ else if (m_xRbtTransLinear->get_active())
+ {
+ ClickTransLinearHdl_Impl(*m_xRbtTransLinear);
+ }
+ else if (m_xRbtTransGradient->get_active())
+ {
+ ClickTransGradientHdl_Impl(*m_xRbtTransGradient);
+ }
+
+ // Get fillstyle for preview
+ rXFSet.Put ( rSet.Get(XATTR_FILLSTYLE) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLCOLOR) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLGRADIENT) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLHATCH) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBACKGROUND) );
+ rXFSet.Put ( rSet.Get(XATTR_FILLBITMAP) );
+
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+
+ bBitmap = rSet.Get(XATTR_FILLSTYLE).GetValue() == drawing::FillStyle_BITMAP;
+
+ // show the right preview window
+ if ( bBitmap )
+ {
+ m_xCtlBitmapBorder->show();
+ m_xCtlXRectBorder->hide();
+ }
+ else
+ {
+ m_xCtlBitmapBorder->hide();
+ m_xCtlXRectBorder->show();
+ }
+
+ return !m_xRbtTransOff->get_active();
+}
+
+void SvxTransparenceTabPage::InvalidatePreview (bool bEnable)
+{
+ if ( bBitmap )
+ {
+ if ( bEnable )
+ {
+ m_xCtlBitmapPreview->set_sensitive(true);
+ m_aCtlBitmapPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlBitmapPreview->set_sensitive(false);
+ m_xCtlBitmapPreview->queue_draw();
+ }
+ else
+ {
+ if ( bEnable )
+ {
+ m_xCtlXRectPreview->set_sensitive(true);
+ m_aCtlXRectPreview.SetAttributes( aXFillAttr.GetItemSet() );
+ }
+ else
+ m_xCtlXRectPreview->set_sensitive(false);
+ m_xCtlXRectPreview->queue_draw();
+ }
+}
+
+void SvxTransparenceTabPage::PageCreated(const SfxAllItemSet& aSet)
+{
+ const SfxUInt16Item* pPageTypeItem = aSet.GetItem<SfxUInt16Item>(SID_PAGE_TYPE, false);
+ const SfxUInt16Item* pDlgTypeItem = aSet.GetItem<SfxUInt16Item>(SID_DLG_TYPE, false);
+
+ if (pPageTypeItem)
+ SetPageType(static_cast<PageType>(pPageTypeItem->GetValue()));
+ if (pDlgTypeItem)
+ SetDlgType(pDlgTypeItem->GetValue());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/tabpages/transfrm.cxx b/cui/source/tabpages/transfrm.cxx
new file mode 100644
index 000000000..77c3b7e7e
--- /dev/null
+++ b/cui/source/tabpages/transfrm.cxx
@@ -0,0 +1,1584 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <algorithm>
+
+#include <svx/EnhancedCustomShape2d.hxx>
+#include <svx/svdundo.hxx>
+#include <svx/svdview.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/sderitm.hxx>
+#include <svx/svxids.hrc>
+#include <svx/transfrmhelper.hxx>
+#include <svtools/unitconv.hxx>
+
+#include <transfrm.hxx>
+#include <svx/dlgutil.hxx>
+#include <svx/anchorid.hxx>
+#include <svl/rectitem.hxx>
+#include <swpossizetabpage.hxx>
+#include <vcl/canvastools.hxx>
+#include <vcl/fieldvalues.hxx>
+
+// static ----------------------------------------------------------------
+
+const sal_uInt16 SvxPositionSizeTabPage::pPosSizeRanges[] =
+{
+ SID_ATTR_TRANSFORM_POS_X,
+ SID_ATTR_TRANSFORM_POS_Y,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_ANCHOR,
+ SID_ATTR_TRANSFORM_VERT_ORIENT,
+ SID_ATTR_TRANSFORM_WIDTH,
+ SID_ATTR_TRANSFORM_SIZE_POINT,
+ SID_ATTR_TRANSFORM_PROTECT_POS,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_AUTOWIDTH,
+ SID_ATTR_TRANSFORM_AUTOHEIGHT,
+ 0
+};
+
+const sal_uInt16 SvxAngleTabPage::pAngleRanges[] =
+{
+ SID_ATTR_TRANSFORM_ROT_X,
+ SID_ATTR_TRANSFORM_ANGLE,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_INTERN,
+ 0
+};
+
+const sal_uInt16 SvxSlantTabPage::pSlantRanges[] =
+{
+ SDRATTR_ECKENRADIUS,
+ SDRATTR_ECKENRADIUS,
+ SID_ATTR_TRANSFORM_SHEAR,
+ SID_ATTR_TRANSFORM_SHEAR_VERTICAL,
+ SID_ATTR_TRANSFORM_INTERN,
+ SID_ATTR_TRANSFORM_INTERN,
+ 0
+};
+
+/*************************************************************************
+|*
+|* constructor of the tab dialog: adds the pages to the dialog
+|*
+\************************************************************************/
+
+SvxTransformTabDialog::SvxTransformTabDialog(weld::Window* pParent, const SfxItemSet* pAttr,
+ const SdrView* pSdrView, SvxAnchorIds nAnchorTypes)
+ : SfxTabDialogController(pParent, "cui/ui/positionsizedialog.ui", "PositionAndSizeDialog", pAttr)
+ , pView(pSdrView)
+ , nAnchorCtrls(nAnchorTypes)
+{
+ DBG_ASSERT(pView, "no valid view (!)");
+
+ //different positioning page in Writer
+ if(nAnchorCtrls & (SvxAnchorIds::Paragraph | SvxAnchorIds::Character | SvxAnchorIds::Page | SvxAnchorIds::Fly))
+ {
+ AddTabPage("RID_SVXPAGE_SWPOSSIZE", SvxSwPosSizeTabPage::Create, SvxSwPosSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_POSITION_SIZE");
+ }
+ else
+ {
+ AddTabPage("RID_SVXPAGE_POSITION_SIZE", SvxPositionSizeTabPage::Create, SvxPositionSizeTabPage::GetRanges);
+ RemoveTabPage("RID_SVXPAGE_SWPOSSIZE");
+ }
+
+ AddTabPage("RID_SVXPAGE_ANGLE", SvxAngleTabPage::Create, SvxAngleTabPage::GetRanges);
+ AddTabPage("RID_SVXPAGE_SLANT", SvxSlantTabPage::Create, SvxSlantTabPage::GetRanges);
+}
+
+
+void SvxTransformTabDialog::PageCreated(const OString& rId, SfxTabPage &rPage)
+{
+ if (rId == "RID_SVXPAGE_POSITION_SIZE")
+ {
+ SvxPositionSizeTabPage& rSvxPos = static_cast<SvxPositionSizeTabPage&>(rPage);
+ rSvxPos.SetView(pView);
+ rSvxPos.Construct();
+
+ if(nAnchorCtrls & SvxAnchorIds::NoResize)
+ {
+ rSvxPos.DisableResize();
+ }
+
+ if(nAnchorCtrls & SvxAnchorIds::NoProtect)
+ {
+ rSvxPos.DisableProtect();
+ rSvxPos.UpdateControlStates();
+ }
+ }
+ else if (rId == "RID_SVXPAGE_SWPOSSIZE")
+ {
+ SvxSwPosSizeTabPage& rSwPos = static_cast<SvxSwPosSizeTabPage&>(rPage);
+
+ rSwPos.EnableAnchorTypes(nAnchorCtrls);
+ rSwPos.SetValidateFramePosLink(aValidateLink);
+ rSwPos.SetView(pView);
+ }
+ else if (rId == "RID_SVXPAGE_ANGLE")
+ {
+ SvxAngleTabPage& rSvxAng = static_cast<SvxAngleTabPage&>(rPage);
+
+ rSvxAng.SetView( pView );
+ rSvxAng.Construct();
+ }
+ else if (rId == "RID_SVXPAGE_SLANT")
+ {
+ SvxSlantTabPage& rSvxSlnt = static_cast<SvxSlantTabPage&>(rPage);
+
+ rSvxSlnt.SetView( pView );
+ rSvxSlnt.Construct();
+ }
+}
+
+void SvxTransformTabDialog::SetValidateFramePosLink(const Link<SvxSwFrameValidation&,void>& rLink)
+{
+ aValidateLink = rLink;
+}
+
+/*************************************************************************
+|*
+|* dialog for changing the positions of the rotation
+|* angle and the rotation angle of the graphic objects
+|*
+\************************************************************************/
+SvxAngleTabPage::SvxAngleTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/rotationtabpage.ui", "Rotation", rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_aCtlRect(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlRect(new weld::CustomWeld(*m_xBuilder, "CTL_RECT", m_aCtlRect))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_ANGLE"))
+ , m_xNfAngle(m_xBuilder->weld_metric_spin_button("NF_ANGLE", FieldUnit::DEGREE))
+ , m_xCtlAngle(new svx::DialControl)
+ , m_xCtlAngleWin(new weld::CustomWeld(*m_xBuilder, "CTL_ANGLE", *m_xCtlAngle))
+{
+ // calculate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ ePoolUnit = pPool->GetMetric(SID_ATTR_TRANSFORM_POS_X);
+
+ m_xCtlAngle->SetLinkedField(m_xNfAngle.get(), 2);
+}
+
+SvxAngleTabPage::~SvxAngleTabPage()
+{
+}
+
+void SvxAngleTabPage::Construct()
+{
+ DBG_ASSERT(pView, "No valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrPosX, eDlgUnit, true);
+ SetFieldUnit(*m_xMtrPosY, eDlgUnit, true);
+
+ if (FieldUnit::MILE == eDlgUnit || FieldUnit::KM == eDlgUnit)
+ {
+ m_xMtrPosX->set_digits(3);
+ m_xMtrPosY->set_digits(3);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // Take anchor into account (Writer)
+ const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(pView->GetModel()->GetUIScale());
+ TransfrmHelper::ScaleRect(maRange, aUIScale);
+
+ // take UI units into account
+ sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect(maRange, nDigits, ePoolUnit, eDlgUnit);
+
+ if(!pView->IsRotateAllowed())
+ {
+ m_xFlPosition->set_sensitive(false);
+ m_xFlAngle->set_sensitive(false);
+ }
+}
+
+bool SvxAngleTabPage::FillItemSet(SfxItemSet* rSet)
+{
+ bool bModified = false;
+
+ if (m_xCtlAngle->IsValueModified() || m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+ const double fTmpX((GetCoreValue(*m_xMtrPosX, ePoolUnit) + maAnchor.getX()) * fUIScale);
+ const double fTmpY((GetCoreValue(*m_xMtrPosY, ePoolUnit) + maAnchor.getY()) * fUIScale);
+
+ rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ANGLE), m_xCtlAngle->GetRotation()));
+ rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_X), basegfx::fround(fTmpX)));
+ rSet->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_ROT_Y), basegfx::fround(fTmpY)));
+
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+
+void SvxAngleTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+
+ const SfxPoolItem* pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ROT_X );
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosX->set_text(OUString());
+ }
+
+ pItem = GetItem(*rAttrs, SID_ATTR_TRANSFORM_ROT_Y);
+ if(pItem)
+ {
+ const double fTmp((static_cast<double>(static_cast<const SfxInt32Item*>(pItem)->GetValue()) - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrPosY->set_text(OUString());
+ }
+
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_ANGLE );
+ if(pItem)
+ {
+ m_xCtlAngle->SetRotation(static_cast<const SfxInt32Item*>(pItem)->GetValue());
+ }
+ else
+ {
+ m_xCtlAngle->SetRotation(0);
+ }
+ m_xCtlAngle->SaveValue();
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+}
+
+std::unique_ptr<SfxTabPage> SvxAngleTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxAngleTabPage>(pPage, pController, *rSet);
+}
+
+void SvxAngleTabPage::ActivatePage(const SfxItemSet& rSet)
+{
+ SfxBoolItem const * bPosProtect = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( GetWhich(SID_ATTR_TRANSFORM_PROTECT_POS ) , false, reinterpret_cast<SfxPoolItem const **>(&bPosProtect) ))
+ {
+ m_xFlPosition->set_sensitive(!bPosProtect->GetValue());
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+}
+
+DeactivateRC SvxAngleTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+void SvxAngleTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea != m_aCtlRect.GetDrawingArea())
+ return;
+
+ switch(eRP)
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+}
+
+/*************************************************************************
+|*
+|* dialog for changing slant and corner radius
+|*
+\************************************************************************/
+SvxSlantTabPage::SvxSlantTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/slantcornertabpage.ui", "SlantAndCornerRadius", &rInAttrs)
+ , pView(nullptr)
+ , eDlgUnit(FieldUnit::NONE)
+ , m_xFlRadius(m_xBuilder->weld_widget("FL_RADIUS"))
+ , m_xMtrRadius(m_xBuilder->weld_metric_spin_button("MTR_FLD_RADIUS", FieldUnit::CM))
+ , m_xFlAngle(m_xBuilder->weld_widget("FL_SLANT"))
+ , m_xMtrAngle(m_xBuilder->weld_metric_spin_button("MTR_FLD_ANGLE", FieldUnit::DEGREE))
+{
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlGroups[i] = m_xBuilder->weld_widget("controlgroups" + OString::number(i+1));
+ m_aControlGroupX[i] = m_xBuilder->weld_widget("controlgroupx" + OString::number(i+1));
+ m_aControlX[i] = m_xBuilder->weld_metric_spin_button("controlx" + OString::number(i+1), FieldUnit::CM);
+ m_aControlGroupY[i] = m_xBuilder->weld_widget("controlgroupy" + OString::number(i+1));
+ m_aControlY[i] = m_xBuilder->weld_metric_spin_button("controly" + OString::number(i+1), FieldUnit::CM);
+ }
+
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = rInAttrs.GetPool();
+ assert(pPool && "no pool (!)");
+ ePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+}
+
+SvxSlantTabPage::~SvxSlantTabPage()
+{
+}
+
+void SvxSlantTabPage::Construct()
+{
+ // get the range
+ DBG_ASSERT(pView, "no valid view (!)");
+ eDlgUnit = GetModuleFieldUnit(GetItemSet());
+ SetFieldUnit(*m_xMtrRadius, eDlgUnit, true);
+ for (int i = 0; i < 2; ++i)
+ {
+ SetFieldUnit(*m_aControlX[i], eDlgUnit, true);
+ SetFieldUnit(*m_aControlY[i], eDlgUnit, true);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ }
+}
+
+bool SvxSlantTabPage::FillItemSet(SfxItemSet* rAttrs)
+{
+ bool bModified = false;
+
+ if (m_xMtrRadius->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = pView->GetModel()->GetUIScale();
+ long nTmp = long(GetCoreValue(*m_xMtrRadius, ePoolUnit) * aUIScale);
+
+ rAttrs->Put( makeSdrEckenradiusItem( nTmp ) );
+ bModified = true;
+ }
+
+ if (m_xMtrAngle->get_value_changed_from_saved())
+ {
+ sal_Int32 nValue = static_cast<sal_Int32>(m_xMtrAngle->get_value(FieldUnit::NONE));
+ rAttrs->Put( SfxInt32Item( SID_ATTR_TRANSFORM_SHEAR, nValue ) );
+ bModified = true;
+ }
+
+ if( bModified )
+ {
+ // set reference points
+ ::tools::Rectangle aObjectRect(pView->GetAllMarkedRect());
+ pView->GetSdrPageView()->LogicToPagePos(aObjectRect);
+ Point aPt = aObjectRect.Center();
+
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X, aPt.X()));
+ rAttrs->Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y, aPt.Y()));
+ rAttrs->Put( SfxBoolItem( SID_ATTR_TRANSFORM_SHEAR_VERTICAL, false ) );
+ }
+
+ bool bControlPointsChanged = false;
+ for (int i = 0; i < 2; ++i)
+ {
+ bControlPointsChanged |= (m_aControlX[i]->get_value_changed_from_saved() ||
+ m_aControlY[i]->get_value_changed_from_saved());
+ }
+
+ if (!bControlPointsChanged)
+ return bModified;
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(nullptr == pView)
+ {
+ break;
+ }
+
+ if(0 == pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+ SdrModel& rModel(rSdrObjCustomShape.getSdrModelFromSdrObject());
+ std::unique_ptr<SdrUndoAction> pUndo;
+ if (rModel.IsUndoEnabled())
+ pUndo = rModel.GetSdrUndoFactory().CreateUndoAttrObject(rSdrObjCustomShape);
+
+ if(pUndo)
+ {
+ rModel.BegUndo(pUndo->GetComment());
+ }
+
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (m_aControlX[i]->get_value_changed_from_saved() || m_aControlY[i]->get_value_changed_from_saved())
+ {
+ Point aNewPosition(GetCoreValue(*m_aControlX[i], ePoolUnit),
+ GetCoreValue(*m_aControlY[i], ePoolUnit));
+ aNewPosition.Move(aLogicRect.Left(), aLogicRect.Top());
+
+ css::awt::Point aPosition;
+ aPosition.X = aNewPosition.X();
+ aPosition.Y = aNewPosition.Y();
+
+ aShape.SetHandleControllerPosition(i, aPosition);
+ }
+ }
+
+ rSdrObjCustomShape.SetChanged();
+ rSdrObjCustomShape.BroadcastObjectChange();
+ bModified = true;
+
+ if (pUndo)
+ {
+ rModel.AddUndo(std::move(pUndo));
+ rModel.EndUndo();
+ }
+ }
+
+ return bModified;
+}
+
+void SvxSlantTabPage::Reset(const SfxItemSet* rAttrs)
+{
+ // if the view has selected objects, items with SfxItemState::DEFAULT need to be disabled
+ const SfxPoolItem* pItem;
+
+ // corner radius
+ if(!pView->IsEdgeRadiusAllowed())
+ {
+ m_xMtrRadius->set_text("");
+ m_xFlRadius->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SDRATTR_ECKENRADIUS );
+
+ if( pItem )
+ {
+ const double fUIScale(double(pView->GetModel()->GetUIScale()));
+ const double fTmp(static_cast<double>(static_cast<const SdrMetricItem*>(pItem)->GetValue()) / fUIScale);
+ SetMetricValue(*m_xMtrRadius, basegfx::fround(fTmp), ePoolUnit);
+ }
+ else
+ {
+ m_xMtrRadius->set_text("");
+ }
+ }
+
+ m_xMtrRadius->save_value();
+
+ // slant: angle
+ if( !pView->IsShearAllowed() )
+ {
+ m_xMtrAngle->set_text( "" );
+ m_xFlAngle->set_sensitive(false);
+ }
+ else
+ {
+ pItem = GetItem( *rAttrs, SID_ATTR_TRANSFORM_SHEAR );
+
+ if( pItem )
+ {
+ m_xMtrAngle->set_value(static_cast<const SfxInt32Item*>(pItem)->GetValue(), FieldUnit::NONE);
+ }
+ else
+ {
+ m_xMtrAngle->set_text("");
+ }
+ }
+
+ m_xMtrAngle->save_value();
+
+ bool bSelectionIsSdrObjCustomShape(false);
+
+ while(true)
+ {
+ if(1 != pView->GetMarkedObjectList().GetMarkCount())
+ {
+ break;
+ }
+
+ SdrObject* pCandidate(pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj());
+
+ if(nullptr == pCandidate)
+ {
+ break;
+ }
+
+ if(nullptr == dynamic_cast< SdrObjCustomShape* >(pCandidate))
+ {
+ break;
+ }
+
+ bSelectionIsSdrObjCustomShape = true;
+ break;
+ }
+
+ if(bSelectionIsSdrObjCustomShape)
+ {
+ SdrObjCustomShape& rSdrObjCustomShape(
+ static_cast< SdrObjCustomShape& >(
+ *pView->GetMarkedObjectList().GetMark(0)->GetMarkedSdrObj()));
+
+ //save geometry
+ SdrCustomShapeGeometryItem aInitialGeometry(rSdrObjCustomShape.GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY));
+ EnhancedCustomShape2d aShape(rSdrObjCustomShape);
+
+ for (int i = 0; i < 2; ++i)
+ {
+ Point aInitialPosition;
+ if (!aShape.GetHandlePosition(i, aInitialPosition))
+ break;
+ m_aControlGroups[i]->set_sensitive(true);
+ css::awt::Point aPosition;
+
+ aPosition.X = SAL_MAX_INT32/2;
+ aPosition.Y = SAL_MAX_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMaxPosition;
+ aShape.GetHandlePosition(i, aMaxPosition);
+
+ aPosition.X = SAL_MIN_INT32/2;
+ aPosition.Y = SAL_MIN_INT32/2;
+ aShape.SetHandleControllerPosition(i, aPosition);
+ Point aMinPosition;
+ aShape.GetHandlePosition(i, aMinPosition);
+
+ ::tools::Rectangle aLogicRect = aShape.GetLogicRect();
+ aInitialPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMaxPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+ aMinPosition.Move(-aLogicRect.Left(), -aLogicRect.Top());
+
+ SetMetricValue(*m_aControlX[i], aInitialPosition.X(), ePoolUnit);
+ SetMetricValue(*m_aControlY[i], aInitialPosition.Y(), ePoolUnit);
+
+ if (aMaxPosition.X() == aMinPosition.X())
+ m_aControlGroupX[i]->set_sensitive(false);
+ else
+ m_aControlX[i]->set_range(aMinPosition.X(), aMaxPosition.X(), FieldUnit::MM);
+ if (aMaxPosition.Y() == aMinPosition.Y())
+ m_aControlGroupY[i]->set_sensitive(false);
+ else
+ m_aControlY[i]->set_range(aMinPosition.Y(), aMaxPosition.Y(), FieldUnit::MM);
+ }
+
+ //restore geometry
+ rSdrObjCustomShape.SetMergedItem(aInitialGeometry);
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ m_aControlX[i]->save_value();
+ m_aControlY[i]->save_value();
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSlantTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxSlantTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxSlantTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ SfxBoolItem const * bPosProtect = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( GetWhich(SID_ATTR_TRANSFORM_PROTECT_POS ) , false, reinterpret_cast<SfxPoolItem const **>(&bPosProtect) ))
+ {
+ m_xFlAngle->set_sensitive(!bPosProtect->GetValue());
+ }
+ SfxBoolItem const * bSizeProtect = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( GetWhich(SID_ATTR_TRANSFORM_PROTECT_SIZE ) , false, reinterpret_cast<SfxPoolItem const **>(&bSizeProtect) ))
+ {
+ m_xFlAngle->set_sensitive(!bSizeProtect->GetValue());
+ }
+
+}
+
+DeactivateRC SvxSlantTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if(_pSet)
+ {
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+/*************************************************************************
+|*
+|* Dialog for changing position and size of graphic objects
+|*
+\************************************************************************/
+SvxPositionSizeTabPage::SvxPositionSizeTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SvxTabPage(pPage, pController, "cui/ui/possizetabpage.ui", "PositionAndSize", rInAttrs)
+ , mrOutAttrs(rInAttrs)
+ , mpView(nullptr)
+ , meDlgUnit(FieldUnit::NONE)
+ , mnProtectSizeState(TRISTATE_FALSE)
+ , mbPageDisabled(false)
+ , mbProtectDisabled(false)
+ , mbSizeDisabled(false)
+ , mbAdjustDisabled(true)
+ , mbIgnoreAutoGrowWidth(true)
+ , mbIgnoreAutoGrowHeight(true)
+ , mfOldWidth(0.0)
+ , mfOldHeight(0.0)
+ , m_aCtlPos(this)
+ , m_aCtlSize(this)
+ , m_xFlPosition(m_xBuilder->weld_widget("FL_POSITION"))
+ , m_xMtrPosX(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_X", FieldUnit::CM))
+ , m_xMtrPosY(m_xBuilder->weld_metric_spin_button("MTR_FLD_POS_Y", FieldUnit::CM))
+ , m_xCtlPos(new weld::CustomWeld(*m_xBuilder, "CTL_POSRECT", m_aCtlPos))
+ , m_xFlSize(m_xBuilder->weld_widget("FL_SIZE"))
+ , m_xFtWidth(m_xBuilder->weld_label("FT_WIDTH"))
+ , m_xMtrWidth(m_xBuilder->weld_metric_spin_button("MTR_FLD_WIDTH", FieldUnit::CM))
+ , m_xFtHeight(m_xBuilder->weld_label("FT_HEIGHT"))
+ , m_xMtrHeight(m_xBuilder->weld_metric_spin_button("MTR_FLD_HEIGHT", FieldUnit::CM))
+ , m_xCbxScale(m_xBuilder->weld_check_button("CBX_SCALE"))
+ , m_xCtlSize(new weld::CustomWeld(*m_xBuilder, "CTL_SIZERECT", m_aCtlSize))
+ , m_xFlProtect(m_xBuilder->weld_widget("FL_PROTECT"))
+ , m_xTsbPosProtect(m_xBuilder->weld_check_button("TSB_POSPROTECT"))
+ , m_xTsbSizeProtect(m_xBuilder->weld_check_button("TSB_SIZEPROTECT"))
+ , m_xFlAdjust(m_xBuilder->weld_widget("FL_ADJUST"))
+ , m_xTsbAutoGrowWidth(m_xBuilder->weld_check_button("TSB_AUTOGROW_WIDTH"))
+ , m_xTsbAutoGrowHeight(m_xBuilder->weld_check_button("TSB_AUTOGROW_HEIGHT"))
+{
+ // this page needs ExchangeSupport
+ SetExchangeSupport();
+
+ // evaluate PoolUnit
+ SfxItemPool* pPool = mrOutAttrs.GetPool();
+ DBG_ASSERT( pPool, "no pool (!)" );
+ mePoolUnit = pPool->GetMetric( SID_ATTR_TRANSFORM_POS_X );
+
+ m_aCtlPos.SetActualRP(RectPoint::LT);
+ m_aCtlSize.SetActualRP(RectPoint::LT);
+ meRP = RectPoint::LT; // see above
+
+ m_xMtrWidth->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeWidthHdl ) );
+ m_xMtrHeight->connect_value_changed( LINK( this, SvxPositionSizeTabPage, ChangeHeightHdl ) );
+ m_xCbxScale->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickAutoHdl ) );
+
+ m_xFlAdjust->set_sensitive(false);
+
+ // #i2379# disable controls when protected
+ m_xTsbPosProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangePosProtectHdl ) );
+ m_xTsbSizeProtect->connect_toggled( LINK( this, SvxPositionSizeTabPage, ChangeSizeProtectHdl ) );
+}
+
+SvxPositionSizeTabPage::~SvxPositionSizeTabPage()
+{
+}
+
+void SvxPositionSizeTabPage::Construct()
+{
+ // get range and work area
+ DBG_ASSERT( mpView, "no valid view (!)" );
+ meDlgUnit = GetModuleFieldUnit( GetItemSet() );
+ SetFieldUnit( *m_xMtrPosX, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrPosY, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrWidth, meDlgUnit, true );
+ SetFieldUnit( *m_xMtrHeight, meDlgUnit, true );
+
+ if(FieldUnit::MILE == meDlgUnit || FieldUnit::KM == meDlgUnit)
+ {
+ m_xMtrPosX->set_digits( 3 );
+ m_xMtrPosY->set_digits( 3 );
+ m_xMtrWidth->set_digits( 3 );
+ m_xMtrHeight->set_digits( 3 );
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetWorkArea());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maWorkRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // take anchor into account (Writer)
+ const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
+
+ if(rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ maAnchor = basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y());
+
+ if(!maAnchor.equalZero()) // -> Writer
+ {
+ for(size_t i = 1; i < rMarkList.GetMarkCount(); ++i)
+ {
+ pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
+
+ if(maAnchor != basegfx::B2DPoint(pObj->GetAnchorPos().X(), pObj->GetAnchorPos().Y()))
+ {
+ // different anchor positions
+ m_xMtrPosX->set_text("");
+ m_xMtrPosY->set_text("");
+ mbPageDisabled = true;
+ return;
+ }
+ }
+
+ // translate ranges about anchor
+ maRange = basegfx::B2DRange(maRange.getMinimum() - maAnchor, maRange.getMaximum() - maAnchor);
+ maWorkRange = basegfx::B2DRange(maWorkRange.getMinimum() - maAnchor, maWorkRange.getMaximum() - maAnchor);
+ }
+ }
+
+ // this should happen via SID_ATTR_TRANSFORM_AUTOSIZE
+ if(1 == rMarkList.GetMarkCount())
+ {
+ const SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ const SdrObjKind eKind(static_cast<SdrObjKind>(pObj->GetObjIdentifier()));
+
+ if((pObj->GetObjInventor() == SdrInventor::Default) &&
+ (OBJ_TEXT == eKind || OBJ_TITLETEXT == eKind || OBJ_OUTLINETEXT == eKind) &&
+ pObj->HasText())
+ {
+ mbAdjustDisabled = false;
+
+ m_xFlAdjust->set_sensitive(true);
+
+ m_xTsbAutoGrowWidth->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+ m_xTsbAutoGrowHeight->connect_toggled( LINK( this, SvxPositionSizeTabPage, ClickSizeProtectHdl ) );
+
+ // is used as flag to evaluate if its selectable
+ mbIgnoreAutoGrowWidth = false;
+ mbIgnoreAutoGrowHeight = false;
+ }
+ }
+
+ // take scale into account
+ const Fraction aUIScale(mpView->GetModel()->GetUIScale());
+ TransfrmHelper::ScaleRect( maWorkRange, aUIScale );
+ TransfrmHelper::ScaleRect( maRange, aUIScale );
+
+ // take UI units into account
+ const sal_uInt16 nDigits(m_xMtrPosX->get_digits());
+ TransfrmHelper::ConvertRect( maWorkRange, nDigits, mePoolUnit, meDlgUnit );
+ TransfrmHelper::ConvertRect( maRange, nDigits, mePoolUnit, meDlgUnit );
+
+ SetMinMaxPosition();
+}
+
+
+bool SvxPositionSizeTabPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ bool bModified(false);
+
+ if ( m_xMtrWidth->has_focus() )
+ {
+ ChangeWidthHdl( *m_xMtrWidth );
+ }
+
+ if ( m_xMtrHeight->has_focus() )
+ {
+ ChangeHeightHdl( *m_xMtrHeight );
+ }
+
+ if( !mbPageDisabled )
+ {
+ if (m_xMtrPosX->get_value_changed_from_saved() || m_xMtrPosY->get_value_changed_from_saved())
+ {
+ const double fUIScale(double(mpView->GetModel()->GetUIScale()));
+ double fX((GetCoreValue( *m_xMtrPosX, mePoolUnit ) + maAnchor.getX()) * fUIScale);
+ double fY((GetCoreValue( *m_xMtrPosY, mePoolUnit ) + maAnchor.getY()) * fUIScale);
+
+ { // #i75273#
+ ::tools::Rectangle aTempRect(mpView->GetAllMarkedRect());
+ mpView->GetSdrPageView()->LogicToPagePos(aTempRect);
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ // #101581# GetTopLeftPosition(...) needs coordinates after UI scaling, in real PagePositions
+ GetTopLeftPosition(fX, fY, maRange);
+
+ rOutAttrs->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_POS_X), basegfx::fround(fX)));
+ rOutAttrs->Put(SfxInt32Item(GetWhich(SID_ATTR_TRANSFORM_POS_Y), basegfx::fround(fY)));
+
+ bModified = true;
+ }
+
+ if (m_xTsbPosProtect->get_state_changed_from_saved())
+ {
+ if( m_xTsbPosProtect->get_inconsistent() )
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_POS );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
+ m_xTsbPosProtect->get_active() ) );
+ }
+
+ bModified = true;
+ }
+ }
+
+ if (m_xMtrWidth->get_value_changed_from_saved() || m_xMtrHeight->get_value_changed_from_saved())
+ {
+ Fraction aUIScale = mpView->GetModel()->GetUIScale();
+
+ // get Width
+ double nWidth = static_cast<double>(m_xMtrWidth->get_value(FieldUnit::MM_100TH));
+ long lWidth = long(nWidth * static_cast<double>(aUIScale));
+ lWidth = OutputDevice::LogicToLogic( lWidth, MapUnit::Map100thMM, mePoolUnit );
+ lWidth = static_cast<long>(m_xMtrWidth->denormalize( lWidth ));
+
+ // get Height
+ double nHeight = static_cast<double>(m_xMtrHeight->get_value(FieldUnit::MM_100TH));
+ long lHeight = long(nHeight * static_cast<double>(aUIScale));
+ lHeight = OutputDevice::LogicToLogic( lHeight, MapUnit::Map100thMM, mePoolUnit );
+ lHeight = static_cast<long>(m_xMtrHeight->denormalize( lHeight ));
+
+ // put Width & Height to itemset
+ rOutAttrs->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_WIDTH ), static_cast<sal_uInt32>(lWidth) ) );
+ rOutAttrs->Put( SfxUInt32Item( GetWhich( SID_ATTR_TRANSFORM_HEIGHT ), static_cast<sal_uInt32>(lHeight) ) );
+ rOutAttrs->Put( SfxUInt16Item( GetWhich( SID_ATTR_TRANSFORM_SIZE_POINT ), sal::static_int_cast< sal_uInt16 >( meRP ) ) );
+ bModified = true;
+ }
+
+ if (m_xTsbSizeProtect->get_state_changed_from_saved())
+ {
+ if ( m_xTsbSizeProtect->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
+ m_xTsbSizeProtect->get_active() ) );
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowWidth->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowWidth)
+ {
+ if( m_xTsbAutoGrowWidth->get_inconsistent() )
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOWIDTH );
+ else
+ rOutAttrs->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_AUTOWIDTH ),
+ m_xTsbAutoGrowWidth->get_active() ) );
+ }
+ bModified = true;
+ }
+
+ if (m_xTsbAutoGrowHeight->get_state_changed_from_saved())
+ {
+ if (!mbIgnoreAutoGrowHeight)
+ {
+ if (m_xTsbAutoGrowHeight->get_inconsistent())
+ {
+ rOutAttrs->InvalidateItem( SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ }
+ else
+ {
+ rOutAttrs->Put(
+ SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_AUTOHEIGHT ),
+ m_xTsbAutoGrowHeight->get_active() ) );
+ }
+ }
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxPositionSizeTabPage::Reset( const SfxItemSet* )
+{
+ const SfxPoolItem* pItem;
+ const double fUIScale(double(mpView->GetModel()->GetUIScale()));
+
+ if ( !mbPageDisabled )
+ {
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_X );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getX()) / fUIScale);
+ SetMetricValue(*m_xMtrPosX, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_POS_Y );
+ if ( pItem )
+ {
+ const double fTmp((static_cast<const SfxInt32Item*>(pItem)->GetValue() - maAnchor.getY()) / fUIScale);
+ SetMetricValue(*m_xMtrPosY, basegfx::fround(fTmp), mePoolUnit);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_POS );
+ if ( pItem )
+ {
+ bool bProtected = static_cast<const SfxBoolItem*>( pItem )->GetValue();
+ m_xTsbPosProtect->set_active(bProtected);
+ }
+ else
+ {
+ m_xTsbPosProtect->set_inconsistent(true);
+ }
+
+ m_xTsbPosProtect->save_state();
+ m_aCtlPos.Reset();
+
+ // #i2379# Disable controls for protected objects
+ ChangePosProtectHdl(*m_xTsbPosProtect);
+ }
+
+ { // #i75273# set width
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_WIDTH );
+ mfOldWidth = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpWidth((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldWidth), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrWidth->get_digits())
+ fTmpWidth *= pow(10.0, m_xMtrWidth->get_digits());
+ m_xMtrWidth->set_value(static_cast<int>(fTmpWidth), FieldUnit::MM_100TH);
+ }
+
+ { // #i75273# set height
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_HEIGHT );
+ mfOldHeight = std::max( pItem ? static_cast<double>(static_cast<const SfxUInt32Item*>(pItem)->GetValue()) : 0.0, 1.0 );
+ double fTmpHeight((OutputDevice::LogicToLogic(static_cast<sal_Int32>(mfOldHeight), mePoolUnit, MapUnit::Map100thMM)) / fUIScale);
+ if (m_xMtrHeight->get_digits())
+ fTmpHeight *= pow(10.0, m_xMtrHeight->get_digits());
+ m_xMtrHeight->set_value(static_cast<int>(fTmpHeight), FieldUnit::MM_100TH);
+ }
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_PROTECT_SIZE );
+ if ( pItem )
+ {
+ m_xTsbSizeProtect->set_active(static_cast<const SfxBoolItem*>(pItem)->GetValue());
+ }
+ else
+ m_xTsbSizeProtect->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOWIDTH );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowWidth->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowWidth->set_inconsistent(true);
+
+ pItem = GetItem( mrOutAttrs, SID_ATTR_TRANSFORM_AUTOHEIGHT );
+ if ( pItem )
+ {
+ m_xTsbAutoGrowHeight->set_active(static_cast<const SfxBoolItem*>( pItem )->GetValue());
+ }
+ else
+ m_xTsbAutoGrowHeight->set_inconsistent(true);
+
+ // Is matching set?
+ OUString aStr = GetUserData();
+ m_xCbxScale->set_active(aStr.toInt32() != 0);
+
+ m_xMtrPosX->save_value();
+ m_xMtrPosY->save_value();
+ m_xMtrWidth->save_value();
+ m_xMtrHeight->save_value();
+
+ m_xTsbSizeProtect->save_state();
+ m_xTsbAutoGrowWidth->save_state();
+ m_xTsbAutoGrowHeight->save_state();
+ ClickSizeProtectHdl(*m_xTsbAutoGrowHeight);
+
+ // #i2379# Disable controls for protected objects
+ ChangeSizeProtectHdl(*m_xTsbSizeProtect);
+}
+
+std::unique_ptr<SfxTabPage> SvxPositionSizeTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rOutAttrs)
+{
+ return std::make_unique<SvxPositionSizeTabPage>(pPage, pController, *rOutAttrs);
+}
+
+void SvxPositionSizeTabPage::ActivatePage( const SfxItemSet& rSet )
+{
+ SfxRectangleItem const * pRectItem = nullptr;
+
+ if( SfxItemState::SET == rSet.GetItemState( GetWhich( SID_ATTR_TRANSFORM_INTERN ) , false, reinterpret_cast<SfxPoolItem const **>(&pRectItem) ) )
+ {
+ { // #i75273#
+ const ::tools::Rectangle aTempRect(pRectItem->GetValue());
+ maRange = vcl::unotools::b2DRectangleFromRectangle(aTempRect);
+ }
+
+ SetMinMaxPosition();
+ }
+}
+
+
+DeactivateRC SvxPositionSizeTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ {
+ double fX(static_cast<double>(m_xMtrPosX->get_value(FieldUnit::NONE)));
+ double fY(static_cast<double>(m_xMtrPosY->get_value(FieldUnit::NONE)));
+
+ GetTopLeftPosition(fX, fY, maRange);
+ const ::tools::Rectangle aOutRectangle(
+ basegfx::fround(fX), basegfx::fround(fY),
+ basegfx::fround(fX + maRange.getWidth()), basegfx::fround(fY + maRange.getHeight()));
+ _pSet->Put(SfxRectangleItem(SID_ATTR_TRANSFORM_INTERN, aOutRectangle));
+ _pSet->Put(SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_POS ),
+ m_xTsbPosProtect->get_state() == TRISTATE_TRUE ));
+ _pSet->Put(SfxBoolItem( GetWhich( SID_ATTR_TRANSFORM_PROTECT_SIZE ),
+ m_xTsbSizeProtect->get_state() == TRISTATE_TRUE ));
+ FillItemSet(_pSet);
+ }
+
+ return DeactivateRC::LeavePage;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangePosProtectHdl, weld::ToggleButton&, void)
+{
+ // #106572# Remember user's last choice
+ m_xTsbSizeProtect->set_state(m_xTsbPosProtect->get_state() == TRISTATE_TRUE ? TRISTATE_TRUE : mnProtectSizeState);
+ UpdateControlStates();
+}
+
+
+void SvxPositionSizeTabPage::UpdateControlStates()
+{
+ const bool bPosProtect = m_xTsbPosProtect->get_state() == TRISTATE_TRUE;
+ const bool bSizeProtect = m_xTsbSizeProtect->get_state() == TRISTATE_TRUE;
+ const bool bHeightChecked = !mbIgnoreAutoGrowHeight && (m_xTsbAutoGrowHeight->get_active());
+ const bool bWidthChecked = !mbIgnoreAutoGrowWidth && (m_xTsbAutoGrowWidth->get_active());
+
+ m_xFlPosition->set_sensitive(!bPosProtect && !mbPageDisabled);
+
+ m_xTsbPosProtect->set_sensitive( !mbProtectDisabled && !mbPageDisabled );
+
+ m_xFlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect );
+
+ m_xFtWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+ m_xMtrWidth->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bWidthChecked );
+
+ m_xFtHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+ m_xMtrHeight->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked );
+
+ m_xCbxScale->set_sensitive( !mbSizeDisabled && !bSizeProtect && !bHeightChecked && !bWidthChecked );
+ m_xCtlSize->set_sensitive( !mbSizeDisabled && !bSizeProtect && (!bHeightChecked || !bWidthChecked) );
+
+ m_xFlProtect->set_sensitive( !mbProtectDisabled );
+ m_xTsbSizeProtect->set_sensitive( !mbProtectDisabled && !bPosProtect );
+
+ m_xFlAdjust->set_sensitive( !mbSizeDisabled && !bSizeProtect && !mbAdjustDisabled );
+
+ m_aCtlSize.Invalidate();
+ m_aCtlPos.Invalidate();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeSizeProtectHdl, weld::ToggleButton&, void)
+{
+ if (m_xTsbSizeProtect->get_sensitive())
+ {
+ // #106572# Remember user's last choice
+
+ // Note: this works only as long as the dialog is open. When
+ // the user closes the dialog, there is no way to remember
+ // whether size was enabled or disabled before pos protect was
+ // clicked. Thus, if pos protect is selected, the dialog is
+ // closed and reopened again, unchecking pos protect will
+ // always uncheck size protect, too. That's life.
+ mnProtectSizeState = m_xTsbSizeProtect->get_state();
+ }
+
+ UpdateControlStates();
+}
+
+void SvxPositionSizeTabPage::SetMinMaxPosition()
+{
+ // position
+ double fLeft(maWorkRange.getMinX());
+ double fTop(maWorkRange.getMinY());
+ double fRight(maWorkRange.getMaxX());
+ double fBottom(maWorkRange.getMaxY());
+
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fRight -= maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fLeft += maRange.getWidth();
+ fBottom -= maRange.getHeight();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight() / 2.0;
+ fBottom -= maRange.getHeight() / 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fRight -= maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fLeft += maRange.getWidth() / 2.0;
+ fRight -= maRange.getWidth() / 2.0;
+ fTop += maRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fLeft += maRange.getWidth();
+ fTop += maRange.getHeight();
+ break;
+ }
+ }
+
+ const double fMaxLong(static_cast<double>(vcl::ConvertValue( LONG_MAX, 0, MapUnit::Map100thMM, meDlgUnit ) - 1));
+ fLeft = std::clamp(fLeft, -fMaxLong, fMaxLong);
+ fRight = std::clamp(fRight, -fMaxLong, fMaxLong);
+ fTop = std::clamp(fTop, - fMaxLong, fMaxLong);
+ fBottom = std::clamp(fBottom, -fMaxLong, fMaxLong);
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrPosX->set_range(basegfx::fround64(fLeft), basegfx::fround64(fRight), FieldUnit::NONE);
+ m_xMtrPosY->set_range(basegfx::fround64(fTop), basegfx::fround64(fBottom), FieldUnit::NONE);
+
+ // size
+ fLeft = maWorkRange.getMinX();
+ fTop = maWorkRange.getMinY();
+ fRight = maWorkRange.getMaxX();
+ fBottom = maWorkRange.getMaxY();
+ double fNewX(0);
+ double fNewY(0);
+
+ switch (m_aCtlSize.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( maRange.getMinY() - fTop );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::MM:
+ {
+ const double f1(maRange.getCenter().getX() - fLeft);
+ const double f2(fRight - maRange.getCenter().getX());
+ const double f3(std::min(f1, f2));
+ const double f4(maRange.getCenter().getY() - fTop);
+ const double f5(fBottom - maRange.getCenter().getY());
+ const double f6(std::min(f4, f5));
+
+ fNewX = f3 * 2.0;
+ fNewY = f6 * 3.0;
+
+ break;
+ }
+ case RectPoint::RM:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = std::min( maRange.getCenter().getY() - fTop, fBottom - maRange.getCenter().getY() ) * 2.0;
+ break;
+ }
+ case RectPoint::LB:
+ {
+ fNewX = maWorkRange.getWidth() - ( maRange.getMinX() - fLeft );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ fNewX = std::min( maRange.getCenter().getX() - fLeft, fRight - maRange.getCenter().getX() ) * 2.0;
+ fNewY = maWorkRange.getHeight() - ( maRange.getMaxY() - fBottom );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ fNewX = maWorkRange.getWidth() - ( fRight - maRange.getMaxX() );
+ fNewY = maWorkRange.getHeight() - ( fBottom - maRange.getMaxY() );
+ break;
+ }
+ }
+
+ // #i75273# normalizing when setting the min/max values was wrong, removed
+ m_xMtrWidth->set_max(basegfx::fround64(fNewX), FieldUnit::NONE);
+ m_xMtrHeight->set_max(basegfx::fround64(fNewY), FieldUnit::NONE);
+}
+
+void SvxPositionSizeTabPage::GetTopLeftPosition(double& rfX, double& rfY, const basegfx::B2DRange& rRange)
+{
+ switch (m_aCtlPos.GetActualRP())
+ {
+ case RectPoint::LT:
+ {
+ break;
+ }
+ case RectPoint::MT:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ break;
+ }
+ case RectPoint::RT:
+ {
+ rfX -= rRange.getWidth();
+ break;
+ }
+ case RectPoint::LM:
+ {
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::MM:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::RM:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getCenter().getY() - rRange.getMinY();
+ break;
+ }
+ case RectPoint::LB:
+ {
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::MB:
+ {
+ rfX -= rRange.getCenter().getX() - rRange.getMinX();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ case RectPoint::RB:
+ {
+ rfX -= rRange.getWidth();
+ rfY -= rRange.getHeight();
+ break;
+ }
+ }
+}
+
+void SvxPositionSizeTabPage::PointChanged(weld::DrawingArea* pDrawingArea, RectPoint eRP)
+{
+ if (pDrawingArea == m_aCtlPos.GetDrawingArea())
+ {
+ SetMinMaxPosition();
+ switch( eRP )
+ {
+ case RectPoint::LT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RT:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMinY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RM:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getCenter().getY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::LB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMinX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::MB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getCenter().getX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ case RectPoint::RB:
+ {
+ m_xMtrPosX->set_value( basegfx::fround64(maRange.getMaxX()), FieldUnit::NONE );
+ m_xMtrPosY->set_value( basegfx::fround64(maRange.getMaxY()), FieldUnit::NONE );
+ break;
+ }
+ }
+ }
+ else
+ {
+ meRP = eRP;
+ SetMinMaxPosition();
+ }
+}
+
+void SvxPositionSizeTabPage::DisableResize()
+{
+ mbSizeDisabled = true;
+}
+
+
+void SvxPositionSizeTabPage::DisableProtect()
+{
+ mbProtectDisabled = true;
+}
+
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeWidthHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(m_xMtrWidth->get_value(FieldUnit::NONE))) / mfOldWidth));
+ int nMin, nMax;
+ m_xMtrHeight->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nHeight <= nMax)
+ {
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+ else
+ {
+ nHeight = nMax;
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+
+ const sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(nHeight)) / mfOldHeight));
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ChangeHeightHdl, weld::MetricSpinButton&, void)
+{
+ if( !(m_xCbxScale->get_active() && m_xCbxScale->get_sensitive()) )
+ return;
+
+ sal_Int64 nWidth(basegfx::fround64((mfOldWidth * static_cast<double>(m_xMtrHeight->get_value(FieldUnit::NONE))) / mfOldHeight));
+ int nMin, nMax;
+ m_xMtrWidth->get_range(nMin, nMax, FieldUnit::NONE);
+
+ if (nWidth <= nMax)
+ {
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+ }
+ else
+ {
+ nWidth = nMax;
+ m_xMtrWidth->set_value(nWidth, FieldUnit::NONE);
+
+ const sal_Int64 nHeight(basegfx::fround64((mfOldHeight * static_cast<double>(nWidth)) / mfOldWidth));
+ m_xMtrHeight->set_value(nHeight, FieldUnit::NONE);
+ }
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickSizeProtectHdl, weld::ToggleButton&, void)
+{
+ UpdateControlStates();
+}
+
+IMPL_LINK_NOARG(SvxPositionSizeTabPage, ClickAutoHdl, weld::ToggleButton&, void)
+{
+ if (m_xCbxScale->get_active())
+ {
+ mfOldWidth = std::max( static_cast<double>(GetCoreValue( *m_xMtrWidth, mePoolUnit )), 1.0 );
+ mfOldHeight = std::max( static_cast<double>(GetCoreValue( *m_xMtrHeight, mePoolUnit )), 1.0 );
+ }
+}
+
+void SvxPositionSizeTabPage::FillUserData()
+{
+ // matching is saved in the Ini-file
+ OUString aStr = m_xCbxScale->get_active() ? OUString("1") : OUString("0");
+ SetUserData( aStr );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/uno/services.cxx b/cui/source/uno/services.cxx
new file mode 100644
index 000000000..62c6bbaf4
--- /dev/null
+++ b/cui/source/uno/services.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 <sal/types.h>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <colorpicker.hxx>
+
+using namespace com::sun::star;
+
+namespace
+{
+ cppu::ImplementationEntry const entries[] = {
+ { &::cui::ColorPicker_createInstance, &::cui::ColorPicker_getImplementationName, &::cui::ColorPicker_getSupportedServiceNames, &cppu::createSingleComponentFactory, nullptr, 0 },
+ { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
+ };
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT void * cui_component_getFactory( char const * implName, void * serviceManager, void * registryKey)
+{
+ return cppu::component_getFactoryHelper(implName, serviceManager, registryKey, entries);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */