summaryrefslogtreecommitdiffstats
path: root/cui/source/options
diff options
context:
space:
mode:
Diffstat (limited to 'cui/source/options')
-rw-r--r--cui/source/options/certpath.cxx237
-rw-r--r--cui/source/options/certpath.hxx42
-rw-r--r--cui/source/options/cfgchart.cxx280
-rw-r--r--cui/source/options/cfgchart.hxx100
-rw-r--r--cui/source/options/connpoolconfig.cxx196
-rw-r--r--cui/source/options/connpoolconfig.hxx38
-rw-r--r--cui/source/options/connpooloptions.cxx261
-rw-r--r--cui/source/options/connpooloptions.hxx71
-rw-r--r--cui/source/options/connpoolsettings.cxx84
-rw-r--r--cui/source/options/connpoolsettings.hxx86
-rw-r--r--cui/source/options/cuisrchdlg.cxx50
-rw-r--r--cui/source/options/dbregister.cxx315
-rw-r--r--cui/source/options/dbregisterednamesconfig.cxx122
-rw-r--r--cui/source/options/dbregisterednamesconfig.hxx38
-rw-r--r--cui/source/options/dbregistersettings.cxx55
-rw-r--r--cui/source/options/dbregistersettings.hxx80
-rw-r--r--cui/source/options/doclinkdialog.cxx199
-rw-r--r--cui/source/options/doclinkdialog.hxx61
-rw-r--r--cui/source/options/fontsubs.cxx405
-rw-r--r--cui/source/options/fontsubs.hxx61
-rw-r--r--cui/source/options/optaboutconfig.cxx965
-rw-r--r--cui/source/options/optaboutconfig.hxx95
-rw-r--r--cui/source/options/optaccessibility.cxx111
-rw-r--r--cui/source/options/optaccessibility.hxx42
-rw-r--r--cui/source/options/optasian.cxx383
-rw-r--r--cui/source/options/optbasic.cxx131
-rw-r--r--cui/source/options/optbasic.hxx47
-rw-r--r--cui/source/options/optchart.cxx274
-rw-r--r--cui/source/options/optchart.hxx79
-rw-r--r--cui/source/options/optcolor.cxx896
-rw-r--r--cui/source/options/optcolor.hxx68
-rw-r--r--cui/source/options/optctl.cxx146
-rw-r--r--cui/source/options/optctl.hxx45
-rw-r--r--cui/source/options/optdict.cxx774
-rw-r--r--cui/source/options/optfltr.cxx346
-rw-r--r--cui/source/options/optfltr.hxx80
-rw-r--r--cui/source/options/optgdlg.cxx1806
-rw-r--r--cui/source/options/optgdlg.hxx181
-rw-r--r--cui/source/options/optgenrl.cxx507
-rw-r--r--cui/source/options/opthtml.cxx169
-rw-r--r--cui/source/options/opthtml.hxx59
-rw-r--r--cui/source/options/optinet2.cxx938
-rw-r--r--cui/source/options/optinet2.hxx158
-rw-r--r--cui/source/options/optjava.cxx960
-rw-r--r--cui/source/options/optjava.hxx206
-rw-r--r--cui/source/options/optjsearch.cxx358
-rw-r--r--cui/source/options/optjsearch.hxx71
-rw-r--r--cui/source/options/optlanguagetool.cxx76
-rw-r--r--cui/source/options/optlanguagetool.hxx44
-rw-r--r--cui/source/options/optlingu.cxx1974
-rw-r--r--cui/source/options/optopencl.cxx88
-rw-r--r--cui/source/options/optopencl.hxx42
-rw-r--r--cui/source/options/optpath.cxx697
-rw-r--r--cui/source/options/optsave.cxx635
-rw-r--r--cui/source/options/optsave.hxx78
-rw-r--r--cui/source/options/optupdt.cxx405
-rw-r--r--cui/source/options/optupdt.hxx70
-rw-r--r--cui/source/options/personalization.cxx166
-rw-r--r--cui/source/options/personalization.hxx62
-rw-r--r--cui/source/options/sdbcdriverenum.cxx99
-rw-r--r--cui/source/options/sdbcdriverenum.hxx54
-rw-r--r--cui/source/options/securityoptions.cxx79
-rw-r--r--cui/source/options/securityoptions.hxx61
-rw-r--r--cui/source/options/treeopt.cxx2115
-rw-r--r--cui/source/options/tsaurls.cxx128
-rw-r--r--cui/source/options/tsaurls.hxx41
-rw-r--r--cui/source/options/webconninfo.cxx229
-rw-r--r--cui/source/options/webconninfo.hxx51
68 files changed, 19870 insertions, 0 deletions
diff --git a/cui/source/options/certpath.cxx b/cui/source/options/certpath.cxx
new file mode 100644
index 000000000..3aff94b32
--- /dev/null
+++ b/cui/source/options/certpath.cxx
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <tools/diagnose_ex.h>
+#include "certpath.hxx"
+
+#include <com/sun/star/xml/crypto/NSSInitializer.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <comphelper/processfactory.hxx>
+
+using namespace ::com::sun::star;
+
+CertPathDialog::CertPathDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/certdialog.ui", "CertDialog")
+ , m_xManualButton(m_xBuilder->weld_button("add"))
+ , m_xOKButton(m_xBuilder->weld_button("ok"))
+ , m_xCertPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_sAddDialogText(m_xBuilder->weld_label("certdir")->get_label())
+ , m_sManualLabel(m_xBuilder->weld_label("manual")->get_label())
+{
+ m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 70,
+ m_xCertPathList->get_height_rows(6));
+
+ m_xCertPathList->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
+
+ m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
+ m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
+}
+
+void CertPathDialog::Init()
+{
+ m_xCertPathList->clear();
+ m_xCertPathList->set_sensitive(true);
+
+ try
+ {
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
+
+ OUString sActivePath = xCipherContextSupplier->getNSSPath();
+ auto aProductList = xCipherContextSupplier->getNSSProfiles();
+
+ // these map to the integer values of mozilla::MozillaProductType
+ const char* const productNames[4] = {
+ "",
+ "mozilla",
+ "firefox",
+ "thunderbird"
+ };
+
+ for (const auto& rNSSProfile : std::as_const(aProductList))
+ {
+ if (rNSSProfile.Type == mozilla::MozillaProductType_Default)
+ {
+ if (rNSSProfile.Name == "MOZILLA_CERTIFICATE_FOLDER" && !rNSSProfile.Path.isEmpty())
+ {
+ AddCertPath("$MOZILLA_CERTIFICATE_FOLDER", rNSSProfile.Path);
+ m_xCertPathList->set_sensitive(false);
+ }
+ else if (rNSSProfile.Name == "MANUAL")
+ AddManualCertPath(rNSSProfile.Path);
+ }
+ else
+ {
+ OUString sEntry = OUString::createFromAscii(
+ productNames[static_cast<int>(rNSSProfile.Type)]) + ":" + rNSSProfile.Name;
+ AddCertPath(sEntry, rNSSProfile.Path, rNSSProfile.Path == sActivePath);
+ }
+ }
+
+ OUString sManualCertPath = officecfg::Office::Common::Security::Scripting::ManualCertDir::get();
+ if (!sManualCertPath.isEmpty())
+ AddManualCertPath(sManualCertPath, false);
+ }
+ catch (const uno::Exception&)
+ {
+ }
+}
+
+void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
+{
+ if (sUserSetCertPath.isEmpty())
+ return;
+
+ ::osl::DirectoryItem aUserPathItem;
+ OUString sUserSetCertURLPath;
+ osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
+ if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
+ {
+ ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
+ if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
+ // the cert path exists
+ AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
+ }
+}
+
+IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ const int nEntry = m_xCertPathList->get_selected_index();
+ officecfg::Office::Common::Security::Scripting::CertDir::set(
+ nEntry == -1 ? OUString() : m_xCertPathList->get_id(nEntry), batch);
+ officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
+ batch->commit();
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+bool CertPathDialog::isActiveServicePath() const
+{
+ int nEntry = m_xCertPathList->get_selected_index();
+ if (nEntry == -1)
+ return true;
+
+ try
+ {
+ uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
+ uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
+
+ if (!xCipherContextSupplier->getIsNSSinitialized())
+ return true;
+ return (xCipherContextSupplier->getNSSPath() == m_xCertPathList->get_id(nEntry));
+ }
+ catch (const uno::Exception&)
+ {
+ return false;
+ }
+}
+
+CertPathDialog::~CertPathDialog()
+{
+}
+
+IMPL_LINK(CertPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ HandleEntryChecked(m_xCertPathList->get_iter_index_in_parent(rRowCol.first));
+}
+
+void CertPathDialog::HandleEntryChecked(int nRow)
+{
+ const bool bChecked = m_xCertPathList->get_toggle(nRow) == TRISTATE_TRUE;
+ if (bChecked)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xCertPathList->select(nRow);
+ const int nCount = m_xCertPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (i != nRow)
+ m_xCertPathList->set_toggle(i, TRISTATE_FALSE);
+ }
+ }
+}
+
+void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
+{
+ int nRow = -1;
+ for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
+ {
+ OUString sCertPath = m_xCertPathList->get_id(i);
+ //already exists, just select the original one
+ if (sCertPath == rPath)
+ {
+ const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i);
+ m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE);
+ HandleEntryChecked(i);
+ return;
+ }
+ else if (m_xCertPathList->get_text(i, 0) == rProfile)
+ nRow = i;
+ }
+
+ if (m_sManualLabel == rProfile)
+ m_sManualPath = rPath;
+
+ if (nRow < 0)
+ {
+ m_xCertPathList->append();
+ nRow = m_xCertPathList->n_children() - 1;
+ }
+ m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xCertPathList->set_text(nRow, rProfile, 0);
+ m_xCertPathList->set_text(nRow, rPath, 1);
+ m_xCertPathList->set_id(nRow, rPath);
+ HandleEntryChecked(nRow);
+}
+
+IMPL_LINK_NOARG(CertPathDialog, ManualHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
+ comphelper::getProcessComponentContext(), m_xDialog.get());
+
+ OUString sURL;
+ if (!m_sManualPath.isEmpty())
+ osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
+ if (sURL.isEmpty())
+ osl::Security().getHomeDir(sURL);
+ xFolderPicker->setDisplayDirectory(sURL);
+ xFolderPicker->setDescription(m_sAddDialogText);
+
+ if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ sURL = xFolderPicker->getDirectory();
+ OUString aPath;
+ if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
+ AddCertPath(m_sManualLabel, aPath);
+ }
+ }
+ catch (const uno::Exception &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/certpath.hxx b/cui/source/options/certpath.hxx
new file mode 100644
index 000000000..50addc1e8
--- /dev/null
+++ b/cui/source/options/certpath.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+class CertPathDialog : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Button> m_xManualButton;
+ std::unique_ptr<weld::Button> m_xOKButton;
+ std::unique_ptr<weld::TreeView> m_xCertPathList;
+ OUString m_sAddDialogText;
+ OUString m_sManualLabel;
+ OUString m_sManualPath;
+
+ DECL_LINK(CheckHdl_Impl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(ManualHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+
+ void HandleEntryChecked(int nRow);
+ void AddCertPath(const OUString& rProfile, const OUString& rPath, bool bSelect = true);
+ void AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect = true);
+
+public:
+ explicit CertPathDialog(weld::Window* pParent);
+ virtual ~CertPathDialog() override;
+
+ void Init();
+
+ // returns true, if the service currently uses the selected path or is not initialized
+ // yet and therefore has no active NSS path.
+ bool isActiveServicePath() const;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.cxx b/cui/source/options/cfgchart.cxx
new file mode 100644
index 000000000..13ed520d0
--- /dev/null
+++ b/cui/source/options/cfgchart.cxx
@@ -0,0 +1,280 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/debug.hxx>
+#include <sal/log.hxx>
+#include "cfgchart.hxx"
+#include <dialmgr.hxx>
+#include <strings.hrc>
+#include <utility>
+
+#define ROW_COLOR_COUNT 12
+
+using namespace com::sun::star;
+
+// accessors
+size_t SvxChartColorTable::size() const
+{
+ return m_aColorEntries.size();
+}
+
+const XColorEntry & SvxChartColorTable::operator[]( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::[] invalid index" );
+ return m_aColorEntries[ 0 ];
+ }
+
+ return m_aColorEntries[ _nIndex ];
+}
+
+Color SvxChartColorTable::getColor( size_t _nIndex ) const
+{
+ if ( _nIndex >= m_aColorEntries.size() )
+ {
+ SAL_WARN( "cui.options", "SvxChartColorTable::getColorData invalid index" );
+ return COL_BLACK;
+ }
+
+ return m_aColorEntries[ _nIndex ].GetColor().GetRGBColor();
+}
+
+// mutators
+void SvxChartColorTable::clear()
+{
+ m_aColorEntries.clear();
+}
+
+void SvxChartColorTable::append( const XColorEntry & _rEntry )
+{
+ m_aColorEntries.push_back( _rEntry );
+}
+
+void SvxChartColorTable::remove( size_t _nIndex )
+{
+ if (!m_aColorEntries.empty())
+ m_aColorEntries.erase( m_aColorEntries.begin() + _nIndex);
+
+ for (size_t i=0 ; i<m_aColorEntries.size(); i++)
+ {
+ m_aColorEntries[ i ].SetName( getDefaultName( i ) );
+ }
+}
+
+void SvxChartColorTable::replace( size_t _nIndex, const XColorEntry & _rEntry )
+{
+ DBG_ASSERT( _nIndex <= m_aColorEntries.size(),
+ "SvxChartColorTable::replace invalid index" );
+
+ m_aColorEntries[ _nIndex ] = _rEntry;
+}
+
+void SvxChartColorTable::useDefault()
+{
+ static const Color aColors[] = {
+ Color( 0x00, 0x45, 0x86 ),
+ Color( 0xff, 0x42, 0x0e ),
+ Color( 0xff, 0xd3, 0x20 ),
+ Color( 0x57, 0x9d, 0x1c ),
+ Color( 0x7e, 0x00, 0x21 ),
+ Color( 0x83, 0xca, 0xff ),
+ Color( 0x31, 0x40, 0x04 ),
+ Color( 0xae, 0xcf, 0x00 ),
+ Color( 0x4b, 0x1f, 0x6f ),
+ Color( 0xff, 0x95, 0x0e ),
+ Color( 0xc5, 0x00, 0x0b ),
+ Color( 0x00, 0x84, 0xd1 )
+ };
+
+ clear();
+
+ for( sal_Int32 i=0; i<ROW_COLOR_COUNT; i++ )
+ {
+ append( XColorEntry( aColors[ i % sizeof( aColors ) ], getDefaultName( i ) ));
+ }
+}
+
+OUString SvxChartColorTable::getDefaultName( size_t _nIndex )
+{
+ OUString aName;
+
+ std::u16string_view sDefaultNamePrefix;
+ std::u16string_view sDefaultNamePostfix;
+ OUString aResName( CuiResId( RID_CUISTR_DIAGRAM_ROW ) );
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ sDefaultNamePrefix = aResName.subView( 0, nPos );
+ sDefaultNamePostfix = aResName.subView( nPos + sizeof( "$(ROW)" ) - 1 );
+ }
+ else
+ {
+ sDefaultNamePrefix = aResName;
+ }
+
+ aName = sDefaultNamePrefix + OUString::number(_nIndex + 1) + sDefaultNamePostfix;
+
+ return aName;
+}
+
+// comparison
+bool SvxChartColorTable::operator==( const SvxChartColorTable & _rOther ) const
+{
+ // note: XColorEntry has no operator ==
+ bool bEqual = ( m_aColorEntries.size() == _rOther.m_aColorEntries.size() );
+
+ if( bEqual )
+ {
+ for( size_t i = 0; i < m_aColorEntries.size(); ++i )
+ {
+ if( getColor( i ) != _rOther.getColor( i ))
+ {
+ bEqual = false;
+ break;
+ }
+ }
+ }
+
+ return bEqual;
+}
+
+
+
+
+SvxChartOptions::SvxChartOptions() :
+ ::utl::ConfigItem( "Office.Chart" ),
+ mbIsInitialized( false ),
+ maPropertyNames{ "DefaultColor/Series" }
+{
+}
+
+SvxChartOptions::~SvxChartOptions()
+{
+}
+
+const SvxChartColorTable& SvxChartOptions::GetDefaultColors()
+{
+ if ( !mbIsInitialized )
+ mbIsInitialized = RetrieveOptions();
+ return maDefColors;
+}
+
+void SvxChartOptions::SetDefaultColors( const SvxChartColorTable& aCol )
+{
+ maDefColors = aCol;
+ SetModified();
+}
+
+bool SvxChartOptions::RetrieveOptions()
+{
+ // get sequence containing all properties
+
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aProperties( aNames.getLength());
+ aProperties = GetProperties( aNames );
+
+ if( aProperties.getLength() != aNames.getLength())
+ return false;
+
+ // 1. default colors for series
+ maDefColors.clear();
+ uno::Sequence< sal_Int64 > aColorSeq;
+ aProperties[ 0 ] >>= aColorSeq;
+
+ sal_Int32 nCount = aColorSeq.getLength();
+ Color aCol;
+
+ // create strings for entry names
+ OUString aResName( CuiResId( RID_CUISTR_DIAGRAM_ROW ) );
+ std::u16string_view aPrefix, aPostfix;
+ OUString aName;
+ sal_Int32 nPos = aResName.indexOf( "$(ROW)" );
+ if( nPos != -1 )
+ {
+ aPrefix = aResName.subView( 0, nPos );
+ sal_Int32 idx = nPos + sizeof( "$(ROW)" ) - 1;
+ aPostfix = aResName.subView( idx );
+ }
+ else
+ aPrefix = aResName;
+
+ // set color values
+ for( sal_Int32 i=0; i < nCount; i++ )
+ {
+ aCol = Color(ColorTransparency, aColorSeq[ i ]);
+
+ aName = aPrefix + OUString::number(i + 1) + aPostfix;
+
+ maDefColors.append( XColorEntry( aCol, aName ));
+ }
+ return true;
+}
+
+void SvxChartOptions::ImplCommit()
+{
+ uno::Sequence< OUString > aNames = GetPropertyNames();
+ uno::Sequence< uno::Any > aValues( aNames.getLength());
+
+ if( aValues.hasElements() )
+ {
+ // 1. default colors for series
+ // convert list to sequence
+ const size_t nCount = maDefColors.size();
+ uno::Sequence< sal_Int64 > aColors( nCount );
+ auto aColorsRange = asNonConstRange(aColors);
+ for( size_t i=0; i < nCount; i++ )
+ {
+ Color aData = maDefColors.getColor( i );
+ aColorsRange[ i ] = sal_uInt32(aData);
+ }
+
+ aValues.getArray()[0] <<= aColors;
+ }
+
+ PutProperties( aNames, aValues );
+}
+
+void SvxChartOptions::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+
+
+
+SvxChartColorTableItem::SvxChartColorTableItem( sal_uInt16 nWhich_, SvxChartColorTable aTable ) :
+ SfxPoolItem( nWhich_ ),
+ m_aColorTable(std::move( aTable ))
+{
+}
+
+SvxChartColorTableItem* SvxChartColorTableItem::Clone( SfxItemPool * ) const
+{
+ return new SvxChartColorTableItem( *this );
+}
+
+bool SvxChartColorTableItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ assert(SfxPoolItem::operator==(rAttr));
+
+ return static_cast<const SvxChartColorTableItem & >( rAttr ).m_aColorTable == m_aColorTable;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cfgchart.hxx b/cui/source/options/cfgchart.hxx
new file mode 100644
index 000000000..8e49e190d
--- /dev/null
+++ b/cui/source/options/cfgchart.hxx
@@ -0,0 +1,100 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <unotools/configitem.hxx>
+#include <svl/poolitem.hxx>
+#include <svx/xtable.hxx>
+
+#include <vector>
+
+class SvxChartColorTable
+{
+private:
+ std::vector< XColorEntry > m_aColorEntries;
+
+public:
+ // accessors
+ size_t size() const;
+ const XColorEntry & operator[]( size_t _nIndex ) const;
+ Color getColor( size_t _nIndex ) const;
+
+ // mutators
+ void clear();
+ void append( const XColorEntry & _rEntry );
+ void remove( size_t _nIndex );
+ void replace( size_t _nIndex, const XColorEntry & _rEntry );
+ void useDefault();
+ static OUString getDefaultName(size_t _nIndex);
+
+ // comparison
+ bool operator==( const SvxChartColorTable & _rOther ) const;
+};
+
+
+// all options
+
+class SvxChartOptions : public ::utl::ConfigItem
+{
+private:
+ SvxChartColorTable maDefColors;
+ bool mbIsInitialized;
+
+ css::uno::Sequence< OUString >
+ maPropertyNames;
+
+ const css::uno::Sequence< OUString >& GetPropertyNames() const
+ { return maPropertyNames; }
+ bool RetrieveOptions();
+
+ virtual void ImplCommit() override;
+
+public:
+ SvxChartOptions();
+ virtual ~SvxChartOptions() override;
+
+ const SvxChartColorTable& GetDefaultColors();
+ void SetDefaultColors( const SvxChartColorTable& aCol );
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+};
+
+
+// items
+// Make Item read-only (no non-const access methods). Two reasons:
+// (1) Preparation for Item refactor
+// (2) Dangerous due to SfxItem may not be what you expect (e.g. when
+// ::Set in SfxItemSet, not your instance may be used there, no control
+// about what will happen without deep knowledge about SfxItems/SfxItemSets)
+class SvxChartColorTableItem : public SfxPoolItem
+{
+public:
+ SvxChartColorTableItem( sal_uInt16 nWhich, SvxChartColorTable );
+
+ virtual SvxChartColorTableItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+ virtual bool operator==( const SfxPoolItem& ) const override;
+
+ const SvxChartColorTable & GetColorList() const { return m_aColorTable;}
+
+private:
+ SvxChartColorTable m_aColorTable;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.cxx b/cui/source/options/connpoolconfig.cxx
new file mode 100644
index 000000000..8bf95ee0d
--- /dev/null
+++ b/cui/source/options/connpoolconfig.cxx
@@ -0,0 +1,196 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "connpoolconfig.hxx"
+#include "connpoolsettings.hxx"
+
+#include <svl/itemset.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <unotools/confignode.hxx>
+#include <svl/eitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include "sdbcdriverenum.hxx"
+
+#include <com/sun/star/uno/Sequence.hxx>
+
+namespace offapp
+{
+
+
+ using namespace ::utl;
+ using namespace ::com::sun::star::uno;
+
+
+ static OUString getConnectionPoolNodeName()
+ {
+ return "org.openoffice.Office.DataAccess/ConnectionPool";
+ }
+
+
+ static OUString getEnablePoolingNodeName()
+ {
+ return "EnablePooling";
+ }
+
+
+ static OUString getDriverSettingsNodeName()
+ {
+ return "DriverSettings";
+ }
+
+
+ static OUString getDriverNameNodeName()
+ {
+ return "DriverName";
+ }
+
+
+ static OUString getEnableNodeName()
+ {
+ return "Enable";
+ }
+
+
+ static OUString getTimeoutNodeName()
+ {
+ return "Timeout";
+ }
+
+ void ConnectionPoolConfig::GetOptions(SfxItemSet& _rFillItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName(), -1, OConfigurationTreeRoot::CM_READONLY);
+
+ // the global "enabled" flag
+ Any aEnabled = aConnectionPoolRoot.getNodeValue(getEnablePoolingNodeName());
+ bool bEnabled = true;
+ aEnabled >>= bEnabled;
+ _rFillItems.Put(SfxBoolItem(SID_SB_POOLING_ENABLED, bEnabled));
+
+ // the settings for the single drivers
+ DriverPoolingSettings aSettings;
+ // first get all the drivers register at the driver manager
+ ODriverEnumeration aEnumDrivers;
+ for (auto const& elem : aEnumDrivers)
+ {
+ aSettings.push_back(DriverPooling(elem));
+ }
+
+ // then look for which of them settings are stored in the configuration
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+
+ Sequence< OUString > aDriverKeys = aDriverSettings.getNodeNames();
+ const OUString* pDriverKeys = aDriverKeys.getConstArray();
+ const OUString* pDriverKeysEnd = pDriverKeys + aDriverKeys.getLength();
+ for (;pDriverKeys != pDriverKeysEnd; ++pDriverKeys)
+ {
+ // the name of the driver in this round
+ OConfigurationNode aThisDriverSettings = aDriverSettings.openNode(*pDriverKeys);
+ OUString sThisDriverName;
+ aThisDriverSettings.getNodeValue(getDriverNameNodeName()) >>= sThisDriverName;
+
+ // look if we (resp. the driver manager) know this driver
+ // doing O(n) search here, which is expensive, but this doesn't matter in this small case ...
+ DriverPoolingSettings::iterator aLookup;
+ for ( aLookup = aSettings.begin();
+ aLookup != aSettings.end();
+ ++aLookup
+ )
+ if (sThisDriverName == aLookup->sName)
+ break;
+
+ if (aLookup == aSettings.end())
+ { // do not know the driver - add it
+ aSettings.push_back(DriverPooling(sThisDriverName));
+
+ // and the position of the new entry
+ aLookup = aSettings.end();
+ --aLookup;
+ }
+
+ // now fill this entry with the settings from the configuration
+ aThisDriverSettings.getNodeValue(getEnableNodeName()) >>= aLookup->bEnabled;
+ aThisDriverSettings.getNodeValue(getTimeoutNodeName()) >>= aLookup->nTimeoutSeconds;
+ }
+
+ _rFillItems.Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, aSettings));
+ }
+
+
+ void ConnectionPoolConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the config node where all pooling relevant info are stored under
+ OConfigurationTreeRoot aConnectionPoolRoot = OConfigurationTreeRoot::createWithComponentContext(
+ ::comphelper::getProcessComponentContext(), getConnectionPoolNodeName());
+
+ if (!aConnectionPoolRoot.isValid())
+ // already asserted by the OConfigurationTreeRoot
+ return;
+
+ bool bNeedCommit = false;
+
+ // the global "enabled" flag
+ const SfxBoolItem* pEnabled = _rSourceItems.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ if (pEnabled)
+ {
+ bool bEnabled = pEnabled->GetValue();
+ aConnectionPoolRoot.setNodeValue(getEnablePoolingNodeName(), Any(bEnabled));
+ bNeedCommit = true;
+ }
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSourceItems.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ {
+ OConfigurationNode aDriverSettings = aConnectionPoolRoot.openNode(getDriverSettingsNodeName());
+ if (!aDriverSettings.isValid())
+ return;
+
+ OUString sThisDriverName;
+ OConfigurationNode aThisDriverSettings;
+
+ const DriverPoolingSettings& rNewSettings = pDriverSettings->getSettings();
+ for (auto const& newSetting : rNewSettings)
+ {
+ // need the name as OUString
+ sThisDriverName = newSetting.sName;
+
+ // the sub-node for this driver
+ if (aDriverSettings.hasByName(newSetting.sName))
+ aThisDriverSettings = aDriverSettings.openNode(newSetting.sName);
+ else
+ aThisDriverSettings = aDriverSettings.createNode(newSetting.sName);
+
+ // set the values
+ aThisDriverSettings.setNodeValue(getDriverNameNodeName(), Any(sThisDriverName));
+ aThisDriverSettings.setNodeValue(getEnableNodeName(), Any(newSetting.bEnabled));
+ aThisDriverSettings.setNodeValue(getTimeoutNodeName(), Any(newSetting.nTimeoutSeconds));
+ }
+ bNeedCommit = true;
+ }
+ if (bNeedCommit)
+ aConnectionPoolRoot.commit();
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolconfig.hxx b/cui/source/options/connpoolconfig.hxx
new file mode 100644
index 000000000..41ec88d5b
--- /dev/null
+++ b/cui/source/options/connpoolconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace offapp
+{
+
+ class ConnectionPoolConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.cxx b/cui/source/options/connpooloptions.cxx
new file mode 100644
index 000000000..c067af0c3
--- /dev/null
+++ b/cui/source/options/connpooloptions.cxx
@@ -0,0 +1,261 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include <osl/diagnose.h>
+#include "connpooloptions.hxx"
+#include "connpoolsettings.hxx"
+#include <svl/eitem.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+namespace offapp
+{
+ bool ConnectionPoolOptionsPage::isModifiedDriverList() const
+ {
+ if (m_aSettings.size() != m_aSavedSettings.size())
+ return true;
+
+ DriverPoolingSettings::const_iterator aSaved = m_aSavedSettings.begin();
+ for (auto const& currentSetting : m_aSettings)
+ {
+ if (currentSetting != *aSaved)
+ return true;
+ ++aSaved;
+ }
+
+ return false;
+ }
+
+ ConnectionPoolOptionsPage::ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet)
+ : SfxTabPage(pPage, pController, "cui/ui/connpooloptions.ui", "ConnPoolPage", &_rAttrSet)
+ , m_sYes(CuiResId(RID_CUISTR_YES))
+ , m_sNo(CuiResId(RID_CUISTR_NO))
+ , m_xEnablePooling(m_xBuilder->weld_check_button("connectionpooling"))
+ , m_xDriversLabel(m_xBuilder->weld_label("driverslabel"))
+ , m_xDriverList(m_xBuilder->weld_tree_view("driverlist"))
+ , m_xDriverLabel(m_xBuilder->weld_label("driverlabel"))
+ , m_xDriver(m_xBuilder->weld_label("driver"))
+ , m_xDriverPoolingEnabled(m_xBuilder->weld_check_button("enablepooling"))
+ , m_xTimeoutLabel(m_xBuilder->weld_label("timeoutlabel"))
+ , m_xTimeout(m_xBuilder->weld_spin_button("timeout"))
+ {
+ m_xDriverList->set_size_request(m_xDriverList->get_approximate_digit_width() * 60,
+ m_xDriverList->get_height_rows(15));
+ m_xDriverList->show();
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xDriverList->get_approximate_digit_width() * 50),
+ o3tl::narrowing<int>(m_xDriverList->get_approximate_digit_width() * 8)
+ };
+ m_xDriverList->set_column_fixed_widths(aWidths);
+
+ m_xEnablePooling->connect_toggled( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+ m_xDriverPoolingEnabled->connect_toggled( LINK(this, ConnectionPoolOptionsPage, OnEnabledDisabled) );
+
+ m_xDriverList->connect_changed(LINK(this, ConnectionPoolOptionsPage, OnDriverRowChanged));
+ m_xTimeout->connect_value_changed(LINK(this, ConnectionPoolOptionsPage, OnSpinValueChanged));
+ }
+
+ void ConnectionPoolOptionsPage::updateRow(size_t nRow)
+ {
+ auto const& currentSetting = m_aSettings[nRow];
+ m_xDriverList->set_text(nRow, currentSetting.sName, 0);
+ if (currentSetting.bEnabled)
+ {
+ m_xDriverList->set_text(nRow, m_sYes, 1);
+ m_xDriverList->set_text(nRow, OUString::number(currentSetting.nTimeoutSeconds), 2);
+ }
+ else
+ {
+ m_xDriverList->set_text(nRow, m_sNo, 1);
+ m_xDriverList->set_text(nRow, "-", 2);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::updateCurrentRow()
+ {
+ int nRow = m_xDriverList->get_selected_index();
+ if (nRow == -1)
+ return;
+ updateRow(nRow);
+ }
+
+ void ConnectionPoolOptionsPage::UpdateDriverList(const DriverPoolingSettings& _rSettings)
+ {
+ m_aSettings = _rSettings;
+
+ m_xDriverList->freeze();
+ m_xDriverList->clear();
+
+ for (size_t i = 0; i < m_aSettings.size(); ++i)
+ {
+ m_xDriverList->append();
+ updateRow(i);
+ }
+
+ m_xDriverList->thaw();
+
+ if (!m_aSettings.empty())
+ {
+ m_xDriverList->select(0);
+ OnDriverRowChanged(*m_xDriverList);
+ }
+ }
+
+ ConnectionPoolOptionsPage::~ConnectionPoolOptionsPage()
+ {
+ }
+
+ std::unique_ptr<SfxTabPage> ConnectionPoolOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet)
+ {
+ return std::make_unique<ConnectionPoolOptionsPage>(pPage, pController, *_rAttrSet);
+ }
+
+ void ConnectionPoolOptionsPage::implInitControls(const SfxItemSet& _rSet)
+ {
+ // the enabled flag
+ const SfxBoolItem* pEnabled = _rSet.GetItem<SfxBoolItem>(SID_SB_POOLING_ENABLED);
+ OSL_ENSURE(pEnabled, "ConnectionPoolOptionsPage::implInitControls: missing the Enabled item!");
+ m_xEnablePooling->set_active(pEnabled == nullptr || pEnabled->GetValue());
+
+ m_xEnablePooling->save_state();
+
+ // the settings for the single drivers
+ const DriverPoolingSettingsItem* pDriverSettings = _rSet.GetItem<DriverPoolingSettingsItem>(SID_SB_DRIVER_TIMEOUTS);
+ if (pDriverSettings)
+ UpdateDriverList(pDriverSettings->getSettings());
+ else
+ {
+ OSL_FAIL("ConnectionPoolOptionsPage::implInitControls: missing the DriverTimeouts item!");
+ UpdateDriverList(DriverPoolingSettings());
+ }
+ saveDriverList();
+
+ // reflect the new settings
+ OnEnabledDisabled(*m_xEnablePooling);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnSpinValueChanged, weld::SpinButton&, void)
+ {
+ commitTimeoutField();
+ }
+
+ bool ConnectionPoolOptionsPage::FillItemSet(SfxItemSet* _rSet)
+ {
+ commitTimeoutField();
+
+ bool bModified = false;
+ // the enabled flag
+ if (m_xEnablePooling->get_state_changed_from_saved())
+ {
+ _rSet->Put(SfxBoolItem(SID_SB_POOLING_ENABLED, m_xEnablePooling->get_active()));
+ bModified = true;
+ }
+
+ // the settings for the single drivers
+ if (isModifiedDriverList())
+ {
+ _rSet->Put(DriverPoolingSettingsItem(SID_SB_DRIVER_TIMEOUTS, m_aSettings));
+ bModified = true;
+ }
+
+ return bModified;
+ }
+
+ void ConnectionPoolOptionsPage::ActivatePage( const SfxItemSet& _rSet)
+ {
+ SfxTabPage::ActivatePage(_rSet);
+ implInitControls(_rSet);
+ }
+
+ void ConnectionPoolOptionsPage::Reset(const SfxItemSet* _rSet)
+ {
+ implInitControls(*_rSet);
+ }
+
+ IMPL_LINK_NOARG(ConnectionPoolOptionsPage, OnDriverRowChanged, weld::TreeView&, void)
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ bool bValidRow = (nDriverPos != -1);
+ m_xDriverPoolingEnabled->set_sensitive(bValidRow && m_xEnablePooling->get_active());
+ m_xTimeoutLabel->set_sensitive(bValidRow);
+ m_xTimeout->set_sensitive(bValidRow);
+
+ if (!bValidRow)
+ { // positioned on an invalid row
+ m_xDriver->set_label(OUString());
+ }
+ else
+ {
+ auto const& currentSetting = m_aSettings[nDriverPos];
+ m_xDriver->set_label(currentSetting.sName);
+ m_xDriverPoolingEnabled->set_active(currentSetting.bEnabled);
+ m_xTimeout->set_value(currentSetting.nTimeoutSeconds);
+
+ OnEnabledDisabled(*m_xDriverPoolingEnabled);
+ }
+ }
+
+ void ConnectionPoolOptionsPage::commitTimeoutField()
+ {
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].nTimeoutSeconds = m_xTimeout->get_value();
+ updateCurrentRow();
+ }
+
+ IMPL_LINK( ConnectionPoolOptionsPage, OnEnabledDisabled, weld::Toggleable&, rCheckBox, void )
+ {
+ bool bGloballyEnabled = m_xEnablePooling->get_active();
+ bool bLocalDriverChanged = m_xDriverPoolingEnabled.get() == &rCheckBox;
+
+ if (m_xEnablePooling.get() == &rCheckBox)
+ {
+ m_xDriversLabel->set_sensitive(bGloballyEnabled);
+ m_xDriverList->set_sensitive(bGloballyEnabled);
+ if (!bGloballyEnabled)
+ m_xDriverList->select(-1);
+ m_xDriverLabel->set_sensitive(bGloballyEnabled);
+ m_xDriver->set_sensitive(bGloballyEnabled);
+ m_xDriverPoolingEnabled->set_sensitive(bGloballyEnabled);
+ }
+ else
+ OSL_ENSURE(bLocalDriverChanged, "ConnectionPoolOptionsPage::OnEnabledDisabled: where did this come from?");
+
+ m_xTimeoutLabel->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+ m_xTimeout->set_sensitive(bGloballyEnabled && m_xDriverPoolingEnabled->get_active());
+
+ if (bLocalDriverChanged)
+ {
+ // update the list
+ const int nDriverPos = m_xDriverList->get_selected_index();
+ if (nDriverPos == -1)
+ return;
+ m_aSettings[nDriverPos].bEnabled = m_xDriverPoolingEnabled->get_active();
+ updateCurrentRow();
+ }
+ }
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpooloptions.hxx b/cui/source/options/connpooloptions.hxx
new file mode 100644
index 000000000..549448e21
--- /dev/null
+++ b/cui/source/options/connpooloptions.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+#include "connpoolsettings.hxx"
+
+namespace offapp
+{
+ class ConnectionPoolOptionsPage final : public SfxTabPage
+ {
+ OUString m_sYes;
+ OUString m_sNo;
+ DriverPoolingSettings m_aSettings;
+ DriverPoolingSettings m_aSavedSettings;
+
+ std::unique_ptr<weld::CheckButton> m_xEnablePooling;
+ std::unique_ptr<weld::Label> m_xDriversLabel;
+ std::unique_ptr<weld::TreeView> m_xDriverList;
+ std::unique_ptr<weld::Label> m_xDriverLabel;
+ std::unique_ptr<weld::Label> m_xDriver;
+ std::unique_ptr<weld::CheckButton> m_xDriverPoolingEnabled;
+ std::unique_ptr<weld::Label> m_xTimeoutLabel;
+ std::unique_ptr<weld::SpinButton> m_xTimeout;
+
+ public:
+ ConnectionPoolOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& _rAttrSet);
+ virtual ~ConnectionPoolOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* _rAttrSet);
+
+ private:
+ virtual bool FillItemSet(SfxItemSet* _rSet) override;
+ virtual void Reset(const SfxItemSet* _rSet) override;
+ virtual void ActivatePage( const SfxItemSet& _rSet) override;
+
+ void updateRow(size_t nRow);
+ void updateCurrentRow();
+ void UpdateDriverList(const DriverPoolingSettings& _rSettings);
+ bool isModifiedDriverList() const;
+ void saveDriverList() { m_aSavedSettings = m_aSettings; }
+
+ DECL_LINK(OnEnabledDisabled, weld::Toggleable&, void);
+ DECL_LINK(OnSpinValueChanged, weld::SpinButton&, void);
+ DECL_LINK(OnDriverRowChanged, weld::TreeView&, void);
+
+ void implInitControls(const SfxItemSet& _rSet);
+
+ void commitTimeoutField();
+ };
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.cxx b/cui/source/options/connpoolsettings.cxx
new file mode 100644
index 000000000..e92b26da5
--- /dev/null
+++ b/cui/source/options/connpoolsettings.cxx
@@ -0,0 +1,84 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+
+#include "connpoolsettings.hxx"
+
+
+namespace offapp
+{
+
+ DriverPooling::DriverPooling( OUString _aName )
+ :sName(std::move(_aName))
+ ,bEnabled(false)
+ ,nTimeoutSeconds(120)
+ {
+ }
+
+
+ bool DriverPooling::operator == (const DriverPooling& _rR) const
+ {
+ return (sName == _rR.sName)
+ && (bEnabled == _rR.bEnabled)
+ && (nTimeoutSeconds == _rR.nTimeoutSeconds);
+ }
+
+ DriverPoolingSettings::DriverPoolingSettings()
+ {
+ }
+
+
+ DriverPoolingSettingsItem::DriverPoolingSettingsItem( sal_uInt16 _nId, DriverPoolingSettings _aSettings )
+ :SfxPoolItem(_nId)
+ ,m_aSettings(std::move(_aSettings))
+ {
+ }
+
+
+ bool DriverPoolingSettingsItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ assert(SfxPoolItem::operator==(_rCompare));
+ const DriverPoolingSettingsItem* pItem = static_cast<const DriverPoolingSettingsItem*>( &_rCompare );
+
+ if (m_aSettings.size() != pItem->m_aSettings.size())
+ return false;
+
+ DriverPoolingSettings::const_iterator aForeign = pItem->m_aSettings.begin();
+ for (auto const& ownSetting : m_aSettings)
+ {
+ if (ownSetting != *aForeign)
+ return false;
+
+ ++aForeign;
+ }
+
+ return true;
+ }
+
+ DriverPoolingSettingsItem* DriverPoolingSettingsItem::Clone( SfxItemPool * ) const
+ {
+ return new DriverPoolingSettingsItem(*this);
+ }
+
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/connpoolsettings.hxx b/cui/source/options/connpoolsettings.hxx
new file mode 100644
index 000000000..1e2404b88
--- /dev/null
+++ b/cui/source/options/connpoolsettings.hxx
@@ -0,0 +1,86 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <vector>
+
+#include <rtl/ustring.hxx>
+#include <svl/poolitem.hxx>
+
+
+namespace offapp
+{
+
+ struct DriverPooling
+ {
+ OUString sName;
+ bool bEnabled;
+ sal_Int32 nTimeoutSeconds;
+
+ explicit DriverPooling( OUString _aName );
+
+ bool operator == (const DriverPooling& _rR) const;
+ bool operator != (const DriverPooling& _rR) const { return !operator ==(_rR); }
+ };
+
+ class DriverPoolingSettings final
+ {
+ typedef std::vector<DriverPooling> DriverSettings;
+ DriverSettings m_aDrivers;
+
+ public:
+ typedef DriverSettings::const_iterator const_iterator;
+ typedef DriverSettings::iterator iterator;
+
+ DriverPoolingSettings();
+
+ size_t size() const { return m_aDrivers.size(); }
+ DriverPooling& operator[]( size_t nPos ) { return m_aDrivers[nPos]; }
+ bool empty() const { return m_aDrivers.empty(); }
+
+ const_iterator begin() const { return m_aDrivers.begin(); }
+ const_iterator end() const { return m_aDrivers.end(); }
+
+ iterator begin() { return m_aDrivers.begin(); }
+ iterator end() { return m_aDrivers.end(); }
+
+ void push_back(const DriverPooling& _rElement) { m_aDrivers.push_back(_rElement); }
+ };
+
+ class DriverPoolingSettingsItem final : public SfxPoolItem
+ {
+ DriverPoolingSettings m_aSettings;
+
+ public:
+
+ DriverPoolingSettingsItem( sal_uInt16 _nId, DriverPoolingSettings _aSettings );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DriverPoolingSettingsItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DriverPoolingSettings& getSettings() const { return m_aSettings; }
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/cuisrchdlg.cxx b/cui/source/options/cuisrchdlg.cxx
new file mode 100644
index 000000000..f58985d90
--- /dev/null
+++ b/cui/source/options/cuisrchdlg.cxx
@@ -0,0 +1,50 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sfx2/basedlgs.hxx>
+
+#include <cuisrchdlg.hxx>
+
+#include "optjsearch.hxx"
+
+
+// class SvxJSearchOptionsDialog -----------------------------------------
+
+SvxJSearchOptionsDialog::SvxJSearchOptionsDialog(weld::Window *pParent,
+ const SfxItemSet& rOptionsSet, TransliterationFlags nInitialFlags)
+ : SfxSingleTabDialogController(pParent, &rOptionsSet)
+{
+ // m_xPage will be implicitly destroyed by the
+ // SfxSingleTabDialog destructor
+ SetTabPage(SvxJSearchOptionsPage::Create(get_content_area(), this, &rOptionsSet)); //! implicitly calls m_xPage->Reset(...)!
+ m_pPage = static_cast<SvxJSearchOptionsPage*>(GetTabPage());
+ m_pPage->EnableSaveOptions(false);
+ m_pPage->SetTransliterationFlags(nInitialFlags);
+}
+
+SvxJSearchOptionsDialog::~SvxJSearchOptionsDialog()
+{
+}
+
+TransliterationFlags SvxJSearchOptionsDialog::GetTransliterationFlags() const
+{
+ return m_pPage->GetTransliterationFlags();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregister.cxx b/cui/source/options/dbregister.cxx
new file mode 100644
index 000000000..143112c58
--- /dev/null
+++ b/cui/source/options/dbregister.cxx
@@ -0,0 +1,315 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <dbregister.hxx>
+#include "dbregistersettings.hxx"
+#include <o3tl/safeint.hxx>
+#include <svl/filenotation.hxx>
+#include <helpids.h>
+#include <tools/debug.hxx>
+#include <strings.hrc>
+#include <bitmaps.hlst>
+#include <utility>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svl/itemset.hxx>
+#include "doclinkdialog.hxx"
+#include <dialmgr.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <svx/databaseregistrationui.hxx>
+#include <o3tl/string_view.hxx>
+
+#define COL_TYPE 0
+
+namespace svx
+{
+
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+using namespace ::svt;
+
+// class RegistrationItemSetHolder -------------------------------------------------
+
+RegistrationItemSetHolder::RegistrationItemSetHolder( SfxItemSet _aMasterSet )
+ :m_aRegistrationItems(std::move( _aMasterSet ))
+{
+ DbRegisteredNamesConfig::GetOptions( m_aRegistrationItems );
+}
+
+RegistrationItemSetHolder::~RegistrationItemSetHolder()
+{
+}
+
+// class DatabaseRegistrationDialog ------------------------------------------------
+
+DatabaseRegistrationDialog::DatabaseRegistrationDialog(weld::Window* pParent, const SfxItemSet& rInAttrs)
+ : RegistrationItemSetHolder(rInAttrs)
+ , SfxSingleTabDialogController(pParent, &getRegistrationItems())
+{
+ SetTabPage(DbRegistrationOptionsPage::Create(get_content_area(), this, &getRegistrationItems()));
+ m_xDialog->set_title(CuiResId(RID_CUISTR_REGISTERED_DATABASES));
+}
+
+short DatabaseRegistrationDialog::run()
+{
+ short result = SfxSingleTabDialogController::run();
+ if (result == RET_OK)
+ {
+ DBG_ASSERT( GetOutputItemSet(), "DatabaseRegistrationDialog::Execute: no output items!" );
+ if ( GetOutputItemSet() )
+ DbRegisteredNamesConfig::SetOptions( *GetOutputItemSet() );
+ }
+ return result;
+}
+
+// class DbRegistrationOptionsPage --------------------------------------------------
+
+DbRegistrationOptionsPage::DbRegistrationOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/dbregisterpage.ui", "DbRegisterPage", &rSet)
+ , m_nOldCount(0)
+ , m_bModified(false)
+ , m_xNew(m_xBuilder->weld_button("new"))
+ , m_xEdit(m_xBuilder->weld_button("edit"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("pathctrl"))
+ , m_xIter(m_xPathBox->make_iterator())
+{
+ Size aControlSize(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(12));
+ m_xPathBox->set_size_request(aControlSize.Width(), aControlSize.Height());
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xPathBox->get_approximate_digit_width() * 20)
+ };
+ m_xPathBox->set_column_fixed_widths(aWidths);
+
+ m_xNew->connect_clicked( LINK( this, DbRegistrationOptionsPage, NewHdl ) );
+ m_xEdit->connect_clicked( LINK( this, DbRegistrationOptionsPage, EditHdl ) );
+ m_xDelete->connect_clicked( LINK( this, DbRegistrationOptionsPage, DeleteHdl ) );
+
+ m_xPathBox->connect_column_clicked(LINK(this, DbRegistrationOptionsPage, HeaderSelect_Impl));
+
+ m_xPathBox->make_sorted();
+ m_xPathBox->connect_row_activated( LINK( this, DbRegistrationOptionsPage, PathBoxDoubleClickHdl ) );
+ m_xPathBox->connect_changed( LINK( this, DbRegistrationOptionsPage, PathSelect_Impl ) );
+
+ m_xPathBox->set_help_id(HID_DBPATH_CTL_PATH);
+}
+
+DbRegistrationOptionsPage::~DbRegistrationOptionsPage()
+{
+ for (int i = 0, nCount = m_xPathBox->n_children(); i < nCount; ++i )
+ delete weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(i));
+}
+
+std::unique_ptr<SfxTabPage> DbRegistrationOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<DbRegistrationOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool DbRegistrationOptionsPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ // the settings for the single drivers
+ bool bModified = false;
+ DatabaseRegistrations aRegistrations;
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ DatabaseRegistration* pRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(i));
+ if ( pRegistration && !pRegistration->sLocation.isEmpty() )
+ {
+ OUString sName(m_xPathBox->get_text(i, 0));
+ OFileNotation aTransformer( pRegistration->sLocation );
+ aRegistrations[ sName ] = DatabaseRegistration( aTransformer.get( OFileNotation::N_URL ), pRegistration->bReadOnly );
+ }
+ }
+ if ( m_nOldCount != aRegistrations.size() || m_bModified )
+ {
+ rCoreSet->Put(DatabaseMapItem( SID_SB_DB_REGISTER, std::move(aRegistrations) ));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void DbRegistrationOptionsPage::Reset( const SfxItemSet* rSet )
+{
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = rSet->GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ m_xPathBox->clear();
+
+ const DatabaseRegistrations& rRegistrations = pRegistrations->getRegistrations();
+ m_nOldCount = rRegistrations.size();
+ for (auto const& elem : rRegistrations)
+ {
+ OFileNotation aTransformer( elem.second.sLocation );
+ insertNewEntry( elem.first, aTransformer.get( OFileNotation::N_SYSTEM ), elem.second.bReadOnly );
+ }
+
+ OUString aUserData = GetUserData();
+ if ( aUserData.isEmpty() )
+ return;
+
+ sal_Int32 nIdx {0};
+ // restore column width
+ std::vector<int> aWidths
+ {
+ o3tl::toInt32(o3tl::getToken(aUserData, 0, ';', nIdx))
+ };
+ m_xPathBox->set_column_fixed_widths(aWidths);
+ // restore sort direction
+ bool bUp = o3tl::toInt32(o3tl::getToken(aUserData, 0, ';', nIdx)) != 0;
+ m_xPathBox->set_sort_order(bUp);
+ m_xPathBox->set_sort_indicator(bUp ? TRISTATE_TRUE : TRISTATE_FALSE, COL_TYPE);
+}
+
+void DbRegistrationOptionsPage::FillUserData()
+{
+ OUString aUserData = OUString::number( m_xPathBox->get_column_width(COL_TYPE) ) + ";";
+ bool bUp = m_xPathBox->get_sort_order();
+ aUserData += (bUp ? std::u16string_view(u"1") : std::u16string_view(u"0"));
+ SetUserData( aUserData );
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, DeleteHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo, CuiResId(RID_CUISTR_QUERY_DELETE_CONFIRM)));
+ if (xQuery->run() == RET_YES)
+ m_xPathBox->remove(nEntry);
+ }
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, NewHdl, weld::Button&, void)
+{
+ openLinkDialog(OUString(),OUString());
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathBoxDoubleClickHdl, weld::TreeView&, bool)
+{
+ EditHdl(*m_xEdit);
+ return true;
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, EditHdl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry == -1)
+ return;
+
+ DatabaseRegistration* pOldRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(nEntry));
+ if (!pOldRegistration || pOldRegistration->bReadOnly)
+ return;
+
+ OUString sOldName = m_xPathBox->get_text(nEntry, 0);
+ openLinkDialog(sOldName, pOldRegistration->sLocation, nEntry);
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, HeaderSelect_Impl, int, nCol, void )
+{
+ if (nCol != COL_TYPE)
+ return;
+
+ bool bSortMode = m_xPathBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ bSortMode = !bSortMode;
+ m_xPathBox->set_sort_order(bSortMode);
+
+ //sort lists
+ m_xPathBox->set_sort_indicator(bSortMode ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+}
+
+IMPL_LINK_NOARG(DbRegistrationOptionsPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ DatabaseRegistration* pRegistration = weld::fromId<DatabaseRegistration*>(m_xPathBox->get_selected_id());
+
+ bool bReadOnly = true;
+ if (pRegistration)
+ {
+ bReadOnly = pRegistration->bReadOnly;
+ }
+
+ m_xEdit->set_sensitive( !bReadOnly );
+ m_xDelete->set_sensitive( !bReadOnly );
+}
+
+void DbRegistrationOptionsPage::insertNewEntry(const OUString& _sName,const OUString& _sLocation, const bool _bReadOnly)
+{
+ OUString sId(weld::toId(new DatabaseRegistration(_sLocation, _bReadOnly)));
+ m_xPathBox->insert(nullptr, -1, &_sName, &sId, nullptr, nullptr, false, m_xIter.get());
+
+ if (_bReadOnly)
+ m_xPathBox->set_image(*m_xIter, RID_SVXBMP_LOCK);
+
+ m_xPathBox->set_text(*m_xIter, _sLocation, 1);
+}
+
+void DbRegistrationOptionsPage::openLinkDialog(const OUString& sOldName, const OUString& sOldLocation, int nEntry)
+{
+ ODocumentLinkDialog aDlg(GetFrameWeld(), nEntry == -1);
+
+ aDlg.setLink(sOldName, sOldLocation);
+ aDlg.setNameValidator(LINK( this, DbRegistrationOptionsPage, NameValidator ) );
+
+ if (aDlg.run() != RET_OK)
+ return;
+
+ OUString sNewName,sNewLocation;
+ aDlg.getLink(sNewName,sNewLocation);
+ if ( nEntry == -1 || sNewName != sOldName || sNewLocation != sOldLocation )
+ {
+ if (nEntry != -1)
+ {
+ delete weld::fromId<DatabaseRegistration*>(m_xPathBox->get_id(nEntry));
+ m_xPathBox->remove(nEntry);
+ }
+ insertNewEntry( sNewName, sNewLocation, false );
+ m_bModified = true;
+ }
+}
+
+IMPL_LINK( DbRegistrationOptionsPage, NameValidator, const OUString&, _rName, bool )
+{
+ int nCount = m_xPathBox->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (m_xPathBox->get_text(i, 0) == _rName)
+ return false;
+ }
+ return true;
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.cxx b/cui/source/options/dbregisterednamesconfig.cxx
new file mode 100644
index 000000000..b33e9ded6
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.cxx
@@ -0,0 +1,122 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregisterednamesconfig.hxx"
+#include "dbregistersettings.hxx"
+#include <svx/databaseregistrationui.hxx>
+#include <com/sun/star/sdb/DatabaseContext.hpp>
+#include <comphelper/processfactory.hxx>
+#include <svl/itemset.hxx>
+#include <tools/diagnose_ex.h>
+
+
+namespace svx
+{
+
+
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::sdb;
+ using namespace ::com::sun::star::container;
+
+ void DbRegisteredNamesConfig::GetOptions( SfxItemSet& _rFillItems )
+ {
+ DatabaseRegistrations aSettings;
+
+ try
+ {
+ Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(xContext) );
+
+ Sequence< OUString > aRegistrationNames( xRegistrations->getRegistrationNames() );
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ OUString sLocation( xRegistrations->getDatabaseLocation( *pRegistrationName ) );
+ aSettings[ *pRegistrationName ] =
+ DatabaseRegistration( sLocation, xRegistrations->isDatabaseRegistrationReadOnly( *pRegistrationName ) );
+ }
+ }
+ catch( const Exception& )
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options");
+ }
+
+ _rFillItems.Put( DatabaseMapItem( SID_SB_DB_REGISTER, std::move(aSettings) ) );
+ }
+
+
+ void DbRegisteredNamesConfig::SetOptions(const SfxItemSet& _rSourceItems)
+ {
+ // the settings for the single drivers
+ const DatabaseMapItem* pRegistrations = _rSourceItems.GetItem<DatabaseMapItem>(SID_SB_DB_REGISTER);
+ if ( !pRegistrations )
+ return;
+
+ try
+ {
+ Reference< XDatabaseContext > xRegistrations(
+ DatabaseContext::create(
+ comphelper::getProcessComponentContext()));
+
+ const DatabaseRegistrations& rNewRegistrations = pRegistrations->getRegistrations();
+ for ( DatabaseRegistrations::const_iterator reg = rNewRegistrations.begin();
+ reg != rNewRegistrations.end();
+ ++reg
+ )
+ {
+ const OUString sName = reg->first;
+ const OUString sLocation = reg->second.sLocation;
+
+ if ( xRegistrations->hasRegisteredDatabase( sName ) )
+ {
+ if ( !xRegistrations->isDatabaseRegistrationReadOnly( sName ) )
+ xRegistrations->changeDatabaseLocation( sName, sLocation );
+ else
+ {
+ OSL_ENSURE( xRegistrations->getDatabaseLocation( sName ) == sLocation,
+ "DbRegisteredNamesConfig::SetOptions: somebody changed a read-only registration. How unrespectful." );
+ }
+ }
+ else
+ xRegistrations->registerDatabaseLocation( sName, sLocation );
+ }
+
+ // delete unused entries
+ Sequence< OUString > aRegistrationNames = xRegistrations->getRegistrationNames();
+ const OUString* pRegistrationName = aRegistrationNames.getConstArray();
+ const OUString* pRegistrationNamesEnd = pRegistrationName + aRegistrationNames.getLength();
+ for ( ; pRegistrationName != pRegistrationNamesEnd; ++pRegistrationName )
+ {
+ if ( rNewRegistrations.find( *pRegistrationName ) == rNewRegistrations.end() )
+ xRegistrations->revokeDatabaseLocation( *pRegistrationName );
+ }
+ }
+ catch( const Exception& )
+ {
+ //DBG_UNHANDLED_EXCEPTION();
+ }
+ }
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregisterednamesconfig.hxx b/cui/source/options/dbregisterednamesconfig.hxx
new file mode 100644
index 000000000..9decf7e11
--- /dev/null
+++ b/cui/source/options/dbregisterednamesconfig.hxx
@@ -0,0 +1,38 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+class SfxItemSet;
+
+namespace svx
+{
+
+ class DbRegisteredNamesConfig
+ {
+
+ public:
+ static void GetOptions(SfxItemSet& _rFillItems);
+ static void SetOptions(const SfxItemSet& _rSourceItems);
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.cxx b/cui/source/options/dbregistersettings.cxx
new file mode 100644
index 000000000..c544e1111
--- /dev/null
+++ b/cui/source/options/dbregistersettings.cxx
@@ -0,0 +1,55 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "dbregistersettings.hxx"
+
+#include <rtl/ustring.hxx>
+
+
+namespace svx
+{
+
+ DatabaseMapItem::DatabaseMapItem( sal_uInt16 _nId, DatabaseRegistrations&& _rRegistrations )
+ :SfxPoolItem( _nId )
+ ,m_aRegistrations( std::move(_rRegistrations) )
+ {
+ }
+
+ bool DatabaseMapItem::operator==( const SfxPoolItem& _rCompare ) const
+ {
+ if (!SfxPoolItem::operator==(_rCompare))
+ return false;
+ const DatabaseMapItem* pItem = static_cast<const DatabaseMapItem*>( &_rCompare );
+ if ( !pItem )
+ return false;
+
+ if ( m_aRegistrations.size() != pItem->m_aRegistrations.size() )
+ return false;
+
+ return m_aRegistrations == pItem->m_aRegistrations;
+ }
+
+ DatabaseMapItem* DatabaseMapItem::Clone( SfxItemPool* ) const
+ {
+ return new DatabaseMapItem( *this );
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/dbregistersettings.hxx b/cui/source/options/dbregistersettings.hxx
new file mode 100644
index 000000000..b1db16542
--- /dev/null
+++ b/cui/source/options/dbregistersettings.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <map>
+
+#include <svl/poolitem.hxx>
+#include <utility>
+
+
+namespace svx
+{
+
+
+ struct DatabaseRegistration
+ {
+ OUString sLocation;
+ bool bReadOnly;
+
+ DatabaseRegistration()
+ :sLocation()
+ ,bReadOnly( true )
+ {
+ }
+
+ DatabaseRegistration( OUString _aLocation, const bool _bReadOnly )
+ :sLocation(std::move( _aLocation ))
+ ,bReadOnly( _bReadOnly )
+ {
+ }
+
+ bool operator==( const DatabaseRegistration& _rhs ) const
+ {
+ return ( sLocation == _rhs.sLocation );
+ // do not take the read-only-ness into account, this is not maintained everywhere, but only
+ // properly set when filling the struct from the XDatabaseRegistrations data
+ }
+
+ };
+
+ typedef std::map< OUString, DatabaseRegistration > DatabaseRegistrations;
+
+ class DatabaseMapItem final : public SfxPoolItem
+ {
+ DatabaseRegistrations m_aRegistrations;
+
+ public:
+
+ DatabaseMapItem( sal_uInt16 _nId, DatabaseRegistrations&& _rRegistrations );
+
+ virtual bool operator==( const SfxPoolItem& ) const override;
+ virtual DatabaseMapItem* Clone( SfxItemPool *pPool = nullptr ) const override;
+
+ const DatabaseRegistrations&
+ getRegistrations() const { return m_aRegistrations; }
+ };
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.cxx b/cui/source/options/doclinkdialog.cxx
new file mode 100644
index 000000000..4218a18a1
--- /dev/null
+++ b/cui/source/options/doclinkdialog.cxx
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "doclinkdialog.hxx"
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <comphelper/processfactory.hxx>
+#include <strings.hrc>
+#include <svl/filenotation.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <ucbhelper/content.hxx>
+#include <dialmgr.hxx>
+#include <tools/urlobj.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/docfilt.hxx>
+
+namespace svx
+{
+ using namespace ::com::sun::star;
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::ucb;
+ using namespace ::svt;
+
+ ODocumentLinkDialog::ODocumentLinkDialog(weld::Window* pParent, bool _bCreateNew)
+ : GenericDialogController(pParent, "cui/ui/databaselinkdialog.ui", "DatabaseLinkDialog")
+ , m_xBrowseFile(m_xBuilder->weld_button("browse"))
+ , m_xName(m_xBuilder->weld_entry("name"))
+ , m_xOK(m_xBuilder->weld_button("ok"))
+ , m_xAltTitle(m_xBuilder->weld_label("alttitle"))
+ , m_xURL(new SvtURLBox(m_xBuilder->weld_combo_box("url")))
+ {
+ if (!_bCreateNew)
+ m_xDialog->set_title(m_xAltTitle->get_label());
+
+ m_xURL->SetSmartProtocol(INetProtocol::File);
+ m_xURL->DisableHistory();
+ m_xURL->SetFilter("*.odb");
+
+ m_xName->connect_changed( LINK(this, ODocumentLinkDialog, OnEntryModified) );
+ m_xURL->connect_changed( LINK(this, ODocumentLinkDialog, OnComboBoxModified) );
+ m_xBrowseFile->connect_clicked( LINK(this, ODocumentLinkDialog, OnBrowseFile) );
+ m_xOK->connect_clicked( LINK(this, ODocumentLinkDialog, OnOk) );
+
+ validate();
+ }
+
+ ODocumentLinkDialog::~ODocumentLinkDialog()
+ {
+ }
+
+ void ODocumentLinkDialog::setLink(const OUString& rName, const OUString& rURL)
+ {
+ m_xName->set_text(rName);
+ m_xURL->set_entry_text(rURL);
+ validate();
+ }
+
+ void ODocumentLinkDialog::getLink(OUString& rName, OUString& rURL) const
+ {
+ rName = m_xName->get_text();
+ rURL = m_xURL->get_active_text();
+ }
+
+ void ODocumentLinkDialog::validate( )
+ {
+ m_xOK->set_sensitive((!m_xName->get_text().isEmpty()) && (!m_xURL->get_active_text().isEmpty()));
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnOk, weld::Button&, void)
+ {
+ // get the current URL
+ OUString sURL = m_xURL->get_active_text();
+ OFileNotation aTransformer(sURL);
+ sURL = aTransformer.get(OFileNotation::N_URL);
+
+ // check for the existence of the selected file
+ bool bFileExists = false;
+ try
+ {
+ ::ucbhelper::Content aFile(sURL, Reference< XCommandEnvironment >(), comphelper::getProcessComponentContext());
+ if (aFile.isDocument())
+ bFileExists = true;
+ }
+ catch(Exception&)
+ {
+ }
+
+ if (!bFileExists)
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_DOESNOTEXIST);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ } // if (!bFileExists)
+ INetURLObject aURL( sURL );
+ if ( aURL.GetProtocol() != INetProtocol::File )
+ {
+ OUString sMsg = CuiResId(STR_LINKEDDOC_NO_SYSTEM_FILE);
+ sMsg = sMsg.replaceFirst("$file$", m_xURL->get_active_text());
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+ return;
+ }
+
+ OUString sCurrentText = m_xName->get_text();
+ if ( m_aNameValidator.IsSet() )
+ {
+ if ( !m_aNameValidator.Call( sCurrentText ) )
+ {
+ OUString sMsg = CuiResId(STR_NAME_CONFLICT);
+ sMsg = sMsg.replaceFirst("$file$", sCurrentText);
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok, sMsg));
+ xErrorBox->run();
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ return;
+ }
+ }
+
+ m_xDialog->response(RET_OK);
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnBrowseFile, weld::Button&, void)
+ {
+ ::sfx2::FileDialogHelper aFileDlg(
+ ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION, FileDialogFlags::NONE, m_xDialog.get());
+ std::shared_ptr<const SfxFilter> pFilter = SfxFilter::GetFilterByName("StarOffice XML (Base)");
+ if ( pFilter )
+ {
+ aFileDlg.AddFilter(pFilter->GetUIName(),pFilter->GetDefaultExtension());
+ aFileDlg.SetCurrentFilter(pFilter->GetUIName());
+ }
+
+ OUString sPath = m_xURL->get_active_text();
+ if (!sPath.isEmpty())
+ {
+ OFileNotation aTransformer( sPath, OFileNotation::N_SYSTEM );
+ aFileDlg.SetDisplayDirectory( aTransformer.get( OFileNotation::N_URL ) );
+ }
+
+ if (ERRCODE_NONE != aFileDlg.Execute())
+ return;
+
+ if (m_xName->get_text().isEmpty())
+ { // default the name to the base of the chosen URL
+ INetURLObject aParser;
+
+ aParser.SetSmartProtocol(INetProtocol::File);
+ aParser.SetSmartURL(aFileDlg.GetPath());
+
+ m_xName->set_text(aParser.getBase(INetURLObject::LAST_SEGMENT, true, INetURLObject::DecodeMechanism::WithCharset));
+
+ m_xName->select_region(0, -1);
+ m_xName->grab_focus();
+ }
+ else
+ m_xURL->grab_focus();
+
+ // get the path in system notation
+ OFileNotation aTransformer(aFileDlg.GetPath(), OFileNotation::N_URL);
+ m_xURL->set_entry_text(aTransformer.get(OFileNotation::N_SYSTEM));
+
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnEntryModified, weld::Entry&, void)
+ {
+ validate();
+ }
+
+ IMPL_LINK_NOARG(ODocumentLinkDialog, OnComboBoxModified, weld::ComboBox&, void)
+ {
+ validate();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/doclinkdialog.hxx b/cui/source/options/doclinkdialog.hxx
new file mode 100644
index 000000000..371dc6504
--- /dev/null
+++ b/cui/source/options/doclinkdialog.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+#include <svtools/inettbc.hxx>
+
+namespace svx
+{
+ /** dialog for editing document links associated with data sources
+ */
+ class ODocumentLinkDialog final : public weld::GenericDialogController
+ {
+ Link<const OUString&,bool> m_aNameValidator;
+
+ std::unique_ptr<weld::Button> m_xBrowseFile;
+ std::unique_ptr<weld::Entry> m_xName;
+ std::unique_ptr<weld::Button> m_xOK;
+ std::unique_ptr<weld::Label> m_xAltTitle;
+ std::unique_ptr<SvtURLBox> m_xURL;
+
+ public:
+ ODocumentLinkDialog(weld::Window* pParent, bool bCreateNew);
+ virtual ~ODocumentLinkDialog() override;
+
+ // name validation has to be done by an external instance
+ // the validator link gets a pointer to a String, and should return 0 if the string is not
+ // acceptable
+ void setNameValidator( const Link<const OUString&,bool>& _rValidator ) { m_aNameValidator = _rValidator; }
+
+ void setLink( const OUString& _rName, const OUString& _rURL );
+ void getLink( OUString& _rName, OUString& _rURL ) const;
+
+ private:
+ DECL_LINK( OnEntryModified, weld::Entry&, void );
+ DECL_LINK( OnComboBoxModified, weld::ComboBox&, void );
+ DECL_LINK( OnBrowseFile, weld::Button&, void );
+ DECL_LINK( OnOk, weld::Button&, void );
+
+ void validate();
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.cxx b/cui/source/options/fontsubs.cxx
new file mode 100644
index 000000000..93c8b03d9
--- /dev/null
+++ b/cui/source/options/fontsubs.cxx
@@ -0,0 +1,405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <officecfg/Office/Common.hxx>
+#include <svtools/ctrltool.hxx>
+#include <vcl/svapp.hxx>
+#include <svtools/fontsubstconfig.hxx>
+#include "fontsubs.hxx"
+#include <helpids.h>
+
+/*********************************************************************/
+/* */
+/* TabPage font replacement */
+/* */
+/*********************************************************************/
+
+SvxFontSubstTabPage::SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfontspage.ui", "OptFontsPage", &rSet)
+ , m_xUseTableCB(m_xBuilder->weld_check_button("usetable"))
+ , m_xFont1CB(m_xBuilder->weld_combo_box("font1"))
+ , m_xFont2CB(m_xBuilder->weld_combo_box("font2"))
+ , m_xApply(m_xBuilder->weld_button("apply"))
+ , m_xDelete(m_xBuilder->weld_button("delete"))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklb"))
+ , m_xFontNameLB(m_xBuilder->weld_combo_box("fontname"))
+ , m_xNonPropFontsOnlyCB(m_xBuilder->weld_check_button("nonpropfontonly"))
+ , m_xFontHeightLB(m_xBuilder->weld_combo_box("fontheight"))
+{
+ m_xFont1CB->make_sorted();
+ m_xFont1CB->set_size_request(1, -1);
+ m_xFont2CB->make_sorted();
+ m_xFont2CB->set_size_request(1, -1);
+ m_sAutomatic = m_xFontNameLB->get_text(0);
+ assert(!m_sAutomatic.isEmpty());
+
+ m_xCheckLB->set_size_request(m_xCheckLB->get_approximate_digit_width() * 60,
+ m_xCheckLB->get_height_rows(8));
+ m_xCheckLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xCheckLB->set_help_id(HID_OFA_FONT_SUBST_CLB);
+ m_xCheckLB->set_selection_mode(SelectionMode::Multiple);
+
+ setColSizes(m_xCheckLB->get_size_request());
+ m_xCheckLB->connect_size_allocate(LINK(this, SvxFontSubstTabPage, ResizeHdl));
+
+ m_xCheckLB->set_centered_column(0);
+ m_xCheckLB->set_centered_column(1);
+
+ Link<weld::ComboBox&,void> aLink2(LINK(this, SvxFontSubstTabPage, SelectComboBoxHdl));
+ Link<weld::Button&,void> aClickLink(LINK(this, SvxFontSubstTabPage, ClickHdl));
+
+ m_xCheckLB->connect_changed(LINK(this, SvxFontSubstTabPage, TreeListBoxSelectHdl));
+ m_xCheckLB->connect_column_clicked(LINK(this, SvxFontSubstTabPage, HeaderBarClick));
+ m_xUseTableCB->connect_toggled(LINK(this, SvxFontSubstTabPage, ToggleHdl));
+ m_xFont1CB->connect_changed(aLink2);
+ m_xFont2CB->connect_changed(aLink2);
+ m_xApply->connect_clicked(aClickLink);
+ m_xDelete->connect_clicked(aClickLink);
+
+ m_xNonPropFontsOnlyCB->connect_toggled(LINK(this, SvxFontSubstTabPage, NonPropFontsHdl));
+
+ sal_uInt16 nHeight;
+ for(nHeight = 6; nHeight <= 16; nHeight++)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 18; nHeight <= 28; nHeight+= 2)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 32; nHeight <= 48; nHeight+= 4)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 54; nHeight <= 72; nHeight+= 6)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+ for(nHeight = 80; nHeight <= 96; nHeight+= 8)
+ m_xFontHeightLB->append_text(OUString::number(nHeight));
+}
+
+IMPL_LINK(SvxFontSubstTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = m_xCheckLB->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xCheckLB->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xCheckLB->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ m_xCheckLB->set_sort_indicator(TRISTATE_INDET, m_xCheckLB->get_sort_column());
+ m_xCheckLB->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xCheckLB->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+void SvxFontSubstTabPage::setColSizes(const Size& rSize)
+{
+ int nW1 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(2)).Width();
+ int nW2 = m_xCheckLB->get_pixel_size(m_xCheckLB->get_column_title(3)).Width();
+ int nMax = std::max( nW1, nW2 ) + 6; // width of the longest header + a little offset
+ int nMin = m_xCheckLB->get_checkbox_column_width();
+ nMax = std::max(nMax, nMin);
+ const int nDoubleMax = 2*nMax;
+ const int nRest = rSize.Width() - nDoubleMax;
+ std::vector<int> aWidths { nMax, nMax, nRest/2 };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ResizeHdl, const Size&, rSize, void)
+{
+ setColSizes(rSize);
+}
+
+SvxFontSubstTabPage::~SvxFontSubstTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxFontSubstTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxFontSubstTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxFontSubstTabPage::FillItemSet( SfxItemSet* )
+{
+ std::vector<SubstitutionStruct> aNewFontSubs;
+
+ m_xCheckLB->all_foreach([this, &aNewFontSubs](weld::TreeIter& rIter) {
+ SubstitutionStruct aAdd;
+ aAdd.sFont = m_xCheckLB->get_text(rIter, 2);
+ aAdd.sReplaceBy = m_xCheckLB->get_text(rIter, 3);
+ aAdd.bReplaceAlways = m_xCheckLB->get_toggle(rIter, 0);
+ aAdd.bReplaceOnScreenOnly = m_xCheckLB->get_toggle(rIter, 1);
+ aNewFontSubs.push_back(aAdd);
+ return false;
+ });
+
+ svtools::SetFontSubstitutions(m_xUseTableCB->get_active(), aNewFontSubs);
+ svtools::ApplyFontSubstitutionsToVcl();
+
+ std::shared_ptr< comphelper::ConfigurationChanges > batch(
+ comphelper::ConfigurationChanges::create());
+ if (m_xFontHeightLB->get_value_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::set(
+ static_cast< sal_Int16 >(m_xFontHeightLB->get_active_text().toInt32()),
+ batch);
+ if (m_xNonPropFontsOnlyCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::set(
+ m_xNonPropFontsOnlyCB->get_active(), batch);
+ //font name changes cannot be detected by saved values
+ OUString sFontName;
+ if (m_xFontNameLB->get_active() != -1)
+ sFontName = m_xFontNameLB->get_active_text();
+ officecfg::Office::Common::Font::SourceViewFont::FontName::set(
+ std::optional< OUString >(sFontName), batch);
+ batch->commit();
+
+ return false;
+}
+
+void SvxFontSubstTabPage::Reset( const SfxItemSet* )
+{
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ m_xFont1CB->freeze();
+ m_xFont1CB->clear();
+ m_xFont2CB->freeze();
+ m_xFont2CB->clear();
+
+ FontList aFntLst(Application::GetDefaultDevice());
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for (sal_uInt16 i = 0; i < nFontCount; ++i)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName(i);
+ m_xFont1CB->append_text(rFontMetric.GetFamilyName());
+ m_xFont2CB->append_text(rFontMetric.GetFamilyName());
+ }
+
+ m_xFont2CB->thaw();
+ m_xFont1CB->thaw();
+
+ m_xUseTableCB->set_active(svtools::IsFontSubstitutionsEnabled());
+
+ std::vector<SubstitutionStruct> aFontSubs = svtools::GetFontSubstitutions();
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ for (auto const & sub: aFontSubs)
+ {
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceAlways ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, sub.bReplaceOnScreenOnly ? TRISTATE_TRUE : TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sub.sFont, 2);
+ m_xCheckLB->set_text(*xIter, sub.sReplaceBy, 3);
+ }
+
+ m_xCheckLB->thaw();
+
+ m_xCheckLB->make_sorted();
+ m_xCheckLB->set_sort_column(2);
+ m_xCheckLB->set_sort_indicator(TRISTATE_TRUE, 2);
+
+ SelectHdl(m_xFont1CB.get());
+
+ //fill font name box first
+ m_xNonPropFontsOnlyCB->set_active(
+ officecfg::Office::Common::Font::SourceViewFont::
+ NonProportionalFontsOnly::get());
+ NonPropFontsHdl(*m_xNonPropFontsOnlyCB);
+ OUString sFontName(
+ officecfg::Office::Common::Font::SourceViewFont::FontName::get().
+ value_or(OUString()));
+ if(!sFontName.isEmpty())
+ m_xFontNameLB->set_active_text(sFontName);
+ else
+ m_xFontNameLB->set_active(0);
+ m_xFontHeightLB->set_active_text(
+ OUString::number(
+ officecfg::Office::Common::Font::SourceViewFont::FontHeight::
+ get()));
+ m_xNonPropFontsOnlyCB->save_state();
+ m_xFontHeightLB->save_value();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ToggleHdl, weld::Toggleable&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, ClickHdl, weld::Button&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, TreeListBoxSelectHdl, weld::TreeView&, rButton, void)
+{
+ SelectHdl(&rButton);
+}
+
+IMPL_LINK(SvxFontSubstTabPage, SelectComboBoxHdl, weld::ComboBox&, rBox, void)
+{
+ SelectHdl(&rBox);
+}
+
+namespace
+{
+ // search in the "font" column
+ int findText(const weld::TreeView& rTreeView, std::u16string_view rCol)
+ {
+ for (int i = 0, nEntryCount = rTreeView.n_children(); i < nEntryCount; ++i)
+ {
+ if (rTreeView.get_text(i, 2) == rCol)
+ return i;
+ }
+ return -1;
+ }
+
+ bool findRow(const weld::TreeView& rTreeView, std::u16string_view rCol1, std::u16string_view rCol2)
+ {
+ int nRow = findText(rTreeView, rCol1);
+ if (nRow == -1)
+ return false;
+ return rTreeView.get_text(nRow, 3) == rCol2;
+ }
+}
+
+void SvxFontSubstTabPage::SelectHdl(const weld::Widget* pWin)
+{
+ if (pWin == m_xApply.get() || pWin == m_xDelete.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+ if (pWin == m_xApply.get())
+ {
+ m_xCheckLB->unselect_all();
+ if (nPos != -1)
+ {
+ // change entry
+ m_xCheckLB->set_text(nPos, m_xFont2CB->get_active_text(), 3);
+ m_xCheckLB->select(nPos);
+ }
+ else
+ {
+ // new entry
+ OUString sFont1 = m_xFont1CB->get_active_text();
+ OUString sFont2 = m_xFont2CB->get_active_text();
+
+ std::unique_ptr<weld::TreeIter> xIter(m_xCheckLB->make_iterator());
+ m_xCheckLB->append(xIter.get());
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 0);
+ m_xCheckLB->set_toggle(*xIter, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(*xIter, sFont1, 2);
+ m_xCheckLB->set_text(*xIter, sFont2, 3);
+ m_xCheckLB->select(*xIter);
+ }
+ }
+ else if (pWin == m_xDelete.get())
+ {
+ m_xCheckLB->remove_selection();
+ }
+ }
+
+ if (pWin == m_xCheckLB.get())
+ {
+ const int nSelectedRowCount = m_xCheckLB->count_selected_rows();
+ if (nSelectedRowCount == 1)
+ {
+ int nRow = m_xCheckLB->get_selected_index();
+ m_xFont1CB->set_entry_text(m_xCheckLB->get_text(nRow, 2));
+ m_xFont2CB->set_entry_text(m_xCheckLB->get_text(nRow, 3));
+ }
+ else if (nSelectedRowCount > 1)
+ {
+ m_xFont1CB->set_entry_text(OUString());
+ m_xFont2CB->set_entry_text(OUString());
+ }
+ }
+
+ if (pWin == m_xFont1CB.get())
+ {
+ int nPos = findText(*m_xCheckLB, m_xFont1CB->get_active_text());
+
+ if (nPos != -1)
+ {
+ int nSelectedRow = m_xCheckLB->get_selected_index();
+ if (nPos != nSelectedRow)
+ {
+ m_xCheckLB->unselect_all();
+ m_xCheckLB->select(nPos);
+ }
+ }
+ else
+ m_xCheckLB->unselect_all();
+ }
+
+ CheckEnable();
+}
+
+IMPL_LINK(SvxFontSubstTabPage, NonPropFontsHdl, weld::Toggleable&, rBox, void)
+{
+ OUString sFontName = m_xFontNameLB->get_active_text();
+ bool bNonPropOnly = rBox.get_active();
+ m_xFontNameLB->clear();
+ FontList aFntLst( Application::GetDefaultDevice() );
+ m_xFontNameLB->append_text(m_sAutomatic);
+ sal_uInt16 nFontCount = aFntLst.GetFontNameCount();
+ for(sal_uInt16 nFont = 0; nFont < nFontCount; nFont++)
+ {
+ const FontMetric& rFontMetric = aFntLst.GetFontName( nFont );
+ if(!bNonPropOnly || rFontMetric.GetPitch() == PITCH_FIXED)
+ m_xFontNameLB->append_text(rFontMetric.GetFamilyName());
+ }
+ m_xFontNameLB->set_active_text(sFontName);
+}
+
+void SvxFontSubstTabPage::CheckEnable()
+{
+ bool bEnableAll = m_xUseTableCB->get_active();
+ m_xCheckLB->set_sensitive(bEnableAll);
+ m_xFont1CB->set_sensitive(bEnableAll);
+ m_xFont2CB->set_sensitive(bEnableAll);
+
+ bool bApply = bEnableAll, bDelete = bEnableAll;
+
+ if (bEnableAll)
+ {
+ int nEntry = m_xCheckLB->get_selected_index();
+
+ if (m_xFont1CB->get_active_text().isEmpty() || m_xFont2CB->get_active_text().isEmpty())
+ bApply = false;
+ else if (m_xFont1CB->get_active_text() == m_xFont2CB->get_active_text())
+ bApply = false;
+ else if (findRow(*m_xCheckLB, m_xFont1CB->get_active_text(), m_xFont2CB->get_active_text()))
+ bApply = false;
+ else if (nEntry != -1 && m_xCheckLB->count_selected_rows() != 1)
+ bApply = false;
+ else
+ bApply = true;
+
+ bDelete = nEntry != -1;
+ }
+
+ m_xApply->set_sensitive(bApply);
+ m_xDelete->set_sensitive(bDelete);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/fontsubs.hxx b/cui/source/options/fontsubs.hxx
new file mode 100644
index 000000000..dc55d9434
--- /dev/null
+++ b/cui/source/options/fontsubs.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxFontSubstTabPage ----------------------------------------------------
+class SvtFontSubstConfig;
+class SvxFontSubstTabPage : public SfxTabPage
+{
+ OUString m_sAutomatic;
+
+ std::unique_ptr<weld::CheckButton> m_xUseTableCB;
+ std::unique_ptr<weld::ComboBox> m_xFont1CB;
+ std::unique_ptr<weld::ComboBox> m_xFont2CB;
+ std::unique_ptr<weld::Button> m_xApply;
+ std::unique_ptr<weld::Button> m_xDelete;
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::ComboBox> m_xFontNameLB;
+ std::unique_ptr<weld::CheckButton> m_xNonPropFontsOnlyCB;
+ std::unique_ptr<weld::ComboBox> m_xFontHeightLB;
+
+ DECL_LINK(SelectComboBoxHdl, weld::ComboBox&, void);
+ DECL_LINK(ToggleHdl, weld::Toggleable&, void);
+ DECL_LINK(ClickHdl, weld::Button&, void);
+ DECL_LINK(TreeListBoxSelectHdl, weld::TreeView&, void);
+ DECL_LINK(NonPropFontsHdl, weld::Toggleable&, void);
+ DECL_LINK(HeaderBarClick, int, void);
+ DECL_LINK(ResizeHdl, const Size&, void);
+
+ void SelectHdl(const weld::Widget* pWidget);
+
+ void CheckEnable();
+ void setColSizes(const Size& rSize);
+
+public:
+ SvxFontSubstTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+ virtual ~SvxFontSubstTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.cxx b/cui/source/options/optaboutconfig.cxx
new file mode 100644
index 000000000..c4dafaf5c
--- /dev/null
+++ b/cui/source/options/optaboutconfig.cxx
@@ -0,0 +1,965 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <o3tl/safeint.hxx>
+#include <o3tl/string_view.hxx>
+#include "optaboutconfig.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/uno/Reference.hxx>
+#include <com/sun/star/uno/Type.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <cppu/unotype.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <unotools/textsearch.hxx>
+#include <utility>
+#include <vcl/event.hxx>
+#include <sal/log.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <algorithm>
+#include <memory>
+#include <vector>
+
+using namespace ::com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::container;
+
+#define SHORT_LEN_LIMIT 7
+#define LONG_LEN_LIMIT 11
+#define HYPER_LEN_LIMIT 20
+
+struct Prop_Impl
+{
+ OUString Name;
+ OUString Property;
+ Any Value;
+
+ Prop_Impl( OUString sName, OUString sProperty, Any aValue )
+ : Name(std::move( sName ))
+ , Property(std::move( sProperty ))
+ , Value(std::move( aValue ))
+ {}
+};
+
+struct UserData
+{
+ bool bIsPropertyPath;
+ OUString sPropertyPath;
+ int aLineage;
+ Reference<XNameAccess> aXNameAccess;
+
+ explicit UserData( OUString aPropertyPath )
+ : bIsPropertyPath( true )
+ , sPropertyPath(std::move(aPropertyPath))
+ , aLineage(0)
+ {}
+
+ explicit UserData( Reference<XNameAccess> const & rXNameAccess, int rIndex )
+ : bIsPropertyPath( false )
+ , aLineage(rIndex)
+ , aXNameAccess( rXNameAccess )
+ {}
+};
+
+IMPL_LINK(CuiAboutConfigValueDialog, KeyInputHdl, const KeyEvent&, rKeyEvent, bool)
+{
+ bool bValid = false;
+ bool bNonSpace = rKeyEvent.GetKeyCode().GetCode() != KEY_SPACE;
+ if (m_bNumericOnly && bNonSpace )
+ {
+ const vcl::KeyCode& rKeyCode = rKeyEvent.GetKeyCode();
+ sal_uInt16 nGroup = rKeyCode.GetGroup();
+ sal_uInt16 nKey = rKeyCode.GetCode();
+
+ switch ( nGroup ) {
+ case KEYGROUP_NUM :
+ case KEYGROUP_CURSOR :
+ {
+ bValid = true;
+ break;
+ }
+
+ case KEYGROUP_MISC :
+ {
+ switch ( nKey ) {
+ case KEY_SUBTRACT :
+ case KEY_COMMA :
+ case KEY_POINT :
+ {
+ bValid = true;
+ break;
+ }
+
+ default :
+ {
+ if( nKey < KEY_ADD || nKey > KEY_EQUAL )
+ bValid = true;
+ break;
+ }
+ }
+ break;
+ }
+
+ default :
+ {
+ bValid = false;
+ break;
+ }
+ }
+
+ //Select all, Copy, Paste, Cut, Undo Keys
+ if ( !bValid && ( rKeyCode.IsMod1() && (
+ KEY_A == nKey || KEY_C == nKey || KEY_V == nKey || KEY_X == nKey || KEY_Z == nKey ) ) )
+ bValid = true;
+ }
+ else
+ bValid = true;
+
+ //if value return true to claim that it has been handled
+ return !bValid;
+}
+
+CuiAboutConfigTabPage::CuiAboutConfigTabPage(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/aboutconfigdialog.ui", "AboutConfig")
+ , m_xResetBtn(m_xBuilder->weld_button("reset"))
+ , m_xEditBtn(m_xBuilder->weld_button("edit"))
+ , m_xSearchBtn(m_xBuilder->weld_button("searchButton"))
+ , m_xSearchEdit(m_xBuilder->weld_entry("searchEntry"))
+ , m_xPrefBox(m_xBuilder->weld_tree_view("preferences"))
+ , m_xScratchIter(m_xPrefBox->make_iterator())
+ , m_bSorted(false)
+{
+ m_xPrefBox->set_size_request(m_xPrefBox->get_approximate_digit_width() * 100,
+ m_xPrefBox->get_height_rows(23));
+ m_xPrefBox->connect_column_clicked(LINK(this, CuiAboutConfigTabPage, HeaderBarClick));
+
+ m_xEditBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, StandardHdl_Impl));
+ m_xResetBtn->connect_clicked(LINK( this, CuiAboutConfigTabPage, ResetBtnHdl_Impl));
+ m_xPrefBox->connect_row_activated(LINK(this, CuiAboutConfigTabPage, DoubleClickHdl_Impl));
+ m_xPrefBox->connect_expanding(LINK(this, CuiAboutConfigTabPage, ExpandingHdl_Impl));
+ m_xSearchBtn->connect_clicked(LINK(this, CuiAboutConfigTabPage, SearchHdl_Impl));
+
+ m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
+ m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ m_options.searchFlag |= (util::SearchFlags::REG_NOT_BEGINOFLINE |
+ util::SearchFlags::REG_NOT_ENDOFLINE);
+
+ float fWidth = m_xPrefBox->get_approximate_digit_width();
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(fWidth * 65),
+ o3tl::narrowing<int>(fWidth * 20),
+ o3tl::narrowing<int>(fWidth * 8)
+ };
+ m_xPrefBox->set_column_fixed_widths(aWidths);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, HeaderBarClick, int, nColumn, void)
+{
+ if (!m_bSorted)
+ {
+ m_xPrefBox->make_sorted();
+ m_bSorted = true;
+ }
+
+ bool bSortAtoZ = m_xPrefBox->get_sort_order();
+
+ //set new arrow positions in headerbar
+ if (nColumn == m_xPrefBox->get_sort_column())
+ {
+ bSortAtoZ = !bSortAtoZ;
+ m_xPrefBox->set_sort_order(bSortAtoZ);
+ }
+ else
+ {
+ int nOldSortColumn = m_xPrefBox->get_sort_column();
+ if (nOldSortColumn != -1)
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, nOldSortColumn);
+ m_xPrefBox->set_sort_column(nColumn);
+ }
+
+ if (nColumn != -1)
+ {
+ //sort lists
+ m_xPrefBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+ }
+}
+
+CuiAboutConfigTabPage::~CuiAboutConfigTabPage()
+{
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const OUString& rPropertyPath, const OUString& rProp, const OUString& rStatus,
+ const OUString& rType, const OUString& rValue, const weld::TreeIter* pParentEntry,
+ bool bInsertToPrefBox)
+{
+ m_vectorUserData.push_back(std::make_unique<UserData>(rPropertyPath));
+ if (bInsertToPrefBox)
+ {
+ OUString sId(weld::toId(m_vectorUserData.back().get()));
+ m_xPrefBox->insert(pParentEntry, -1, &rProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rValue, 3);
+ }
+ else
+ {
+ m_prefBoxEntries.push_back({rProp, rStatus, rType, rValue, m_vectorUserData.back().get()});
+ }
+}
+
+void CuiAboutConfigTabPage::Reset()
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->clear();
+ m_vectorOfModified.clear();
+ if (m_bSorted)
+ {
+ m_xPrefBox->set_sort_indicator(TRISTATE_INDET, m_xPrefBox->get_sort_column());
+ m_xPrefBox->make_unsorted();
+ m_bSorted = false;
+ }
+ m_prefBoxEntries.clear();
+ m_modifiedPrefBoxEntries.clear();
+
+ m_xPrefBox->freeze();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ //Load all XNameAccess to m_prefBoxEntries
+ FillItems( xConfigAccess, nullptr, 0, true );
+ //Load xConfigAccess' children to m_prefBox
+ FillItems( xConfigAccess );
+ m_xPrefBox->thaw();
+}
+
+void CuiAboutConfigTabPage::FillItemSet()
+{
+ std::vector< std::shared_ptr< Prop_Impl > >::iterator pIter;
+ for( pIter = m_vectorOfModified.begin() ; pIter != m_vectorOfModified.end(); ++pIter )
+ {
+ Reference< XNameAccess > xUpdateAccess = getConfigAccess( (*pIter)->Name , true );
+ Reference< XNameReplace > xNameReplace( xUpdateAccess, UNO_QUERY_THROW );
+
+ xNameReplace->replaceByName( (*pIter)->Property, (*pIter)->Value );
+
+ Reference< util::XChangesBatch > xChangesBatch( xUpdateAccess, UNO_QUERY_THROW );
+ xChangesBatch->commitChanges();
+ }
+}
+
+void CuiAboutConfigTabPage::FillItems(const Reference< XNameAccess >& xNameAccess, const weld::TreeIter* pParentEntry,
+ int lineage, bool bLoadAll)
+{
+ OUString sPath = Reference< XHierarchicalName >(
+ xNameAccess, uno::UNO_QUERY_THROW )->getHierarchicalName();
+ const uno::Sequence< OUString > seqItems = xNameAccess->getElementNames();
+ for( const OUString& item : seqItems )
+ {
+ Any aNode = xNameAccess->getByName( item );
+
+ bool bNotLeaf = false;
+
+ Reference< XNameAccess > xNextNameAccess;
+ try
+ {
+ xNextNameAccess.set(aNode, uno::UNO_QUERY);
+ bNotLeaf = xNextNameAccess.is();
+ }
+ catch (const RuntimeException&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "CuiAboutConfigTabPage");
+ }
+
+ if (bNotLeaf)
+ {
+ if(bLoadAll)
+ FillItems(xNextNameAccess, nullptr, lineage + 1, true);
+ else
+ {
+ // not leaf node
+ m_vectorUserData.push_back(std::make_unique<UserData>(xNextNameAccess, lineage + 1));
+ OUString sId(weld::toId(m_vectorUserData.back().get()));
+
+ m_xPrefBox->insert(pParentEntry, -1, &item, &sId, nullptr, nullptr, true, m_xScratchIter.get());
+ // Necessary, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*m_xScratchIter, "", 1);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 2);
+ m_xPrefBox->set_text(*m_xScratchIter, "", 3);
+ }
+ }
+ else
+ {
+ // leaf node
+ OUString sPropertyName = item;
+ auto it = std::find_if(m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&sPath, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == sPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ OUString sType = aNode.getValueTypeName();
+ OUStringBuffer sValue;
+
+ if (it != m_modifiedPrefBoxEntries.end())
+ sValue = it->sValue;
+ else
+ {
+ switch( aNode.getValueType().getTypeClass() )
+ {
+ case css::uno::TypeClass_VOID:
+ break;
+
+ case css::uno::TypeClass_BOOLEAN:
+ sValue = OUString::boolean( aNode.get<bool>() );
+ break;
+
+ case css::uno::TypeClass_SHORT:
+ case css::uno::TypeClass_LONG:
+ case css::uno::TypeClass_HYPER:
+ sValue = OUString::number( aNode.get<sal_Int64>() );
+ break;
+
+ case css::uno::TypeClass_DOUBLE:
+ sValue = OUString::number( aNode.get<double>() );
+ break;
+
+ case css::uno::TypeClass_STRING:
+ sValue = aNode.get<OUString>();
+ break;
+
+ case css::uno::TypeClass_SEQUENCE:
+ if( sType == "[]boolean" )
+ {
+ uno::Sequence<sal_Bool> seq = aNode.get< uno::Sequence<sal_Bool> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(OUString::boolean( seq[j] ));
+ }
+ }
+ else if( sType == "[]byte" )
+ {
+ const uno::Sequence<sal_Int8> seq = aNode.get< uno::Sequence<sal_Int8> >();
+ for( sal_Int8 j : seq )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(j), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ else if( sType == "[][]byte" )
+ {
+ const uno::Sequence< uno::Sequence<sal_Int8> > seq = aNode.get< uno::Sequence< uno::Sequence<sal_Int8> > >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ for( sal_Int8 k : seq[j] )
+ {
+ OUString s = OUString::number(
+ static_cast<sal_uInt8>(k), 16 );
+ if( s.getLength() == 1 )
+ {
+ sValue.append("0");
+ }
+ sValue.append(s.toAsciiUpperCase());
+ }
+ }
+ }
+ else if( sType == "[]short" )
+ {
+ uno::Sequence<sal_Int16> seq = aNode.get< uno::Sequence<sal_Int16> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( static_cast<sal_Int32>(seq[j]) );
+ }
+ }
+ else if( sType == "[]long" )
+ {
+ uno::Sequence<sal_Int32> seq = aNode.get< uno::Sequence<sal_Int32> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]hyper" )
+ {
+ uno::Sequence<sal_Int64> seq = aNode.get< uno::Sequence<sal_Int64> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]double" )
+ {
+ uno::Sequence<double> seq = aNode.get< uno::Sequence<double> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append( seq[j] );
+ }
+ }
+ else if( sType == "[]string" )
+ {
+ uno::Sequence<OUString> seq = aNode.get< uno::Sequence<OUString> >();
+ for( sal_Int32 j = 0; j != seq.getLength(); ++j )
+ {
+ if( j != 0 )
+ {
+ sValue.append(",");
+ }
+ sValue.append(seq[j]);
+ }
+ }
+ else
+ {
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ }
+ break;
+
+ default:
+ SAL_WARN(
+ "cui.options",
+ "path \"" << sPath << "\" member " << item
+ << " of unsupported type " << sType);
+ break;
+ }
+ }
+
+ //Short name
+ int index = 0;
+ for(int j = 1; j < lineage; ++j)
+ index = sPath.indexOf("/", index + 1);
+
+ InsertEntry(sPath, sPath.copy(index+1), item, sType, sValue.makeStringAndClear(), pParentEntry, !bLoadAll);
+ }
+ }
+}
+
+Reference< XNameAccess > CuiAboutConfigTabPage::getConfigAccess( const OUString& sNodePath, bool bUpdate )
+{
+ uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= sNodePath;
+
+ uno::Sequence< uno::Any > aArgumentList{ uno::Any(aProperty) };
+
+ OUString sAccessString;
+
+ if( bUpdate )
+ sAccessString = "com.sun.star.configuration.ConfigurationUpdateAccess";
+ else
+ sAccessString = "com.sun.star.configuration.ConfigurationAccess";
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ sAccessString, aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ return xNameAccess;
+}
+
+void CuiAboutConfigTabPage::AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp )
+{
+ bool isModifiedBefore = false;
+ //Check if value modified before
+ for(std::shared_ptr<Prop_Impl> & nInd : m_vectorOfModified)
+ {
+ if( rProp->Name == nInd->Name && rProp->Property == nInd->Property )
+ {
+ //property modified before. Assign reference to the modified value
+ //do your changes on this object. They will be saved later.
+ nInd = rProp;
+ isModifiedBefore = true;
+ break;
+ }
+ }
+
+ if( !isModifiedBefore )
+ m_vectorOfModified.push_back( rProp );
+ //property is not modified before
+}
+
+std::vector< OUString > CuiAboutConfigTabPage::commaStringToSequence( std::u16string_view rCommaSepString )
+{
+ std::vector<OUString> tempVector;
+
+ sal_Int32 index = 0;
+ do
+ {
+ OUString word( o3tl::getToken(rCommaSepString, 0, u',', index) );
+ word = word.trim();
+ if( !word.isEmpty())
+ tempVector.push_back(word);
+ }while( index >= 0 );
+ return tempVector;
+}
+
+CuiAboutConfigValueDialog::CuiAboutConfigValueDialog(weld::Window* pWindow,
+ const OUString& rValue,
+ int limit)
+ : GenericDialogController(pWindow, "cui/ui/aboutconfigvaluedialog.ui", "AboutConfigValueDialog")
+ , m_bNumericOnly(limit != 0)
+ , m_xEDValue(m_xBuilder->weld_entry("valuebox"))
+{
+ if (limit)
+ m_xEDValue->set_max_length(limit);
+ m_xEDValue->set_text(rValue);
+ m_xEDValue->connect_key_press(LINK(this, CuiAboutConfigValueDialog, KeyInputHdl));
+}
+
+CuiAboutConfigValueDialog::~CuiAboutConfigValueDialog()
+{
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, ResetBtnHdl_Impl, weld::Button&, void )
+{
+ Reset();
+}
+
+IMPL_LINK_NOARG(CuiAboutConfigTabPage, DoubleClickHdl_Impl, weld::TreeView&, bool)
+{
+ StandardHdl_Impl(*m_xEditBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, StandardHdl_Impl, weld::Button&, void )
+{
+ if (!m_xPrefBox->get_selected(m_xScratchIter.get()))
+ return;
+
+ UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(*m_xScratchIter));
+ if (!(pUserData && pUserData->bIsPropertyPath))
+ return;
+
+ //if selection is a node
+ OUString sPropertyName = m_xPrefBox->get_text(*m_xScratchIter, 1);
+ OUString sPropertyType = m_xPrefBox->get_text(*m_xScratchIter, 2);
+ OUString sPropertyValue = m_xPrefBox->get_text(*m_xScratchIter, 3);
+
+ // If the configuration property has a nil value, determine its static type:
+ if (sPropertyType == "void")
+ {
+ css::uno::Reference<css::beans::XPropertySetInfo> info(
+ CuiAboutConfigTabPage::getConfigAccess(pUserData->sPropertyPath, false),
+ css::uno::UNO_QUERY_THROW);
+ css::uno::Type t;
+ try {
+ t = info->getPropertyByName(sPropertyName).Type;
+ } catch (css::beans::UnknownPropertyException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", pUserData->sPropertyPath << " " << sPropertyName);
+ }
+ // If the configuration property is of type any (or an UnknownPropertyException was caught
+ // above), stick to "void" for now (ideally, properties of type any would allow setting
+ // values of arbitrary type, regardless of their current value, in this dialog anyway):
+ if (t != cppu::UnoType<void>::get()) {
+ sPropertyType = t.getTypeName();
+ switch (t.getTypeClass()) {
+ case css::uno::TypeClass_BOOLEAN:
+ sPropertyValue = "false";
+ break;
+ case css::uno::TypeClass_SHORT:
+ case css::uno::TypeClass_LONG:
+ case css::uno::TypeClass_HYPER:
+ case css::uno::TypeClass_DOUBLE:
+ sPropertyValue = "0";
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ auto pProperty = std::make_shared<Prop_Impl>( pUserData->sPropertyPath, sPropertyName, Any( sPropertyValue ) );
+ bool bSaveChanges = false;
+
+ bool bOpenDialog = true;
+ OUString sDialogValue;
+
+ if( sPropertyType == "boolean" )
+ {
+ bool bValue;
+ if( sPropertyValue == "true" )
+ {
+ sDialogValue = "false";
+ bValue = false;
+ }
+ else
+ {
+ sDialogValue = "true";
+ bValue = true;
+ }
+
+ pProperty->Value <<= bValue;
+ bOpenDialog = false;
+ bSaveChanges = true;
+ }
+ else if ( sPropertyType == "void" )
+ {
+ bOpenDialog = false;
+ }
+ else
+ {
+ sDialogValue = sPropertyValue;
+ bOpenDialog = true;
+ }
+
+ try
+ {
+ if( bOpenDialog )
+ {
+ //Cosmetic length limit for integer values.
+ int limit=0;
+ if( sPropertyType == "short" )
+ limit = SHORT_LEN_LIMIT;
+ else if( sPropertyType == "long" )
+ limit = LONG_LEN_LIMIT;
+ else if( sPropertyType == "hyper" )
+ limit = HYPER_LEN_LIMIT;
+
+ CuiAboutConfigValueDialog aValueDialog(m_xDialog.get(), sDialogValue, limit);
+
+ if (aValueDialog.run() == RET_OK )
+ {
+ OUString sNewValue = aValueDialog.getValue();
+ bSaveChanges = true;
+ if ( sPropertyType == "short")
+ {
+ sal_Int16 nShort;
+ sal_Int32 nNumb = sNewValue.toInt32();
+
+ //if the value is 0 and length is not 1, there is something wrong
+ if( ( nNumb==0 && sNewValue.getLength()!=1 ) || nNumb > SAL_MAX_INT16 || nNumb < SAL_MIN_INT16)
+ throw uno::Exception("out of range short", nullptr);
+ nShort = static_cast<sal_Int16>(nNumb);
+ pProperty->Value <<= nShort;
+ }
+ else if( sPropertyType == "long" )
+ {
+ sal_Int32 nLong = sNewValue.toInt32();
+ if( nLong==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range long", nullptr);
+ pProperty->Value <<= nLong;
+ }
+ else if( sPropertyType == "hyper")
+ {
+ sal_Int64 nHyper = sNewValue.toInt64();
+ if( nHyper==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range hyper", nullptr);
+ pProperty->Value <<= nHyper;
+ }
+ else if( sPropertyType == "double")
+ {
+ double nDoub = sNewValue.toDouble();
+ if( nDoub ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range double", nullptr);
+ pProperty->Value <<= nDoub;
+ }
+ else if( sPropertyType == "float")
+ {
+ float nFloat = sNewValue.toFloat();
+ if( nFloat ==0 && sNewValue.getLength()!=1)
+ throw uno::Exception("out of range float", nullptr);
+ pProperty->Value <<= nFloat;
+ }
+ else if( sPropertyType == "string" )
+ {
+ pProperty->Value <<= sNewValue;
+ }
+ else if( sPropertyType == "[]short" )
+ {
+ //create string sequence from comma separated string
+ //uno::Sequence< OUString > seqStr;
+ std::vector< OUString > seqStr = commaStringToSequence( sNewValue );
+
+ //create appropriate sequence with same size as string sequence
+ uno::Sequence< sal_Int16 > seqShort( seqStr.size() );
+ //convert all strings to appropriate type
+ std::transform(seqStr.begin(), seqStr.end(), seqShort.getArray(),
+ [](const auto& str)
+ { return static_cast<sal_Int16>(str.toInt32()); });
+ pProperty->Value <<= seqShort;
+ }
+ else if( sPropertyType == "[]long" )
+ {
+ std::vector< OUString > seqStrLong = commaStringToSequence( sNewValue );
+
+ uno::Sequence< sal_Int32 > seqLong( seqStrLong.size() );
+ std::transform(seqStrLong.begin(), seqStrLong.end(), seqLong.getArray(),
+ [](const auto& str) { return str.toInt32(); });
+ pProperty->Value <<= seqLong;
+ }
+ else if( sPropertyType == "[]hyper" )
+ {
+ std::vector< OUString > seqStrHyper = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int64 > seqHyper( seqStrHyper.size() );
+ std::transform(seqStrHyper.begin(), seqStrHyper.end(), seqHyper.getArray(),
+ [](const auto& str) { return str.toInt64(); });
+ pProperty->Value <<= seqHyper;
+ }
+ else if( sPropertyType == "[]double" )
+ {
+ std::vector< OUString > seqStrDoub = commaStringToSequence( sNewValue );
+ uno::Sequence< double > seqDoub( seqStrDoub.size() );
+ std::transform(seqStrDoub.begin(), seqStrDoub.end(), seqDoub.getArray(),
+ [](const auto& str) { return str.toDouble(); });
+ pProperty->Value <<= seqDoub;
+ }
+ else if( sPropertyType == "[]float" )
+ {
+ std::vector< OUString > seqStrFloat = commaStringToSequence( sNewValue );
+ uno::Sequence< sal_Int16 > seqFloat( seqStrFloat.size() );
+ std::transform(seqStrFloat.begin(), seqStrFloat.end(), seqFloat.getArray(),
+ [](const auto& str) { return str.toFloat(); });
+ pProperty->Value <<= seqFloat;
+ }
+ else if( sPropertyType == "[]string" )
+ {
+ pProperty->Value <<= comphelper::containerToSequence( commaStringToSequence( sNewValue ));
+ }
+ else //unknown
+ throw uno::Exception("unknown property type " + sPropertyType, nullptr);
+
+ sDialogValue = sNewValue;
+ }
+ }
+
+ if(bSaveChanges)
+ {
+ AddToModifiedVector( pProperty );
+
+ //update listbox value.
+ m_xPrefBox->set_text(*m_xScratchIter, sPropertyType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, sDialogValue, 3);
+ //update m_prefBoxEntries
+ auto it = std::find_if(m_prefBoxEntries.begin(), m_prefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+ if (it != m_prefBoxEntries.end())
+ {
+ it->sValue = sDialogValue;
+
+ auto modifiedIt = std::find_if(
+ m_modifiedPrefBoxEntries.begin(), m_modifiedPrefBoxEntries.end(),
+ [&pUserData, &sPropertyName](const prefBoxEntry& rEntry) -> bool
+ {
+ return rEntry.pUserData->sPropertyPath == pUserData->sPropertyPath
+ && rEntry.sStatus == sPropertyName;
+ }
+ );
+
+ if (modifiedIt != m_modifiedPrefBoxEntries.end())
+ {
+ modifiedIt->sValue = sDialogValue;
+ }
+ else
+ {
+ m_modifiedPrefBoxEntries.push_back(*it);
+ }
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {
+ }
+}
+
+IMPL_LINK_NOARG( CuiAboutConfigTabPage, SearchHdl_Impl, weld::Button&, void)
+{
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xPrefBox->hide();
+ m_xPrefBox->clear();
+ m_xPrefBox->freeze();
+
+ if (m_bSorted)
+ m_xPrefBox->make_unsorted();
+
+ if (m_xSearchEdit->get_text().isEmpty())
+ {
+ m_xPrefBox->clear();
+ Reference< XNameAccess > xConfigAccess = getConfigAccess( "/", false );
+ FillItems( xConfigAccess );
+ }
+ else
+ {
+ m_options.searchString = m_xSearchEdit->get_text();
+ utl::TextSearch textSearch( m_options );
+ for (auto const& it : m_prefBoxEntries)
+ {
+ sal_Int32 endPos, startPos = 0;
+
+ for(size_t i = 0; i < 5; ++i)
+ {
+ OUString scrTxt;
+
+ if (i == 0)
+ scrTxt = it.pUserData->sPropertyPath;
+ else if (i == 1)
+ scrTxt = it.sProp;
+ else if (i == 2)
+ scrTxt = it.sStatus;
+ else if (i == 3)
+ scrTxt = it.sType;
+ else if (i == 4)
+ scrTxt = it.sValue;
+
+ endPos = scrTxt.getLength();
+ if (textSearch.SearchForward(scrTxt, &startPos, &endPos))
+ {
+ InsertEntry(it);
+ break;
+ }
+ }
+ }
+ }
+
+ m_xPrefBox->thaw();
+ if (m_bSorted)
+ m_xPrefBox->make_sorted();
+
+ m_xPrefBox->all_foreach([this](weld::TreeIter& rEntry) {
+ m_xPrefBox->expand_row(rEntry);
+ return false;
+ });
+ m_xPrefBox->show();
+}
+
+void CuiAboutConfigTabPage::InsertEntry(const prefBoxEntry& rEntry)
+{
+ OUString sPathWithProperty = rEntry.pUserData->sPropertyPath;
+ sal_Int32 index = sPathWithProperty.lastIndexOf(rEntry.sProp);
+ OUString sPath = sPathWithProperty.copy(0, index);
+ index = 0;
+ std::unique_ptr<weld::TreeIter> xParentEntry(m_xPrefBox->make_iterator());
+ std::unique_ptr<weld::TreeIter> xGrandParentEntry;
+
+ do
+ {
+ int prevIndex = index;
+ index = sPath.indexOf("/", index+1);
+ // deal with no parent case (tdf#107811)
+ if (index < 0)
+ {
+ OUString sId(weld::toId(rEntry.pUserData));
+ m_xPrefBox->insert(nullptr, -1, &rEntry.sProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+ return;
+ }
+ OUString sParentName = sPath.copy(prevIndex+1, index - prevIndex - 1);
+
+ bool hasEntry = false;
+ bool bStartOk;
+
+ if (!xGrandParentEntry)
+ bStartOk = m_xPrefBox->get_iter_first(*xParentEntry);
+ else
+ {
+ m_xPrefBox->copy_iterator(*xGrandParentEntry, *xParentEntry);
+ bStartOk = m_xPrefBox->iter_children(*xParentEntry);
+ }
+
+ if (bStartOk)
+ {
+ do
+ {
+ if (m_xPrefBox->get_text(*xParentEntry, 0) == sParentName)
+ {
+ hasEntry = true;
+ break;
+ }
+ } while (m_xPrefBox->iter_next_sibling(*xParentEntry));
+ }
+
+ if (!hasEntry)
+ {
+ m_xPrefBox->insert(xGrandParentEntry.get(), -1, &sParentName, nullptr, nullptr, nullptr, false, xParentEntry.get());
+ //It is needed, without this the selection line will be truncated.
+ m_xPrefBox->set_text(*xParentEntry, "", 1);
+ m_xPrefBox->set_text(*xParentEntry, "", 2);
+ m_xPrefBox->set_text(*xParentEntry, "", 3);
+ }
+
+ xGrandParentEntry = m_xPrefBox->make_iterator(xParentEntry.get());
+ } while(index < sPath.getLength() - 1);
+
+ OUString sId(weld::toId(rEntry.pUserData));
+ m_xPrefBox->insert(xParentEntry.get(), -1, &rEntry.sProp, &sId, nullptr, nullptr, false, m_xScratchIter.get());
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sStatus, 1);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sType, 2);
+ m_xPrefBox->set_text(*m_xScratchIter, rEntry.sValue, 3);
+}
+
+IMPL_LINK(CuiAboutConfigTabPage, ExpandingHdl_Impl, const weld::TreeIter&, rEntry, bool)
+{
+ if (m_xPrefBox->iter_has_child(rEntry))
+ return true;
+ UserData *pUserData = weld::fromId<UserData*>(m_xPrefBox->get_id(rEntry));
+ if (pUserData && !pUserData->bIsPropertyPath)
+ {
+ assert(pUserData->aXNameAccess.is());
+ FillItems(pUserData->aXNameAccess, &rEntry, pUserData->aLineage);
+ }
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaboutconfig.hxx b/cui/source/options/optaboutconfig.hxx
new file mode 100644
index 000000000..64443bcff
--- /dev/null
+++ b/cui/source/options/optaboutconfig.hxx
@@ -0,0 +1,95 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <com/sun/star/container/XNameAccess.hpp>
+
+#include <i18nutil/searchopt.hxx>
+#include <vcl/weld.hxx>
+
+#include <vector>
+
+class CuiAboutConfigTabPage;
+class CuiAboutConfigValueDialog;
+struct Prop_Impl;
+struct UserData;
+
+struct prefBoxEntry
+{
+ OUString sProp;
+ OUString sStatus;
+ OUString sType;
+ OUString sValue;
+ UserData* pUserData;
+};
+
+class CuiAboutConfigTabPage : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xResetBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+ std::unique_ptr<weld::Button> m_xSearchBtn;
+ std::unique_ptr<weld::Entry> m_xSearchEdit;
+ std::unique_ptr<weld::TreeView> m_xPrefBox;
+ std::unique_ptr<weld::TreeIter> m_xScratchIter;
+
+ std::vector < std::unique_ptr<UserData> > m_vectorUserData;
+
+ std::vector<prefBoxEntry> m_modifiedPrefBoxEntries;
+ std::vector< std::shared_ptr< Prop_Impl > > m_vectorOfModified;
+
+ //for search
+ i18nutil::SearchOptions2 m_options;
+ std::vector<prefBoxEntry> m_prefBoxEntries;
+
+ bool m_bSorted;
+
+ void AddToModifiedVector( const std::shared_ptr< Prop_Impl >& rProp );
+ static std::vector< OUString > commaStringToSequence( std::u16string_view rCommaSepString );
+ void InsertEntry(const prefBoxEntry& rEntry);
+
+ DECL_LINK(StandardHdl_Impl, weld::Button&, void);
+ DECL_LINK(DoubleClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(ResetBtnHdl_Impl, weld::Button&, void);
+ DECL_LINK(SearchHdl_Impl, weld::Button&, void);
+ DECL_LINK(ExpandingHdl_Impl, const weld::TreeIter&, bool);
+ DECL_LINK(HeaderBarClick, int, void);
+
+public:
+ explicit CuiAboutConfigTabPage(weld::Window* pParent);
+ virtual ~CuiAboutConfigTabPage() override;
+ void InsertEntry(const OUString &rPropertyPath, const OUString& rProp, const OUString& rStatus, const OUString& rType, const OUString& rValue,
+ const weld::TreeIter* pParentEntry, bool bInsertToPrefBox);
+ void Reset();
+ void FillItems(const css::uno::Reference<css::container::XNameAccess>& xNameAccess,
+ const weld::TreeIter* pParentEntry = nullptr, int lineage = 0, bool bLoadAll = false);
+ static css::uno::Reference< css::container::XNameAccess > getConfigAccess( const OUString& sNodePath, bool bUpdate );
+ void FillItemSet();
+};
+
+class CuiAboutConfigValueDialog : public weld::GenericDialogController
+{
+private:
+ bool m_bNumericOnly;
+ std::unique_ptr<weld::Entry> m_xEDValue;
+
+ DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
+
+public:
+ CuiAboutConfigValueDialog(weld::Window* pWindow, const OUString& rValue , int limit);
+ virtual ~CuiAboutConfigValueDialog() override;
+
+ OUString getValue() const
+ {
+ return m_xEDValue->get_text();
+ }
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.cxx b/cui/source/options/optaccessibility.cxx
new file mode 100644
index 000000000..a394ff955
--- /dev/null
+++ b/cui/source/options/optaccessibility.cxx
@@ -0,0 +1,111 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optaccessibility.hxx"
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <officecfg/Office/Common.hxx>
+
+SvxAccessibilityOptionsTabPage::SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optaccessibilitypage.ui", "OptAccessibilityPage", &rSet)
+ , m_xAccessibilityTool(m_xBuilder->weld_check_button("acctool"))
+ , m_xTextSelectionInReadonly(m_xBuilder->weld_check_button("textselinreadonly"))
+ , m_xAnimatedGraphics(m_xBuilder->weld_check_button("animatedgraphics"))
+ , m_xAnimatedTexts(m_xBuilder->weld_check_button("animatedtext"))
+ , m_xAutoDetectHC(m_xBuilder->weld_check_button("autodetecthc"))
+ , m_xAutomaticFontColor(m_xBuilder->weld_check_button("autofontcolor"))
+ , m_xPagePreviews(m_xBuilder->weld_check_button("systempagepreviewcolor"))
+{
+#ifdef UNX
+ // UNIX: read the gconf2 setting instead to use the checkbox
+ m_xAccessibilityTool->hide();
+#endif
+}
+
+SvxAccessibilityOptionsTabPage::~SvxAccessibilityOptionsTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAccessibilityOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAccessibilityOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAccessibilityOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch( comphelper::ConfigurationChanges::create() );
+ if ( !officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsForPagePreviews::set(m_xPagePreviews->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::set(m_xAnimatedGraphics->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAllowAnimatedText::set(m_xAnimatedTexts->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsAutomaticFontColor::set(m_xAutomaticFontColor->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ officecfg::Office::Common::Accessibility::IsSelectionInReadonly::set(m_xTextSelectionInReadonly->get_active(), batch);
+ if ( !officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ officecfg::Office::Common::Accessibility::AutoDetectSystemHC::set(m_xAutoDetectHC->get_active(), batch);
+ batch->commit();
+
+ AllSettings aAllSettings = Application::GetSettings();
+ MiscSettings aMiscSettings = aAllSettings.GetMiscSettings();
+#ifndef UNX
+ aMiscSettings.SetEnableATToolSupport(m_xAccessibilityTool->get_active());
+#endif
+ aAllSettings.SetMiscSettings(aMiscSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+
+ return false;
+}
+
+void SvxAccessibilityOptionsTabPage::Reset( const SfxItemSet* )
+{
+ m_xPagePreviews->set_active( officecfg::Office::Common::Accessibility::IsForPagePreviews::get() );
+ if( officecfg::Office::Common::Accessibility::IsForPagePreviews::isReadOnly() )
+ m_xPagePreviews->set_sensitive(false);
+
+ m_xAnimatedGraphics->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedGraphics::isReadOnly() )
+ m_xAnimatedGraphics->set_sensitive(false);
+
+ m_xAnimatedTexts->set_active( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::get() );
+ if( officecfg::Office::Common::Accessibility::IsAllowAnimatedText::isReadOnly() )
+ m_xAnimatedTexts->set_sensitive(false);
+
+ m_xAutomaticFontColor->set_active( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::get() );
+ if( officecfg::Office::Common::Accessibility::IsAutomaticFontColor::isReadOnly() )
+ m_xAutomaticFontColor->set_sensitive(false);
+
+ m_xTextSelectionInReadonly->set_active( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::get() );
+ if( officecfg::Office::Common::Accessibility::IsSelectionInReadonly::isReadOnly() )
+ m_xTextSelectionInReadonly->set_sensitive(false);
+
+ m_xAutoDetectHC->set_active( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::get() );
+ if( officecfg::Office::Common::Accessibility::AutoDetectSystemHC::isReadOnly() )
+ m_xAutoDetectHC->set_sensitive(false);
+
+ AllSettings aAllSettings = Application::GetSettings();
+ const MiscSettings& aMiscSettings = aAllSettings.GetMiscSettings();
+ m_xAccessibilityTool->set_active(aMiscSettings.GetEnableATToolSupport());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optaccessibility.hxx b/cui/source/options/optaccessibility.hxx
new file mode 100644
index 000000000..35d5fdefd
--- /dev/null
+++ b/cui/source/options/optaccessibility.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxAccessibilityOptionsTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xAccessibilityTool;
+ std::unique_ptr<weld::CheckButton> m_xTextSelectionInReadonly;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedGraphics;
+ std::unique_ptr<weld::CheckButton> m_xAnimatedTexts;
+ std::unique_ptr<weld::CheckButton> m_xAutoDetectHC;
+ std::unique_ptr<weld::CheckButton> m_xAutomaticFontColor;
+ std::unique_ptr<weld::CheckButton> m_xPagePreviews;
+
+public:
+ SvxAccessibilityOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxAccessibilityOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optasian.cxx b/cui/source/options/optasian.cxx
new file mode 100644
index 000000000..84d23b42e
--- /dev/null
+++ b/cui/source/options/optasian.cxx
@@ -0,0 +1,383 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <map>
+#include <optasian.hxx>
+#include <tools/debug.hxx>
+#include <tools/diagnose_ex.h>
+#include <o3tl/any.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <svl/asiancfg.hxx>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/i18n/XForbiddenCharacters.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/objsh.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::i18n;
+using namespace com::sun::star::frame;
+using namespace com::sun::star::beans;
+
+constexpr OUStringLiteral cIsKernAsianPunctuation = u"IsKernAsianPunctuation";
+constexpr OUStringLiteral cCharacterCompressionType = u"CharacterCompressionType";
+
+namespace {
+
+struct SvxForbiddenChars_Impl
+{
+ bool bRemoved;
+ std::unique_ptr<ForbiddenCharacters> pCharacters;
+};
+
+}
+
+struct SvxAsianLayoutPage_Impl
+{
+ SvxAsianConfig aConfig;
+ SvxAsianLayoutPage_Impl() {}
+
+ Reference< XForbiddenCharacters > xForbidden;
+ Reference< XPropertySet > xPrSet;
+ Reference< XPropertySetInfo > xPrSetInfo;
+ std::map< LanguageType, std::unique_ptr<SvxForbiddenChars_Impl> >
+ aChangedLanguagesMap;
+
+ bool hasForbiddenCharacters(LanguageType eLang);
+ SvxForbiddenChars_Impl* getForbiddenCharacters(LanguageType eLang);
+ void addForbiddenCharacters(LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden);
+};
+
+bool SvxAsianLayoutPage_Impl::hasForbiddenCharacters(LanguageType eLang)
+{
+ return aChangedLanguagesMap.count( eLang );
+}
+
+SvxForbiddenChars_Impl* SvxAsianLayoutPage_Impl::getForbiddenCharacters(LanguageType eLang)
+{
+ auto it = aChangedLanguagesMap.find( eLang );
+ DBG_ASSERT( ( it != aChangedLanguagesMap.end() ), "language not available");
+ if( it != aChangedLanguagesMap.end() )
+ return it->second.get();
+ return nullptr;
+}
+
+void SvxAsianLayoutPage_Impl::addForbiddenCharacters(
+ LanguageType eLang, std::unique_ptr<ForbiddenCharacters> pForbidden)
+{
+ auto itOld = aChangedLanguagesMap.find( eLang );
+ if( itOld == aChangedLanguagesMap.end() )
+ {
+ std::unique_ptr<SvxForbiddenChars_Impl> pChar(new SvxForbiddenChars_Impl);
+ pChar->bRemoved = nullptr == pForbidden;
+ pChar->pCharacters = std::move(pForbidden);
+ aChangedLanguagesMap.emplace( eLang, std::move(pChar) );
+ }
+ else
+ {
+ itOld->second->bRemoved = nullptr == pForbidden;
+ itOld->second->pCharacters = std::move(pForbidden);
+ }
+}
+
+static LanguageType eLastUsedLanguageTypeForForbiddenCharacters(USHRT_MAX);
+
+SvxAsianLayoutPage::SvxAsianLayoutPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optasianpage.ui", "OptAsianPage", &rSet)
+ , pImpl(new SvxAsianLayoutPage_Impl)
+ , m_xCharKerningRB(m_xBuilder->weld_radio_button("charkerning"))
+ , m_xCharPunctKerningRB(m_xBuilder->weld_radio_button("charpunctkerning"))
+ , m_xNoCompressionRB(m_xBuilder->weld_radio_button("nocompression"))
+ , m_xPunctCompressionRB(m_xBuilder->weld_radio_button("punctcompression"))
+ , m_xPunctKanaCompressionRB(m_xBuilder->weld_radio_button("punctkanacompression"))
+ , m_xLanguageFT(m_xBuilder->weld_label("languageft"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xStandardCB(m_xBuilder->weld_check_button("standard"))
+ , m_xStartFT(m_xBuilder->weld_label("startft"))
+ , m_xStartED(m_xBuilder->weld_entry("start"))
+ , m_xEndFT(m_xBuilder->weld_label("endft"))
+ , m_xEndED(m_xBuilder->weld_entry("end"))
+ , m_xHintFT(m_xBuilder->weld_label("hintft"))
+{
+ LanguageHdl(*m_xLanguageLB->get_widget());
+ m_xLanguageLB->connect_changed(LINK(this, SvxAsianLayoutPage, LanguageHdl));
+ m_xStandardCB->connect_toggled(LINK(this, SvxAsianLayoutPage, ChangeStandardHdl));
+ Link<weld::Entry&,void> aLk(LINK(this, SvxAsianLayoutPage, ModifyHdl));
+ m_xStartED->connect_changed(aLk);
+ m_xEndED->connect_changed(aLk);
+
+ m_xLanguageLB->SetLanguageList( SvxLanguageListFlags::FBD_CHARS, false, false );
+}
+
+SvxAsianLayoutPage::~SvxAsianLayoutPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxAsianLayoutPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxAsianLayoutPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxAsianLayoutPage::FillItemSet( SfxItemSet* )
+{
+ if(m_xCharKerningRB->get_state_changed_from_saved())
+ {
+ pImpl->aConfig.SetKerningWesternTextOnly(m_xCharKerningRB->get_active());
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ bool bVal = !m_xCharKerningRB->get_active();
+ pImpl->xPrSet->setPropertyValue(sPunct, Any(bVal));
+ }
+ }
+
+ if(m_xNoCompressionRB->get_state_changed_from_saved() ||
+ m_xPunctCompressionRB->get_state_changed_from_saved())
+ {
+ CharCompressType nSet = m_xNoCompressionRB->get_active() ? CharCompressType::NONE :
+ m_xPunctCompressionRB->get_active() ? CharCompressType::PunctuationOnly :
+ CharCompressType::PunctuationAndKana;
+ pImpl->aConfig.SetCharDistanceCompression(nSet);
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo.is() && pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ pImpl->xPrSet->setPropertyValue(sCompress, Any(static_cast<sal_uInt16>(nSet)));
+ }
+ }
+ pImpl->aConfig.Commit();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ for (auto const& changedLanguage : pImpl->aChangedLanguagesMap)
+ {
+ Locale aLocale( LanguageTag::convertToLocale(changedLanguage.first));
+ if(changedLanguage.second->bRemoved)
+ pImpl->xForbidden->removeForbiddenCharacters( aLocale );
+ else if(changedLanguage.second->pCharacters)
+ pImpl->xForbidden->setForbiddenCharacters( aLocale, *( changedLanguage.second->pCharacters ) );
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ eLastUsedLanguageTypeForForbiddenCharacters = m_xLanguageLB->get_active_id();
+
+ return false;
+}
+
+void SvxAsianLayoutPage::Reset( const SfxItemSet* )
+{
+ SfxViewFrame* pCurFrm = SfxViewFrame::Current();
+ SfxObjectShell* pDocSh = pCurFrm ? pCurFrm->GetObjectShell() : nullptr;
+ Reference< XModel > xModel;
+ if(pDocSh)
+ xModel = pDocSh->GetModel();
+ Reference<XMultiServiceFactory> xFact(xModel, UNO_QUERY);
+ if(xFact.is())
+ {
+ pImpl->xPrSet.set(xFact->createInstance("com.sun.star.document.Settings"), UNO_QUERY);
+ }
+ if( pImpl->xPrSet.is() )
+ pImpl->xPrSetInfo = pImpl->xPrSet->getPropertySetInfo();
+ bool bKernWesternText = pImpl->aConfig.IsKerningWesternTextOnly();
+ CharCompressType nCompress = pImpl->aConfig.GetCharDistanceCompression();
+ if(pImpl->xPrSetInfo.is())
+ {
+ OUString sForbidden("ForbiddenCharacters");
+ if(pImpl->xPrSetInfo->hasPropertyByName(sForbidden))
+ {
+ Any aForbidden = pImpl->xPrSet->getPropertyValue(sForbidden);
+ aForbidden >>= pImpl->xForbidden;
+ }
+ OUString sCompress(cCharacterCompressionType);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sCompress))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sCompress);
+ sal_uInt16 nTmp;
+ if (aVal >>= nTmp)
+ nCompress = static_cast<CharCompressType>(nTmp);
+ }
+ OUString sPunct(cIsKernAsianPunctuation);
+ if(pImpl->xPrSetInfo->hasPropertyByName(sPunct))
+ {
+ Any aVal = pImpl->xPrSet->getPropertyValue(sPunct);
+ bKernWesternText = !*o3tl::doAccess<bool>(aVal);
+ }
+ }
+ else
+ {
+ m_xLanguageFT->set_sensitive(false);
+ m_xLanguageLB->set_sensitive(false);
+ m_xStandardCB->set_sensitive(false);
+ m_xStartFT->set_sensitive(false);
+ m_xStartED->set_sensitive(false);
+ m_xEndFT->set_sensitive(false);
+ m_xEndED->set_sensitive(false);
+ m_xHintFT->set_sensitive(false);
+ }
+ if(bKernWesternText)
+ m_xCharKerningRB->set_active(true);
+ else
+ m_xCharPunctKerningRB->set_active(true);
+ switch(nCompress)
+ {
+ case CharCompressType::NONE : m_xNoCompressionRB->set_active(true); break;
+ case CharCompressType::PunctuationOnly : m_xPunctCompressionRB->set_active(true); break;
+ default: m_xPunctKanaCompressionRB->set_active(true);
+ }
+ m_xCharKerningRB->save_state();
+ m_xNoCompressionRB->save_state();
+ m_xPunctCompressionRB->save_state();
+ m_xPunctKanaCompressionRB->save_state();
+
+ m_xLanguageLB->set_active(0);
+ //preselect the system language in the box - if available
+ if(LanguageType(USHRT_MAX) == eLastUsedLanguageTypeForForbiddenCharacters)
+ {
+ eLastUsedLanguageTypeForForbiddenCharacters =
+ Application::GetSettings().GetLanguageTag().getLanguageType();
+ if (MsLangId::isSimplifiedChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_SIMPLIFIED;
+ else if (MsLangId::isTraditionalChinese(eLastUsedLanguageTypeForForbiddenCharacters))
+ eLastUsedLanguageTypeForForbiddenCharacters = LANGUAGE_CHINESE_TRADITIONAL;
+ }
+ m_xLanguageLB->set_active_id(eLastUsedLanguageTypeForForbiddenCharacters);
+ LanguageHdl(*m_xLanguageLB->get_widget());
+}
+
+IMPL_LINK_NOARG(SvxAsianLayoutPage, LanguageHdl, weld::ComboBox&, void)
+{
+ //set current value
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ LanguageTag aLanguageTag( eSelectLanguage);
+ const Locale& aLocale( aLanguageTag.getLocale());
+
+ OUString sStart, sEnd;
+ bool bAvail;
+ if(pImpl->xForbidden.is())
+ {
+ bAvail = pImpl->hasForbiddenCharacters(eSelectLanguage);
+ if(bAvail)
+ {
+ SvxForbiddenChars_Impl* pElement = pImpl->getForbiddenCharacters(eSelectLanguage);
+ if(pElement->bRemoved || !pElement->pCharacters)
+ {
+ bAvail = false;
+ }
+ else
+ {
+ sStart = pElement->pCharacters->beginLine;
+ sEnd = pElement->pCharacters->endLine;
+ }
+ }
+ else
+ {
+ try
+ {
+ bAvail = pImpl->xForbidden->hasForbiddenCharacters(aLocale);
+ if(bAvail)
+ {
+ ForbiddenCharacters aForbidden = pImpl->xForbidden->getForbiddenCharacters( aLocale );
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ }
+ else
+ {
+ bAvail = pImpl->aConfig.GetStartEndChars( aLocale, sStart, sEnd );
+ }
+ if(!bAvail)
+ {
+ LocaleDataWrapper aWrap( std::move(aLanguageTag) );
+ ForbiddenCharacters aForbidden = aWrap.getForbiddenCharacters();
+ sStart = aForbidden.beginLine;
+ sEnd = aForbidden.endLine;
+ }
+ m_xStandardCB->set_active(!bAvail);
+ m_xStartED->set_sensitive(bAvail);
+ m_xEndED->set_sensitive(bAvail);
+ m_xStartFT->set_sensitive(bAvail);
+ m_xEndFT->set_sensitive(bAvail);
+ m_xStartED->set_text(sStart);
+ m_xEndED->set_text(sEnd);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ChangeStandardHdl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ m_xStartED->set_sensitive(!bCheck);
+ m_xEndED->set_sensitive(!bCheck);
+ m_xStartFT->set_sensitive(!bCheck);
+ m_xEndFT->set_sensitive(!bCheck);
+
+ ModifyHdl(*m_xStartED);
+}
+
+IMPL_LINK(SvxAsianLayoutPage, ModifyHdl, weld::Entry&, rEdit, void)
+{
+ LanguageType eSelectLanguage = m_xLanguageLB->get_active_id();
+ Locale aLocale( LanguageTag::convertToLocale( eSelectLanguage ));
+ OUString sStart = m_xStartED->get_text();
+ OUString sEnd = m_xEndED->get_text();
+ bool bEnable = rEdit.get_sensitive();
+ if(pImpl->xForbidden.is())
+ {
+ try
+ {
+ if(bEnable)
+ {
+ std::unique_ptr<ForbiddenCharacters> pFCSet(new ForbiddenCharacters);
+ pFCSet->beginLine = sStart;
+ pFCSet->endLine = sEnd;
+ pImpl->addForbiddenCharacters(eSelectLanguage, std::move(pFCSet));
+ }
+ else
+ pImpl->addForbiddenCharacters(eSelectLanguage, nullptr);
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "in XForbiddenCharacters");
+ }
+ }
+ pImpl->aConfig.SetStartEndChars( aLocale, bEnable ? &sStart : nullptr, bEnable ? &sEnd : nullptr);
+}
+
+WhichRangesContainer SvxAsianLayoutPage::GetRanges()
+{
+ //no items are used
+ return WhichRangesContainer();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.cxx b/cui/source/options/optbasic.cxx
new file mode 100644
index 000000000..c550d9440
--- /dev/null
+++ b/cui/source/options/optbasic.cxx
@@ -0,0 +1,131 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optbasic.hxx"
+#include <basic/codecompletecache.hxx>
+#include <officecfg/Office/BasicIDE.hxx>
+
+SvxBasicIDEOptionsPage::SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optbasicidepage.ui", "OptBasicIDEPage", &rSet)
+ , m_xCodeCompleteChk(m_xBuilder->weld_check_button("codecomplete_enable"))
+ , m_xAutocloseProcChk(m_xBuilder->weld_check_button("autoclose_proc"))
+ , m_xAutocloseParenChk(m_xBuilder->weld_check_button("autoclose_paren"))
+ , m_xAutocloseQuotesChk(m_xBuilder->weld_check_button("autoclose_quotes"))
+ , m_xAutoCorrectChk(m_xBuilder->weld_check_button("autocorrect"))
+ , m_xUseExtendedTypesChk(m_xBuilder->weld_check_button("extendedtypes_enable"))
+{
+ LoadConfig();
+}
+
+SvxBasicIDEOptionsPage::~SvxBasicIDEOptionsPage()
+{
+}
+
+void SvxBasicIDEOptionsPage::LoadConfig()
+{
+ m_xCodeCompleteChk->set_active( officecfg::Office::BasicIDE::Autocomplete::CodeComplete::get() );
+ m_xCodeCompleteChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::CodeComplete::isReadOnly() );
+ m_xAutocloseProcChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::get() );
+ m_xAutocloseProcChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::isReadOnly() );
+ m_xAutocloseQuotesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::get() );
+ m_xAutocloseQuotesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::isReadOnly() );
+ m_xAutocloseParenChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::get() );
+ m_xAutocloseParenChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::isReadOnly() );
+ m_xAutoCorrectChk->set_active( officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::get() );
+ m_xAutoCorrectChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::isReadOnly() );
+ m_xUseExtendedTypesChk->set_active( officecfg::Office::BasicIDE::Autocomplete::UseExtended::get() );
+ m_xUseExtendedTypesChk->set_sensitive( !officecfg::Office::BasicIDE::Autocomplete::UseExtended::isReadOnly() );
+}
+
+bool SvxBasicIDEOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+ std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+
+ if( m_xAutocloseProcChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseProc::set( m_xAutocloseProcChk->get_active(), batch );
+ CodeCompleteOptions::SetProcedureAutoCompleteOn( m_xAutocloseProcChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xCodeCompleteChk->get_state_changed_from_saved() )
+ {
+ //std::shared_ptr< comphelper::ConfigurationChanges > batch( comphelper::ConfigurationChanges::create() );
+ officecfg::Office::BasicIDE::Autocomplete::CodeComplete::set( m_xCodeCompleteChk->get_active(), batch );
+ CodeCompleteOptions::SetCodeCompleteOn( m_xCodeCompleteChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xUseExtendedTypesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::UseExtended::set( m_xUseExtendedTypesChk->get_active(), batch );
+ CodeCompleteOptions::SetExtendedTypeDeclaration( m_xUseExtendedTypesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseParenChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseParenthesis::set( m_xAutocloseParenChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseParenthesisOn( m_xAutocloseParenChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutocloseQuotesChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutocloseDoubleQuotes::set( m_xAutocloseQuotesChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCloseQuotesOn( m_xAutocloseQuotesChk->get_active() );
+ bModified = true;
+ }
+
+ if( m_xAutoCorrectChk->get_state_changed_from_saved() )
+ {
+ officecfg::Office::BasicIDE::Autocomplete::AutoCorrect::set( m_xAutoCorrectChk->get_active(), batch );
+ CodeCompleteOptions::SetAutoCorrectOn( m_xAutoCorrectChk->get_active() );
+ bModified = true;
+ }
+
+ if( bModified )
+ batch->commit();
+
+ return bModified;
+}
+
+void SvxBasicIDEOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ LoadConfig();
+ m_xCodeCompleteChk->save_state();
+ m_xAutocloseProcChk->save_state();
+ m_xAutocloseQuotesChk->save_state();
+ m_xAutocloseParenChk->save_state();
+ m_xAutoCorrectChk->save_state();
+ m_xUseExtendedTypesChk->save_state();
+}
+
+std::unique_ptr<SfxTabPage> SvxBasicIDEOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxBasicIDEOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxBasicIDEOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optbasic.hxx b/cui/source/options/optbasic.hxx
new file mode 100644
index 000000000..990b54d4e
--- /dev/null
+++ b/cui/source/options/optbasic.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class SvxBasicIDEOptionsPage: public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xCodeCompleteChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseProcChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseParenChk;
+ std::unique_ptr<weld::CheckButton> m_xAutocloseQuotesChk;
+ std::unique_ptr<weld::CheckButton> m_xAutoCorrectChk;
+ std::unique_ptr<weld::CheckButton> m_xUseExtendedTypesChk;
+
+ void LoadConfig();
+
+public:
+ SvxBasicIDEOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxBasicIDEOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.cxx b/cui/source/options/optchart.cxx
new file mode 100644
index 000000000..af9b92322
--- /dev/null
+++ b/cui/source/options/optchart.cxx
@@ -0,0 +1,274 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optchart.hxx"
+#include <svx/SvxColorValueSet.hxx>
+#include <vcl/virdev.hxx>
+#include <vcl/weld.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svxids.hrc>
+#include <osl/diagnose.h>
+#include <officecfg/Office/Common.hxx>
+
+void SvxDefaultColorOptPage::InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ const Color& rColor = rEntry.GetColor();
+ const OUString& rStr = rEntry.GetName();
+
+ const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
+ Size aImageSize = rStyleSettings.GetListBoxPreviewDefaultPixelSize();
+
+ ScopedVclPtrInstance<VirtualDevice> xDevice;
+ xDevice->SetOutputSize(aImageSize);
+ const ::tools::Rectangle aRect(Point(0, 0), aImageSize);
+ xDevice->SetFillColor(rColor);
+ xDevice->SetLineColor(rStyleSettings.GetDisableColor());
+ xDevice->DrawRect(aRect);
+
+ m_xLbChartColors->insert(nullptr, nPos, &rStr, nullptr,
+ nullptr, xDevice.get(), false, nullptr);
+
+ if (nPos == -1)
+ aColorList.push_back( rColor );
+ else
+ {
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance( it, nPos );
+ aColorList.insert( it, rColor );
+ }
+}
+
+void SvxDefaultColorOptPage::RemoveColorEntry(sal_Int32 nPos)
+{
+ m_xLbChartColors->remove(nPos);
+ ImpColorList::iterator it = aColorList.begin();
+ std::advance(it, nPos);
+ aColorList.erase(it);
+}
+
+void SvxDefaultColorOptPage::ClearColorEntries()
+{
+ aColorList.clear();
+ m_xLbChartColors->clear();
+}
+
+void SvxDefaultColorOptPage::ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos)
+{
+ RemoveColorEntry(nPos);
+ InsertColorEntry(rEntry, nPos);
+}
+
+void SvxDefaultColorOptPage::FillBoxChartColorLB()
+{
+ if (!m_SvxChartColorTableUniquePtr)
+ return;
+
+ m_xLbChartColors->freeze();
+ ClearColorEntries();
+ const tools::Long nCount(m_SvxChartColorTableUniquePtr->size());
+ for (tools::Long i = 0; i < nCount; ++i)
+ InsertColorEntry((*m_SvxChartColorTableUniquePtr)[i]);
+ m_xLbChartColors->thaw();
+}
+
+SvxDefaultColorOptPage::SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs)
+ : SfxTabPage(pPage, pController, "cui/ui/optchartcolorspage.ui", "OptChartColorsPage", &rInAttrs)
+ , m_xLbChartColors(m_xBuilder->weld_tree_view("colors"))
+ , m_xLbPaletteSelector(m_xBuilder->weld_combo_box("paletteselector"))
+ , m_xPBDefault(m_xBuilder->weld_button("default"))
+ , m_xPBAdd(m_xBuilder->weld_button("add"))
+ , m_xPBRemove(m_xBuilder->weld_button("delete"))
+ , m_xValSetColorBox(new SvxColorValueSet(m_xBuilder->weld_scrolled_window("tablewin", true)))
+ , m_xValSetColorBoxWin(new weld::CustomWeld(*m_xBuilder, "table", *m_xValSetColorBox))
+{
+ m_xLbChartColors->set_size_request(-1, m_xLbChartColors->get_height_rows(16));
+
+ m_xPBDefault->connect_clicked( LINK( this, SvxDefaultColorOptPage, ResetToDefaults ) );
+ m_xPBAdd->connect_clicked( LINK( this, SvxDefaultColorOptPage, AddChartColor ) );
+ m_xPBRemove->connect_clicked( LINK( this, SvxDefaultColorOptPage, RemoveChartColor ) );
+ m_xValSetColorBox->SetSelectHdl( LINK( this, SvxDefaultColorOptPage, BoxClickedHdl ) );
+ m_xLbPaletteSelector->connect_changed( LINK( this, SvxDefaultColorOptPage, SelectPaletteLbHdl ) );
+
+ m_xValSetColorBox->SetStyle( m_xValSetColorBox->GetStyle()
+ | WB_ITEMBORDER | WB_NAMEFIELD | WB_VSCROLL );
+
+ m_SvxChartOptionsUniquePtr.reset(new SvxChartOptions);
+
+ if ( const SvxChartColorTableItem* pEditOptionsItem = rInAttrs.GetItemIfSet( SID_SCH_EDITOPTIONS, false ) )
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>(
+ pEditOptionsItem->GetColorList());
+ }
+ else
+ {
+ m_SvxChartColorTableUniquePtr = std::make_unique<SvxChartColorTable>();
+ m_SvxChartColorTableUniquePtr->useDefault();
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ }
+
+ Construct();
+}
+
+SvxDefaultColorOptPage::~SvxDefaultColorOptPage()
+{
+ m_xValSetColorBoxWin.reset();
+ m_xValSetColorBox.reset();
+}
+
+void SvxDefaultColorOptPage::Construct()
+{
+ FillBoxChartColorLB();
+ FillPaletteLB();
+
+ m_xLbChartColors->select( 0 );
+}
+
+std::unique_ptr<SfxTabPage> SvxDefaultColorOptPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrs )
+{
+ return std::make_unique<SvxDefaultColorOptPage>( pPage, pController, *rAttrs );
+}
+
+bool SvxDefaultColorOptPage::FillItemSet( SfxItemSet* rOutAttrs )
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ rOutAttrs->Put(SvxChartColorTableItem(SID_SCH_EDITOPTIONS, *m_SvxChartColorTableUniquePtr));
+ }
+
+ return true;
+}
+
+void SvxDefaultColorOptPage::Reset( const SfxItemSet* )
+{
+ m_xLbChartColors->select( 0 );
+}
+
+void SvxDefaultColorOptPage::FillPaletteLB()
+{
+ m_xLbPaletteSelector->clear();
+ std::vector<OUString> aPaletteList = aPaletteManager.GetPaletteList();
+ for (auto const& palette : aPaletteList)
+ m_xLbPaletteSelector->append_text(palette);
+
+ OUString aPaletteName(officecfg::Office::Common::UserColors::PaletteName::get());
+ m_xLbPaletteSelector->set_active_text(aPaletteName);
+ if (m_xLbPaletteSelector->get_active() != -1)
+ SelectPaletteLbHdl( *m_xLbPaletteSelector );
+}
+
+void SvxDefaultColorOptPage::SaveChartOptions()
+{
+ if (m_SvxChartOptionsUniquePtr && m_SvxChartColorTableUniquePtr)
+ {
+ m_SvxChartOptionsUniquePtr->SetDefaultColors(*m_SvxChartColorTableUniquePtr);
+ m_SvxChartOptionsUniquePtr->Commit();
+ }
+}
+
+// event handlers
+
+
+// ResetToDefaults
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, ResetToDefaults, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ m_SvxChartColorTableUniquePtr->useDefault();
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select( 0 );
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// AddChartColor
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, AddChartColor, weld::Button&, void)
+{
+ if( m_SvxChartColorTableUniquePtr )
+ {
+ Color const black( 0x00, 0x00, 0x00 );
+
+ m_SvxChartColorTableUniquePtr->append(
+ XColorEntry(black, SvxChartColorTable::getDefaultName(m_SvxChartColorTableUniquePtr->size())));
+
+ FillBoxChartColorLB();
+ m_xLbChartColors->grab_focus();
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ m_xPBRemove->set_sensitive(true);
+ }
+}
+
+// RemoveChartColor
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, RemoveChartColor, weld::Button&, void )
+{
+ sal_Int32 nIndex = m_xLbChartColors->get_selected_index();
+ if (nIndex == -1)
+ return;
+
+ if( !m_SvxChartColorTableUniquePtr )
+ return;
+
+ OSL_ENSURE(m_SvxChartColorTableUniquePtr->size() > 1, "don't delete the last chart color");
+
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletechartcolordialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteChartColorDialog"));
+
+ if (RET_YES != xQuery->run())
+ return;
+
+ m_SvxChartColorTableUniquePtr->remove(nIndex);
+
+ FillBoxChartColorLB();
+
+ m_xLbChartColors->grab_focus();
+
+ if (nIndex == m_xLbChartColors->n_children() && m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select(m_SvxChartColorTableUniquePtr->size() - 1);
+ else if (m_xLbChartColors->n_children() > 0)
+ m_xLbChartColors->select( nIndex );
+ else
+ m_xPBRemove->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG( SvxDefaultColorOptPage, SelectPaletteLbHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nPos = m_xLbPaletteSelector->get_active();
+ aPaletteManager.SetPalette( nPos );
+ aPaletteManager.ReloadColorSet( *m_xValSetColorBox );
+ m_xValSetColorBox->Resize();
+}
+
+IMPL_LINK_NOARG(SvxDefaultColorOptPage, BoxClickedHdl, ValueSet*, void)
+{
+ sal_Int32 nIdx = m_xLbChartColors->get_selected_index();
+ if (nIdx != -1)
+ {
+ const XColorEntry aEntry(m_xValSetColorBox->GetItemColor(m_xValSetColorBox->GetSelectedItemId()), m_xLbChartColors->get_selected_text());
+
+ ModifyColorEntry(aEntry, nIdx);
+ m_SvxChartColorTableUniquePtr->replace(nIdx, aEntry);
+
+ m_xLbChartColors->select(nIdx); // reselect entry
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optchart.hxx b/cui/source/options/optchart.hxx
new file mode 100644
index 000000000..11221617a
--- /dev/null
+++ b/cui/source/options/optchart.hxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svtools/valueset.hxx>
+#include <svx/xtable.hxx>
+#include <svx/PaletteManager.hxx>
+#include <vcl/customweld.hxx>
+
+#include "cfgchart.hxx"
+
+typedef std::vector<Color> ImpColorList;
+
+class SvxDefaultColorOptPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxChartOptions> m_SvxChartOptionsUniquePtr;
+ // no reason to use a cloned SfxItem here (SvxChartColorTableItem)
+ // that just leads to non-const SfxItem and potential trouble
+ std::unique_ptr<SvxChartColorTable> m_SvxChartColorTableUniquePtr;
+
+ ImpColorList aColorList;
+ PaletteManager aPaletteManager;
+
+ std::unique_ptr<weld::TreeView> m_xLbChartColors;
+ std::unique_ptr<weld::ComboBox> m_xLbPaletteSelector;
+ std::unique_ptr<weld::Button> m_xPBDefault;
+ std::unique_ptr<weld::Button> m_xPBAdd;
+ std::unique_ptr<weld::Button> m_xPBRemove;
+ std::unique_ptr<SvxColorValueSet> m_xValSetColorBox;
+ std::unique_ptr<weld::CustomWeld> m_xValSetColorBoxWin;
+
+ DECL_LINK(ResetToDefaults, weld::Button&, void);
+ DECL_LINK(AddChartColor, weld::Button&, void);
+ DECL_LINK(RemoveChartColor, weld::Button&, void);
+ DECL_LINK(BoxClickedHdl, ValueSet*, void);
+ DECL_LINK(SelectPaletteLbHdl, weld::ComboBox&, void);
+
+ void FillPaletteLB();
+
+private:
+ void InsertColorEntry(const XColorEntry& rEntry, sal_Int32 nPos = -1);
+ void RemoveColorEntry(sal_Int32 nPos);
+ void ModifyColorEntry(const XColorEntry& rEntry, sal_Int32 nPos);
+ void ClearColorEntries();
+ void FillBoxChartColorLB();
+
+public:
+ SvxDefaultColorOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rInAttrs);
+ virtual ~SvxDefaultColorOptPage() override;
+
+ void Construct();
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rInAttrs );
+ virtual bool FillItemSet( SfxItemSet* rOutAttrs ) override;
+ virtual void Reset( const SfxItemSet* rInAttrs ) override;
+
+ void SaveChartOptions();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.cxx b/cui/source/options/optcolor.cxx
new file mode 100644
index 000000000..2249b70e4
--- /dev/null
+++ b/cui/source/options/optcolor.cxx
@@ -0,0 +1,896 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <bitset>
+
+#include <tools/debug.hxx>
+#include <editeng/editids.hrc>
+#include <svtools/colorcfg.hxx>
+#include <svtools/extcolorcfg.hxx>
+#include <svx/colorbox.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <svx/svxdlg.hxx>
+#include <helpids.h>
+#include <dialmgr.hxx>
+#include "optcolor.hxx"
+#include <strings.hrc>
+
+using namespace ::com::sun::star;
+using namespace ::svtools;
+
+namespace
+{
+
+// list of default groups
+enum Group
+{
+ Group_General,
+ Group_Writer,
+ Group_Html,
+ Group_Calc,
+ Group_Draw,
+ Group_Basic,
+ Group_Sql,
+
+ nGroupCount
+};
+
+// group data
+struct
+{
+ // group
+ Group eGroup;
+ // .ui group name
+ const char *pGroup;
+}
+const vGroupInfo[] =
+{
+ // the groups are in the same order as in enum Group above
+ { Group_General, "general" },
+ { Group_Writer, "writer" },
+ { Group_Html, "html" },
+ { Group_Calc, "calc" },
+ { Group_Draw, "draw" },
+ { Group_Basic, "basic" },
+ { Group_Sql, "sql" }
+};
+
+// color config entry data (see ColorConfigWindow_Impl::Entry below)
+struct
+{
+ // group
+ Group eGroup;
+ //checkbox (or simple text)
+ const char *pText;
+ //color listbox
+ const char *pColor;
+ // has checkbox?
+ bool bCheckBox;
+}
+const vEntryInfo[] =
+{
+ #define IDS(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), false
+
+ #define IDS_CB(Name) \
+ SAL_STRINGIFY(Name), SAL_STRINGIFY(Name##_lb), true
+
+ // The list of these entries (enum ColorConfigEntry) are in colorcfg.hxx.
+
+ { Group_General, IDS(doccolor) },
+ { Group_General, IDS_CB(docboundaries) },
+ { Group_General, IDS(appback) },
+ { Group_General, IDS_CB(objboundaries) },
+ { Group_General, IDS_CB(tblboundaries) },
+ { Group_General, IDS(font) },
+ { Group_General, IDS_CB(unvisitedlinks) },
+ { Group_General, IDS_CB(visitedlinks) },
+ { Group_General, IDS(autospellcheck) },
+ { Group_General, IDS(smarttags) },
+ { Group_General, IDS_CB(shadows) },
+
+ { Group_Writer, IDS(writergrid) },
+ { Group_Writer, IDS_CB(field) },
+ { Group_Writer, IDS_CB(index) },
+ { Group_Writer, IDS(direct) },
+ { Group_Writer, IDS(script) },
+ { Group_Writer, IDS_CB(section) },
+ { Group_Writer, IDS(hdft) },
+ { Group_Writer, IDS(pagebreak) },
+
+ { Group_Html, IDS(sgml) },
+ { Group_Html, IDS(htmlcomment) },
+ { Group_Html, IDS(htmlkeyword) },
+ { Group_Html, IDS(unknown) },
+
+ { Group_Calc, IDS(calcgrid) },
+ { Group_Calc, IDS(brk) },
+ { Group_Calc, IDS(brkmanual) },
+ { Group_Calc, IDS(brkauto) },
+ { Group_Calc, IDS_CB(hiddencolrow) },
+ { Group_Calc, IDS(det) },
+ { Group_Calc, IDS(deterror) },
+ { Group_Calc, IDS(ref) },
+ { Group_Calc, IDS(notes) },
+ { Group_Calc, IDS(values) },
+ { Group_Calc, IDS(formulas) },
+ { Group_Calc, IDS(text) },
+ { Group_Calc, IDS(protectedcells) },
+
+ { Group_Draw, IDS(drawgrid) },
+
+ { Group_Basic, IDS(basicid) },
+ { Group_Basic, IDS(basiccomment) },
+ { Group_Basic, IDS(basicnumber) },
+ { Group_Basic, IDS(basicstring) },
+ { Group_Basic, IDS(basicop) },
+ { Group_Basic, IDS(basickeyword) },
+ { Group_Basic, IDS(error) },
+
+ { Group_Sql, IDS(sqlid) },
+ { Group_Sql, IDS(sqlnumber) },
+ { Group_Sql, IDS(sqlstring) },
+ { Group_Sql, IDS(sqlop) },
+ { Group_Sql, IDS(sqlkeyword) },
+ { Group_Sql, IDS(sqlparam) },
+ { Group_Sql, IDS(sqlcomment) }
+
+ #undef IDS
+};
+
+// ColorConfigWindow_Impl
+
+class ColorConfigWindow_Impl
+{
+public:
+ explicit ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent);
+
+public:
+ void SetLinks(Link<weld::Toggleable&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&,
+ weld::ScrolledWindow& rScroll);
+ void Update(EditableColorConfig const*, EditableExtendedColorConfig const*);
+ void ClickHdl(EditableColorConfig*, const weld::Toggleable&);
+ void ColorHdl(EditableColorConfig*, EditableExtendedColorConfig*, const ColorListBox*);
+
+ weld::Widget& GetWidget1()
+ {
+ return *m_xWidget1;
+ }
+
+ weld::Widget& GetWidget2()
+ {
+ return *m_xWidget2;
+ }
+
+ weld::Widget& GetBody()
+ {
+ return *m_xBox;
+ }
+
+ int GetLabelIndent() const
+ {
+ return m_nCheckBoxLabelOffset;
+ }
+
+private:
+ // Chapter -- horizontal group separator stripe with text
+ class Chapter
+ {
+ // text
+ std::unique_ptr<weld::Label> m_xText;
+ public:
+ Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow);
+ void SetText(const OUString& rLabel) { m_xText->set_label(rLabel); }
+ };
+
+ // Entry -- a color config entry:
+ // text (checkbox) + color list box
+ class Entry
+ {
+ public:
+ Entry(weld::Window* pTopLevel, weld::Builder& rBuilder, const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor, int nCheckBoxLabelOffset, bool bCheckBox, bool bShow);
+ public:
+ void SetText(const OUString& rLabel) { dynamic_cast<weld::Label&>(*m_xText).set_label(rLabel); }
+ int get_height_request() const
+ {
+ return std::max(m_xText->get_preferred_size().Height(),
+ m_xColorList->get_widget().get_preferred_size().Height());
+ }
+ void Hide ();
+ public:
+ void SetLinks(Link<weld::Toggleable&,void> const&,
+ Link<ColorListBox&,void> const&,
+ Link<weld::Widget&,void> const&);
+ void Update (ColorConfigValue const&);
+ void Update (ExtendedColorConfigValue const&);
+ void ColorChanged (ColorConfigValue&);
+ void ColorChanged (ExtendedColorConfigValue&);
+ public:
+ bool Is(const weld::Toggleable* pBox) const { return m_xText.get() == pBox; }
+ bool Is(const ColorListBox* pBox) const { return m_xColorList.get() == pBox; }
+ private:
+ // checkbox (CheckBox) or simple text (FixedText)
+ std::unique_ptr<weld::Widget> m_xText;
+ // color list box
+ std::unique_ptr<ColorListBox> m_xColorList;
+ // default color
+ Color m_aDefaultColor;
+ };
+
+private:
+ weld::Window* m_pTopLevel;
+ int m_nCheckBoxLabelOffset;
+ std::unique_ptr<weld::Builder> m_xBuilder;
+ std::unique_ptr<weld::Box> m_xBox;
+ std::unique_ptr<weld::Widget> m_xWidget1;
+ std::unique_ptr<weld::Widget> m_xWidget2;
+
+ std::vector<std::unique_ptr<weld::Builder>> vExtBuilders;
+ std::vector<std::unique_ptr<weld::Container>> vExtContainers;
+ // vChapters -- groups (group headers)
+ std::vector<std::shared_ptr<Chapter> > vChapters;
+ // vEntries -- color options
+ std::vector<std::shared_ptr<Entry> > vEntries;
+
+ // module options
+ SvtModuleOptions aModuleOptions;
+
+ // initialization
+ void CreateEntries();
+
+private:
+
+ bool IsGroupVisible (Group) const;
+};
+
+} // namespace
+
+// ColorConfigWindow_Impl::Chapter
+
+// ctor for default groups
+// rParent: parent window (ColorConfigWindow_Impl)
+// eGroup: which group is this?
+ColorConfigWindow_Impl::Chapter::Chapter(weld::Builder& rBuilder, const char* pLabelWidget, bool bShow)
+ : m_xText(rBuilder.weld_label(pLabelWidget))
+{
+ if (!bShow)
+ m_xText->hide();
+}
+
+// ColorConfigWindow_Impl::Entry
+ColorConfigWindow_Impl::Entry::Entry(weld::Window* pTopLevel, weld::Builder& rBuilder,
+ const char* pTextWidget, const char* pColorWidget,
+ const Color& rColor,
+ int nCheckBoxLabelOffset, bool bCheckBox, bool bShow)
+ : m_xColorList(new ColorListBox(rBuilder.weld_menu_button(pColorWidget), [pTopLevel]{ return pTopLevel; }))
+ , m_aDefaultColor(rColor)
+{
+ if (bCheckBox)
+ m_xText = rBuilder.weld_check_button(pTextWidget);
+ else
+ m_xText = rBuilder.weld_label(pTextWidget);
+
+ // color list
+ m_xColorList->SetSlotId(SID_ATTR_CHAR_COLOR);
+ m_xColorList->SetAutoDisplayColor(m_aDefaultColor);
+
+ if (!bCheckBox)
+ {
+ m_xText->set_margin_start(m_xText->get_margin_start() +
+ nCheckBoxLabelOffset);
+ }
+
+ if (!bShow)
+ Hide();
+}
+
+void ColorConfigWindow_Impl::Entry::Hide()
+{
+ m_xText->hide();
+ m_xColorList->hide();
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::Entry::SetLinks(Link<weld::Toggleable&,void> const& rCheckLink,
+ Link<ColorListBox&,void> const& rColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink)
+{
+ m_xColorList->SetSelectHdl(rColorLink);
+ m_xColorList->connect_focus_in(rGetFocusLink);
+ if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
+ {
+ pCheckBox->connect_toggled(rCheckLink);
+ pCheckBox->connect_focus_in(rGetFocusLink);
+ }
+}
+
+// updates a default color config entry
+void ColorConfigWindow_Impl::Entry::Update(ColorConfigValue const& rValue)
+{
+ Color aColor(rValue.nColor);
+ m_xColorList->SelectEntry(aColor);
+ if (weld::Toggleable* pCheckBox = dynamic_cast<weld::Toggleable*>(m_xText.get()))
+ pCheckBox->set_active(rValue.bIsVisible);
+}
+
+// updates an extended color config entry
+void ColorConfigWindow_Impl::Entry::Update(ExtendedColorConfigValue const& rValue)
+{
+ Color aColor(rValue.getColor());
+ if (rValue.getColor() == rValue.getDefaultColor())
+ m_xColorList->SelectEntry(COL_AUTO);
+ else
+ m_xColorList->SelectEntry(aColor);
+}
+
+// color of a default entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.nColor = aColor;
+}
+
+// color of an extended entry has changed
+void ColorConfigWindow_Impl::Entry::ColorChanged(ExtendedColorConfigValue& rValue)
+{
+ Color aColor = m_xColorList->GetSelectEntryColor();
+ rValue.setColor(aColor);
+ if (aColor == COL_AUTO)
+ {
+ rValue.setColor(rValue.getDefaultColor());
+ }
+}
+
+// ColorConfigWindow_Impl
+ColorConfigWindow_Impl::ColorConfigWindow_Impl(weld::Window* pTopLevel, weld::Container* pParent)
+ : m_pTopLevel(pTopLevel)
+ , m_xBuilder(Application::CreateBuilder(pParent, "cui/ui/colorconfigwin.ui"))
+ , m_xBox(m_xBuilder->weld_box("ColorConfigWindow"))
+ , m_xWidget1(m_xBuilder->weld_widget("docboundaries"))
+ , m_xWidget2(m_xBuilder->weld_widget("docboundaries_lb"))
+{
+ CreateEntries();
+}
+
+void ColorConfigWindow_Impl::CreateEntries()
+{
+ std::bitset<nGroupCount> aModulesInstalled;
+ // creating group headers
+ vChapters.reserve(nGroupCount);
+ for (unsigned i = 0; i != nGroupCount; ++i)
+ {
+ aModulesInstalled[i] = IsGroupVisible(vGroupInfo[i].eGroup);
+ vChapters.push_back(std::make_shared<Chapter>(*m_xBuilder, vGroupInfo[i].pGroup, aModulesInstalled[i]));
+ }
+
+ // Here we want to get the amount to add to the position of a FixedText to
+ // get it to align its contents with that of a CheckBox
+ {
+ OUString sSampleText("XXXXXX");
+ std::unique_ptr<weld::CheckButton> xCheckBox(m_xBuilder->weld_check_button("docboundaries"));
+ std::unique_ptr<weld::Label> xFixedText(m_xBuilder->weld_label("doccolor"));
+ OUString sOrigCheck(xCheckBox->get_label());
+ OUString sOrigFixed(xFixedText->get_label());
+ xCheckBox->set_label(sSampleText);
+ xFixedText->set_label(sSampleText);
+ Size aCheckSize(xCheckBox->get_preferred_size());
+ Size aFixedSize(xFixedText->get_preferred_size());
+ xCheckBox->set_label(sOrigCheck);
+ xFixedText->set_label(sOrigFixed);
+ m_nCheckBoxLabelOffset = aCheckSize.Width() - aFixedSize.Width();
+ }
+
+ // creating entries
+ vEntries.reserve(ColorConfigEntryCount);
+ for (size_t i = 0; i < std::size(vEntryInfo); ++i)
+ {
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *m_xBuilder,
+ vEntryInfo[i].pText, vEntryInfo[i].pColor,
+ ColorConfig::GetDefaultColor(static_cast<ColorConfigEntry>(i)),
+ m_nCheckBoxLabelOffset,
+ vEntryInfo[i].bCheckBox,
+ aModulesInstalled[vEntryInfo[i].eGroup]));
+ }
+
+ // extended entries
+ ExtendedColorConfig aExtConfig;
+ unsigned const nExtGroupCount = aExtConfig.GetComponentCount();
+ if (!nExtGroupCount)
+ return;
+
+ for (unsigned j = 0; j != nExtGroupCount; ++j)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(m_xBox.get(), "cui/ui/chapterfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_frame("ChapterFragment"));
+
+ OUString const sComponentName = aExtConfig.GetComponentName(j);
+ vChapters.push_back(std::make_shared<Chapter>(
+ *vExtBuilders.back(), "chapter", true));
+ vChapters.back()->SetText(aExtConfig.GetComponentDisplayName(sComponentName));
+
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_box("contents"));
+ weld::Container* pChapterBox = vExtContainers.back().get();
+
+ unsigned nColorCount = aExtConfig.GetComponentColorCount(sComponentName);
+ for (unsigned i = 0; i != nColorCount; ++i)
+ {
+ vExtBuilders.emplace_back(Application::CreateBuilder(pChapterBox, "cui/ui/colorfragment.ui"));
+ vExtContainers.emplace_back(vExtBuilders.back()->weld_container("ColorFragment"));
+
+ ExtendedColorConfigValue const aColorEntry =
+ aExtConfig.GetComponentColorConfigValue(sComponentName, i);
+ vEntries.push_back(std::make_shared<Entry>(m_pTopLevel, *vExtBuilders.back(),
+ "label", "button", aColorEntry.getDefaultColor(),
+ m_nCheckBoxLabelOffset, false, true));
+ vEntries.back()->SetText(aColorEntry.getDisplayName());
+ }
+ }
+}
+
+// SetLinks()
+void ColorConfigWindow_Impl::SetLinks(Link<weld::Toggleable&,void> const& aCheckLink,
+ Link<ColorListBox&,void> const& aColorLink,
+ Link<weld::Widget&,void> const& rGetFocusLink,
+ weld::ScrolledWindow& rScroll)
+{
+ if (vEntries.empty())
+ return;
+ for (auto const & i: vEntries)
+ i->SetLinks(aCheckLink, aColorLink, rGetFocusLink);
+ // 6 is the spacing set on ColorConfigWindow
+ rScroll.vadjustment_set_step_increment(vEntries[0]->get_height_request() + 6);
+}
+
+// Update()
+void ColorConfigWindow_Impl::Update (
+ EditableColorConfig const* pConfig,
+ EditableExtendedColorConfig const* pExtConfig)
+{
+ // updating default entries
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ vEntries[i]->Update(
+ pConfig->GetColorValue(aColorEntry)
+ );
+ }
+
+ // updating extended entries
+ decltype(vEntries)::size_type i = ColorConfigEntryCount;
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ for (unsigned k = 0; i != vEntries.size() && k != nColorCount; ++i, ++k)
+ vEntries[i]->Update(
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k)
+ );
+ }
+}
+
+// ClickHdl()
+void ColorConfigWindow_Impl::ClickHdl(EditableColorConfig* pConfig, const weld::Toggleable& rBox)
+{
+ for (unsigned i = 0; i != ColorConfigEntryCount; ++i)
+ {
+ if (vEntries[i]->Is(&rBox))
+ {
+ ColorConfigEntry const aEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aEntry);
+ aValue.bIsVisible = rBox.get_active();
+ pConfig->SetColorValue(aEntry, aValue);
+ break;
+ }
+ }
+}
+
+// ColorHdl()
+void ColorConfigWindow_Impl::ColorHdl(
+ EditableColorConfig* pConfig, EditableExtendedColorConfig* pExtConfig,
+ const ColorListBox* pBox)
+{
+ unsigned i = 0;
+
+ // default entries
+ for ( ; i != ColorConfigEntryCount; ++i)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ColorConfigEntry const aColorEntry = static_cast<ColorConfigEntry>(i);
+ ColorConfigValue aValue = pConfig->GetColorValue(aColorEntry);
+ vEntries[i]->ColorChanged(aValue);
+ pConfig->SetColorValue(aColorEntry, aValue);
+ break;
+ }
+ }
+
+ // extended entries
+ unsigned const nExtCount = pExtConfig->GetComponentCount();
+ i = ColorConfigEntryCount;
+ for (unsigned j = 0; j != nExtCount; ++j)
+ {
+ OUString sComponentName = pExtConfig->GetComponentName(j);
+ unsigned const nColorCount = pExtConfig->GetComponentColorCount(sComponentName);
+ unsigned const nCount = vEntries.size();
+ for (unsigned k = 0; i != nCount && k != nColorCount; ++i, ++k)
+ {
+ if (pBox && vEntries[i]->Is(pBox))
+ {
+ ExtendedColorConfigValue aValue =
+ pExtConfig->GetComponentColorConfigValue(sComponentName, k);
+ vEntries[i]->ColorChanged(aValue);
+ pExtConfig->SetColorValue(sComponentName, aValue);
+ break;
+ }
+ }
+ }
+}
+
+
+// IsGroupVisible()
+bool ColorConfigWindow_Impl::IsGroupVisible (Group eGroup) const
+{
+ switch (eGroup)
+ {
+ case Group_Writer:
+ case Group_Html:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::WRITER);
+ case Group_Calc:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::CALC);
+ case Group_Draw:
+ return
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DRAW) ||
+ aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::IMPRESS);
+ case Group_Sql:
+ return aModuleOptions.IsModuleInstalled(SvtModuleOptions::EModule::DATABASE);
+ default:
+ return true;
+ }
+}
+
+class ColorConfigCtrl_Impl
+{
+ std::unique_ptr<weld::ScrolledWindow> m_xVScroll;
+ std::unique_ptr<weld::Container> m_xBody;
+ std::unique_ptr<ColorConfigWindow_Impl> m_xScrollWindow;
+
+ EditableColorConfig* pColorConfig;
+ EditableExtendedColorConfig* pExtColorConfig;
+
+ DECL_LINK(ClickHdl, weld::Toggleable&, void);
+ DECL_LINK(ColorHdl, ColorListBox&, void);
+ DECL_LINK(ControlFocusHdl, weld::Widget&, void);
+
+public:
+ explicit ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rbuilder);
+
+ void SetConfig (EditableColorConfig& rConfig) { pColorConfig = &rConfig; }
+ void SetExtendedConfig (EditableExtendedColorConfig& rConfig) { pExtColorConfig = &rConfig; }
+ void Update();
+ tools::Long GetScrollPosition() const
+ {
+ return m_xVScroll->vadjustment_get_value();
+ }
+ void SetScrollPosition(tools::Long nSet)
+ {
+ m_xVScroll->vadjustment_set_value(nSet);
+ }
+ weld::Widget& GetWidget1()
+ {
+ return m_xScrollWindow->GetWidget1();
+ }
+ weld::Widget& GetWidget2()
+ {
+ return m_xScrollWindow->GetWidget2();
+ }
+ int GetLabelIndent() const
+ {
+ return m_xScrollWindow->GetLabelIndent();
+ }
+};
+
+ColorConfigCtrl_Impl::ColorConfigCtrl_Impl(weld::Window* pTopLevel, weld::Builder& rBuilder)
+ : m_xVScroll(rBuilder.weld_scrolled_window("scroll"))
+ , m_xBody(rBuilder.weld_container("colorconfig"))
+ , m_xScrollWindow(std::make_unique<ColorConfigWindow_Impl>(pTopLevel, m_xBody.get()))
+ , pColorConfig(nullptr)
+ , pExtColorConfig(nullptr)
+{
+ m_xBody->set_stack_background();
+
+ Link<weld::Toggleable&,void> aCheckLink = LINK(this, ColorConfigCtrl_Impl, ClickHdl);
+ Link<ColorListBox&,void> aColorLink = LINK(this, ColorConfigCtrl_Impl, ColorHdl);
+ Link<weld::Widget&,void> const& aGetFocusLink = LINK(this, ColorConfigCtrl_Impl, ControlFocusHdl);
+ m_xScrollWindow->SetLinks(aCheckLink, aColorLink, aGetFocusLink, *m_xVScroll);
+}
+
+void ColorConfigCtrl_Impl::Update ()
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->Update(pColorConfig, pExtColorConfig);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ClickHdl, weld::Toggleable&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set");
+ m_xScrollWindow->ClickHdl(pColorConfig, rBox);
+}
+
+// a color list has changed
+IMPL_LINK(ColorConfigCtrl_Impl, ColorHdl, ColorListBox&, rBox, void)
+{
+ DBG_ASSERT(pColorConfig, "Configuration not set" );
+ m_xScrollWindow->ColorHdl(pColorConfig, pExtColorConfig, &rBox);
+}
+
+IMPL_LINK(ColorConfigCtrl_Impl, ControlFocusHdl, weld::Widget&, rCtrl, void)
+{
+ // determine whether a control is completely visible
+ // and make it visible
+ unsigned const nWinHeight = m_xVScroll->vadjustment_get_page_size();
+
+ // calc visible area
+ auto nThumbPos = m_xVScroll->vadjustment_get_value();
+ int const nWinTop = nThumbPos;
+ int const nWinBottom = nWinTop + nWinHeight;
+
+ int x, nCtrlPosY, width, nHeight;
+ rCtrl.get_extents_relative_to(m_xScrollWindow->GetBody(), x, nCtrlPosY, width, nHeight);
+
+ int const nSelectedItemTop = nCtrlPosY;
+ int const nSelectedItemBottom = nCtrlPosY + nHeight;
+ bool const shouldScrollDown = nSelectedItemBottom >= nWinBottom;
+ bool const shouldScrollUp = nSelectedItemTop <= nWinTop;
+ bool const isNeedToScroll = shouldScrollDown || shouldScrollUp || nCtrlPosY < 0;
+
+ if (!isNeedToScroll)
+ return;
+
+ if (shouldScrollDown)
+ {
+ int nOffset = nSelectedItemBottom - nWinBottom;
+ nThumbPos += nOffset + 2;
+ }
+ else
+ {
+ int nOffset = nWinTop - nSelectedItemTop;
+ nThumbPos -= nOffset + 2;
+ if(nThumbPos < 0)
+ nThumbPos = 0;
+ }
+ m_xVScroll->vadjustment_set_value(nThumbPos);
+}
+
+// SvxColorOptionsTabPage
+SvxColorOptionsTabPage::SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optappearancepage.ui", "OptAppearancePage", &rCoreSet)
+ , bFillItemSetCalled(false)
+ , m_nSizeAllocEventId(nullptr)
+ , m_xColorSchemeLB(m_xBuilder->weld_combo_box("colorschemelb"))
+ , m_xSaveSchemePB(m_xBuilder->weld_button("save"))
+ , m_xDeleteSchemePB(m_xBuilder->weld_button("delete"))
+ , m_xColorConfigCT(new ColorConfigCtrl_Impl(pController->getDialog(), *m_xBuilder))
+ , m_xTable(m_xBuilder->weld_widget("table"))
+ , m_xOnFT(m_xBuilder->weld_label("on"))
+ , m_xElementFT(m_xBuilder->weld_label("uielements"))
+ , m_xColorFT(m_xBuilder->weld_label("colorsetting"))
+ , m_rWidget1(m_xColorConfigCT->GetWidget1())
+ , m_rWidget2(m_xColorConfigCT->GetWidget2())
+{
+ m_xColorSchemeLB->make_sorted();
+ m_xColorSchemeLB->connect_changed(LINK(this, SvxColorOptionsTabPage, SchemeChangedHdl_Impl));
+ Link<weld::Button&,void> aLk = LINK(this, SvxColorOptionsTabPage, SaveDeleteHdl_Impl );
+ m_xSaveSchemePB->connect_clicked(aLk);
+ m_xDeleteSchemePB->connect_clicked(aLk);
+
+ m_rWidget1.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+ m_rWidget2.connect_size_allocate(LINK(this, SvxColorOptionsTabPage, AdjustHeaderBar));
+}
+
+SvxColorOptionsTabPage::~SvxColorOptionsTabPage()
+{
+ if (pColorConfig)
+ {
+ //when the dialog is cancelled but the color scheme ListBox has been changed these
+ //changes need to be undone
+ if (!bFillItemSetCalled && m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ OUString sOldScheme = m_xColorSchemeLB->get_saved_value();
+ if(!sOldScheme.isEmpty())
+ {
+ pColorConfig->SetCurrentSchemeName(sOldScheme);
+ pExtColorConfig->SetCurrentSchemeName(sOldScheme);
+ }
+ }
+ pColorConfig->ClearModified();
+ pColorConfig->EnableBroadcast();
+ pColorConfig.reset();
+
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->EnableBroadcast();
+ pExtColorConfig.reset();
+ }
+ m_xColorConfigCT.reset();
+ if (m_nSizeAllocEventId)
+ Application::RemoveUserEvent(m_nSizeAllocEventId);
+}
+
+std::unique_ptr<SfxTabPage> SvxColorOptionsTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxColorOptionsTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxColorOptionsTabPage::FillItemSet( SfxItemSet* )
+{
+ bFillItemSetCalled = true;
+ if (m_xColorSchemeLB->get_value_changed_from_saved())
+ {
+ pColorConfig->SetModified();
+ pExtColorConfig->SetModified();
+ }
+ if (pColorConfig->IsModified())
+ pColorConfig->Commit();
+ if (pExtColorConfig->IsModified())
+ pExtColorConfig->Commit();
+ return true;
+}
+
+void SvxColorOptionsTabPage::Reset( const SfxItemSet* )
+{
+ if(pColorConfig)
+ {
+ pColorConfig->ClearModified();
+ pColorConfig->DisableBroadcast();
+ }
+ pColorConfig.reset(new EditableColorConfig);
+ m_xColorConfigCT->SetConfig(*pColorConfig);
+
+ if(pExtColorConfig)
+ {
+ pExtColorConfig->ClearModified();
+ pExtColorConfig->DisableBroadcast();
+ }
+ pExtColorConfig.reset(new EditableExtendedColorConfig);
+ m_xColorConfigCT->SetExtendedConfig(*pExtColorConfig);
+
+ OUString sUser = GetUserData();
+ //has to be called always to speed up accessibility tools
+ m_xColorConfigCT->SetScrollPosition(sUser.toInt32());
+ m_xColorSchemeLB->clear();
+ const uno::Sequence< OUString > aSchemes = pColorConfig->GetSchemeNames();
+ for(const OUString& s : aSchemes)
+ m_xColorSchemeLB->append_text(s);
+ m_xColorSchemeLB->set_active_text(pColorConfig->GetCurrentSchemeName());
+ m_xColorSchemeLB->save_value();
+ m_xDeleteSchemePB->set_sensitive( aSchemes.getLength() > 1 );
+ UpdateColorConfig();
+}
+
+DeactivateRC SvxColorOptionsTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+void SvxColorOptionsTabPage::UpdateColorConfig()
+{
+ //update the color config control
+ m_xColorConfigCT->Update();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SchemeChangedHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ pColorConfig->LoadScheme(rBox.get_active_text());
+ pExtColorConfig->LoadScheme(rBox.get_active_text());
+ UpdateColorConfig();
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, SaveDeleteHdl_Impl, weld::Button&, rButton, void)
+{
+ if (m_xSaveSchemePB.get() == &rButton)
+ {
+ OUString sName;
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> aNameDlg(pFact->CreateSvxNameDialog(GetFrameWeld(),
+ sName, CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE2) ));
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ aNameDlg->SetText(CuiResId(RID_CUISTR_COLOR_CONFIG_SAVE1));
+ aNameDlg->SetHelpId(HID_OPTIONS_COLORCONFIG_SAVE_SCHEME);
+ aNameDlg->SetCheckNameHdl( LINK(this, SvxColorOptionsTabPage, CheckNameHdl_Impl));
+ if(RET_OK == aNameDlg->Execute())
+ {
+ aNameDlg->GetName(sName);
+ pColorConfig->AddScheme(sName);
+ pExtColorConfig->AddScheme(sName);
+ m_xColorSchemeLB->append_text(sName);
+ m_xColorSchemeLB->set_active_text(sName);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ }
+ }
+ else
+ {
+ DBG_ASSERT(m_xColorSchemeLB->get_count() > 1, "don't delete the last scheme");
+ std::unique_ptr<weld::MessageDialog> xQuery(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE)));
+ xQuery->set_title(CuiResId(RID_CUISTR_COLOR_CONFIG_DELETE_TITLE));
+ if (RET_YES == xQuery->run())
+ {
+ OUString sDeleteScheme(m_xColorSchemeLB->get_active_text());
+ m_xColorSchemeLB->remove(m_xColorSchemeLB->get_active());
+ m_xColorSchemeLB->set_active(0);
+ SchemeChangedHdl_Impl(*m_xColorSchemeLB);
+ //first select the new scheme and then delete the old one
+ pColorConfig->DeleteScheme(sDeleteScheme);
+ pExtColorConfig->DeleteScheme(sDeleteScheme);
+ }
+ }
+ m_xDeleteSchemePB->set_sensitive(m_xColorSchemeLB->get_count() > 1);
+}
+
+IMPL_LINK(SvxColorOptionsTabPage, CheckNameHdl_Impl, AbstractSvxNameDialog&, rDialog, bool )
+{
+ OUString sName;
+ rDialog.GetName(sName);
+ return !sName.isEmpty() && m_xColorSchemeLB->find_text(sName) == -1;
+}
+
+void SvxColorOptionsTabPage::FillUserData()
+{
+ SetUserData(OUString::number(m_xColorConfigCT->GetScrollPosition()));
+}
+
+IMPL_LINK_NOARG(SvxColorOptionsTabPage, AdjustHeaderBar, const Size&, void)
+{
+ if (m_nSizeAllocEventId)
+ return;
+ m_nSizeAllocEventId = Application::PostUserEvent(LINK(this, SvxColorOptionsTabPage, PostAdjustHeaderBar));
+}
+
+IMPL_LINK_NOARG(SvxColorOptionsTabPage, PostAdjustHeaderBar, void*, void)
+{
+ m_nSizeAllocEventId = nullptr;
+
+ // horizontal positions
+ int nX1, nX2, nX3, y, width, height;
+ if (!m_rWidget1.get_extents_relative_to(*m_xTable, nX1, y, width, height))
+ return;
+ if (!m_rWidget2.get_extents_relative_to(*m_xTable, nX2, y, width, height))
+ return;
+ if (!m_xTable->get_extents_relative_to(*m_xTable, nX3, y, width, height))
+ return;
+
+ // 6 is the column-spacing of the parent grid of these labels
+ auto nTextWidth1 = nX1 + m_xColorConfigCT->GetLabelIndent() - 6;
+ m_xOnFT->set_size_request(nTextWidth1, -1);
+ auto nTextWidth3 = width - nX2;
+ m_xColorFT->set_size_request(nTextWidth3, -1);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optcolor.hxx b/cui/source/options/optcolor.hxx
new file mode 100644
index 000000000..ede03dc6b
--- /dev/null
+++ b/cui/source/options/optcolor.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+namespace svtools {class EditableColorConfig;class EditableExtendedColorConfig;}
+class ColorConfigCtrl_Impl;
+class AbstractSvxNameDialog;
+struct ImplSVEvent;
+
+class SvxColorOptionsTabPage : public SfxTabPage
+{
+ bool bFillItemSetCalled;
+
+ ImplSVEvent* m_nSizeAllocEventId;
+
+ std::unique_ptr<weld::ComboBox> m_xColorSchemeLB;
+ std::unique_ptr<weld::Button> m_xSaveSchemePB;
+ std::unique_ptr<weld::Button> m_xDeleteSchemePB;
+ std::unique_ptr<ColorConfigCtrl_Impl> m_xColorConfigCT;
+ std::unique_ptr<weld::Widget> m_xTable;
+ std::unique_ptr<weld::Label> m_xOnFT;
+ std::unique_ptr<weld::Label> m_xElementFT;
+ std::unique_ptr<weld::Label> m_xColorFT;
+ weld::Widget& m_rWidget1;
+ weld::Widget& m_rWidget2;
+
+ std::unique_ptr<svtools::EditableColorConfig> pColorConfig;
+ std::unique_ptr<svtools::EditableExtendedColorConfig> pExtColorConfig;
+
+ DECL_LINK(SchemeChangedHdl_Impl, weld::ComboBox&, void);
+ DECL_LINK(SaveDeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNameHdl_Impl, AbstractSvxNameDialog&, bool);
+ DECL_LINK(AdjustHeaderBar, const Size&, void);
+ DECL_LINK(PostAdjustHeaderBar, void *, void);
+ void UpdateColorConfig();
+
+public:
+ SvxColorOptionsTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxColorOptionsTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.cxx b/cui/source/options/optctl.cxx
new file mode 100644
index 000000000..52bd18fc8
--- /dev/null
+++ b/cui/source/options/optctl.cxx
@@ -0,0 +1,146 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optctl.hxx"
+#include <svl/ctloptions.hxx>
+#include <sal/log.hxx>
+#include <tools/debug.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+IMPL_LINK_NOARG(SvxCTLOptionsPage, SequenceCheckingCB_Hdl, weld::Toggleable&, void)
+{
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+ // #i48117#: by default restricted and type&replace have to be switched on
+ if (bIsSequenceChecking)
+ {
+ m_xTypeReplaceCB->set_active(true);
+ m_xRestrictedCB->set_active(true);
+ }
+}
+
+SvxCTLOptionsPage::SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optctlpage.ui", "OptCTLPage", &rSet)
+ , m_xSequenceCheckingCB(m_xBuilder->weld_check_button("sequencechecking"))
+ , m_xRestrictedCB(m_xBuilder->weld_check_button("restricted"))
+ , m_xTypeReplaceCB(m_xBuilder->weld_check_button("typeandreplace"))
+ , m_xMovementLogicalRB(m_xBuilder->weld_radio_button("movementlogical"))
+ , m_xMovementVisualRB(m_xBuilder->weld_radio_button("movementvisual"))
+ , m_xNumeralsLB(m_xBuilder->weld_combo_box("numerals"))
+{
+ m_xSequenceCheckingCB->connect_toggled(LINK(this, SvxCTLOptionsPage, SequenceCheckingCB_Hdl));
+}
+
+SvxCTLOptionsPage::~SvxCTLOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxCTLOptionsPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxCTLOptionsPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxCTLOptionsPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ SvtCTLOptions aCTLOptions;
+
+ // Sequence checking
+ bool bChecked = m_xSequenceCheckingCB->get_active();
+ if ( m_xSequenceCheckingCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceChecking( bChecked );
+ bModified = true;
+ }
+
+ bChecked = m_xRestrictedCB->get_active();
+ if( m_xRestrictedCB->get_state_changed_from_saved() )
+ {
+ aCTLOptions.SetCTLSequenceCheckingRestricted( bChecked );
+ bModified = true;
+ }
+ bChecked = m_xTypeReplaceCB->get_active();
+ if( m_xTypeReplaceCB->get_state_changed_from_saved())
+ {
+ aCTLOptions.SetCTLSequenceCheckingTypeAndReplace(bChecked);
+ bModified = true;
+ }
+
+ bool bLogicalChecked = m_xMovementLogicalRB->get_active();
+ if ( m_xMovementLogicalRB->get_state_changed_from_saved() ||
+ m_xMovementVisualRB->get_state_changed_from_saved() )
+ {
+ SvtCTLOptions::CursorMovement eMovement =
+ bLogicalChecked ? SvtCTLOptions::MOVEMENT_LOGICAL : SvtCTLOptions::MOVEMENT_VISUAL;
+ aCTLOptions.SetCTLCursorMovement( eMovement );
+ bModified = true;
+ }
+
+ if (m_xNumeralsLB->get_value_changed_from_saved())
+ {
+ const sal_Int32 nPos = m_xNumeralsLB->get_active();
+ aCTLOptions.SetCTLTextNumerals( static_cast<SvtCTLOptions::TextNumerals>(nPos) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void SvxCTLOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtCTLOptions aCTLOptions;
+
+ m_xSequenceCheckingCB->set_active( aCTLOptions.IsCTLSequenceChecking() );
+ m_xRestrictedCB->set_active( aCTLOptions.IsCTLSequenceCheckingRestricted() );
+ m_xTypeReplaceCB->set_active( aCTLOptions.IsCTLSequenceCheckingTypeAndReplace() );
+
+ SvtCTLOptions::CursorMovement eMovement = aCTLOptions.GetCTLCursorMovement();
+ switch ( eMovement )
+ {
+ case SvtCTLOptions::MOVEMENT_LOGICAL :
+ m_xMovementLogicalRB->set_active(true);
+ break;
+
+ case SvtCTLOptions::MOVEMENT_VISUAL :
+ m_xMovementVisualRB->set_active(true);
+ break;
+
+ default:
+ SAL_WARN( "cui.options", "SvxCTLOptionsPage::Reset(): invalid movement enum" );
+ }
+
+ sal_uInt16 nPos = static_cast<sal_uInt16>(aCTLOptions.GetCTLTextNumerals());
+ DBG_ASSERT( nPos < m_xNumeralsLB->get_count(), "SvxCTLOptionsPage::Reset(): invalid numerals enum" );
+ m_xNumeralsLB->set_active(nPos);
+
+ m_xSequenceCheckingCB->save_state();
+ m_xRestrictedCB->save_state();
+ m_xTypeReplaceCB->save_state();
+ m_xMovementLogicalRB->save_state();
+ m_xMovementVisualRB->save_state();
+ m_xNumeralsLB->save_value();
+
+ bool bIsSequenceChecking = m_xSequenceCheckingCB->get_active();
+ m_xRestrictedCB->set_sensitive( bIsSequenceChecking );
+ m_xTypeReplaceCB->set_sensitive( bIsSequenceChecking );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optctl.hxx b/cui/source/options/optctl.hxx
new file mode 100644
index 000000000..0cc24951b
--- /dev/null
+++ b/cui/source/options/optctl.hxx
@@ -0,0 +1,45 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+// class SvxCTLOptionsPage -----------------------------------------------------
+
+class SvxCTLOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xSequenceCheckingCB;
+ std::unique_ptr<weld::CheckButton> m_xRestrictedCB;
+ std::unique_ptr<weld::CheckButton> m_xTypeReplaceCB;
+ std::unique_ptr<weld::RadioButton> m_xMovementLogicalRB;
+ std::unique_ptr<weld::RadioButton> m_xMovementVisualRB;
+ std::unique_ptr<weld::ComboBox> m_xNumeralsLB;
+
+ DECL_LINK( SequenceCheckingCB_Hdl, weld::Toggleable&, void );
+
+public:
+ SvxCTLOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxCTLOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optdict.cxx b/cui/source/options/optdict.cxx
new file mode 100644
index 000000000..f0efb39ca
--- /dev/null
+++ b/cui/source/options/optdict.cxx
@@ -0,0 +1,774 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <editeng/unolingu.hxx>
+#include <o3tl/safeint.hxx>
+#include <svx/dialmgr.hxx>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <comphelper/string.hxx>
+#include <tools/debug.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+
+#include <linguistic/misc.hxx>
+#include <strings.hrc>
+#include <optdict.hxx>
+#include <dialmgr.hxx>
+#include <svx/svxerr.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::linguistic2;
+using namespace linguistic;
+
+// static function -------------------------------------------------------
+
+static OUString getNormDicEntry_Impl(std::u16string_view rText)
+{
+ OUString aTmp(comphelper::string::stripEnd(rText, '.'));
+ // non-standard hyphenation
+ if (aTmp.indexOf('[') > -1)
+ {
+ OUStringBuffer aTmp2 ( aTmp.getLength() );
+ bool bSkip = false;
+ for (sal_Int32 i = 0; i < aTmp.getLength(); i++)
+ {
+ sal_Unicode cTmp = aTmp[i];
+ if (cTmp == '[')
+ bSkip = true;
+ else if (!bSkip)
+ aTmp2.append( cTmp );
+ else if (cTmp == ']')
+ bSkip = false;
+ }
+ aTmp = aTmp2.makeStringAndClear();
+ }
+ return aTmp.replaceAll("=", "");
+}
+
+namespace {
+
+// Compare Dictionary Entry result
+enum CDE_RESULT { CDE_EQUAL, CDE_SIMILAR, CDE_DIFFERENT };
+
+}
+
+static CDE_RESULT cmpDicEntry_Impl( std::u16string_view rText1, std::u16string_view rText2 )
+{
+ CDE_RESULT eRes = CDE_DIFFERENT;
+
+ if (rText1 == rText2)
+ eRes = CDE_EQUAL;
+ else
+ { // similar = equal up to trailing '.' and hyphenation positions
+ // marked with '=' and '[' + alternative spelling pattern + ']'
+ if (getNormDicEntry_Impl( rText1 ) == getNormDicEntry_Impl( rText2 ))
+ eRes = CDE_SIMILAR;
+ }
+
+ return eRes;
+}
+
+// class SvxNewDictionaryDialog -------------------------------------------
+
+SvxNewDictionaryDialog::SvxNewDictionaryDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/optnewdictionarydialog.ui", "OptNewDictionaryDialog")
+ , m_xNameEdit(m_xBuilder->weld_entry("nameedit"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+ , m_xExceptBtn(m_xBuilder->weld_check_button("except"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+{
+ // Prevent creation of dictionary without a name.
+ m_xOKBtn->set_sensitive(false);
+
+ // install handler
+ m_xNameEdit->connect_changed(LINK(this, SvxNewDictionaryDialog, ModifyHdl_Impl));
+ m_xOKBtn->connect_clicked(LINK(this, SvxNewDictionaryDialog, OKHdl_Impl));
+
+ // display languages
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::ALL, true, true);
+ m_xLanguageLB->set_active(0);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, OKHdl_Impl, weld::Button&, void)
+{
+
+ // add extension for personal dictionaries
+ OUString sDict = comphelper::string::stripEnd(m_xNameEdit->get_text(), ' ') + ".dic";
+
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+
+ Sequence< Reference< XDictionary > > aDics;
+ if (xDicList.is())
+ aDics = xDicList->getDictionaries();
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ bool bFound = false;
+ sal_Int32 i;
+ for (i = 0; !bFound && i < nCount; ++i )
+ if ( sDict.equalsIgnoreAsciiCase( pDic[i]->getName()) )
+ bFound = true;
+
+ if ( sDict.indexOf("/") != -1 || sDict.indexOf("\\") != -1 )
+ {
+ // Detected an invalid character.
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_INVALID_DICT_NAME)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ if ( bFound )
+ {
+ // duplicate names?
+ std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Info, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_DOUBLE_DICTS)));
+ xInfoBox->run();
+ m_xNameEdit->grab_focus();
+ return;
+ }
+
+ // create and add
+ LanguageType nLang = m_xLanguageLB->get_active_id();
+ try
+ {
+ // create new dictionary
+ DictionaryType eType = m_xExceptBtn->get_active() ?
+ DictionaryType_NEGATIVE : DictionaryType_POSITIVE;
+ if (xDicList.is())
+ {
+ lang::Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ OUString aURL( linguistic::GetWritableDictionaryURL( sDict ) );
+ m_xNewDic = xDicList->createDictionary(sDict, aLocale, eType, aURL);
+ m_xNewDic->setActive(true);
+ }
+ DBG_ASSERT(m_xNewDic.is(), "NULL pointer");
+ }
+ catch(...)
+ {
+ m_xNewDic = nullptr;
+ // error: couldn't create new dictionary
+ SfxErrorContext aContext( ERRCTX_SVX_LINGU_DICTIONARY, OUString(),
+ m_xDialog.get(), RID_SVXERRCTX, SvxResLocale() );
+ ErrorHandler::HandleError( *new StringErrorInfo(
+ ERRCODE_SVX_LINGU_DICT_NOTWRITEABLE, sDict ) );
+ m_xDialog->response(RET_CANCEL);
+ }
+
+ if (xDicList.is() && m_xNewDic.is())
+ {
+ xDicList->addDictionary(m_xNewDic);
+
+ // refresh list of dictionaries
+ //! dictionaries may have been added/removed elsewhere too.
+ aDics = xDicList->getDictionaries();
+ }
+
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxNewDictionaryDialog, ModifyHdl_Impl, weld::Entry&, void)
+{
+ m_xOKBtn->set_sensitive(!m_xNameEdit->get_text().isEmpty());
+}
+
+// class SvxEditDictionaryDialog -------------------------------------------
+
+SvxEditDictionaryDialog::SvxEditDictionaryDialog(weld::Window* pParent, std::u16string_view rName)
+ : GenericDialogController(pParent, "cui/ui/editdictionarydialog.ui", "EditDictionaryDialog")
+ , sModify(CuiResId(STR_MODIFY))
+ , bFirstSelect(false)
+ , bDoNothing(false)
+ , bDicIsReadonly(false)
+ , m_xAllDictsLB(m_xBuilder->weld_combo_box("book"))
+ , m_xLangFT(m_xBuilder->weld_label("lang_label"))
+ , m_xLangLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("lang")))
+ , m_xWordED(m_xBuilder->weld_entry("word"))
+ , m_xReplaceFT(m_xBuilder->weld_label("replace_label"))
+ , m_xReplaceED(m_xBuilder->weld_entry("replace"))
+ , m_xSingleColumnLB(m_xBuilder->weld_tree_view("words"))
+ , m_xDoubleColumnLB(m_xBuilder->weld_tree_view("replaces"))
+ , m_xNewReplacePB(m_xBuilder->weld_button("newreplace"))
+ , m_xDeletePB(m_xBuilder->weld_button("delete"))
+{
+ sReplaceFT_Text = m_xReplaceFT->get_label();
+ m_xSingleColumnLB->set_size_request(-1, m_xSingleColumnLB->get_height_rows(8));
+ m_xDoubleColumnLB->set_size_request(-1, m_xDoubleColumnLB->get_height_rows(8));
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ m_xSingleColumnLB->hide();
+
+ //set to max of both sizes to avoid resizes
+ sNew = m_xNewReplacePB->get_label();
+ auto nNewWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sModify);
+ auto nReplaceWidth = m_xNewReplacePB->get_preferred_size().Width();
+ m_xNewReplacePB->set_label(sNew);
+ m_xNewReplacePB->set_size_request(std::max(nNewWidth, nReplaceWidth), -1);
+
+ if (LinguMgr::GetDictionaryList().is())
+ aDics = LinguMgr::GetDictionaryList()->getDictionaries();
+
+ m_xSingleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+ m_xDoubleColumnLB->connect_changed(LINK(this, SvxEditDictionaryDialog, SelectHdl));
+
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xDoubleColumnLB->get_approximate_digit_width() * 22)
+ };
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+
+ // install handler
+ m_xNewReplacePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+ m_xDeletePB->connect_clicked(
+ LINK( this, SvxEditDictionaryDialog, NewDelButtonHdl));
+
+ m_xLangLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectLangHdl_Impl ) );
+ m_xAllDictsLB->connect_changed(
+ LINK( this, SvxEditDictionaryDialog, SelectBookHdl_Impl ) );
+
+ m_xWordED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xReplaceED->connect_changed(LINK(this, SvxEditDictionaryDialog, ModifyHdl));
+ m_xWordED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+ m_xReplaceED->connect_activate(LINK(this, SvxEditDictionaryDialog, NewDelActionHdl));
+
+ // fill listbox with all available WB's
+ const Reference< XDictionary > *pDic = aDics.getConstArray();
+ sal_Int32 nCount = aDics.getLength();
+
+ OUString aLookUpEntry;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ {
+ Reference< XDictionary > xDic = pDic[i];
+ if (xDic.is())
+ {
+ bool bNegative = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+ OUString aDicName( xDic->getName() );
+ const OUString aTxt( ::GetDicInfoStr( aDicName,
+ LanguageTag( xDic->getLocale() ).getLanguageType(), bNegative ) );
+ m_xAllDictsLB->append_text(aTxt);
+
+ if (rName == aDicName)
+ aLookUpEntry = aTxt;
+ }
+ }
+
+ m_xLangLB->SetLanguageList( SvxLanguageListFlags::ALL, true, true );
+
+ Link<OUString&,bool> aLink = LINK(this, SvxEditDictionaryDialog, InsertTextHdl);
+ m_xReplaceED->connect_insert_text(aLink);
+ m_xWordED->connect_insert_text(aLink);
+
+ if ( nCount > 0 )
+ {
+ m_xAllDictsLB->set_active_text(aLookUpEntry);
+ int nPos = m_xAllDictsLB->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = 0;
+ m_xAllDictsLB->set_active(nPos);
+ }
+ Reference< XDictionary > xDic;
+ if (nPos != -1)
+ xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ // check if dictionary is read-only
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+ ShowWords_Impl( nPos );
+ }
+ else
+ {
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(false);
+ }
+
+ m_xWordED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+ m_xReplaceED->connect_size_allocate(LINK(this, SvxEditDictionaryDialog, EntrySizeAllocHdl));
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, EntrySizeAllocHdl, const Size&, void)
+{
+ std::vector<int> aWidths;
+ int x, y, width, height;
+ if (m_xReplaceED->get_extents_relative_to(*m_pWordsLB, x, y, width, height))
+ {
+ aWidths.push_back(x);
+ m_xDoubleColumnLB->set_column_fixed_widths(aWidths);
+ }
+}
+
+SvxEditDictionaryDialog::~SvxEditDictionaryDialog()
+{
+}
+
+void SvxEditDictionaryDialog::SetDicReadonly_Impl(
+ Reference< XDictionary > const &xDic )
+{
+ // enable or disable new and delete button according to file attributes
+ bDicIsReadonly = true;
+ if (xDic.is())
+ {
+ Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( !xStor.is() // non persistent dictionary
+ || !xStor->hasLocation() // not yet persistent
+ || !xStor->isReadonly() )
+ {
+ bDicIsReadonly = false;
+ }
+ }
+}
+
+void SvxEditDictionaryDialog::SetLanguage_Impl(LanguageType nLanguage)
+{
+ // select language
+ m_xLangLB->set_active_id(nLanguage);
+}
+
+int SvxEditDictionaryDialog::GetLBInsertPos(std::u16string_view rDicWord)
+{
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ int j;
+ int nCount = m_pWordsLB->n_children();
+ for (j = 0; j < nCount; ++j)
+ {
+ OUString aNormEntry( getNormDicEntry_Impl( rDicWord ) );
+ sal_Int32 nCmpRes = pCollator->
+ compareString( aNormEntry, getNormDicEntry_Impl( m_pWordsLB->get_text(j, 0) ) );
+ if (nCmpRes < 0)
+ break;
+ }
+
+ return j;
+}
+
+void SvxEditDictionaryDialog::RemoveDictEntry(int nEntry)
+{
+ int nLBPos = m_xAllDictsLB->get_active();
+ if (nEntry != -1 && nLBPos != -1)
+ {
+ OUString sTmpShort(m_pWordsLB->get_text(nEntry, 0));
+
+ Reference<XDictionary> xDic = aDics.getConstArray()[nLBPos];
+ if (xDic->remove(sTmpShort)) // sal_True on success
+ {
+ m_pWordsLB->remove(nEntry);
+ SelectHdl(*m_pWordsLB);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectBookHdl_Impl, weld::ComboBox&, void)
+{
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos == -1)
+ return;
+
+ m_xNewReplacePB->set_sensitive( false );
+ m_xDeletePB->set_sensitive( false );
+ // display dictionary
+ ShowWords_Impl( nPos );
+ // enable or disable new and delete button according to file attributes
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ SetLanguage_Impl( LanguageTag( xDic->getLocale() ).getLanguageType() );
+
+ SetDicReadonly_Impl(xDic);
+ bool bEnable = !IsDicReadonly_Impl();
+ m_xLangFT->set_sensitive( bEnable );
+ m_xLangLB->set_sensitive( bEnable );
+}
+
+IMPL_LINK_NOARG(SvxEditDictionaryDialog, SelectLangHdl_Impl, weld::ComboBox&, void)
+{
+ int nDicPos = m_xAllDictsLB->get_active();
+ LanguageType nLang = m_xLangLB->get_active_id();
+ Reference< XDictionary > const & xDic = aDics[ nDicPos ];
+ LanguageType nOldLang = LanguageTag( xDic->getLocale() ).getLanguageType();
+
+ if ( nLang == nOldLang )
+ return;
+
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ CuiResId(RID_CUISTR_CONFIRM_SET_LANGUAGE)));
+ OUString sTxt(xBox->get_primary_text());
+ sTxt = sTxt.replaceFirst("%1", m_xAllDictsLB->get_active_text());
+ xBox->set_primary_text(sTxt);
+
+ if (xBox->run() == RET_YES)
+ {
+ xDic->setLocale( LanguageTag::convertToLocale( nLang ) );
+ bool bNegativ = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ const OUString sName(
+ ::GetDicInfoStr( xDic->getName(),
+ LanguageTag( xDic->getLocale() ).getLanguageType(),
+ bNegativ ) );
+ m_xAllDictsLB->remove(nDicPos);
+ m_xAllDictsLB->insert_text(nDicPos, sName);
+ m_xAllDictsLB->set_active(nDicPos);
+ }
+ else
+ SetLanguage_Impl( nOldLang );
+}
+
+void SvxEditDictionaryDialog::ShowWords_Impl( sal_uInt16 nId )
+{
+ Reference< XDictionary > xDic = aDics.getConstArray()[ nId ];
+
+ weld::WaitObject aWait(m_xDialog.get());
+
+ m_xWordED->set_text(OUString());
+ m_xReplaceED->set_text(OUString());
+
+ bool bIsNegative = xDic->getDictionaryType() != DictionaryType_POSITIVE;
+ bool bLangNone = LanguageTag(
+ xDic->getLocale() ).getLanguageType() == LANGUAGE_NONE;
+
+ // The label is "Replace By" only in negative dictionaries (forbidden
+ // words), otherwise "Grammar By" in language-specific dictionaries
+ // (where the optional second word is the sample word for
+ // the Hunspell based affixation/compounding of the new dictionary word)
+ if (bIsNegative)
+ {
+ m_xReplaceFT->set_label(sReplaceFT_Text);
+ } else if (!bLangNone) {
+ m_xReplaceFT->set_label(CuiResId(RID_CUISTR_OPT_GRAMMAR_BY));
+ }
+
+ if(bIsNegative || !bLangNone)
+ {
+ // make controls for replacement text active
+ if (!m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->show();
+ m_xReplaceED->show();
+ m_xSingleColumnLB->hide();
+ m_xDoubleColumnLB->show();
+ m_pWordsLB = m_xDoubleColumnLB.get();
+ }
+ }
+ else
+ {
+ // deactivate controls for replacement text
+ if (m_xReplaceFT->get_visible())
+ {
+ m_xReplaceFT->hide();
+ m_xReplaceED->hide();
+ m_xDoubleColumnLB->hide();
+ m_xSingleColumnLB->show();
+ m_pWordsLB = m_xSingleColumnLB.get();
+ }
+ }
+
+ m_pWordsLB->clear();
+
+ Sequence< Reference< XDictionaryEntry > > aEntries( xDic->getEntries() );
+ const Reference< XDictionaryEntry > *pEntry = aEntries.getConstArray();
+ sal_Int32 nCount = aEntries.getLength();
+ std::vector<OUString> aSortedDicEntries;
+ aSortedDicEntries.reserve(nCount);
+ for (sal_Int32 i = 0; i < nCount; i++)
+ {
+ OUString aStr = pEntry[i]->getDictionaryWord();
+ if(!pEntry[i]->getReplacementText().isEmpty())
+ {
+ aStr += "\t" + pEntry[i]->getReplacementText();
+ }
+ aSortedDicEntries.push_back(aStr);
+ }
+
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ const CollatorWrapper* pCollator = aIntlWrapper.getCollator();
+ std::sort(aSortedDicEntries.begin(), aSortedDicEntries.end(),
+ [&] (OUString const & lhs, OUString const & rhs)
+ {
+ sal_Int32 nCmpRes = pCollator->
+ compareString( getNormDicEntry_Impl(lhs), getNormDicEntry_Impl( rhs ) );
+ return nCmpRes < 0;
+ });
+
+ m_pWordsLB->freeze(); // speed up insert
+ int nRow = 0;
+ for (OUString const & rStr : aSortedDicEntries)
+ {
+ m_pWordsLB->append_text(rStr.getToken(0, '\t'));
+ if (m_pWordsLB == m_xDoubleColumnLB.get())
+ {
+ OUString sReplace = rStr.getToken(1, '\t');
+ m_pWordsLB->set_text(nRow, sReplace, 1);
+ ++nRow;
+ }
+ }
+ m_pWordsLB->thaw();
+
+ if (m_pWordsLB->n_children())
+ {
+ m_pWordsLB->select(0);
+ m_pWordsLB->set_cursor(0);
+ SelectHdl(*m_pWordsLB);
+ }
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, SelectHdl, weld::TreeView&, rBox, void)
+{
+ if (bDoNothing)
+ return;
+
+ int nEntry = rBox.get_selected_index();
+
+ if(!bFirstSelect)
+ {
+ if (nEntry != -1)
+ {
+ OUString sTmpShort(rBox.get_text(nEntry, 0));
+ // without this the cursor is always at the beginning of a word, if the text
+ // is set over the ModifyHdl, although you're editing there at the moment
+ if (m_xWordED->get_text() != sTmpShort)
+ m_xWordED->set_text(sTmpShort);
+ if (&rBox == m_xDoubleColumnLB.get())
+ m_xReplaceED->set_text(rBox.get_text(nEntry, 1));
+ }
+ }
+ else
+ bFirstSelect = false;
+
+ // entries in the list box should exactly correspond to those from the
+ // dictionary. Thus:
+ m_xNewReplacePB->set_sensitive(false);
+ m_xDeletePB->set_sensitive(nEntry != -1 && !IsDicReadonly_Impl());
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelButtonHdl, weld::Button&, rBtn, void)
+{
+ NewDelHdl(&rBtn);
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, NewDelActionHdl, weld::Entry&, rDictEdit, bool)
+{
+ return NewDelHdl(&rDictEdit);
+}
+
+bool SvxEditDictionaryDialog::NewDelHdl(const weld::Widget* pBtn)
+{
+ if (pBtn == m_xDeletePB.get())
+ {
+ m_xWordED->set_text("");
+ m_xReplaceED->set_text("");
+ m_xDeletePB->set_sensitive(false);
+
+ int nEntry = m_pWordsLB->get_selected_index();
+ RemoveDictEntry(nEntry); // remove entry from dic and list-box
+ }
+ if (pBtn == m_xNewReplacePB.get() || m_xNewReplacePB->get_sensitive())
+ {
+ int nEntry = m_pWordsLB->get_selected_index();
+ OUString aNewWord(m_xWordED->get_text());
+ OUString sEntry(aNewWord);
+ OUString aReplaceStr(m_xReplaceED->get_text());
+
+ DictionaryError nAddRes = DictionaryError::UNKNOWN;
+ int nPos = m_xAllDictsLB->get_active();
+ if (nPos != -1 && !aNewWord.isEmpty())
+ {
+ DBG_ASSERT(nPos < aDics.getLength(), "invalid dictionary index");
+ Reference< XDictionary > const & xDic = aDics[ nPos ];
+ if (xDic.is())
+ {
+ // make changes in dic
+
+ bool bIsNegEntry = xDic->getDictionaryType() == DictionaryType_NEGATIVE;
+
+ OUString aRplcText;
+ if(!aReplaceStr.isEmpty())
+ aRplcText = aReplaceStr;
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ xDic->remove(m_pWordsLB->get_text(nEntry, 0));
+ // if remove has failed the following add should fail too
+ // and thus a warning message should be triggered...
+
+ nAddRes = linguistic::AddEntryToDic( xDic,
+ aNewWord, bIsNegEntry,
+ aRplcText, false );
+ }
+ }
+ if (DictionaryError::NONE != nAddRes)
+ SvxDicError(m_xDialog.get(), nAddRes);
+
+ if (DictionaryError::NONE == nAddRes && !sEntry.isEmpty())
+ {
+ // insert new entry in list-box etc...
+ m_pWordsLB->freeze();
+
+ if (nEntry != -1) // entry selected in m_pWordsLB ie action = modify entry
+ {
+ m_pWordsLB->set_text(nEntry, sEntry);
+ if (!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+ else
+ {
+ nEntry = GetLBInsertPos(aNewWord);
+ m_pWordsLB->insert_text(nEntry, sEntry);
+ if(!aReplaceStr.isEmpty())
+ m_pWordsLB->set_text(nEntry, aReplaceStr, 1);
+ }
+
+ m_pWordsLB->thaw();
+ m_pWordsLB->scroll_to_row(nEntry);
+
+ // if the request came from the ReplaceEdit, give focus to the ShortEdit
+ if (m_xReplaceED->has_focus())
+ m_xWordED->grab_focus();
+ }
+ }
+ else
+ {
+ // this can only be an enter in one of the two edit fields
+ // which means EndDialog() - has to be evaluated in KeyInput
+ return false;
+ }
+ ModifyHdl(*m_xWordED);
+ return true;
+}
+
+IMPL_LINK(SvxEditDictionaryDialog, ModifyHdl, weld::Entry&, rEdt, void)
+{
+ OUString rEntry = rEdt.get_text();
+
+ sal_Int32 nWordLen = rEntry.getLength();
+ const OUString& rRepString = m_xReplaceED->get_text();
+
+ bool bEnableNewReplace = false;
+ bool bEnableDelete = false;
+ OUString aNewReplaceText = sNew;
+
+ if (&rEdt == m_xWordED.get())
+ {
+ if(nWordLen>0)
+ {
+ bool bFound = false;
+ bool bTmpSelEntry=false;
+ CDE_RESULT eCmpRes = CDE_DIFFERENT;
+
+ bool bDoubleColumn = m_pWordsLB == m_xDoubleColumnLB.get();
+
+ for (int i = 0, nCount = m_pWordsLB->n_children(); i < nCount; ++i)
+ {
+ OUString aTestStr(m_pWordsLB->get_text(i, 0));
+ eCmpRes = cmpDicEntry_Impl( rEntry, aTestStr );
+ if(CDE_DIFFERENT != eCmpRes)
+ {
+ if(!rRepString.isEmpty())
+ bFirstSelect = true;
+ bDoNothing=true;
+ m_pWordsLB->set_cursor(i);
+ bDoNothing=false;
+ if (bDoubleColumn)
+ m_xReplaceED->set_text(m_pWordsLB->get_text(i, 1));
+
+ if (CDE_SIMILAR == eCmpRes)
+ {
+ aNewReplaceText = sModify;
+ bEnableNewReplace = true;
+ }
+ bFound= true;
+ break;
+ }
+ else if(getNormDicEntry_Impl(aTestStr).indexOf(
+ getNormDicEntry_Impl( rEntry ) ) == 0
+ && !bTmpSelEntry)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(i);
+ bDoNothing=false;
+ bTmpSelEntry=true;
+
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ }
+
+ if(!bFound)
+ {
+ m_pWordsLB->unselect_all();
+ aNewReplaceText = sNew;
+ bEnableNewReplace = true;
+ }
+ bEnableDelete = CDE_DIFFERENT != eCmpRes;
+ }
+ else if (m_pWordsLB->n_children() > 0)
+ {
+ bDoNothing=true;
+ m_pWordsLB->scroll_to_row(0);
+ bDoNothing=false;
+ }
+ }
+ else if(&rEdt == m_xReplaceED.get())
+ {
+ OUString aReplaceText;
+ OUString aWordText;
+ int nFirstSel = m_pWordsLB->get_selected_index();
+ if (nFirstSel != -1) // a m_pWordsLB entry is selected
+ {
+ aWordText = m_pWordsLB->get_text(nFirstSel, 0);
+ aReplaceText = m_pWordsLB->get_text(nFirstSel, 1);
+
+ aNewReplaceText = sModify;
+ bEnableDelete = true;
+ }
+ bool bIsChange =
+ CDE_EQUAL != cmpDicEntry_Impl(m_xWordED->get_text(), aWordText)
+ || CDE_EQUAL != cmpDicEntry_Impl(m_xReplaceED->get_text(), aReplaceText);
+ if (!m_xWordED->get_text().isEmpty() && bIsChange)
+ bEnableNewReplace = true;
+ }
+
+ m_xNewReplacePB->set_label(aNewReplaceText);
+ m_xNewReplacePB->set_sensitive(bEnableNewReplace && !IsDicReadonly_Impl());
+ m_xDeletePB->set_sensitive(bEnableDelete && !IsDicReadonly_Impl());
+}
+
+IMPL_STATIC_LINK(SvxEditDictionaryDialog, InsertTextHdl, OUString&, rText, bool)
+{
+ rText = rText.replaceAll(" ", "");
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.cxx b/cui/source/options/optfltr.cxx
new file mode 100644
index 000000000..48840b17e
--- /dev/null
+++ b/cui/source/options/optfltr.cxx
@@ -0,0 +1,346 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/moduleoptions.hxx>
+#include <unotools/fltrcfg.hxx>
+#include <officecfg/Office/Common.hxx>
+#include "optfltr.hxx"
+#include <strings.hrc>
+#include <dialmgr.hxx>
+
+enum class MSFltrPg2_CheckBoxEntries {
+ Math,
+ Writer,
+ Calc,
+ Impress,
+ SmartArt,
+ Visio,
+ PDF,
+ InvalidCBEntry
+};
+
+
+OfaMSFilterTabPage::OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrpage.ui", "OptFltrPage", &rSet)
+ , m_xWBasicCodeCB(m_xBuilder->weld_check_button("wo_basic"))
+ , m_xWBasicWbctblCB(m_xBuilder->weld_check_button("wo_exec"))
+ , m_xWBasicStgCB(m_xBuilder->weld_check_button("wo_saveorig"))
+ , m_xEBasicCodeCB(m_xBuilder->weld_check_button("ex_basic"))
+ , m_xEBasicExectblCB(m_xBuilder->weld_check_button("ex_exec"))
+ , m_xEBasicStgCB(m_xBuilder->weld_check_button("ex_saveorig"))
+ , m_xPBasicCodeCB(m_xBuilder->weld_check_button("pp_basic"))
+ , m_xPBasicStgCB(m_xBuilder->weld_check_button("pp_saveorig"))
+{
+ m_xWBasicCodeCB->connect_toggled( LINK( this, OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl ) );
+ m_xEBasicCodeCB->connect_toggled( LINK( this, OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl ) );
+}
+
+OfaMSFilterTabPage::~OfaMSFilterTabPage()
+{
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadWordBasicCheckHdl_Impl, weld::Toggleable&, void)
+{
+ m_xWBasicWbctblCB->set_sensitive(m_xWBasicCodeCB->get_active());
+}
+
+IMPL_LINK_NOARG(OfaMSFilterTabPage, LoadExcelBasicCheckHdl_Impl, weld::Toggleable&, void)
+{
+ m_xEBasicExectblCB->set_sensitive(m_xEBasicCodeCB->get_active());
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaMSFilterTabPage::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ if( m_xWBasicCodeCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicCode( m_xWBasicCodeCB->get_active() );
+ if( m_xWBasicWbctblCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicExecutable( m_xWBasicWbctblCB->get_active() );
+ if( m_xWBasicStgCB->get_state_changed_from_saved() )
+ rOpt.SetLoadWordBasicStorage( m_xWBasicStgCB->get_active() );
+
+ if( m_xEBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicCode( m_xEBasicCodeCB->get_active() );
+ if( m_xEBasicExectblCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicExecutable( m_xEBasicExectblCB->get_active() );
+ if( m_xEBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadExcelBasicStorage( m_xEBasicStgCB->get_active() );
+
+ if( m_xPBasicCodeCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicCode( m_xPBasicCodeCB->get_active() );
+ if( m_xPBasicStgCB->get_state_changed_from_saved())
+ rOpt.SetLoadPPointBasicStorage( m_xPBasicStgCB->get_active() );
+
+ return false;
+}
+
+void OfaMSFilterTabPage::Reset( const SfxItemSet* )
+{
+ const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xWBasicCodeCB->set_active( rOpt.IsLoadWordBasicCode() );
+ m_xWBasicCodeCB->save_state();
+ m_xWBasicWbctblCB->set_active( rOpt.IsLoadWordBasicExecutable() );
+ m_xWBasicWbctblCB->save_state();
+ m_xWBasicStgCB->set_active( rOpt.IsLoadWordBasicStorage() );
+ m_xWBasicStgCB->save_state();
+ LoadWordBasicCheckHdl_Impl( *m_xWBasicCodeCB );
+
+ m_xEBasicCodeCB->set_active( rOpt.IsLoadExcelBasicCode() );
+ m_xEBasicCodeCB->save_state();
+ m_xEBasicExectblCB->set_active( rOpt.IsLoadExcelBasicExecutable() );
+ m_xEBasicExectblCB->save_state();
+ m_xEBasicStgCB->set_active( rOpt.IsLoadExcelBasicStorage() );
+ m_xEBasicStgCB->save_state();
+ LoadExcelBasicCheckHdl_Impl( *m_xEBasicCodeCB );
+
+ m_xPBasicCodeCB->set_active( rOpt.IsLoadPPointBasicCode() );
+ m_xPBasicCodeCB->save_state();
+ m_xPBasicStgCB->set_active( rOpt.IsLoadPPointBasicStorage() );
+ m_xPBasicStgCB->save_state();
+}
+
+OfaMSFilterTabPage2::OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optfltrembedpage.ui", "OptFilterPage", &rSet)
+ , sChgToFromMath(CuiResId(RID_CUISTR_CHG_MATH))
+ , sChgToFromWriter(CuiResId(RID_CUISTR_CHG_WRITER))
+ , sChgToFromCalc(CuiResId(RID_CUISTR_CHG_CALC))
+ , sChgToFromImpress(CuiResId(RID_CUISTR_CHG_IMPRESS))
+ , sChgToFromSmartArt(CuiResId(RID_CUISTR_CHG_SMARTART))
+ , sChgToFromVisio(CuiResId(RID_CUISTR_CHG_VISIO))
+ , sChgToFromPDF(CuiResId(RID_CUISTR_CHG_PDF))
+ , m_xCheckLB(m_xBuilder->weld_tree_view("checklbcontainer"))
+ , m_xHighlightingRB(m_xBuilder->weld_radio_button("highlighting"))
+ , m_xShadingRB(m_xBuilder->weld_radio_button("shading"))
+ , m_xMSOLockFileCB(m_xBuilder->weld_check_button("mso_lockfile"))
+{
+ std::vector<int> aWidths
+ {
+ m_xCheckLB->get_checkbox_column_width(),
+ m_xCheckLB->get_checkbox_column_width()
+ };
+ m_xCheckLB->set_column_fixed_widths(aWidths);
+}
+
+OfaMSFilterTabPage2::~OfaMSFilterTabPage2()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMSFilterTabPage2::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMSFilterTabPage2>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMSFilterTabPage2::FillItemSet( SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions::*FnIs)() const;
+ void (SvtFilterOptions::*FnSet)( bool bFlag );
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math,
+ &SvtFilterOptions::SetMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType,
+ &SvtFilterOptions::SetMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer,
+ &SvtFilterOptions::SetWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord,
+ &SvtFilterOptions::SetWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc,
+ &SvtFilterOptions::SetExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel,
+ &SvtFilterOptions::SetCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress,
+ &SvtFilterOptions::SetPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint,
+ &SvtFilterOptions::SetImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape,
+ &SvtFilterOptions::SetSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw,
+ &SvtFilterOptions::SetVisio2Draw },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rEntry : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type(rEntry.eType);
+ if (nEntry != -1)
+ {
+ bool bCheck = m_xCheckLB->get_toggle(nEntry, nCol);
+ if( bCheck != (rOpt.*rEntry.FnIs)() )
+ (rOpt.*rEntry.FnSet)( bCheck );
+ }
+ if (rEntry.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ int nPDFEntry = GetEntry4Type(MSFltrPg2_CheckBoxEntries::PDF);
+ bool bPDFCheck = m_xCheckLB->get_toggle(nPDFEntry, 0);
+ if (bPDFCheck != officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get())
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> pBatch(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::set(bPDFCheck, pBatch);
+ pBatch->commit();
+ }
+
+ if( m_xHighlightingRB->get_state_changed_from_saved() )
+ {
+ if (m_xHighlightingRB->get_active())
+ rOpt.SetCharBackground2Highlighting();
+ else
+ rOpt.SetCharBackground2Shading();
+ }
+
+ if (m_xMSOLockFileCB->get_state_changed_from_saved())
+ {
+ rOpt.EnableMSOLockFileCreation(m_xMSOLockFileCB->get_active());
+ }
+
+ return true;
+}
+
+void OfaMSFilterTabPage2::Reset( const SfxItemSet* )
+{
+ SvtFilterOptions& rOpt = SvtFilterOptions::Get();
+
+ m_xCheckLB->freeze();
+ m_xCheckLB->clear();
+
+ SvtModuleOptions aModuleOpt;
+
+ // int the same sequence as the enums of MSFltrPg2_CheckBoxEntries
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ InsertEntry( sChgToFromMath, MSFltrPg2_CheckBoxEntries::Math );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ InsertEntry( sChgToFromWriter, MSFltrPg2_CheckBoxEntries::Writer );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ InsertEntry( sChgToFromCalc, MSFltrPg2_CheckBoxEntries::Calc );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ InsertEntry( sChgToFromImpress, MSFltrPg2_CheckBoxEntries::Impress );
+ InsertEntry( sChgToFromSmartArt, MSFltrPg2_CheckBoxEntries::SmartArt, false );
+ if (aModuleOpt.IsModuleInstalled(SvtModuleOptions::EModule::DRAW))
+ {
+ InsertEntry(sChgToFromVisio, MSFltrPg2_CheckBoxEntries::Visio, false);
+ InsertEntry(sChgToFromPDF, MSFltrPg2_CheckBoxEntries::PDF, false);
+ }
+
+ static struct ChkCBoxEntries{
+ MSFltrPg2_CheckBoxEntries eType;
+ bool (SvtFilterOptions::*FnIs)() const;
+ } const aChkArr[] = {
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMathType2Math },
+ { MSFltrPg2_CheckBoxEntries::Math, &SvtFilterOptions::IsMath2MathType },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWinWord2Writer },
+ { MSFltrPg2_CheckBoxEntries::Writer, &SvtFilterOptions::IsWriter2WinWord },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsExcel2Calc },
+ { MSFltrPg2_CheckBoxEntries::Calc, &SvtFilterOptions::IsCalc2Excel },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsPowerPoint2Impress },
+ { MSFltrPg2_CheckBoxEntries::Impress, &SvtFilterOptions::IsImpress2PowerPoint },
+ { MSFltrPg2_CheckBoxEntries::SmartArt, &SvtFilterOptions::IsSmartArt2Shape },
+ { MSFltrPg2_CheckBoxEntries::Visio, &SvtFilterOptions::IsVisio2Draw },
+ { MSFltrPg2_CheckBoxEntries::PDF, nullptr },
+ };
+
+ bool bFirstCol = true;
+ for( const ChkCBoxEntries & rArr : aChkArr )
+ {
+ // we loop through the list, alternating reading the first/second column,
+ // each row appears twice in the list (except for smartart and later entries, which are
+ // import only)
+ sal_uInt16 nCol = bFirstCol ? 0 : 1;
+ bFirstCol = !bFirstCol;
+ int nEntry = GetEntry4Type( rArr.eType );
+ if (nEntry != -1)
+ {
+ bool bCheck = false;
+ if (rArr.eType != MSFltrPg2_CheckBoxEntries::PDF)
+ {
+ bCheck = (rOpt.*rArr.FnIs)();
+ }
+ else
+ {
+ bCheck = officecfg::Office::Common::Filter::Adobe::Import::PDFToDraw::get();
+ nCol = 0;
+ }
+ m_xCheckLB->set_toggle(nEntry, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE, nCol);
+ }
+ if (rArr.eType == MSFltrPg2_CheckBoxEntries::SmartArt)
+ {
+ bFirstCol = !bFirstCol;
+ }
+ }
+ m_xCheckLB->thaw();
+
+ if (rOpt.IsCharBackground2Highlighting())
+ m_xHighlightingRB->set_active(true);
+ else
+ m_xShadingRB->set_active(true);
+
+ m_xHighlightingRB->save_state();
+
+ m_xMSOLockFileCB->set_active(rOpt.IsMSOLockFileCreationIsEnabled());
+ m_xMSOLockFileCB->save_state();
+ m_xMSOLockFileCB->set_sensitive(!officecfg::Office::Common::Filter::Microsoft::Import::CreateMSOLockFiles::isReadOnly());
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType )
+{
+ InsertEntry( _rTxt, _nType, true );
+}
+
+void OfaMSFilterTabPage2::InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled )
+{
+ int nPos = m_xCheckLB->n_children();
+ m_xCheckLB->append();
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 0);
+ if (saveEnabled)
+ m_xCheckLB->set_toggle(nPos, TRISTATE_FALSE, 1);
+ m_xCheckLB->set_text(nPos, _rTxt, 2);
+ m_xCheckLB->set_id(nPos, OUString::number(static_cast<sal_Int32>(_nType)));
+}
+
+int OfaMSFilterTabPage2::GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const
+{
+ for (int i = 0, nEntryCount = m_xCheckLB->n_children(); i < nEntryCount; ++i)
+ {
+ if (_nType == static_cast<MSFltrPg2_CheckBoxEntries>(m_xCheckLB->get_id(i).toInt32()))
+ return i;
+ }
+ return -1;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optfltr.hxx b/cui/source/options/optfltr.hxx
new file mode 100644
index 000000000..f38a89366
--- /dev/null
+++ b/cui/source/options/optfltr.hxx
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+
+class OfaMSFilterTabPage : public SfxTabPage
+{
+ std::unique_ptr<weld::CheckButton> m_xWBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicWbctblCB;
+ std::unique_ptr<weld::CheckButton> m_xWBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicExectblCB;
+ std::unique_ptr<weld::CheckButton> m_xEBasicStgCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicCodeCB;
+ std::unique_ptr<weld::CheckButton> m_xPBasicStgCB;
+
+ DECL_LINK(LoadWordBasicCheckHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(LoadExcelBasicCheckHdl_Impl, weld::Toggleable&, void);
+public:
+ OfaMSFilterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~OfaMSFilterTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+enum class MSFltrPg2_CheckBoxEntries;
+
+class OfaMSFilterTabPage2 : public SfxTabPage
+{
+ OUString sChgToFromMath,
+ sChgToFromWriter,
+ sChgToFromCalc,
+ sChgToFromImpress,
+ sChgToFromSmartArt,
+ sChgToFromVisio,
+ sChgToFromPDF;
+
+ std::unique_ptr<weld::TreeView> m_xCheckLB;
+ std::unique_ptr<weld::RadioButton> m_xHighlightingRB;
+ std::unique_ptr<weld::RadioButton> m_xShadingRB;
+ std::unique_ptr<weld::CheckButton> m_xMSOLockFileCB;
+
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType );
+ void InsertEntry( const OUString& _rTxt, MSFltrPg2_CheckBoxEntries _nType,
+ bool saveEnabled );
+ int GetEntry4Type( MSFltrPg2_CheckBoxEntries _nType ) const;
+
+public:
+ OfaMSFilterTabPage2(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~OfaMSFilterTabPage2() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.cxx b/cui/source/options/optgdlg.cxx
new file mode 100644
index 000000000..b9402dfb2
--- /dev/null
+++ b/cui/source/options/optgdlg.cxx
@@ -0,0 +1,1806 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <config_features.h>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/currencytable.hxx>
+#include <svtools/langhelp.hxx>
+#include <unotools/lingucfg.hxx>
+#if defined(_WIN32)
+#include <unotools/resmgr.hxx>
+#endif
+#include <sfx2/bindings.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <unotools/compatibility.hxx>
+#include <svl/languageoptions.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svtools/miscopt.hxx>
+#include <unotools/syslocaleoptions.hxx>
+#include <sfx2/objsh.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
+#include <svtools/langtab.hxx>
+#include <editeng/unolingu.hxx>
+#include <editeng/langitem.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <editeng/editids.hrc>
+#include <svx/svxids.hrc>
+#include <svl/intitem.hxx>
+#include <GraphicsTestsDialog.hxx>
+#include <unotools/searchopt.hxx>
+#include <sal/log.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Setup.hxx>
+#include <comphelper/configuration.hxx>
+#include <tools/diagnose_ex.h>
+#if HAVE_FEATURE_BREAKPAD
+#include <desktop/crashreport.hxx>
+#endif
+
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/i18n/ScriptType.hpp>
+#include <com/sun/star/office/Quickstart.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <comphelper/dispatchcommand.hxx>
+
+#include <vcl/vclenum.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/window.hxx>
+#include <vcl/IconThemeInfo.hxx>
+#include <vcl/skia/SkiaHelper.hxx>
+#include "optgdlg.hxx"
+#include <svtools/apearcfg.hxx>
+#include <svtools/optionsdrawinglayer.hxx>
+#include <svtools/restartdialog.hxx>
+#include <svtools/imgdef.hxx>
+
+#if defined(_WIN32)
+#include <vcl/fileregistration.hxx>
+#endif
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::util;
+using namespace ::utl;
+
+// class OfaMiscTabPage --------------------------------------------------
+
+DeactivateRC OfaMiscTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+OUString impl_SystemFileOpenServiceName()
+{
+ #if defined(_WIN32)
+ return "com.sun.star.ui.dialogs.SystemFilePicker";
+ #elif defined MACOSX
+ return "com.sun.star.ui.dialogs.AquaFilePicker";
+ #else
+ return OUString();
+ #endif
+}
+
+bool lcl_HasSystemFilePicker()
+{
+ if( Application::hasNativeFileSelection() )
+ return true;
+
+ // Otherwise fall-back on querying services
+ bool bRet = false;
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ Reference< XContentEnumerationAccess > xEnumAccess( xFactory, UNO_QUERY );
+ Reference< XSet > xSet( xFactory, UNO_QUERY );
+
+ if ( ! xEnumAccess.is() || ! xSet.is() )
+ return bRet;
+
+ try
+ {
+ OUString aFileService = impl_SystemFileOpenServiceName();
+ Reference< XEnumeration > xEnum = xEnumAccess->createContentEnumeration( aFileService );
+ if ( xEnum.is() && xEnum->hasMoreElements() )
+ bRet = true;
+ }
+ catch (const IllegalArgumentException&)
+ {
+ }
+ catch (const ElementExistException&)
+ {
+ }
+ return bRet;
+}
+}
+
+OfaMiscTabPage::OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optgeneralpage.ui", "OptGeneralPage", &rSet)
+ , m_xExtHelpCB(m_xBuilder->weld_check_button("exthelp"))
+ , m_xPopUpNoHelpCB(m_xBuilder->weld_check_button("popupnohelp"))
+ , m_xShowTipOfTheDay(m_xBuilder->weld_check_button("cbShowTipOfTheDay"))
+ , m_xFileDlgFrame(m_xBuilder->weld_widget("filedlgframe"))
+ , m_xFileDlgROImage(m_xBuilder->weld_widget("lockimage"))
+ , m_xFileDlgCB(m_xBuilder->weld_check_button("filedlg"))
+ , m_xPrintDlgCB(m_xBuilder->weld_check_button("printdlg"))
+ , m_xDocStatusCB(m_xBuilder->weld_check_button("docstatus"))
+ , m_xYearFrame(m_xBuilder->weld_widget("yearframe"))
+ , m_xYearValueField(m_xBuilder->weld_spin_button("year"))
+ , m_xToYearFT(m_xBuilder->weld_label("toyear"))
+ , m_xCrashReport(m_xBuilder->weld_check_button("crashreport"))
+ , m_xQuickStarterFrame(m_xBuilder->weld_widget("quickstarter"))
+ , m_xHelpImproveLabel(m_xBuilder->weld_label("label7")) //"Help Improve"
+#if defined(UNX)
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("systray"))
+#else
+ , m_xQuickLaunchCB(m_xBuilder->weld_check_button("quicklaunch"))
+#endif
+#if defined(_WIN32)
+ , m_xFileAssocFrame(m_xBuilder->weld_widget("fileassoc"))
+ , m_xFileAssocBtn(m_xBuilder->weld_button("assocfiles"))
+ , m_xPerformFileExtCheck(m_xBuilder->weld_check_button("cbPerformFileExtCheck"))
+#endif
+{
+ if (!lcl_HasSystemFilePicker())
+ m_xFileDlgFrame->hide();
+ else if (officecfg::Office::Common::Misc::UseSystemFileDialog::isReadOnly())
+ {
+ m_xFileDlgROImage->show();
+ m_xFileDlgCB->set_sensitive(false);
+ }
+
+ m_xQuickLaunchCB->show();
+
+ //Only available in Win or if building the gtk systray
+#if !defined(_WIN32)
+ m_xQuickStarterFrame->hide();
+ //Hide frame label in case of no content
+ m_xHelpImproveLabel->hide();
+#endif
+
+#if defined(_WIN32)
+ m_xFileAssocFrame->show();
+ m_xFileAssocBtn->connect_clicked(LINK(this, OfaMiscTabPage, FileAssocClick));
+#endif
+
+ m_aStrDateInfo = m_xToYearFT->get_label();
+ m_xYearValueField->connect_value_changed( LINK( this, OfaMiscTabPage, TwoFigureHdl ) );
+
+ SetExchangeSupport();
+}
+
+OfaMiscTabPage::~OfaMiscTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaMiscTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaMiscTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool OfaMiscTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ if ( m_xPopUpNoHelpCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::set(m_xPopUpNoHelpCB->get_active(), batch);
+
+ if ( m_xExtHelpCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Help::ExtendedTip::set(m_xExtHelpCB->get_active(), batch);
+
+ if ( m_xShowTipOfTheDay->get_state_changed_from_saved() )
+ {
+ officecfg::Office::Common::Misc::ShowTipOfTheDay::set(m_xShowTipOfTheDay->get_active(), batch);
+ bModified = true;
+ }
+
+ if ( m_xFileDlgCB->get_state_changed_from_saved() )
+ {
+ officecfg::Office::Common::Misc::UseSystemFileDialog::set( !m_xFileDlgCB->get_active(), batch );
+ bModified = true;
+ }
+
+ if (m_xDocStatusCB->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Print::PrintingModifiesDocument::set(m_xDocStatusCB->get_active(), batch);
+ bModified = true;
+ }
+
+ const SfxUInt16Item* pUInt16Item = GetOldItem( *rSet, SID_ATTR_YEAR2000 );
+ sal_uInt16 nNum = static_cast<sal_uInt16>(m_xYearValueField->get_text().toInt32());
+ if ( pUInt16Item && pUInt16Item->GetValue() != nNum )
+ {
+ bModified = true;
+ rSet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, nNum ) );
+ }
+
+#if HAVE_FEATURE_BREAKPAD
+ if (m_xCrashReport->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::CrashReport::set(m_xCrashReport->get_active(), batch);
+ bModified = true;
+ }
+#endif
+
+#if defined(_WIN32)
+ if (m_xPerformFileExtCheck->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Misc::PerformFileExtCheck::set(
+ m_xPerformFileExtCheck->get_active(), batch);
+ bModified = true;
+ }
+#endif
+
+ batch->commit();
+
+ if( m_xQuickLaunchCB->get_state_changed_from_saved())
+ {
+ rSet->Put(SfxBoolItem(SID_ATTR_QUICKLAUNCHER, m_xQuickLaunchCB->get_active()));
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+void OfaMiscTabPage::Reset( const SfxItemSet* rSet )
+{
+ m_xExtHelpCB->set_active( officecfg::Office::Common::Help::Tip::get() &&
+ officecfg::Office::Common::Help::ExtendedTip::get() );
+ m_xExtHelpCB->save_state();
+ m_xPopUpNoHelpCB->set_active( officecfg::Office::Common::Help::BuiltInHelpNotInstalledPopUp::get() );
+ m_xPopUpNoHelpCB->save_state();
+ m_xShowTipOfTheDay->set_active( officecfg::Office::Common::Misc::ShowTipOfTheDay::get() );
+ m_xShowTipOfTheDay->save_state();
+ m_xFileDlgCB->set_active( !officecfg::Office::Common::Misc::UseSystemFileDialog::get() );
+ m_xFileDlgCB->save_state();
+
+ m_xDocStatusCB->set_active(officecfg::Office::Common::Print::PrintingModifiesDocument::get());
+ m_xDocStatusCB->save_state();
+
+ if ( const SfxUInt16Item* pYearItem = rSet->GetItemIfSet( SID_ATTR_YEAR2000, false ) )
+ {
+ m_xYearValueField->set_value( pYearItem->GetValue() );
+ TwoFigureHdl(*m_xYearValueField);
+ }
+ else
+ m_xYearFrame->set_sensitive(false);
+
+#if HAVE_FEATURE_BREAKPAD
+ m_xCrashReport->set_active(officecfg::Office::Common::Misc::CrashReport::get() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->set_sensitive(!officecfg::Office::Common::Misc::CrashReport::isReadOnly() && CrashReporter::IsDumpEnable());
+ m_xCrashReport->save_state();
+#else
+ m_xCrashReport->hide();
+#endif
+
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = rSet->GetItemState( SID_ATTR_QUICKLAUNCHER, false, &pItem );
+ if ( SfxItemState::SET == eState )
+ m_xQuickLaunchCB->set_active( static_cast<const SfxBoolItem*>(pItem)->GetValue() );
+ else if ( SfxItemState::DISABLED == eState )
+ {
+ // quickstart not installed
+ m_xQuickStarterFrame->hide();
+ }
+
+ m_xQuickLaunchCB->save_state();
+
+#if defined(_WIN32)
+ m_xPerformFileExtCheck->set_active(
+ officecfg::Office::Common::Misc::PerformFileExtCheck::get());
+ m_xPerformFileExtCheck->save_state();
+ m_xPerformFileExtCheck->set_sensitive(!officecfg::Office::Common::Misc::PerformFileExtCheck::isReadOnly());
+#endif
+}
+
+IMPL_LINK_NOARG( OfaMiscTabPage, TwoFigureHdl, weld::SpinButton&, void )
+{
+ OUString aOutput( m_aStrDateInfo );
+ OUString aStr( m_xYearValueField->get_text() );
+ sal_Int32 nNum = aStr.toInt32();
+ if ( aStr.getLength() != 4 || nNum < m_xYearValueField->get_min() || nNum > m_xYearValueField->get_max() )
+ aOutput += "????";
+ else
+ {
+ nNum += 99;
+ aOutput += OUString::number( nNum );
+ }
+ m_xToYearFT->set_label( aOutput );
+}
+
+#if defined(_WIN32)
+IMPL_STATIC_LINK_NOARG(OfaMiscTabPage, FileAssocClick, weld::Button&, void)
+{
+ vcl::fileregistration::LaunchRegistrationUI();
+}
+#endif
+
+class CanvasSettings
+{
+public:
+ CanvasSettings();
+
+ bool IsHardwareAccelerationEnabled() const;
+ bool IsHardwareAccelerationAvailable() const;
+ bool IsHardwareAccelerationRO() const;
+ void EnabledHardwareAcceleration( bool _bEnabled ) const;
+
+private:
+ typedef std::vector< std::pair<OUString,Sequence<OUString> > > ServiceVector;
+
+ Reference<XNameAccess> mxForceFlagNameAccess;
+ ServiceVector maAvailableImplementations;
+ mutable bool mbHWAccelAvailable;
+ mutable bool mbHWAccelChecked;
+};
+
+CanvasSettings::CanvasSettings() :
+ mbHWAccelAvailable(false),
+ mbHWAccelChecked(false)
+{
+ try
+ {
+ Reference<XMultiServiceFactory> xConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+
+ Sequence<Any> aArgs1(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas"))}
+ }));
+ mxForceFlagNameAccess.set(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgs1 ),
+ UNO_QUERY_THROW );
+
+ Sequence<Any> aArgs2(comphelper::InitAnyPropertySequence(
+ {
+ {"nodepath", Any(OUString("/org.openoffice.Office.Canvas/CanvasServiceList"))}
+ }));
+ Reference<XNameAccess> xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess",
+ aArgs2 ), UNO_QUERY_THROW );
+ Reference<XHierarchicalNameAccess> xHierarchicalNameAccess(
+ xNameAccess, UNO_QUERY_THROW);
+
+ Sequence<OUString> serviceNames = xNameAccess->getElementNames();
+ const OUString* pCurr = serviceNames.getConstArray();
+ const OUString* const pEnd = pCurr + serviceNames.getLength();
+ while( pCurr != pEnd )
+ {
+ Reference<XNameAccess> xEntryNameAccess(
+ xHierarchicalNameAccess->getByHierarchicalName(*pCurr),
+ UNO_QUERY );
+
+ if( xEntryNameAccess.is() )
+ {
+ Sequence<OUString> preferredImplementations;
+ if( xEntryNameAccess->getByName("PreferredImplementations") >>= preferredImplementations )
+ maAvailableImplementations.emplace_back(*pCurr,preferredImplementations );
+ }
+
+ ++pCurr;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+}
+
+bool CanvasSettings::IsHardwareAccelerationAvailable() const
+{
+ if( !mbHWAccelChecked )
+ {
+ mbHWAccelChecked = true;
+
+ Reference< XMultiServiceFactory > xFactory = comphelper::getProcessServiceFactory();
+
+ // check whether any of the service lists has an
+ // implementation that presents the "HardwareAcceleration" property
+ for (auto const& availableImpl : maAvailableImplementations)
+ {
+ const OUString* pCurrImpl = availableImpl.second.getConstArray();
+ const OUString* const pEndImpl = pCurrImpl + availableImpl.second.getLength();
+
+ while( pCurrImpl != pEndImpl )
+ {
+ try
+ {
+ Reference<XPropertySet> xPropSet( xFactory->createInstance(
+ pCurrImpl->trim() ),
+ UNO_QUERY_THROW );
+ bool bHasAccel(false);
+ if( xPropSet->getPropertyValue("HardwareAcceleration") >>= bHasAccel )
+ if( bHasAccel )
+ {
+ mbHWAccelAvailable = true;
+ return mbHWAccelAvailable;
+ }
+ }
+ catch (const Exception&)
+ {
+ }
+
+ ++pCurrImpl;
+ }
+ }
+ }
+
+ return mbHWAccelAvailable;
+}
+
+bool CanvasSettings::IsHardwareAccelerationEnabled() const
+{
+ bool bForceLastEntry(false);
+ if( !mxForceFlagNameAccess.is() )
+ return true;
+
+ if( !(mxForceFlagNameAccess->getByName("ForceSafeServiceImpl") >>= bForceLastEntry) )
+ return true;
+
+ return !bForceLastEntry;
+}
+
+bool CanvasSettings::IsHardwareAccelerationRO() const
+{
+ Reference< XPropertySet > xSet(mxForceFlagNameAccess, UNO_QUERY);
+ if (!xSet.is())
+ return true;
+
+ Reference< XPropertySetInfo > xInfo = xSet->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName("ForceSafeServiceImpl");
+ return ((aProp.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY);
+}
+
+void CanvasSettings::EnabledHardwareAcceleration( bool _bEnabled ) const
+{
+ Reference< XNameReplace > xNameReplace(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xNameReplace.is() )
+ return;
+
+ xNameReplace->replaceByName( "ForceSafeServiceImpl", Any(!_bEnabled) );
+
+ Reference< XChangesBatch > xChangesBatch(
+ mxForceFlagNameAccess, UNO_QUERY );
+
+ if( !xChangesBatch.is() )
+ return;
+
+ xChangesBatch->commitChanges();
+}
+
+// class OfaViewTabPage --------------------------------------------------
+
+static bool DisplayNameCompareLessThan(const vcl::IconThemeInfo& rInfo1, const vcl::IconThemeInfo& rInfo2)
+{
+ return rInfo1.GetDisplayName().compareTo(rInfo2.GetDisplayName()) < 0;
+}
+
+OfaViewTabPage::OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optviewpage.ui", "OptViewPage", &rSet)
+ , nSizeLB_InitialSelection(0)
+ , nSidebarSizeLB_InitialSelection(0)
+ , nNotebookbarSizeLB_InitialSelection(0)
+ , nStyleLB_InitialSelection(0)
+ , pAppearanceCfg(new SvtTabAppearanceCfg)
+ , pCanvasSettings(new CanvasSettings)
+ , m_xIconSizeLB(m_xBuilder->weld_combo_box("iconsize"))
+ , m_xSidebarIconSizeLB(m_xBuilder->weld_combo_box("sidebariconsize"))
+ , m_xNotebookbarIconSizeLB(m_xBuilder->weld_combo_box("notebookbariconsize"))
+ , m_xIconStyleLB(m_xBuilder->weld_combo_box("iconstyle"))
+ , m_xFontAntiAliasing(m_xBuilder->weld_check_button("aafont"))
+ , m_xAAPointLimitLabel(m_xBuilder->weld_label("aafrom"))
+ , m_xAAPointLimit(m_xBuilder->weld_metric_spin_button("aanf", FieldUnit::PIXEL))
+ , m_xMenuIconBox(m_xBuilder->weld_widget("menuiconsbox"))
+ , m_xMenuIconsLB(m_xBuilder->weld_combo_box("menuicons"))
+ , m_xContextMenuShortcutsLB(m_xBuilder->weld_combo_box("contextmenushortcuts"))
+ , m_xFontShowCB(m_xBuilder->weld_check_button("showfontpreview"))
+ , m_xUseHardwareAccell(m_xBuilder->weld_check_button("useaccel"))
+ , m_xUseAntiAliase(m_xBuilder->weld_check_button("useaa"))
+ , m_xUseSkia(m_xBuilder->weld_check_button("useskia"))
+ , m_xForceSkiaRaster(m_xBuilder->weld_check_button("forceskiaraster"))
+ , m_xSkiaStatusEnabled(m_xBuilder->weld_label("skiaenabled"))
+ , m_xSkiaStatusDisabled(m_xBuilder->weld_label("skiadisabled"))
+ , m_xMousePosLB(m_xBuilder->weld_combo_box("mousepos"))
+ , m_xMouseMiddleLB(m_xBuilder->weld_combo_box("mousemiddle"))
+ , m_xMoreIcons(m_xBuilder->weld_button("btnMoreIcons"))
+ , m_xRunGPTests(m_xBuilder->weld_button("btn_rungptest"))
+{
+ if (Application::GetToolkitName().startsWith("gtk"))
+ m_xMenuIconBox->hide();
+
+ m_xFontAntiAliasing->connect_toggled( LINK( this, OfaViewTabPage, OnAntialiasingToggled ) );
+
+ m_xUseSkia->connect_toggled(LINK(this, OfaViewTabPage, OnUseSkiaToggled));
+
+ // Set known icon themes
+ OUString sAutoStr( m_xIconStyleLB->get_text( 0 ) );
+ m_xIconStyleLB->clear();
+ StyleSettings aStyleSettings = Application::GetSettings().GetStyleSettings();
+ mInstalledIconThemes = aStyleSettings.GetInstalledIconThemes();
+ std::sort(mInstalledIconThemes.begin(), mInstalledIconThemes.end(), DisplayNameCompareLessThan);
+
+ // Start with the automatically chosen icon theme
+ OUString autoThemeId = aStyleSettings.GetAutomaticallyChosenIconTheme();
+ const vcl::IconThemeInfo& autoIconTheme = vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, autoThemeId);
+
+ OUString entryForAuto = sAutoStr + " (" +
+ autoIconTheme.GetDisplayName() +
+ ")";
+ m_xIconStyleLB->append("auto", entryForAuto); // index 0 means choose style automatically
+
+ // separate auto and other icon themes
+ m_xIconStyleLB->append_separator("");
+
+ for (auto const& installIconTheme : mInstalledIconThemes)
+ m_xIconStyleLB->append(installIconTheme.GetThemeId(), installIconTheme.GetDisplayName());
+
+ m_xIconStyleLB->set_active(0);
+
+ m_xMoreIcons->set_from_icon_name("cmd/sc_additionsdialog.png");
+ m_xMoreIcons->connect_clicked(LINK(this, OfaViewTabPage, OnMoreIconsClick));
+ m_xRunGPTests->connect_clicked( LINK( this, OfaViewTabPage, OnRunGPTestClick));
+}
+
+OfaViewTabPage::~OfaViewTabPage()
+{
+}
+
+IMPL_LINK_NOARG(OfaViewTabPage, OnRunGPTestClick, weld::Button&, void)
+{
+ GraphicsTestsDialog m_xGraphicsTestDialog(m_xContainer.get());
+ m_xGraphicsTestDialog.run();
+}
+
+IMPL_STATIC_LINK_NOARG(OfaViewTabPage, OnMoreIconsClick, weld::Button&, void)
+{
+ css::uno::Sequence<css::beans::PropertyValue> aArgs{ comphelper::makePropertyValue(
+ "AdditionsTag", OUString("Icons")) };
+ comphelper::dispatchCommand(".uno:AdditionsDialog", aArgs);
+}
+
+IMPL_LINK_NOARG( OfaViewTabPage, OnAntialiasingToggled, weld::Toggleable&, void )
+{
+ bool bAAEnabled = m_xFontAntiAliasing->get_active();
+
+ m_xAAPointLimitLabel->set_sensitive(bAAEnabled);
+ m_xAAPointLimit->set_sensitive(bAAEnabled);
+}
+
+IMPL_LINK_NOARG(OfaViewTabPage, OnUseSkiaToggled, weld::Toggleable&, void)
+{
+ UpdateSkiaStatus();
+}
+
+void OfaViewTabPage::HideSkiaWidgets()
+{
+ m_xUseSkia->hide();
+ m_xForceSkiaRaster->hide();
+ m_xSkiaStatusEnabled->hide();
+ m_xSkiaStatusDisabled->hide();
+}
+
+void OfaViewTabPage::UpdateSkiaStatus()
+{
+#if HAVE_FEATURE_SKIA
+ bool skiaHidden = true;
+
+ // For now Skia is used mainly on Windows, enable the controls there.
+ if (Application::GetToolkitName() == "win")
+ skiaHidden = false;
+ // It can also be used on Linux, but only with the rarely used 'gen' backend.
+ if (Application::GetToolkitName() == "x11")
+ skiaHidden = false;
+ // OSX backend has Skia support too.
+ if (Application::GetToolkitName() == "osx")
+ skiaHidden = false;
+
+ if (skiaHidden)
+ {
+ HideSkiaWidgets();
+ return;
+ }
+
+ // Easier than a custom translation string.
+ bool bEnabled = SkiaHelper::isVCLSkiaEnabled();
+ m_xSkiaStatusEnabled->set_visible(bEnabled);
+ m_xSkiaStatusDisabled->set_visible(!bEnabled);
+
+ // FIXME: should really add code to show a 'lock' icon here.
+ m_xUseSkia->set_sensitive(!officecfg::Office::Common::VCL::UseSkia::isReadOnly());
+ m_xForceSkiaRaster->set_sensitive(m_xUseSkia->get_active() && !officecfg::Office::Common::VCL::ForceSkiaRaster::isReadOnly());
+
+ // Technically the 'use hardware acceleration' option could be used to mean !forceSkiaRaster, but the implementation
+ // of the option is so tied to the implementation of the canvas module that it's simpler to ignore it.
+ UpdateHardwareAccelStatus();
+#else
+ HideSkiaWidgets();
+#endif
+}
+
+std::unique_ptr<SfxTabPage> OfaViewTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaViewTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaViewTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ bool bMenuOptModified = false;
+ bool bRepaintWindows(false);
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges(comphelper::ConfigurationChanges::create());
+
+ SvtMiscOptions aMiscOptions;
+ const sal_Int32 nSizeLB_NewSelection = m_xIconSizeLB->get_active();
+ if( nSizeLB_InitialSelection != nSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ sal_Int16 eSet = SFX_SYMBOLS_SIZE_AUTO;
+ switch( nSizeLB_NewSelection )
+ {
+ case 0: eSet = SFX_SYMBOLS_SIZE_AUTO; break;
+ case 1: eSet = SFX_SYMBOLS_SIZE_SMALL; break;
+ case 2: eSet = SFX_SYMBOLS_SIZE_LARGE; break;
+ case 3: eSet = SFX_SYMBOLS_SIZE_32; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xIconSizeLB should not be possible!" );
+ }
+ aMiscOptions.SetSymbolsSize( eSet );
+ }
+
+ const sal_Int32 nSidebarSizeLB_NewSelection = m_xSidebarIconSizeLB->get_active();
+ if( nSidebarSizeLB_InitialSelection != nSidebarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nSidebarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xSidebarIconSizeLB should not be possible!" );
+ }
+ officecfg::Office::Common::Misc::SidebarIconSize::set(static_cast<sal_Int16>(eSet), xChanges);
+ }
+
+ const sal_Int32 nNotebookbarSizeLB_NewSelection = m_xNotebookbarIconSizeLB->get_active();
+ if( nNotebookbarSizeLB_InitialSelection != nNotebookbarSizeLB_NewSelection )
+ {
+ // from now on it's modified, even if via auto setting the same size was set as now selected in the LB
+ ToolBoxButtonSize eSet = ToolBoxButtonSize::DontCare;
+ switch( nNotebookbarSizeLB_NewSelection )
+ {
+ case 0: eSet = ToolBoxButtonSize::DontCare; break;
+ case 1: eSet = ToolBoxButtonSize::Small; break;
+ case 2: eSet = ToolBoxButtonSize::Large; break;
+ default:
+ OSL_FAIL( "OfaViewTabPage::FillItemSet(): This state of m_xNotebookbarIconSizeLB should not be possible!" );
+ }
+ officecfg::Office::Common::Misc::NotebookbarIconSize::set(static_cast<sal_Int16>(eSet), xChanges);
+ }
+
+ const sal_Int32 nStyleLB_NewSelection = m_xIconStyleLB->get_active();
+ if( nStyleLB_InitialSelection != nStyleLB_NewSelection )
+ {
+ aMiscOptions.SetIconTheme(m_xIconStyleLB->get_active_id());
+ nStyleLB_InitialSelection = nStyleLB_NewSelection;
+ }
+
+ bool bAppearanceChanged = false;
+
+ // Mouse Snap Mode
+ SnapType eOldSnap = pAppearanceCfg->GetSnapMode();
+ SnapType eNewSnap = static_cast<SnapType>(m_xMousePosLB->get_active());
+ if(eNewSnap > SnapType::NONE)
+ eNewSnap = SnapType::NONE;
+
+ if ( eNewSnap != eOldSnap )
+ {
+ pAppearanceCfg->SetSnapMode(eNewSnap );
+ bAppearanceChanged = true;
+ }
+
+ // Middle Mouse Button
+ MouseMiddleButtonAction eOldMiddleMouse = pAppearanceCfg->GetMiddleMouseButton();
+ short eNewMiddleMouse = m_xMouseMiddleLB->get_active();
+ if(eNewMiddleMouse > 2)
+ eNewMiddleMouse = 2;
+
+ if ( eNewMiddleMouse != static_cast<short>(eOldMiddleMouse) )
+ {
+ pAppearanceCfg->SetMiddleMouseButton( static_cast<MouseMiddleButtonAction>(eNewMiddleMouse) );
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontAntiAliasing->get_state_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntiAliasing(m_xFontAntiAliasing->get_active());
+ bAppearanceChanged = true;
+ }
+
+ if (m_xAAPointLimit->get_value_changed_from_saved())
+ {
+ pAppearanceCfg->SetFontAntialiasingMinPixelHeight(m_xAAPointLimit->get_value(FieldUnit::PIXEL));
+ bAppearanceChanged = true;
+ }
+
+ if (m_xFontShowCB->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::set(m_xFontShowCB->get_active(), xChanges);
+ bModified = true;
+ }
+
+ if (m_xMenuIconsLB->get_value_changed_from_saved())
+ {
+ officecfg::Office::Common::View::Menu::IsSystemIconsInMenus::set(m_xMenuIconsLB->get_active() == 0, xChanges);
+ officecfg::Office::Common::View::Menu::ShowIconsInMenues::set(m_xMenuIconsLB->get_active() == 2, xChanges);
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ if (m_xContextMenuShortcutsLB->get_value_changed_from_saved())
+ {
+ officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::set(
+ m_xContextMenuShortcutsLB->get_active() == 0 ?
+ TRISTATE_INDET :
+ static_cast<TriState>(m_xContextMenuShortcutsLB->get_active() - 1),
+ xChanges);
+ bModified = true;
+ bMenuOptModified = true;
+ bAppearanceChanged = true;
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseHardwareAccell->get_sensitive())
+ {
+ if(m_xUseHardwareAccell->get_state_changed_from_saved())
+ {
+ pCanvasSettings->EnabledHardwareAcceleration(m_xUseHardwareAccell->get_active());
+ bModified = true;
+ }
+ }
+
+ // #i95644# if disabled, do not use value, see in ::Reset()
+ if (m_xUseAntiAliase->get_sensitive())
+ {
+ if (m_xUseAntiAliase->get_active() != SvtOptionsDrawinglayer::IsAntiAliasing())
+ {
+ SvtOptionsDrawinglayer::SetAntiAliasing(m_xUseAntiAliase->get_active(), /*bTemporary*/false);
+ bModified = true;
+ bRepaintWindows = true;
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ officecfg::Office::Common::VCL::UseSkia::set(m_xUseSkia->get_active(), xChanges);
+ officecfg::Office::Common::VCL::ForceSkiaRaster::set(m_xForceSkiaRaster->get_active(), xChanges);
+ bModified = true;
+ }
+
+ xChanges->commit();
+
+ if( bMenuOptModified )
+ {
+ // Set changed settings to the application instance
+ AllSettings aAllSettings = Application::GetSettings();
+ StyleSettings aStyleSettings = aAllSettings.GetStyleSettings();
+ aAllSettings.SetStyleSettings(aStyleSettings);
+ Application::MergeSystemSettings( aAllSettings );
+ Application::SetSettings(aAllSettings);
+ }
+
+ if ( bAppearanceChanged )
+ {
+ pAppearanceCfg->Commit();
+ pAppearanceCfg->SetApplicationDefaults ( GetpApp() );
+ }
+
+ if(bRepaintWindows)
+ {
+ vcl::Window* pAppWindow = Application::GetFirstTopLevelWindow();
+
+ while(pAppWindow)
+ {
+ pAppWindow->Invalidate();
+ pAppWindow = Application::GetNextTopLevelWindow(pAppWindow);
+ }
+ }
+
+ if (m_xUseSkia->get_state_changed_from_saved() ||
+ m_xForceSkiaRaster->get_state_changed_from_saved())
+ {
+ SolarMutexGuard aGuard;
+ if( svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_SKIA))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void OfaViewTabPage::Reset( const SfxItemSet* )
+{
+ SvtMiscOptions aMiscOptions;
+
+ if (aMiscOptions.GetSymbolsSize() != SFX_SYMBOLS_SIZE_AUTO)
+ {
+ nSizeLB_InitialSelection = 1;
+
+ if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_LARGE)
+ nSizeLB_InitialSelection = 2;
+ else if (aMiscOptions.GetSymbolsSize() == SFX_SYMBOLS_SIZE_32)
+ nSizeLB_InitialSelection = 3;
+ }
+ m_xIconSizeLB->set_active( nSizeLB_InitialSelection );
+ m_xIconSizeLB->save_value();
+
+ ToolBoxButtonSize eSidebarIconSize = static_cast<ToolBoxButtonSize>(officecfg::Office::Common::Misc::SidebarIconSize::get());
+ if( eSidebarIconSize == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( eSidebarIconSize == ToolBoxButtonSize::Small )
+ nSidebarSizeLB_InitialSelection = 1;
+ else if( eSidebarIconSize == ToolBoxButtonSize::Large )
+ nSidebarSizeLB_InitialSelection = 2;
+ m_xSidebarIconSizeLB->set_active( nSidebarSizeLB_InitialSelection );
+ m_xSidebarIconSizeLB->save_value();
+ ToolBoxButtonSize eNotebookbarIconSize = static_cast<ToolBoxButtonSize>(officecfg::Office::Common::Misc::NotebookbarIconSize::get());
+ if( eNotebookbarIconSize == ToolBoxButtonSize::DontCare )
+ ; // do nothing
+ else if( eNotebookbarIconSize == ToolBoxButtonSize::Small )
+ nNotebookbarSizeLB_InitialSelection = 1;
+ else if( eNotebookbarIconSize == ToolBoxButtonSize::Large )
+ nNotebookbarSizeLB_InitialSelection = 2;
+ m_xNotebookbarIconSizeLB->set_active(nNotebookbarSizeLB_InitialSelection);
+ m_xNotebookbarIconSizeLB->save_value();
+
+ if (aMiscOptions.IconThemeWasSetAutomatically()) {
+ nStyleLB_InitialSelection = 0;
+ }
+ else {
+ const OUString& selected = aMiscOptions.GetIconTheme();
+ const vcl::IconThemeInfo& selectedInfo =
+ vcl::IconThemeInfo::FindIconThemeById(mInstalledIconThemes, selected);
+ nStyleLB_InitialSelection = m_xIconStyleLB->find_text(selectedInfo.GetDisplayName());
+ }
+
+ m_xIconStyleLB->set_active(nStyleLB_InitialSelection);
+ m_xIconStyleLB->save_value();
+
+ // Mouse Snap
+ m_xMousePosLB->set_active(static_cast<sal_Int32>(pAppearanceCfg->GetSnapMode()));
+ m_xMousePosLB->save_value();
+
+ // Mouse Snap
+ m_xMouseMiddleLB->set_active(static_cast<short>(pAppearanceCfg->GetMiddleMouseButton()));
+ m_xMouseMiddleLB->save_value();
+
+ m_xFontAntiAliasing->set_active( pAppearanceCfg->IsFontAntiAliasing() );
+ m_xAAPointLimit->set_value(pAppearanceCfg->GetFontAntialiasingMinPixelHeight(), FieldUnit::PIXEL);
+
+ // WorkingSet
+ m_xFontShowCB->set_active(officecfg::Office::Common::Font::View::ShowFontBoxWYSIWYG::get());
+ bool bSystemMenuIcons = officecfg::Office::Common::View::Menu::IsSystemIconsInMenus::get();
+ bool bMenuIcons = officecfg::Office::Common::View::Menu::ShowIconsInMenues::get();
+ m_xMenuIconsLB->set_active(bSystemMenuIcons ? 0 : (bMenuIcons ? 2 : 1));
+ m_xMenuIconsLB->save_value();
+
+ TriState eContextMenuShortcuts = static_cast<TriState>(officecfg::Office::Common::View::Menu::ShortcutsInContextMenus::get());
+ bool bContextMenuShortcutsNonDefault = eContextMenuShortcuts == TRISTATE_FALSE || eContextMenuShortcuts == TRISTATE_TRUE;
+ m_xContextMenuShortcutsLB->set_active(bContextMenuShortcutsNonDefault ? eContextMenuShortcuts + 1 : 0);
+ m_xContextMenuShortcutsLB->save_value();
+
+ UpdateHardwareAccelStatus();
+ m_xUseHardwareAccell->save_state();
+
+ { // #i95644# AntiAliasing
+ if(SvtOptionsDrawinglayer::IsAAPossibleOnThisSystem())
+ {
+ m_xUseAntiAliase->set_active(SvtOptionsDrawinglayer::IsAntiAliasing());
+ }
+ else
+ {
+ m_xUseAntiAliase->set_active(false);
+ m_xUseAntiAliase->set_sensitive(false);
+ }
+
+ m_xUseAntiAliase->save_state();
+ }
+
+ m_xUseSkia->set_active(officecfg::Office::Common::VCL::UseSkia::get());
+ m_xForceSkiaRaster->set_active(officecfg::Office::Common::VCL::ForceSkiaRaster::get());
+ m_xUseSkia->save_state();
+ m_xForceSkiaRaster->save_state();
+
+ m_xFontAntiAliasing->save_state();
+ m_xAAPointLimit->save_value();
+ m_xFontShowCB->save_state();
+
+ OnAntialiasingToggled(*m_xFontAntiAliasing);
+ UpdateSkiaStatus();
+}
+
+void OfaViewTabPage::UpdateHardwareAccelStatus()
+{
+ // #i95644# HW accel (unified to disable mechanism)
+ if(pCanvasSettings->IsHardwareAccelerationAvailable())
+ {
+ m_xUseHardwareAccell->set_active(pCanvasSettings->IsHardwareAccelerationEnabled());
+ m_xUseHardwareAccell->set_sensitive(!pCanvasSettings->IsHardwareAccelerationRO());
+ }
+ else
+ {
+ m_xUseHardwareAccell->set_active(false);
+ m_xUseHardwareAccell->set_sensitive(false);
+ }
+#if HAVE_FEATURE_SKIA
+ m_xUseHardwareAccell->set_sensitive(!m_xUseSkia->get_active());
+#endif
+}
+
+struct LanguageConfig_Impl
+{
+ SvtCTLOptions aCTLLanguageOptions;
+ SvtSysLocaleOptions aSysLocaleOptions;
+ SvtLinguConfig aLinguConfig;
+};
+
+static bool bLanguageCurrentDoc_Impl = false;
+
+// some things we'll need...
+constexpr OUStringLiteral sAccessSrvc = u"com.sun.star.configuration.ConfigurationAccess";
+constexpr OUStringLiteral sAccessUpdSrvc = u"com.sun.star.configuration.ConfigurationUpdateAccess";
+constexpr OUStringLiteral sInstalledLocalesPath = u"org.openoffice.Setup/Office/InstalledLocales";
+constexpr OUStringLiteral sUserLocalePath = u"org.openoffice.Office.Linguistic/General";
+constexpr OUStringLiteral sUserLocaleKey = u"UILocale";
+static Sequence< OUString > seqInstalledLanguages;
+
+static OUString lcl_getDatePatternsConfigString( const LocaleDataWrapper& rLocaleWrapper )
+{
+ Sequence< OUString > aDateAcceptancePatterns = rLocaleWrapper.getDateAcceptancePatterns();
+ sal_Int32 nPatterns = aDateAcceptancePatterns.getLength();
+ OUStringBuffer aBuf( nPatterns * 6 ); // 6 := length of Y-M-D;
+ SAL_WARN_IF( !nPatterns, "cui.options", "No date acceptance pattern");
+ if (nPatterns)
+ {
+ const OUString* pPatterns = aDateAcceptancePatterns.getConstArray();
+ aBuf.append( pPatterns[0]);
+ for (sal_Int32 i=1; i < nPatterns; ++i)
+ aBuf.append(';').append( pPatterns[i]);
+ }
+ return aBuf.makeStringAndClear();
+}
+
+namespace
+{
+ //what ui language will be selected by default if the user override of General::UILocale is unset ?
+ LanguageTag GetInstalledLocaleForSystemUILanguage()
+ {
+ css::uno::Sequence<OUString> inst(officecfg::Setup::Office::InstalledLocales::get()->getElementNames());
+ return LanguageTag(getInstalledLocaleForSystemUILanguage(inst, false)).makeFallback();
+ }
+}
+
+OfaLanguagesTabPage::OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlanguagespage.ui", "OptLanguagesPage", &rSet)
+ , pLangConfig(new LanguageConfig_Impl)
+ , m_bDatePatternsValid(false)
+ , m_xUserInterfaceLB(m_xBuilder->weld_combo_box("userinterface"))
+ , m_xLocaleSettingFT(m_xBuilder->weld_label("localesettingFT"))
+ , m_xLocaleSettingLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("localesetting")))
+ , m_xDecimalSeparatorCB(m_xBuilder->weld_check_button("decimalseparator"))
+ , m_xCurrencyFT(m_xBuilder->weld_label("defaultcurrency"))
+ , m_xCurrencyLB(m_xBuilder->weld_combo_box("currencylb"))
+ , m_xDatePatternsFT(m_xBuilder->weld_label("dataaccpatterns"))
+ , m_xDatePatternsED(m_xBuilder->weld_entry("datepatterns"))
+ , m_xWesternLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("westernlanguage")))
+ , m_xWesternLanguageFT(m_xBuilder->weld_label("western"))
+ , m_xAsianLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("asianlanguage")))
+ , m_xComplexLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("complexlanguage")))
+ , m_xCurrentDocCB(m_xBuilder->weld_check_button("currentdoc"))
+ , m_xAsianSupportCB(m_xBuilder->weld_check_button("asiansupport"))
+ , m_xCTLSupportCB(m_xBuilder->weld_check_button("ctlsupport"))
+ , m_xIgnoreLanguageChangeCB(m_xBuilder->weld_check_button("ignorelanguagechange"))
+{
+ // tdf#125483 save original default label
+ m_sDecimalSeparatorLabel = m_xDecimalSeparatorCB->get_label();
+
+ // initialize user interface language selection
+ m_sSystemDefaultString = SvtLanguageTable::GetLanguageString( LANGUAGE_SYSTEM );
+
+ OUString aUILang = m_sSystemDefaultString +
+ " - " +
+ SvtLanguageTable::GetLanguageString(GetInstalledLocaleForSystemUILanguage().getLanguageType());
+
+ m_xUserInterfaceLB->append("0", aUILang);
+ m_xUserInterfaceLB->append_separator("");
+ try
+ {
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ // find out which locales are currently installed and add them to the listbox
+ Sequence< Any > theArgs{ Any(NamedValue("nodepath", Any(OUString(sInstalledLocalesPath)))) };
+ Reference< XNameAccess > theNameAccess(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs ), UNO_QUERY_THROW );
+ seqInstalledLanguages = theNameAccess->getElementNames();
+ LanguageType aLang = LANGUAGE_DONTKNOW;
+ std::vector< std::pair<sal_Int32, OUString> > aUILanguages;
+ for (sal_Int32 i=0; i<seqInstalledLanguages.getLength(); i++)
+ {
+ aLang = LanguageTag::convertToLanguageTypeWithFallback(seqInstalledLanguages[i]);
+ if (aLang != LANGUAGE_DONTKNOW)
+ {
+ OUString aLangStr( SvtLanguageTable::GetLanguageString( aLang ) );
+ aUILanguages.emplace_back(i+1, aLangStr);
+ }
+ }
+
+ std::sort(aUILanguages.begin(), aUILanguages.end(), [](const auto& l1, const auto& l2) {
+ static const auto aSorter = comphelper::string::NaturalStringSorter(
+ comphelper::getProcessComponentContext(),
+ Application::GetSettings().GetLanguageTag().getLocale());
+ return aSorter.compare(l1.second, l2.second) < 0;
+ });
+
+ // tdf#114694: append the sorted list after the default entry and separator.
+ for (const auto & [ nGroupID, sGroupName ] : aUILanguages)
+ {
+ m_xUserInterfaceLB->append(OUString::number(nGroupID), sGroupName);
+ }
+
+ m_xUserInterfaceLB->set_active(0);
+
+ // find out whether the user has a specific locale specified
+ Sequence< Any > theArgs2{ Any(NamedValue("nodepath", Any(OUString(sUserLocalePath)))) };
+ theNameAccess.set(
+ theConfigProvider->createInstanceWithArguments(sAccessSrvc, theArgs2 ), UNO_QUERY_THROW );
+ if (theNameAccess->hasByName(sUserLocaleKey))
+ theNameAccess->getByName(sUserLocaleKey) >>= m_sUserLocaleValue;
+ // select the user specified locale in the listbox
+ if (!m_sUserLocaleValue.isEmpty())
+ {
+ for (sal_Int32 i = 0, nEntryCount = m_xUserInterfaceLB->get_count(); i < nEntryCount; ++i)
+ {
+ sal_Int32 d = m_xUserInterfaceLB->get_id(i).toInt32();
+ if ( d > 0 && seqInstalledLanguages.getLength() > d-1 && seqInstalledLanguages[d-1] == m_sUserLocaleValue)
+ m_xUserInterfaceLB->set_active(i);
+ }
+ }
+
+ }
+ catch (const Exception &)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring" );
+ }
+
+ m_xWesternLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::WESTERN | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::LATIN);
+
+ m_xAsianLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CJK | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::ASIAN);
+
+ m_xComplexLanguageLB->SetLanguageList(
+ SvxLanguageListFlags::CTL | SvxLanguageListFlags::ONLY_KNOWN, true, false, true, true,
+ LANGUAGE_SYSTEM, css::i18n::ScriptType::COMPLEX);
+
+ m_xLocaleSettingLB->SetLanguageList(
+ SvxLanguageListFlags::ALL | SvxLanguageListFlags::ONLY_KNOWN, false, false, false, true,
+ LANGUAGE_USER_SYSTEM_CONFIG, css::i18n::ScriptType::WEAK);
+
+ const NfCurrencyTable& rCurrTab = SvNumberFormatter::GetTheCurrencyTable();
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry( LANGUAGE_SYSTEM );
+ // insert SYSTEM entry
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->append("default", aDefaultCurr);
+ m_xCurrencyLB->append_separator("");
+
+ assert(m_xCurrencyLB->find_id("default") != -1);
+ // all currencies
+ OUString aTwoSpace( " " );
+ sal_uInt16 nCurrCount = rCurrTab.size();
+ std::vector< const NfCurrencyEntry* > aCurrencies;
+ // first entry is SYSTEM, skip it
+ for ( sal_uInt16 j=1; j < nCurrCount; ++j )
+ {
+ aCurrencies.push_back(&rCurrTab[j]);
+ }
+ std::sort(aCurrencies.begin(), aCurrencies.end(),
+ [](const NfCurrencyEntry* c1, const NfCurrencyEntry* c2) {
+ return c1->GetBankSymbol().compareTo(c2->GetBankSymbol()) < 0;
+ });
+
+ for (auto &v : aCurrencies)
+ {
+ OUString aStr_ = v->GetBankSymbol() +
+ aTwoSpace +
+ v->GetSymbol();
+ aStr_ = ApplyLreOrRleEmbedding( aStr_ ) +
+ aTwoSpace +
+ ApplyLreOrRleEmbedding( SvtLanguageTable::GetLanguageString( v->GetLanguage() ) );
+ m_xCurrencyLB->append(weld::toId(v), aStr_);
+ }
+
+ m_xCurrencyLB->set_active(0);
+
+ m_xLocaleSettingLB->connect_changed( LINK( this, OfaLanguagesTabPage, LocaleSettingHdl ) );
+ m_xDatePatternsED->connect_changed( LINK( this, OfaLanguagesTabPage, DatePatternsHdl ) );
+
+ Link<weld::Toggleable&,void> aLink( LINK( this, OfaLanguagesTabPage, SupportHdl ) );
+ m_xAsianSupportCB->connect_toggled( aLink );
+ m_xCTLSupportCB->connect_toggled( aLink );
+
+ m_bOldAsian = SvtCJKOptions::IsAnyEnabled();
+ m_xAsianSupportCB->set_active(m_bOldAsian);
+ m_xAsianSupportCB->save_state();
+ bool bReadonly = SvtCJKOptions::IsReadOnly(SvtCJKOptions::E_ALL);
+ m_xAsianSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xAsianSupportCB);
+
+ m_bOldCtl = pLangConfig->aCTLLanguageOptions.IsCTLFontEnabled();
+ m_xCTLSupportCB->set_active(m_bOldCtl);
+ m_xCTLSupportCB->save_state();
+ bReadonly = pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT);
+ m_xCTLSupportCB->set_sensitive(!bReadonly);
+ SupportHdl(*m_xCTLSupportCB);
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange() );
+}
+
+OfaLanguagesTabPage::~OfaLanguagesTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaLanguagesTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaLanguagesTabPage>(pPage, pController, *rAttrSet);
+}
+
+static void lcl_Update(std::unique_ptr<SfxVoidItem> pInvalidItems[], std::unique_ptr<SfxBoolItem> pBoolItems[], sal_uInt16 nCount)
+{
+ SfxViewFrame* pCurrentFrm = SfxViewFrame::Current();
+ SfxViewFrame* pViewFrm = SfxViewFrame::GetFirst();
+ while(pViewFrm)
+ {
+ SfxBindings& rBind = pViewFrm->GetBindings();
+ for(sal_uInt16 i = 0; i < nCount; i++)
+ {
+ if(pCurrentFrm == pViewFrm)
+ rBind.InvalidateAll(false);
+ rBind.SetState( *pInvalidItems[i] );
+ rBind.SetState( *pBoolItems[i] );
+ }
+ pViewFrm = SfxViewFrame::GetNext(*pViewFrm);
+ }
+}
+
+bool OfaLanguagesTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ // lock configuration broadcasters so that we can coordinate the notifications
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( true );
+ pLangConfig->aCTLLanguageOptions.BlockBroadcasts( true );
+ pLangConfig->aLinguConfig.BlockBroadcasts( true );
+
+ /*
+ * Sequence checking only matters when CTL support is enabled.
+ *
+ * So we only need to check for sequence checking if
+ * a) previously it was unchecked and is now checked or
+ * b) it was already checked but the CTL language has changed
+ */
+ if (
+ m_xCTLSupportCB->get_active() &&
+ (m_xCTLSupportCB->get_saved_state() != TRISTATE_TRUE ||
+ m_xComplexLanguageLB->get_active_id_changed_from_saved())
+ )
+ {
+ //sequence checking has to be switched on depending on the selected CTL language
+ LanguageType eCTLLang = m_xComplexLanguageLB->get_active_id();
+ bool bOn = MsLangId::needsSequenceChecking( eCTLLang);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingRestricted(bOn);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceChecking(bOn);
+ pLangConfig->aCTLLanguageOptions.SetCTLSequenceCheckingTypeAndReplace(bOn);
+ }
+ try
+ {
+ // handle settings for UI Language
+ // a change of setting needs to bring up a warning message
+ OUString aLangString;
+ sal_Int32 d = m_xUserInterfaceLB->get_active_id().toInt32();
+ if( d > 0 && seqInstalledLanguages.getLength() > d-1)
+ aLangString = seqInstalledLanguages[d-1];
+
+ /*
+ if( m_xUserInterfaceLB->GetSelectedEntryPos() > 0)
+ aLangString = ConvertLanguageToIsoString(m_xUserInterfaceLB->get_active_id());
+ */
+ Reference< XMultiServiceFactory > theConfigProvider(
+ css::configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext()));
+ Sequence< Any > theArgs{ Any(NamedValue("nodepath", Any(OUString(sUserLocalePath)))) };
+ Reference< XPropertySet >xProp(
+ theConfigProvider->createInstanceWithArguments(sAccessUpdSrvc, theArgs ), UNO_QUERY_THROW );
+ if ( m_sUserLocaleValue != aLangString)
+ {
+ // OSL_FAIL("UserInterface language was changed, restart.");
+ // write new value
+ xProp->setPropertyValue(sUserLocaleKey, Any(aLangString));
+ Reference< XChangesBatch >(xProp, UNO_QUERY_THROW)->commitChanges();
+ // display info
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(
+ comphelper::getProcessComponentContext(), GetFrameWeld(),
+ svtools::RESTART_REASON_LANGUAGE_CHANGE))
+ GetDialogController()->response(RET_OK);
+
+ // tell quickstarter to stop being a veto listener
+
+ Reference< XComponentContext > xContext(
+ comphelper::getProcessComponentContext());
+ css::office::Quickstart::createAndSetVeto(xContext, false, false, false/*DisableVeto*/);
+ }
+ }
+ catch (const Exception&)
+ {
+ // we'll just leave the box in its default setting and won't
+ // even give it event handler...
+ TOOLS_WARN_EXCEPTION("cui.options", "ignoring");
+ }
+
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ LanguageType eOldLocale = (aLanguageTag.isSystemLocale() ? LANGUAGE_SYSTEM :
+ aLanguageTag.makeFallback().getLanguageType());
+ LanguageType eNewLocale = m_xLocaleSettingLB->get_active_id();
+
+ // If the "Default ..." entry was selected that means SYSTEM, the actual
+ // eNewLocale value is temporary for the dialog only, do not resolve to
+ // what system currently is.
+ if (eNewLocale == LANGUAGE_USER_SYSTEM_CONFIG)
+ eNewLocale = LANGUAGE_SYSTEM;
+
+ if ( eOldLocale != eNewLocale )
+ {
+ // an empty string denotes SYSTEM locale
+ OUString sNewLang;
+ if ( eNewLocale != LANGUAGE_SYSTEM )
+ sNewLang = LanguageTag::convertToBcp47( eNewLocale);
+
+ // locale nowadays get to AppSettings via notification
+ // this will happen after releasing the lock on the ConfigurationBroadcaster at
+ // the end of this method
+ pLangConfig->aSysLocaleOptions.SetLocaleConfigString( sNewLang );
+ rSet->Put( SfxBoolItem( SID_OPT_LOCALE_CHANGED, true ) );
+
+ SvtScriptType nNewType = SvtLanguageOptions::GetScriptTypeOfLanguage( eNewLocale );
+ bool bNewCJK = bool( nNewType & SvtScriptType::ASIAN );
+ SvtCompatibilityOptions aCompatOpts;
+ aCompatOpts.SetDefault( SvtCompatibilityEntry::Index::ExpandWordSpace, !bNewCJK );
+ }
+
+ if(m_xDecimalSeparatorCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDecimalSeparatorAsLocale(m_xDecimalSeparatorCB->get_active());
+
+ if(m_xIgnoreLanguageChangeCB->get_state_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetIgnoreLanguageChange(m_xIgnoreLanguageChangeCB->get_active());
+
+ // Configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default.
+ OUString sOldCurr = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ OUString sId = m_xCurrencyLB->get_active_id();
+ const NfCurrencyEntry* pCurr = sId == "default" ? nullptr : weld::fromId<const NfCurrencyEntry*>(sId);
+ OUString sNewCurr;
+ if ( pCurr )
+ sNewCurr = SvtSysLocaleOptions::CreateCurrencyConfigString(
+ pCurr->GetBankSymbol(), pCurr->GetLanguage() );
+ if ( sOldCurr != sNewCurr )
+ pLangConfig->aSysLocaleOptions.SetCurrencyConfigString( sNewCurr );
+
+ // Configured date acceptance patterns, for example Y-M-D;M-D or empty for
+ // locale default.
+ if (m_bDatePatternsValid && m_xDatePatternsED->get_value_changed_from_saved())
+ pLangConfig->aSysLocaleOptions.SetDatePatternsConfigString( m_xDatePatternsED->get_text());
+
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ Reference< css::linguistic2::XLinguProperties > xLinguProp = LinguMgr::GetLinguPropertySet();
+ bool bCurrentDocCBChecked = m_xCurrentDocCB->get_active();
+ if (m_xCurrentDocCB->get_sensitive())
+ bLanguageCurrentDoc_Impl = bCurrentDocCBChecked;
+ bool bCurrentDocCBChanged = m_xCurrentDocCB->get_state_changed_from_saved();
+
+ bool bValChanged = m_xWesternLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xWesternLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::LATIN),
+ SID_ATTR_LANGUAGE));
+ }
+ }
+ bValChanged = m_xAsianLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xAsianLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CJK", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CJK( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::ASIAN),
+ SID_ATTR_CHAR_CJK_LANGUAGE));
+ }
+ }
+ bValChanged = m_xComplexLanguageLB->get_active_id_changed_from_saved();
+ if( (bCurrentDocCBChanged && !bCurrentDocCBChecked) || bValChanged)
+ {
+ LanguageType eSelectLang = m_xComplexLanguageLB->get_active_id();
+ if(!bCurrentDocCBChecked)
+ {
+ Any aValue;
+ Locale aLocale = LanguageTag::convertToLocale( eSelectLang, false);
+ aValue <<= aLocale;
+ pLangConfig->aLinguConfig.SetProperty( u"DefaultLocale_CTL", aValue );
+ if (xLinguProp.is())
+ xLinguProp->setDefaultLocale_CTL( aLocale );
+ }
+ if(pCurrentDocShell)
+ {
+ rSet->Put(SvxLanguageItem(MsLangId::resolveSystemLanguageByScriptType(eSelectLang, css::i18n::ScriptType::COMPLEX),
+ SID_ATTR_CHAR_CTL_LANGUAGE));
+ }
+ }
+
+ if(m_xAsianSupportCB->get_state_changed_from_saved() )
+ {
+ bool bChecked = m_xAsianSupportCB->get_active();
+ SvtCJKOptions::SetAll(bChecked);
+
+ //iterate over all bindings to invalidate vertical text direction
+ const sal_uInt16 STATE_COUNT = 2;
+
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_VERTICALTEXT_STATE, false));
+ pBoolItems[1].reset(new SfxBoolItem(SID_TEXT_FITTOSIZE_VERTICAL, false));
+
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_VERTICALTEXT_STATE));
+ pInvalidItems[1].reset(new SfxVoidItem(SID_TEXT_FITTOSIZE_VERTICAL));
+
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( m_xCTLSupportCB->get_state_changed_from_saved() )
+ {
+ SvtSearchOptions aOpt;
+ aOpt.SetIgnoreDiacritics_CTL(true);
+ aOpt.SetIgnoreKashida_CTL(true);
+ aOpt.Commit();
+ pLangConfig->aCTLLanguageOptions.SetCTLFontEnabled( m_xCTLSupportCB->get_active() );
+
+ const sal_uInt16 STATE_COUNT = 1;
+ std::unique_ptr<SfxBoolItem> pBoolItems[STATE_COUNT];
+ pBoolItems[0].reset(new SfxBoolItem(SID_CTLFONT_STATE, false));
+ std::unique_ptr<SfxVoidItem> pInvalidItems[STATE_COUNT];
+ pInvalidItems[0].reset(new SfxVoidItem(SID_CTLFONT_STATE));
+ lcl_Update(pInvalidItems, pBoolItems, STATE_COUNT);
+ }
+
+ if ( pLangConfig->aSysLocaleOptions.IsModified() )
+ pLangConfig->aSysLocaleOptions.Commit();
+
+ // first release the lock on the ConfigurationBroadcaster for Locale changes
+ // it seems that our code relies on the fact that before other changes like e.g. currency
+ // are broadcasted locale changes have been done
+ pLangConfig->aSysLocaleOptions.BlockBroadcasts( false );
+ pLangConfig->aCTLLanguageOptions.BlockBroadcasts( false );
+ pLangConfig->aLinguConfig.BlockBroadcasts( false );
+
+ return false;
+}
+
+void OfaLanguagesTabPage::Reset( const SfxItemSet* rSet )
+{
+ LanguageTag aLanguageTag( pLangConfig->aSysLocaleOptions.GetLanguageTag());
+ if ( aLanguageTag.isSystemLocale() )
+ m_xLocaleSettingLB->set_active_id( LANGUAGE_USER_SYSTEM_CONFIG );
+ else
+ m_xLocaleSettingLB->set_active_id( aLanguageTag.makeFallback().getLanguageType());
+ bool bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Locale);
+ m_xLocaleSettingLB->set_sensitive(!bReadonly);
+ m_xLocaleSettingFT->set_sensitive(!bReadonly);
+
+
+ m_xDecimalSeparatorCB->set_active( pLangConfig->aSysLocaleOptions.IsDecimalSeparatorAsLocale());
+ m_xDecimalSeparatorCB->save_state();
+
+ m_xIgnoreLanguageChangeCB->set_active( pLangConfig->aSysLocaleOptions.IsIgnoreLanguageChange());
+ m_xIgnoreLanguageChangeCB->save_state();
+
+ // let LocaleSettingHdl enable/disable checkboxes for CJK/CTL support
+ // #i15812# must be done *before* the configured currency is set
+ // and update the decimal separator used for the given locale
+ LocaleSettingHdl(*m_xLocaleSettingLB->get_widget());
+
+ // configured currency, for example, USD-en-US or EUR-de-DE, or empty for locale default
+ const NfCurrencyEntry* pCurr = nullptr;
+ OUString sCurrency = pLangConfig->aSysLocaleOptions.GetCurrencyConfigString();
+ if ( !sCurrency.isEmpty() )
+ {
+ LanguageType eLang;
+ OUString aAbbrev;
+ SvtSysLocaleOptions::GetCurrencyAbbrevAndLanguage( aAbbrev, eLang, sCurrency );
+ pCurr = SvNumberFormatter::GetCurrencyEntry( aAbbrev, eLang );
+ }
+ // if pCurr==nullptr the SYSTEM entry is selected
+ OUString sId = !pCurr ? OUString("default") : weld::toId(pCurr);
+ m_xCurrencyLB->set_active_id(sId);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::Currency);
+ m_xCurrencyLB->set_sensitive(!bReadonly);
+ m_xCurrencyFT->set_sensitive(!bReadonly);
+
+ // date acceptance patterns
+ OUString aDatePatternsString = pLangConfig->aSysLocaleOptions.GetDatePatternsConfigString();
+ if (aDatePatternsString.isEmpty())
+ {
+ const LocaleDataWrapper& rLocaleWrapper( Application::GetSettings().GetLocaleDataWrapper() );
+ aDatePatternsString = lcl_getDatePatternsConfigString( rLocaleWrapper);
+ }
+ // Let's assume patterns are valid at this point.
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text(aDatePatternsString);
+ bReadonly = pLangConfig->aSysLocaleOptions.IsReadOnly(SvtSysLocaleOptions::EOption::DatePatterns);
+ m_xDatePatternsED->set_sensitive(!bReadonly);
+ m_xDatePatternsFT->set_sensitive(!bReadonly);
+ m_xDatePatternsED->save_value();
+
+ //western/CJK/CLK language
+ LanguageType eCurLang = LANGUAGE_NONE;
+ LanguageType eCurLangCJK = LANGUAGE_NONE;
+ LanguageType eCurLangCTL = LANGUAGE_NONE;
+ SfxObjectShell* pCurrentDocShell = SfxObjectShell::Current();
+ //collect the configuration values first
+ m_xCurrentDocCB->set_sensitive(false);
+
+ Any aWestLang;
+ Any aCJKLang;
+ Any aCTLLang;
+ try
+ {
+ aWestLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale");
+ Locale aLocale;
+ aWestLang >>= aLocale;
+
+ eCurLang = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCJKLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CJK");
+ aLocale = Locale();
+ aCJKLang >>= aLocale;
+ eCurLangCJK = LanguageTag::convertToLanguageType( aLocale, false);
+
+ aCTLLang = pLangConfig->aLinguConfig.GetProperty(u"DefaultLocale_CTL");
+ aLocale = Locale();
+ aCTLLang >>= aLocale;
+ eCurLangCTL = LanguageTag::convertToLanguageType( aLocale, false);
+ }
+ catch (const Exception&)
+ {
+ }
+ //overwrite them by the values provided by the DocShell
+ if(pCurrentDocShell)
+ {
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(bLanguageCurrentDoc_Impl);
+ if( const SvxLanguageItem* pLangItem = rSet->GetItemIfSet(SID_ATTR_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLangItem->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLang, css::i18n::ScriptType::LATIN) != eTempCurLang)
+ eCurLang = eTempCurLang;
+ }
+
+ if( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CJK_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLang->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCJK, css::i18n::ScriptType::ASIAN) != eTempCurLang)
+ eCurLangCJK = eTempCurLang;
+ }
+
+ if( const SvxLanguageItem* pLang = rSet->GetItemIfSet(SID_ATTR_CHAR_CTL_LANGUAGE, false))
+ {
+ LanguageType eTempCurLang = pLang->GetValue();
+ if (MsLangId::resolveSystemLanguageByScriptType(eCurLangCTL, css::i18n::ScriptType::COMPLEX) != eTempCurLang)
+ eCurLangCTL = eTempCurLang;
+ }
+ }
+ if(LANGUAGE_NONE == eCurLang || LANGUAGE_DONTKNOW == eCurLang)
+ m_xWesternLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xWesternLanguageLB->set_active_id(eCurLang);
+
+ if(LANGUAGE_NONE == eCurLangCJK || LANGUAGE_DONTKNOW == eCurLangCJK)
+ m_xAsianLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xAsianLanguageLB->set_active_id(eCurLangCJK);
+
+ if(LANGUAGE_NONE == eCurLangCTL || LANGUAGE_DONTKNOW == eCurLangCTL)
+ m_xComplexLanguageLB->set_active_id(LANGUAGE_NONE);
+ else
+ m_xComplexLanguageLB->set_active_id(eCurLangCTL);
+
+ m_xWesternLanguageLB->save_active_id();
+ m_xAsianLanguageLB->save_active_id();
+ m_xComplexLanguageLB->save_active_id();
+ m_xIgnoreLanguageChangeCB->save_state();
+ m_xCurrentDocCB->save_state();
+
+ bool bEnable = !pLangConfig->aLinguConfig.IsReadOnly( u"DefaultLocale" );
+ m_xWesternLanguageFT->set_sensitive( bEnable );
+ m_xWesternLanguageLB->set_sensitive( bEnable );
+
+ // check the box "For the current document only"
+ // set the focus to the Western Language box
+ const SfxBoolItem* pLang = rSet->GetItemIfSet(SID_SET_DOCUMENT_LANGUAGE, false );
+ if ( pLang && pLang->GetValue() )
+ {
+ m_xWesternLanguageLB->grab_focus();
+ m_xCurrentDocCB->set_sensitive(true);
+ m_xCurrentDocCB->set_active(true);
+ }
+}
+
+IMPL_LINK(OfaLanguagesTabPage, SupportHdl, weld::Toggleable&, rBox, void)
+{
+ bool bCheck = rBox.get_active();
+ if ( m_xAsianSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CJK");
+ bCheck = ( bCheck && !bReadonly );
+ m_xAsianLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldAsian = bCheck;
+ }
+ else if ( m_xCTLSupportCB.get() == &rBox )
+ {
+ bool bReadonly = pLangConfig->aLinguConfig.IsReadOnly(u"DefaultLocale_CTL");
+ bCheck = ( bCheck && !bReadonly );
+ m_xComplexLanguageLB->set_sensitive( bCheck );
+ if (rBox.get_sensitive())
+ m_bOldCtl = bCheck;
+ }
+ else
+ SAL_WARN( "cui.options", "OfaLanguagesTabPage::SupportHdl(): wrong rBox" );
+}
+
+namespace
+{
+ void lcl_checkLanguageCheckBox(weld::CheckButton& _rCB, bool _bNewValue, bool _bOldValue)
+ {
+ if ( _bNewValue )
+ _rCB.set_active(true);
+ else
+ _rCB.set_active( _bOldValue );
+// #i15082# do not call save_state() in running dialog...
+// _rCB.save_state();
+ _rCB.set_sensitive( !_bNewValue );
+ }
+}
+
+IMPL_LINK_NOARG(OfaLanguagesTabPage, LocaleSettingHdl, weld::ComboBox&, void)
+{
+ LanguageType eLang = m_xLocaleSettingLB->get_active_id();
+ SvtScriptType nType = SvtLanguageOptions::GetScriptTypeOfLanguage(eLang);
+ // first check if CTL must be enabled
+ // #103299# - if CTL font setting is not readonly
+ if(!pLangConfig->aCTLLanguageOptions.IsReadOnly(SvtCTLOptions::E_CTLFONT))
+ {
+ bool bIsCTLFixed = bool(nType & SvtScriptType::COMPLEX);
+ lcl_checkLanguageCheckBox(*m_xCTLSupportCB, bIsCTLFixed, m_bOldCtl);
+ SupportHdl(*m_xCTLSupportCB);
+ }
+ // second check if CJK must be enabled
+ // #103299# - if CJK support is not readonly
+ if(!SvtCJKOptions::IsReadOnly(SvtCJKOptions::E_ALL))
+ {
+ bool bIsCJKFixed = bool(nType & SvtScriptType::ASIAN);
+ lcl_checkLanguageCheckBox(*m_xAsianSupportCB, bIsCJKFixed, m_bOldAsian);
+ SupportHdl(*m_xAsianSupportCB);
+ }
+
+ const NfCurrencyEntry& rCurr = SvNumberFormatter::GetCurrencyEntry(
+ (eLang == LANGUAGE_USER_SYSTEM_CONFIG) ? MsLangId::getConfiguredSystemLanguage() : eLang);
+ const OUString aDefaultID = "default";
+ // Update the "Default ..." currency.
+ m_xCurrencyLB->remove_id(aDefaultID);
+ OUString aDefaultCurr = m_sSystemDefaultString + " - " + rCurr.GetBankSymbol();
+ m_xCurrencyLB->insert(0, aDefaultCurr, &aDefaultID, nullptr, nullptr);
+ assert(m_xCurrencyLB->find_id(aDefaultID) != -1);
+ m_xCurrencyLB->set_active_text(aDefaultCurr);
+
+ // obtain corresponding locale data
+ LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang) ));
+
+ // update the decimal separator key of the related CheckBox
+ OUString sTempLabel(m_sDecimalSeparatorLabel);
+ sTempLabel = sTempLabel.replaceFirst("%1", aLocaleWrapper.getNumDecimalSep() );
+ m_xDecimalSeparatorCB->set_label(sTempLabel);
+
+ // update the date acceptance patterns
+ OUString aDatePatternsString = lcl_getDatePatternsConfigString( aLocaleWrapper);
+ m_bDatePatternsValid = true;
+ m_xDatePatternsED->set_text( aDatePatternsString);
+}
+
+IMPL_LINK( OfaLanguagesTabPage, DatePatternsHdl, weld::Entry&, rEd, void )
+{
+ const OUString aPatterns(rEd.get_text());
+ OUStringBuffer aBuf( aPatterns);
+ sal_Int32 nChar = 0;
+ bool bValid = true;
+ bool bModified = false;
+ if (!aPatterns.isEmpty())
+ {
+ for (sal_Int32 nIndex=0; nIndex >= 0 && bValid; ++nChar)
+ {
+ const OUString aPat( aPatterns.getToken( 0, ';', nIndex));
+ if (aPat.isEmpty() && nIndex < 0)
+ {
+ // Indicating failure when about to append a pattern is too
+ // confusing. Empty patterns are ignored anyway when sequencing
+ // to SvtSysLocale.
+ continue; // for
+ }
+ else if (aPat.getLength() < 2)
+ bValid = false;
+ else
+ {
+ bool bY, bM, bD;
+ bY = bM = bD = false;
+ bool bSep = true;
+ if (aPat.getLength() == 3)
+ {
+ // Disallow a pattern that would match a numeric input with
+ // decimal separator, like M.D
+ const LanguageType eLang = m_xLocaleSettingLB->get_active_id();
+ const LocaleDataWrapper aLocaleWrapper(( LanguageTag(eLang)));
+ if ( aPat[1] == aLocaleWrapper.getNumDecimalSep().toChar()
+ || aPat[1] == aLocaleWrapper.getNumDecimalSepAlt().toChar())
+ {
+ bValid = false;
+ }
+ }
+ for (sal_Int32 i = 0; i < aPat.getLength() && bValid; /*nop*/)
+ {
+ const sal_Int32 j = i;
+ const sal_uInt32 c = aPat.iterateCodePoints( &i);
+ // Only one Y,M,D per pattern, separated by any character(s).
+ switch (c)
+ {
+ case 'y':
+ case 'Y':
+ if (bY || !bSep)
+ bValid = false;
+ else if (c == 'y')
+ {
+ aBuf[nChar] = 'Y';
+ bModified = true;
+ }
+ bY = true;
+ bSep = false;
+ break;
+ case 'm':
+ case 'M':
+ if (bM || !bSep)
+ bValid = false;
+ else if (c == 'm')
+ {
+ aBuf[nChar] = 'M';
+ bModified = true;
+ }
+ bM = true;
+ bSep = false;
+ break;
+ case 'd':
+ case 'D':
+ if (bD || !bSep)
+ bValid = false;
+ else if (c == 'd')
+ {
+ aBuf[nChar] = 'D';
+ bModified = true;
+ }
+ bD = true;
+ bSep = false;
+ break;
+ default:
+ // A pattern must not start with a separator (but
+ // may end with).
+ if (!(bY || bM || bD))
+ bValid = false;
+ bSep = true;
+ }
+ nChar += i-j;
+ }
+ // At least one of Y,M,D
+ bValid &= (bY || bM || bD);
+ }
+ }
+ }
+ if (bModified)
+ {
+ // gtk3 keeps the cursor position on equal length set_text() but at
+ // least the 'gen' backend does not and resets to 0.
+ const int nCursorPos = rEd.get_position();
+ rEd.set_text(aBuf.makeStringAndClear());
+ rEd.set_position(nCursorPos);
+ }
+ if (bValid)
+ rEd.set_message_type(weld::EntryMessageType::Normal);
+ else
+ rEd.set_message_type(weld::EntryMessageType::Error);
+ m_bDatePatternsValid = bValid;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgdlg.hxx b/cui/source/options/optgdlg.hxx
new file mode 100644
index 000000000..75f29c6c5
--- /dev/null
+++ b/cui/source/options/optgdlg.hxx
@@ -0,0 +1,181 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+#include <svx/langbox.hxx>
+
+class CanvasSettings;
+
+namespace vcl {
+ class IconThemeInfo;
+}
+
+class OfaMiscTabPage : public SfxTabPage
+{
+private:
+ OUString m_aStrDateInfo;
+
+ std::unique_ptr<weld::CheckButton> m_xExtHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xPopUpNoHelpCB;
+ std::unique_ptr<weld::CheckButton> m_xShowTipOfTheDay;
+ std::unique_ptr<weld::Widget> m_xFileDlgFrame;
+ std::unique_ptr<weld::Widget> m_xFileDlgROImage;
+ std::unique_ptr<weld::CheckButton> m_xFileDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintDlgCB;
+ std::unique_ptr<weld::CheckButton> m_xDocStatusCB;
+ std::unique_ptr<weld::Widget> m_xYearFrame;
+ std::unique_ptr<weld::SpinButton> m_xYearValueField;
+ std::unique_ptr<weld::Label> m_xToYearFT;
+ std::unique_ptr<weld::CheckButton> m_xCrashReport;
+ std::unique_ptr<weld::Widget> m_xQuickStarterFrame;
+ std::unique_ptr<weld::Label> m_xHelpImproveLabel;
+ std::unique_ptr<weld::CheckButton> m_xQuickLaunchCB;
+#if defined(_WIN32)
+ std::unique_ptr<weld::Widget> m_xFileAssocFrame;
+ std::unique_ptr<weld::Button> m_xFileAssocBtn;
+ std::unique_ptr<weld::CheckButton> m_xPerformFileExtCheck;
+#endif
+
+ DECL_LINK(TwoFigureHdl, weld::SpinButton&, void);
+#if defined(_WIN32)
+ DECL_DLLPRIVATE_STATIC_LINK(OfaMiscTabPage, FileAssocClick, weld::Button&, void);
+#endif
+protected:
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ OfaMiscTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaMiscTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+class SvtTabAppearanceCfg;
+
+class OfaViewTabPage : public SfxTabPage
+{
+private:
+ sal_Int32 nSizeLB_InitialSelection;
+ sal_Int32 nSidebarSizeLB_InitialSelection;
+ sal_Int32 nNotebookbarSizeLB_InitialSelection;
+ sal_Int32 nStyleLB_InitialSelection;
+
+ std::unique_ptr<SvtTabAppearanceCfg> pAppearanceCfg;
+ std::unique_ptr<CanvasSettings> pCanvasSettings;
+
+ std::vector<vcl::IconThemeInfo> mInstalledIconThemes;
+
+ std::unique_ptr<weld::ComboBox> m_xIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xSidebarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xNotebookbarIconSizeLB;
+ std::unique_ptr<weld::ComboBox> m_xIconStyleLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontAntiAliasing;
+ std::unique_ptr<weld::Label> m_xAAPointLimitLabel;
+ std::unique_ptr<weld::MetricSpinButton> m_xAAPointLimit;
+
+ std::unique_ptr<weld::Widget> m_xMenuIconBox;
+ std::unique_ptr<weld::ComboBox> m_xMenuIconsLB;
+
+ std::unique_ptr<weld::ComboBox> m_xContextMenuShortcutsLB;
+
+ std::unique_ptr<weld::CheckButton> m_xFontShowCB;
+
+ std::unique_ptr<weld::CheckButton> m_xUseHardwareAccell;
+ std::unique_ptr<weld::CheckButton> m_xUseAntiAliase;
+ std::unique_ptr<weld::CheckButton> m_xUseSkia;
+ std::unique_ptr<weld::CheckButton> m_xForceSkiaRaster;
+
+ std::unique_ptr<weld::Label> m_xSkiaStatusEnabled;
+ std::unique_ptr<weld::Label> m_xSkiaStatusDisabled;
+
+ std::unique_ptr<weld::ComboBox> m_xMousePosLB;
+ std::unique_ptr<weld::ComboBox> m_xMouseMiddleLB;
+ std::unique_ptr<weld::Button> m_xMoreIcons;
+ std::unique_ptr<weld::Button> m_xRunGPTests;
+
+ DECL_LINK(OnAntialiasingToggled, weld::Toggleable&, void);
+ DECL_LINK(OnUseSkiaToggled, weld::Toggleable&, void);
+ DECL_STATIC_LINK(OfaViewTabPage, OnMoreIconsClick, weld::Button&, void);
+ DECL_LINK(OnRunGPTestClick, weld::Button&, void);
+ void UpdateSkiaStatus();
+ void HideSkiaWidgets();
+ void UpdateHardwareAccelStatus();
+
+public:
+ OfaViewTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaViewTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct LanguageConfig_Impl;
+
+class OfaLanguagesTabPage : public SfxTabPage
+{
+ bool m_bOldAsian;
+ bool m_bOldCtl;
+ std::unique_ptr<LanguageConfig_Impl> pLangConfig;
+
+ OUString m_sUserLocaleValue;
+ OUString m_sSystemDefaultString;
+ OUString m_sDecimalSeparatorLabel;
+
+ bool m_bDatePatternsValid;
+
+ std::unique_ptr<weld::ComboBox> m_xUserInterfaceLB;
+ std::unique_ptr<weld::Label> m_xLocaleSettingFT;
+ std::unique_ptr<SvxLanguageBox> m_xLocaleSettingLB;
+ std::unique_ptr<weld::CheckButton> m_xDecimalSeparatorCB;
+ std::unique_ptr<weld::Label> m_xCurrencyFT;
+ std::unique_ptr<weld::ComboBox> m_xCurrencyLB;
+ std::unique_ptr<weld::Label> m_xDatePatternsFT;
+ std::unique_ptr<weld::Entry> m_xDatePatternsED;
+
+ std::unique_ptr<SvxLanguageBox> m_xWesternLanguageLB;
+ std::unique_ptr<weld::Label> m_xWesternLanguageFT;
+ std::unique_ptr<SvxLanguageBox> m_xAsianLanguageLB;
+ std::unique_ptr<SvxLanguageBox> m_xComplexLanguageLB;
+ std::unique_ptr<weld::CheckButton> m_xCurrentDocCB;
+ std::unique_ptr<weld::CheckButton> m_xAsianSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xCTLSupportCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreLanguageChangeCB;
+
+ DECL_LINK(SupportHdl, weld::Toggleable&, void);
+ DECL_LINK(LocaleSettingHdl, weld::ComboBox&, void);
+ DECL_LINK(DatePatternsHdl, weld::Entry&, void);
+
+public:
+ OfaLanguagesTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaLanguagesTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optgenrl.cxx b/cui/source/options/optgenrl.cxx
new file mode 100644
index 000000000..094089421
--- /dev/null
+++ b/cui/source/options/optgenrl.cxx
@@ -0,0 +1,507 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <comphelper/string.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <config_gpgme.h>
+#if HAVE_FEATURE_GPGME
+# include <com/sun/star/xml/crypto/GPGSEInitializer.hpp>
+# include <com/sun/star/xml/crypto/XXMLSecurityContext.hpp>
+#endif
+
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <o3tl/safeint.hxx>
+#include <vcl/svapp.hxx>
+#include <svl/intitem.hxx>
+#include <vcl/settings.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <unotools/useroptions.hxx>
+#include <cuioptgenrl.hxx>
+#include <svx/svxids.hrc>
+#include <svx/optgenrl.hxx>
+
+using namespace css;
+
+namespace
+{
+
+// rows
+enum RowType
+{
+ Row_Company,
+ Row_Name,
+ Row_Name_Russian,
+ Row_Name_Eastern,
+ Row_Street,
+ Row_Street_Russian,
+ Row_City,
+ Row_City_US,
+ Row_Country,
+ Row_TitlePos,
+ Row_Phone,
+ Row_FaxMail,
+
+ nRowCount
+};
+
+// language flags
+namespace Lang
+{
+ unsigned const Others = 1;
+ unsigned const Russian = 2;
+ unsigned const Eastern = 4;
+ unsigned const US = 8;
+ unsigned const All = static_cast<unsigned>(-1);
+}
+
+
+// vRowInfo[] -- rows (text + one or more edit boxes)
+// The order is the same as in RowType above, which is up to down.
+
+struct
+{
+ // id of the text
+ const char *pTextId;
+ // language flags (see Lang above):
+ // which language is this row for?
+ unsigned nLangFlags;
+}
+const vRowInfo[] =
+{
+ { "companyft", Lang::All },
+ { "nameft", Lang::All & ~Lang::Russian & ~Lang::Eastern },
+ { "rusnameft", Lang::Russian },
+ { "eastnameft", Lang::Eastern },
+ { "streetft", Lang::All & ~Lang::Russian },
+ { "russtreetft", Lang::Russian },
+ { "icityft", Lang::All & ~Lang::US },
+ { "cityft", Lang::US },
+ { "countryft", Lang::All },
+ { "titleft", Lang::All },
+ { "phoneft", Lang::All },
+ { "faxft", Lang::All },
+};
+
+
+// vFieldInfo[] -- edit boxes
+// The order is up to down, and then left to right.
+
+struct
+{
+ // in which row?
+ RowType eRow;
+ // id of the edit box
+ const char *pEditId;
+ // id for SvtUserOptions in unotools/useroptions.hxx
+ UserOptToken nUserOptionsId;
+ // id for settings the focus (defined in svx/optgenrl.hxx)
+ EditPosition nGrabFocusId;
+}
+const vFieldInfo[] =
+{
+ // Company
+ { Row_Company, "company", UserOptToken::Company, EditPosition::COMPANY },
+ // Name
+ { Row_Name, "firstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name, "lastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name, "shortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (russian)
+ { Row_Name_Russian, "ruslastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Russian, "rusfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Russian, "rusfathersname", UserOptToken::FathersName, EditPosition::UNKNOWN },
+ { Row_Name_Russian, "russhortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Name (eastern: reversed name ord
+ { Row_Name_Eastern, "eastlastname", UserOptToken::LastName, EditPosition::LASTNAME },
+ { Row_Name_Eastern, "eastfirstname", UserOptToken::FirstName, EditPosition::FIRSTNAME },
+ { Row_Name_Eastern, "eastshortname", UserOptToken::ID, EditPosition::SHORTNAME },
+ // Street
+ { Row_Street, "street", UserOptToken::Street, EditPosition::STREET },
+ // Street (russian)
+ { Row_Street_Russian, "russtreet", UserOptToken::Street, EditPosition::STREET },
+ { Row_Street_Russian, "apartnum", UserOptToken::Apartment, EditPosition::UNKNOWN },
+ // City
+ { Row_City, "izip", UserOptToken::Zip, EditPosition::PLZ },
+ { Row_City, "icity", UserOptToken::City, EditPosition::CITY },
+ // City (US)
+ { Row_City_US, "city", UserOptToken::City, EditPosition::CITY },
+ { Row_City_US, "state", UserOptToken::State, EditPosition::STATE },
+ { Row_City_US, "zip", UserOptToken::Zip, EditPosition::PLZ },
+ // Country
+ { Row_Country, "country", UserOptToken::Country, EditPosition::COUNTRY },
+ // Title/Position
+ { Row_TitlePos, "title", UserOptToken::Title, EditPosition::TITLE },
+ { Row_TitlePos, "position", UserOptToken::Position, EditPosition::POSITION },
+ // Phone
+ { Row_Phone, "home", UserOptToken::TelephoneHome, EditPosition::TELPRIV },
+ { Row_Phone, "work", UserOptToken::TelephoneWork, EditPosition::TELCOMPANY },
+ // Fax/Mail
+ { Row_FaxMail, "fax", UserOptToken::Fax, EditPosition::FAX },
+ { Row_FaxMail, "email", UserOptToken::Email, EditPosition::EMAIL },
+};
+
+
+} // namespace
+
+
+// Row
+
+struct SvxGeneralTabPage::Row
+{
+ // row label
+ std::unique_ptr<weld::Label> xLabel;
+ // first and last field in the row (last is exclusive)
+ unsigned nFirstField, nLastField;
+
+public:
+ explicit Row (std::unique_ptr<weld::Label> xLabel_)
+ : xLabel(std::move(xLabel_))
+ , nFirstField(0)
+ , nLastField(0)
+ {
+ xLabel->show();
+ }
+};
+
+
+// Field
+
+struct SvxGeneralTabPage::Field
+{
+ // which field is this? (in vFieldInfo[] above)
+ unsigned iField;
+ // edit box
+ std::unique_ptr<weld::Entry> xEdit;
+ std::unique_ptr<weld::Container> xParent;
+
+public:
+ Field (std::unique_ptr<weld::Entry> xEdit_, unsigned iField_)
+ : iField(iField_)
+ , xEdit(std::move(xEdit_))
+ , xParent(xEdit->weld_parent())
+ {
+ //We want all widgets inside a container, so each row of the toplevel
+ //grid has another container in it. To avoid adding spacing to these
+ //empty grids they all default to invisible, so show them if their
+ //children are visible
+ xParent->show();
+ xEdit->show();
+ }
+};
+
+SvxGeneralTabPage::SvxGeneralTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optuserpage.ui", "OptUserPage", &rCoreSet)
+ , m_xUseDataCB(m_xBuilder->weld_check_button("usefordocprop"))
+ , m_xCryptoFrame(m_xBuilder->weld_widget( "cryptography"))
+ , m_xSigningKeyLB(m_xBuilder->weld_combo_box("signingkey"))
+ , m_xEncryptionKeyLB(m_xBuilder->weld_combo_box("encryptionkey"))
+ , m_xEncryptToSelfCB(m_xBuilder->weld_check_button("encrypttoself"))
+{
+ InitControls();
+#if HAVE_FEATURE_GPGME
+ InitCryptography();
+#else
+ m_xCryptoFrame->hide();
+#endif
+
+ SetExchangeSupport(); // this page needs ExchangeSupport
+ SetLinks();
+}
+
+SvxGeneralTabPage::~SvxGeneralTabPage()
+{
+}
+
+// Initializes the titles and the edit boxes,
+// according to vRowInfo[] and vFieldInfo[] above.
+void SvxGeneralTabPage::InitControls ()
+{
+ // which language bit do we use? (see Lang and vRowInfo[] above)
+ unsigned LangBit;
+ LanguageType l = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ if (l == LANGUAGE_ENGLISH_US)
+ LangBit = Lang::US;
+ else if (l == LANGUAGE_RUSSIAN)
+ LangBit = Lang::Russian;
+ else
+ {
+ if (MsLangId::isFamilyNameFirst(l))
+ LangBit = Lang::Eastern;
+ else
+ LangBit = Lang::Others;
+ }
+
+ // creating rows
+ unsigned iField = 0;
+ for (unsigned iRow = 0; iRow != nRowCount; ++iRow)
+ {
+ RowType const eRow = static_cast<RowType>(iRow);
+ // is the row visible?
+ if (!(vRowInfo[iRow].nLangFlags & LangBit))
+ continue;
+ // creating row
+ vRows.push_back(std::make_shared<Row>(
+ m_xBuilder->weld_label(vRowInfo[iRow].pTextId)));
+ Row& rRow = *vRows.back();
+ // fields in the row
+ static unsigned const nFieldCount = std::size(vFieldInfo);
+ // skipping other (invisible) rows
+ while (iField != nFieldCount && vFieldInfo[iField].eRow != eRow)
+ ++iField;
+ // fields in the row
+ rRow.nFirstField = vFields.size();
+ for ( ; iField != nFieldCount && vFieldInfo[iField].eRow == eRow; ++iField)
+ {
+ // creating edit field
+ vFields.push_back(std::make_shared<Field>(
+ m_xBuilder->weld_entry(vFieldInfo[iField].pEditId), iField));
+ // "short name" field?
+ if (vFieldInfo[iField].nUserOptionsId == UserOptToken::ID)
+ {
+ nNameRow = vRows.size() - 1;
+ nShortNameField = vFields.size() - 1;
+ }
+ }
+ rRow.nLastField = vFields.size();
+ }
+}
+
+void SvxGeneralTabPage::InitCryptography()
+{
+#if HAVE_FEATURE_GPGME
+ m_xCryptoFrame->show();
+
+ uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
+ try
+ {
+ xSEInitializer = xml::crypto::GPGSEInitializer::create( comphelper::getProcessComponentContext() );
+ uno::Reference<xml::crypto::XXMLSecurityContext> xSC = xSEInitializer->createSecurityContext( OUString() );
+ if (xSC.is())
+ {
+ uno::Reference<xml::crypto::XSecurityEnvironment> xSE = xSC->getSecurityEnvironment();
+ uno::Sequence<uno::Reference<security::XCertificate>> xCertificates = xSE->getPersonalCertificates();
+
+ if (xCertificates.hasElements())
+ {
+ for (auto& xCert : asNonConstRange(xCertificates))
+ {
+ m_xSigningKeyLB->append_text( xCert->getIssuerName());
+ m_xEncryptionKeyLB->append_text( xCert->getIssuerName());
+ }
+ }
+
+ //tdf#115015: wrap checkbox text and listboxes if necessary
+ int nPrefWidth(m_xEncryptToSelfCB->get_preferred_size().Width());
+ int nMaxWidth = m_xEncryptToSelfCB->get_approximate_digit_width() * 40;
+ if (nPrefWidth > nMaxWidth)
+ {
+ m_xSigningKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptionKeyLB->set_size_request(nMaxWidth, -1);
+ m_xEncryptToSelfCB->set_label_wrap(true);
+ m_xEncryptToSelfCB->set_size_request(nMaxWidth, -1);
+ }
+ }
+ }
+ catch ( uno::Exception const & )
+ {}
+#endif
+
+}
+
+void SvxGeneralTabPage::SetLinks ()
+{
+ // link for updating the initials
+ Link<weld::Entry&,void> aLink = LINK( this, SvxGeneralTabPage, ModifyHdl_Impl );
+ Row& rNameRow = *vRows[nNameRow];
+ for (unsigned i = rNameRow.nFirstField; i != rNameRow.nLastField - 1; ++i)
+ vFields[i]->xEdit->connect_changed(aLink);
+}
+
+
+std::unique_ptr<SfxTabPage> SvxGeneralTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxGeneralTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxGeneralTabPage::FillItemSet( SfxItemSet* )
+{
+ // remove leading and trailing whitespaces
+ for (auto const & i: vFields)
+ i->xEdit->set_text(comphelper::string::strip(i->xEdit->get_text(), ' '));
+
+ bool bModified = false;
+ bModified |= GetData_Impl();
+ if (m_xUseDataCB->get_active() != officecfg::Office::Common::Save::Document::UseUserData::get())
+ {
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ officecfg::Office::Common::Save::Document::UseUserData::set(m_xUseDataCB->get_active(), xChanges);
+ xChanges->commit();
+ bModified = true;
+ }
+ return bModified;
+}
+
+void SvxGeneralTabPage::Reset( const SfxItemSet* rSet )
+{
+ SetData_Impl();
+
+ if (rSet->GetItemState(SID_FIELD_GRABFOCUS) == SfxItemState::SET)
+ {
+ EditPosition nField = static_cast<EditPosition>(static_cast<const SfxUInt16Item&>(rSet->Get(SID_FIELD_GRABFOCUS)).GetValue());
+ if (nField != EditPosition::UNKNOWN)
+ {
+ for (auto const & i: vFields)
+ if (nField == vFieldInfo[i->iField].nGrabFocusId)
+ i->xEdit->grab_focus();
+ }
+ else
+ vFields.front()->xEdit->grab_focus();
+ }
+
+ m_xUseDataCB->set_active(officecfg::Office::Common::Save::Document::UseUserData::get());
+}
+
+
+// ModifyHdl_Impl()
+// This handler updates the initials (short name)
+// when one of the name fields was updated.
+IMPL_LINK( SvxGeneralTabPage, ModifyHdl_Impl, weld::Entry&, rEdit, void )
+{
+ // short name field and row
+ Field& rShortName = *vFields[nShortNameField];
+ Row& rNameRow = *vRows[nNameRow];
+ // number of initials
+ unsigned const nInits = rNameRow.nLastField - rNameRow.nFirstField - 1;
+ // which field was updated? (in rNameRow)
+ unsigned nField = nInits;
+ for (unsigned i = 0; i != nInits; ++i)
+ {
+ if (vFields[rNameRow.nFirstField + i]->xEdit.get() == &rEdit)
+ nField = i;
+ }
+ // updating the initial
+ if (!(nField < nInits && rShortName.xEdit->get_sensitive()))
+ return;
+
+ OUString sShortName = rShortName.xEdit->get_text();
+ // clear short name if it contains more characters than the number of initials
+ if (o3tl::make_unsigned(sShortName.getLength()) > nInits)
+ {
+ rShortName.xEdit->set_text(OUString());
+ }
+ while (o3tl::make_unsigned(sShortName.getLength()) < nInits)
+ sShortName += " ";
+ OUString sName = rEdit.get_text();
+ OUString sLetter = sName.isEmpty()
+ ? OUString(u' ') : sName.copy(0, 1);
+ rShortName.xEdit->set_text(sShortName.replaceAt(nField, 1, sLetter).trim());
+}
+
+
+bool SvxGeneralTabPage::GetData_Impl()
+{
+ // updating
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vFields)
+ aUserOpt.SetToken(
+ vFieldInfo[i->iField].nUserOptionsId,
+ i->xEdit->get_text()
+ );
+
+ // modified?
+ bool bModified = false;
+ for (auto const & i: vFields)
+ {
+ if (i->xEdit->get_value_changed_from_saved())
+ {
+ bModified = true;
+ break;
+ }
+ }
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = m_xSigningKeyLB->get_active() == 0 ? OUString() //i.e. no key
+ : m_xSigningKeyLB->get_active_text();
+ OUString aEK = m_xEncryptionKeyLB->get_active() == 0 ? OUString()
+ : m_xEncryptionKeyLB->get_active_text();
+
+ aUserOpt.SetToken( UserOptToken::SigningKey, aSK );
+ aUserOpt.SetToken( UserOptToken::EncryptionKey, aEK );
+ aUserOpt.SetBoolValue( UserOptToken::EncryptToSelf, m_xEncryptToSelfCB->get_active() );
+
+ bModified |= m_xSigningKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptionKeyLB->get_value_changed_from_saved() ||
+ m_xEncryptToSelfCB->get_state_changed_from_saved();
+#endif
+
+ return bModified;
+}
+
+
+void SvxGeneralTabPage::SetData_Impl()
+{
+ // updating and disabling edit boxes
+ SvtUserOptions aUserOpt;
+ for (auto const & i: vRows)
+ {
+ Row& rRow = *i;
+ // the label is enabled if any of its edit fields are enabled
+ bool bEnableLabel = false;
+ for (unsigned iField = rRow.nFirstField; iField != rRow.nLastField; ++iField)
+ {
+ Field& rField = *vFields[iField];
+ // updating content
+ UserOptToken const nToken = vFieldInfo[rField.iField].nUserOptionsId;
+ rField.xEdit->set_text(aUserOpt.GetToken(nToken));
+ // is enabled?
+ bool const bEnableEdit = !aUserOpt.IsTokenReadonly(nToken);
+ rField.xEdit->set_sensitive(bEnableEdit);
+ bEnableLabel = bEnableLabel || bEnableEdit;
+ }
+ rRow.xLabel->set_sensitive(bEnableLabel);
+ }
+
+ // saving
+ for (auto const & i: vFields)
+ i->xEdit->save_value();
+
+#if HAVE_FEATURE_GPGME
+ OUString aSK = aUserOpt.GetToken(UserOptToken::SigningKey);
+ aSK.isEmpty() ? m_xSigningKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xSigningKeyLB->set_active_text( aSK );
+
+ OUString aEK = aUserOpt.GetToken(UserOptToken::EncryptionKey);
+ aEK.isEmpty() ? m_xEncryptionKeyLB->set_active( 0 ) //i.e. 'No Key'
+ : m_xEncryptionKeyLB->set_active_text( aEK );
+
+ m_xEncryptToSelfCB->set_active( aUserOpt.GetEncryptToSelf() );
+#endif
+}
+
+
+DeactivateRC SvxGeneralTabPage::DeactivatePage( SfxItemSet* pSet_ )
+{
+ if ( pSet_ )
+ FillItemSet( pSet_ );
+ return DeactivateRC::LeavePage;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.cxx b/cui/source/options/opthtml.cxx
new file mode 100644
index 000000000..18e3beceb
--- /dev/null
+++ b/cui/source/options/opthtml.cxx
@@ -0,0 +1,169 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svtools/langtab.hxx>
+#include <svtools/htmlcfg.hxx>
+#include <comphelper/configuration.hxx>
+#include <officecfg/Office/Common.hxx>
+#include "opthtml.hxx"
+
+
+OfaHtmlTabPage::OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/opthtmlpage.ui", "OptHtmlPage", &rSet)
+ , m_xSize1NF(m_xBuilder->weld_spin_button("size1"))
+ , m_xSize2NF(m_xBuilder->weld_spin_button("size2"))
+ , m_xSize3NF(m_xBuilder->weld_spin_button("size3"))
+ , m_xSize4NF(m_xBuilder->weld_spin_button("size4"))
+ , m_xSize5NF(m_xBuilder->weld_spin_button("size5"))
+ , m_xSize6NF(m_xBuilder->weld_spin_button("size6"))
+ , m_xSize7NF(m_xBuilder->weld_spin_button("size7"))
+ , m_xNumbersEnglishUSCB(m_xBuilder->weld_check_button("numbersenglishus"))
+ , m_xUnknownTagCB(m_xBuilder->weld_check_button("unknowntag"))
+ , m_xIgnoreFontNamesCB(m_xBuilder->weld_check_button("ignorefontnames"))
+ , m_xStarBasicCB(m_xBuilder->weld_check_button("starbasic"))
+ , m_xStarBasicWarningCB(m_xBuilder->weld_check_button("starbasicwarning"))
+ , m_xPrintExtensionCB(m_xBuilder->weld_check_button("printextension"))
+ , m_xSaveGrfLocalCB(m_xBuilder->weld_check_button("savegrflocal"))
+{
+ // replace placeholder with UI string from language list
+ OUString aText(m_xNumbersEnglishUSCB->get_label());
+ OUString aPlaceholder("%ENGLISHUSLOCALE");
+ sal_Int32 nPos;
+ if ((nPos = aText.indexOf( aPlaceholder)) != -1)
+ {
+ const OUString& rStr = SvtLanguageTable::GetLanguageString( LANGUAGE_ENGLISH_US);
+ if (!rStr.isEmpty())
+ {
+ aText = aText.replaceAt( nPos, aPlaceholder.getLength(), rStr);
+ m_xNumbersEnglishUSCB->set_label( aText);
+ }
+ }
+
+ m_xStarBasicCB->connect_toggled(LINK(this, OfaHtmlTabPage, CheckBoxHdl_Impl));
+}
+
+OfaHtmlTabPage::~OfaHtmlTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> OfaHtmlTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<OfaHtmlTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool OfaHtmlTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> xChanges = comphelper::ConfigurationChanges::create();
+ if(m_xSize1NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_1::set(
+ static_cast<sal_uInt16>(m_xSize1NF->get_value()), xChanges);
+ if(m_xSize2NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_2::set(
+ static_cast<sal_uInt16>(m_xSize2NF->get_value()), xChanges);
+ if(m_xSize3NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_3::set(
+ static_cast<sal_uInt16>(m_xSize3NF->get_value()), xChanges);
+ if(m_xSize4NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_4::set(
+ static_cast<sal_uInt16>(m_xSize4NF->get_value()), xChanges);
+ if(m_xSize5NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_5::set(
+ static_cast<sal_uInt16>(m_xSize5NF->get_value()), xChanges);
+ if(m_xSize6NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_6::set(
+ static_cast<sal_uInt16>(m_xSize6NF->get_value()), xChanges);
+ if(m_xSize7NF->get_value_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_7::set(
+ static_cast<sal_uInt16>(m_xSize7NF->get_value()), xChanges);
+
+ if(m_xNumbersEnglishUSCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::NumbersEnglishUS::set(
+ m_xNumbersEnglishUSCB->get_active(), xChanges);
+
+ if(m_xUnknownTagCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::UnknownTag::set(
+ m_xUnknownTagCB->get_active(), xChanges);
+
+ if(m_xIgnoreFontNamesCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Import::FontSetting::set(
+ m_xIgnoreFontNamesCB->get_active(), xChanges);
+
+ if(m_xStarBasicCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::Basic::set(
+ m_xStarBasicCB->get_active(), xChanges);
+
+ if(m_xStarBasicWarningCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::Warning::set(
+ m_xStarBasicWarningCB->get_active(), xChanges);
+
+ if(m_xSaveGrfLocalCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::LocalGraphic::set(
+ m_xSaveGrfLocalCB->get_active(), xChanges);
+
+ if(m_xPrintExtensionCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Filter::HTML::Export::PrintLayout::set(
+ m_xPrintExtensionCB->get_active(), xChanges);
+
+ xChanges->commit();
+ return false;
+}
+
+void OfaHtmlTabPage::Reset( const SfxItemSet* )
+{
+ m_xSize1NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_1::get());
+ m_xSize2NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_2::get());
+ m_xSize3NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_3::get());
+ m_xSize4NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_4::get());
+ m_xSize5NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_5::get());
+ m_xSize6NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_6::get());
+ m_xSize7NF->set_value(officecfg::Office::Common::Filter::HTML::Import::FontSize::Size_7::get());
+ m_xNumbersEnglishUSCB->set_active(officecfg::Office::Common::Filter::HTML::Import::NumbersEnglishUS::get());
+ m_xUnknownTagCB->set_active(officecfg::Office::Common::Filter::HTML::Import::UnknownTag::get());
+ m_xIgnoreFontNamesCB->set_active(officecfg::Office::Common::Filter::HTML::Import::FontSetting::get());
+
+ m_xStarBasicCB->set_active(officecfg::Office::Common::Filter::HTML::Export::Basic::get());
+ m_xStarBasicWarningCB->set_active(officecfg::Office::Common::Filter::HTML::Export::Warning::get());
+ m_xStarBasicWarningCB->set_sensitive(!m_xStarBasicCB->get_active());
+ m_xSaveGrfLocalCB->set_active(officecfg::Office::Common::Filter::HTML::Export::LocalGraphic::get());
+ m_xPrintExtensionCB->set_active(SvxHtmlOptions::IsPrintLayoutExtension());
+
+ m_xPrintExtensionCB->save_state();
+ m_xStarBasicCB->save_state();
+ m_xStarBasicWarningCB->save_state();
+ m_xSaveGrfLocalCB->save_state();
+ m_xSize1NF->save_value();
+ m_xSize2NF->save_value();
+ m_xSize3NF->save_value();
+ m_xSize4NF->save_value();
+ m_xSize5NF->save_value();
+ m_xSize6NF->save_value();
+ m_xSize7NF->save_value();
+ m_xNumbersEnglishUSCB->save_state();
+ m_xUnknownTagCB->save_state();
+ m_xIgnoreFontNamesCB->save_state();
+}
+
+IMPL_LINK(OfaHtmlTabPage, CheckBoxHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ m_xStarBasicWarningCB->set_sensitive(!rBox.get_active());
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/opthtml.hxx b/cui/source/options/opthtml.hxx
new file mode 100644
index 000000000..33bff167b
--- /dev/null
+++ b/cui/source/options/opthtml.hxx
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <svx/txencbox.hxx>
+
+class OfaHtmlTabPage : public SfxTabPage
+{
+
+ std::unique_ptr<weld::SpinButton> m_xSize1NF;
+ std::unique_ptr<weld::SpinButton> m_xSize2NF;
+ std::unique_ptr<weld::SpinButton> m_xSize3NF;
+ std::unique_ptr<weld::SpinButton> m_xSize4NF;
+ std::unique_ptr<weld::SpinButton> m_xSize5NF;
+ std::unique_ptr<weld::SpinButton> m_xSize6NF;
+ std::unique_ptr<weld::SpinButton> m_xSize7NF;
+
+ std::unique_ptr<weld::CheckButton> m_xNumbersEnglishUSCB;
+ std::unique_ptr<weld::CheckButton> m_xUnknownTagCB;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreFontNamesCB;
+
+ std::unique_ptr<weld::CheckButton> m_xStarBasicCB;
+ std::unique_ptr<weld::CheckButton> m_xStarBasicWarningCB;
+ std::unique_ptr<weld::CheckButton> m_xPrintExtensionCB;
+ std::unique_ptr<weld::CheckButton> m_xSaveGrfLocalCB;
+
+ DECL_LINK(CheckBoxHdl_Impl, weld::Toggleable&, void);
+
+public:
+ OfaHtmlTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~OfaHtmlTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+
+};
+
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.cxx b/cui/source/options/optinet2.cxx
new file mode 100644
index 000000000..a3dd5826f
--- /dev/null
+++ b/cui/source/options/optinet2.cxx
@@ -0,0 +1,938 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <officecfg/Inet.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <vcl/svapp.hxx>
+#include <unotools/securityoptions.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include <dialmgr.hxx>
+#include "optinet2.hxx"
+#include <strings.hrc>
+
+#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
+#include <com/sun/star/task/InteractionHandler.hpp>
+
+#include <sal/types.h>
+#include <rtl/ustring.hxx>
+#include <osl/file.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XPropertyState.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include "securityoptions.hxx"
+#include "webconninfo.hxx"
+#include "certpath.hxx"
+#include "tsaurls.hxx"
+
+#include <svtools/restartdialog.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::sfx2;
+
+namespace {
+
+bool isValidPort(OUString const & value) {
+ if (!comphelper::string::isdigitAsciiString(value)) {
+ return false;
+ }
+ auto const n = value.toUInt64();
+ if (n > 65535) {
+ return false;
+ }
+ if (n != 0) {
+ return true;
+ }
+ // Overflow in OUString::toUInt64 returns 0, so need to check value contains only zeroes:
+ return std::u16string_view(value).find_first_not_of(u'0') == std::u16string_view::npos;
+}
+
+}
+
+IMPL_LINK(SvxProxyTabPage, PortChangedHdl, weld::Entry&, rEdit, void)
+{
+ if (!isValidPort(rEdit.get_text()))
+ {
+ std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_OPT_PROXYPORTS)));
+ xErrorBox->run();
+ }
+}
+
+constexpr OUStringLiteral g_aProxyModePN = u"ooInetProxyType";
+constexpr OUStringLiteral g_aHttpProxyPN = u"ooInetHTTPProxyName";
+constexpr OUStringLiteral g_aHttpPortPN = u"ooInetHTTPProxyPort";
+constexpr OUStringLiteral g_aHttpsProxyPN = u"ooInetHTTPSProxyName";
+constexpr OUStringLiteral g_aHttpsPortPN = u"ooInetHTTPSProxyPort";
+constexpr OUStringLiteral g_aFtpProxyPN = u"ooInetFTPProxyName";
+constexpr OUStringLiteral g_aFtpPortPN = u"ooInetFTPProxyPort";
+constexpr OUStringLiteral g_aNoProxyDescPN = u"ooInetNoProxy";
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, rTest, bool)
+{
+ OUStringBuffer sAllowed;
+ for (sal_Int32 i = 0, nLen = rTest.getLength(); i < nLen; ++i)
+ {
+ if (rTest[i] >= '0' && rTest[i] <= '9')
+ sAllowed.append(rTest[i]);
+ }
+ rTest = sAllowed.makeStringAndClear();
+ return true;
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, rTest, bool)
+{
+ rTest = rTest.replaceAll(" ", "");
+ return true;
+}
+
+/********************************************************************/
+/* */
+/* SvxProxyTabPage */
+/* */
+/********************************************************************/
+SvxProxyTabPage::SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optproxypage.ui", "OptProxyPage", &rSet)
+ , m_xProxyModeLB(m_xBuilder->weld_combo_box("proxymode"))
+ , m_xHttpProxyFT(m_xBuilder->weld_label("httpft"))
+ , m_xHttpProxyED(m_xBuilder->weld_entry("http"))
+ , m_xHttpPortFT(m_xBuilder->weld_label("httpportft"))
+ , m_xHttpPortED(m_xBuilder->weld_entry("httpport"))
+ , m_xHttpsProxyFT(m_xBuilder->weld_label("httpsft"))
+ , m_xHttpsProxyED(m_xBuilder->weld_entry("https"))
+ , m_xHttpsPortFT(m_xBuilder->weld_label("httpsportft"))
+ , m_xHttpsPortED(m_xBuilder->weld_entry("httpsport"))
+ , m_xFtpProxyFT(m_xBuilder->weld_label("ftpft"))
+ , m_xFtpProxyED(m_xBuilder->weld_entry("ftp"))
+ , m_xFtpPortFT(m_xBuilder->weld_label("ftpportft"))
+ , m_xFtpPortED(m_xBuilder->weld_entry("ftpport"))
+ , m_xNoProxyForFT(m_xBuilder->weld_label("noproxyft"))
+ , m_xNoProxyForED(m_xBuilder->weld_entry("noproxy"))
+ , m_xNoProxyDescFT(m_xBuilder->weld_label("noproxydesc"))
+{
+ m_xHttpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xHttpsProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xHttpsPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xHttpsPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+ m_xFtpProxyED->connect_insert_text(LINK(this, SvxProxyTabPage, NoSpaceTextFilterHdl));
+ m_xFtpPortED->connect_insert_text(LINK(this, SvxProxyTabPage, NumberOnlyTextFilterHdl));
+ m_xFtpPortED->connect_changed(LINK(this, SvxProxyTabPage, PortChangedHdl));
+
+ Link<weld::Widget&,void> aLink = LINK( this, SvxProxyTabPage, LoseFocusHdl_Impl );
+ m_xHttpPortED->connect_focus_out( aLink );
+ m_xHttpsPortED->connect_focus_out( aLink );
+ m_xFtpPortED->connect_focus_out( aLink );
+
+ m_xProxyModeLB->connect_changed(LINK( this, SvxProxyTabPage, ProxyHdl_Impl ));
+
+ Reference< css::lang::XMultiServiceFactory >
+ xConfigurationProvider(
+ configuration::theDefaultProvider::get(
+ comphelper::getProcessComponentContext() ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString( "org.openoffice.Inet/Settings" );
+
+ Sequence< Any > aArgumentList{ Any(aProperty) };
+
+ m_xConfigurationUpdateAccess = xConfigurationProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationUpdateAccess",
+ aArgumentList );
+}
+
+SvxProxyTabPage::~SvxProxyTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxProxyTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxProxyTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxProxyTabPage::ReadConfigData_Impl()
+{
+ sal_Int32 nIntValue = 0;
+
+ std::optional<sal_Int32> x(officecfg::Inet::Settings::ooInetProxyType::get());
+ if (x)
+ {
+ nIntValue = *x;
+ m_xProxyModeLB->set_active(nIntValue);
+ }
+
+ m_xHttpProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xHttpPortED->set_text( "" );
+
+ m_xHttpsProxyED->set_text( officecfg::Inet::Settings::ooInetHTTPSProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetHTTPSProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xHttpsPortED->set_text( "" );
+
+ m_xFtpProxyED->set_text( officecfg::Inet::Settings::ooInetFTPProxyName::get() );
+ x = officecfg::Inet::Settings::ooInetFTPProxyPort::get();
+ if (x)
+ {
+ nIntValue = *x;
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+ else
+ m_xFtpPortED->set_text( "" );
+
+ m_xNoProxyForED->set_text( officecfg::Inet::Settings::ooInetNoProxy::get() );
+}
+
+void SvxProxyTabPage::ReadConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ sal_Int32 nIntValue = 0;
+ OUString aStringValue;
+
+ if( xPropertyState->getPropertyDefault(g_aHttpProxyPN) >>= aStringValue )
+ {
+ m_xHttpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpPortPN) >>= nIntValue )
+ {
+ m_xHttpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsProxyPN) >>= aStringValue )
+ {
+ m_xHttpsProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aHttpsPortPN) >>= nIntValue )
+ {
+ m_xHttpsPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpProxyPN) >>= aStringValue )
+ {
+ m_xFtpProxyED->set_text( aStringValue );
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aFtpPortPN) >>= nIntValue )
+ {
+ m_xFtpPortED->set_text( OUString::number( nIntValue ));
+ }
+
+ if( xPropertyState->getPropertyDefault(g_aNoProxyDescPN) >>= aStringValue )
+ {
+ m_xNoProxyForED->set_text( aStringValue );
+ }
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+}
+
+void SvxProxyTabPage::RestoreConfigDefaults_Impl()
+{
+ try
+ {
+ Reference< beans::XPropertyState > xPropertyState(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+
+ xPropertyState->setPropertyToDefault(g_aProxyModePN);
+ xPropertyState->setPropertyToDefault(g_aHttpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpPortPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsProxyPN);
+ xPropertyState->setPropertyToDefault(g_aHttpsPortPN);
+ xPropertyState->setPropertyToDefault(g_aFtpProxyPN);
+ xPropertyState->setPropertyToDefault(g_aFtpPortPN);
+ xPropertyState->setPropertyToDefault(g_aNoProxyDescPN);
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const beans::UnknownPropertyException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+}
+
+void SvxProxyTabPage::Reset(const SfxItemSet*)
+{
+ ReadConfigData_Impl();
+
+ m_xProxyModeLB->save_value();
+ m_xHttpProxyED->save_value();
+ m_xHttpPortED->save_value();
+ m_xHttpsProxyED->save_value();
+ m_xHttpsPortED->save_value();
+ m_xFtpProxyED->save_value();
+ m_xFtpPortED->save_value();
+ m_xNoProxyForED->save_value();
+
+ EnableControls_Impl();
+}
+
+bool SvxProxyTabPage::FillItemSet(SfxItemSet* )
+{
+ bool bModified = false;
+
+ try {
+ Reference< beans::XPropertySet > xPropertySet(m_xConfigurationUpdateAccess, UNO_QUERY_THROW );
+
+ sal_Int32 nSelPos = m_xProxyModeLB->get_active();
+ if(m_xProxyModeLB->get_value_changed_from_saved())
+ {
+ if( nSelPos == 1 )
+ {
+ RestoreConfigDefaults_Impl();
+ return true;
+ }
+
+ xPropertySet->setPropertyValue(g_aProxyModePN, Any(nSelPos));
+ bModified = true;
+ }
+
+ if(m_xHttpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpProxyPN, Any(m_xHttpProxyED->get_text()));
+ bModified = true;
+ }
+
+ if ( m_xHttpPortED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aHttpPortPN, Any(m_xHttpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if( m_xHttpsProxyED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsProxyPN, Any(m_xHttpsProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xHttpsPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aHttpsPortPN, Any(m_xHttpsPortED->get_text().toInt32()) );
+ bModified = true;
+ }
+
+ if( m_xFtpProxyED->get_value_changed_from_saved())
+ {
+ xPropertySet->setPropertyValue( g_aFtpProxyPN, Any(m_xFtpProxyED->get_text()) );
+ bModified = true;
+ }
+
+ if ( m_xFtpPortED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aFtpPortPN, Any(m_xFtpPortED->get_text().toInt32()));
+ bModified = true;
+ }
+
+ if ( m_xNoProxyForED->get_value_changed_from_saved() )
+ {
+ xPropertySet->setPropertyValue( g_aNoProxyDescPN, Any( m_xNoProxyForED->get_text()));
+ bModified = true;
+ }
+
+ Reference< util::XChangesBatch > xChangesBatch(m_xConfigurationUpdateAccess, UNO_QUERY_THROW);
+ xChangesBatch->commitChanges();
+ }
+ catch (const css::lang::IllegalArgumentException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const beans::UnknownPropertyException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const beans::PropertyVetoException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const css::lang::WrappedTargetException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+ catch (const RuntimeException &) {
+ TOOLS_WARN_EXCEPTION("cui.options", "" );
+ }
+
+ return bModified;
+}
+
+void SvxProxyTabPage::EnableControls_Impl()
+{
+ m_xProxyModeLB->set_sensitive(!officecfg::Inet::Settings::ooInetNoProxy::isReadOnly());
+
+ const bool bManualConfig = m_xProxyModeLB->get_active() == 2;
+
+ const bool bHTTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyName::isReadOnly();
+ const bool bHTTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPProxyPort::isReadOnly();
+ m_xHttpProxyFT->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpProxyED->set_sensitive(bHTTPProxyNameEnabled);
+ m_xHttpPortFT->set_sensitive(bHTTPProxyPortEnabled);
+ m_xHttpPortED->set_sensitive(bHTTPProxyPortEnabled);
+
+ const bool bHTTPSProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyName::isReadOnly();
+ const bool bHTTPSProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetHTTPSProxyPort::isReadOnly();
+ m_xHttpsProxyFT->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsProxyED->set_sensitive(bHTTPSProxyNameEnabled);
+ m_xHttpsPortFT->set_sensitive(bHTTPSProxyPortEnabled);
+ m_xHttpsPortED->set_sensitive(bHTTPSProxyPortEnabled);
+
+ const bool bFTPProxyNameEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyName::isReadOnly();
+ const bool bFTPProxyPortEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetFTPProxyPort::isReadOnly();
+ m_xFtpProxyFT->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpProxyED->set_sensitive(bFTPProxyNameEnabled);
+ m_xFtpPortFT->set_sensitive(bFTPProxyPortEnabled);
+ m_xFtpPortED->set_sensitive(bFTPProxyPortEnabled);
+
+ const bool bInetNoProxyEnabled = bManualConfig && !officecfg::Inet::Settings::ooInetNoProxy::isReadOnly();
+ m_xNoProxyForFT->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyForED->set_sensitive(bInetNoProxyEnabled);
+ m_xNoProxyDescFT->set_sensitive(bInetNoProxyEnabled);
+}
+
+IMPL_LINK(SvxProxyTabPage, ProxyHdl_Impl, weld::ComboBox&, rBox, void)
+{
+ sal_Int32 nPos = rBox.get_active();
+
+ // Restore original system values
+ if( nPos == 1 )
+ {
+ ReadConfigDefaults_Impl();
+ }
+
+ EnableControls_Impl();
+}
+
+IMPL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, rControl, void)
+{
+ weld::Entry* pEdit = dynamic_cast<weld::Entry*>(&rControl);
+ if (pEdit && !isValidPort(pEdit->get_text()))
+ pEdit->set_text(OUString('0'));
+}
+
+/********************************************************************/
+/* */
+/* SvxSecurityTabPage */
+/* */
+/********************************************************************/
+SvxSecurityTabPage::SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optsecuritypage.ui", "OptSecurityPage", &rSet)
+ , m_xSecurityOptionsPB(m_xBuilder->weld_button("options"))
+ , m_xSavePasswordsCB(m_xBuilder->weld_check_button("savepassword"))
+ , m_xShowConnectionsPB(m_xBuilder->weld_button("connections"))
+ , m_xMasterPasswordCB(m_xBuilder->weld_check_button("usemasterpassword"))
+ , m_xMasterPasswordFT(m_xBuilder->weld_label("masterpasswordtext"))
+ , m_xMasterPasswordPB(m_xBuilder->weld_button("masterpassword"))
+ , m_xMacroSecFrame(m_xBuilder->weld_container("macrosecurity"))
+ , m_xMacroSecPB(m_xBuilder->weld_button("macro"))
+ , m_xCertFrame(m_xBuilder->weld_container("certificatepath"))
+ , m_xCertPathPB(m_xBuilder->weld_button("cert"))
+ , m_xTSAURLsFrame(m_xBuilder->weld_container("tsaurls"))
+ , m_xTSAURLsPB(m_xBuilder->weld_button("tsas"))
+ , m_xNoPasswordSaveFT(m_xBuilder->weld_label("nopasswordsave"))
+{
+ //fdo#65595, we need height-for-width support here, but for now we can
+ //bodge it
+ Size aPrefSize(m_xSavePasswordsCB->get_preferred_size());
+ int nMaxWidth = m_xSavePasswordsCB->get_approximate_digit_width() * 40;
+ if (aPrefSize.Width() > nMaxWidth)
+ {
+ m_xSavePasswordsCB->set_label_wrap(true);
+ m_xSavePasswordsCB->set_size_request(nMaxWidth, -1);
+ }
+
+ m_sPasswordStoringDeactivateStr = m_xNoPasswordSaveFT->get_label();
+
+ InitControls();
+
+ m_xSecurityOptionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, SecurityOptionsHdl ) );
+ m_xSavePasswordsCB->connect_toggled( LINK( this, SvxSecurityTabPage, SavePasswordHdl ) );
+ m_xMasterPasswordPB->connect_clicked( LINK( this, SvxSecurityTabPage, MasterPasswordHdl ) );
+ m_xMasterPasswordCB->connect_toggled( LINK( this, SvxSecurityTabPage, MasterPasswordCBHdl ) );
+ m_xShowConnectionsPB->connect_clicked( LINK( this, SvxSecurityTabPage, ShowPasswordsHdl ) );
+ m_xMacroSecPB->connect_clicked( LINK( this, SvxSecurityTabPage, MacroSecPBHdl ) );
+ m_xCertPathPB->connect_clicked( LINK( this, SvxSecurityTabPage, CertPathPBHdl ) );
+ m_xTSAURLsPB->connect_clicked( LINK( this, SvxSecurityTabPage, TSAURLsPBHdl ) );
+
+ ActivatePage( rSet );
+}
+
+SvxSecurityTabPage::~SvxSecurityTabPage()
+{
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SecurityOptionsHdl, weld::Button&, void)
+{
+ if (!m_xSecOptDlg)
+ m_xSecOptDlg.reset(new svx::SecurityOptionsDialog(GetFrameWeld()));
+ m_xSecOptDlg->run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, SavePasswordHdl, weld::Toggleable&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( m_xSavePasswordsCB->get_active() )
+ {
+ bool bOldValue = xMasterPasswd->allowPersistentStoring( true );
+ xMasterPasswd->removeMasterPassword();
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->changeMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ else
+ {
+ xMasterPasswd->allowPersistentStoring( bOldValue );
+ m_xSavePasswordsCB->set_active( false );
+ }
+ }
+ else
+ {
+ std::unique_ptr<weld::MessageDialog> xQueryBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Question, VclButtonsType::YesNo,
+ m_sPasswordStoringDeactivateStr));
+ xQueryBox->set_default_response(RET_NO);
+
+ sal_uInt16 nRet = xQueryBox->run();
+
+ if( RET_YES == nRet )
+ {
+ xMasterPasswd->allowPersistentStoring( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+ }
+ else
+ {
+ m_xSavePasswordsCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+ xMasterPasswd->changeMasterPassword(xTmpHandler);
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MasterPasswordCBHdl, weld::Toggleable&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( m_xMasterPasswordCB->get_active() )
+ {
+ if (xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->changeMasterPassword(xTmpHandler))
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active( false );
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ else
+ {
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->useDefaultMasterPassword(xTmpHandler) )
+ {
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordFT->set_sensitive( false );
+ }
+ else
+ {
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_active( !m_xSavePasswordsCB->get_active() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, ShowPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ uno::Reference<task::XInteractionHandler> xTmpHandler(task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(),
+ GetDialogController()->getDialog()->GetXWindow()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() && xMasterPasswd->authorizateWithMasterPassword(xTmpHandler) )
+ {
+ svx::WebConnectionInfoDialog aDlg(GetFrameWeld());
+ aDlg.run();
+ }
+ }
+ catch (const Exception&)
+ {}
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, CertPathPBHdl, weld::Button&, void)
+{
+ if (!mpCertPathDlg)
+ mpCertPathDlg.reset(new CertPathDialog(GetFrameWeld()));
+ mpCertPathDlg->Init();
+
+ if (mpCertPathDlg->run() == RET_OK && !mpCertPathDlg->isActiveServicePath())
+ {
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr, svtools::RESTART_REASON_ADDING_PATH))
+ GetDialogController()->response(RET_OK);
+ }
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, TSAURLsPBHdl, weld::Button&, void)
+{
+ // Unlike the mpCertPathDlg, we *don't* keep the same dialog object around between
+ // invocations. Seems clearer to my little brain that way.
+ TSAURLsDialog aTSAURLsDlg(GetFrameWeld());
+ aTSAURLsDlg.run();
+}
+
+IMPL_LINK_NOARG(SvxSecurityTabPage, MacroSecPBHdl, weld::Button&, void)
+{
+ try
+ {
+ Reference< security::XDocumentDigitalSignatures > xD(
+ security::DocumentDigitalSignatures::createDefault(comphelper::getProcessComponentContext() ) );
+ xD->setParentWindow(GetDialogController()->getDialog()->GetXWindow());
+ xD->manageTrustedSources();
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "");
+ }
+}
+
+void SvxSecurityTabPage::InitControls()
+{
+#ifndef UNX
+ m_xCertFrame->hide();
+#endif
+
+ m_xMasterPasswordPB->set_sensitive( false );
+ m_xMasterPasswordCB->set_sensitive( false );
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive( false );
+ m_xShowConnectionsPB->set_sensitive( false );
+
+ // initialize the password saving checkbox
+ try
+ {
+ Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ m_xMasterPasswordCB->set_sensitive(true);
+ m_xShowConnectionsPB->set_sensitive(true);
+ m_xSavePasswordsCB->set_active(true);
+
+ if ( xMasterPasswd->isDefaultMasterPasswordUsed() )
+ m_xMasterPasswordCB->set_active( false );
+ else
+ {
+ m_xMasterPasswordPB->set_sensitive(true);
+ m_xMasterPasswordCB->set_active(true);
+ m_xMasterPasswordFT->set_sensitive(true);
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ m_xSavePasswordsCB->set_sensitive( false );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxSecurityTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxSecurityTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSecurityTabPage::ActivatePage( const SfxItemSet& )
+{
+}
+
+DeactivateRC SvxSecurityTabPage::DeactivatePage( SfxItemSet* _pSet )
+{
+ if( _pSet )
+ FillItemSet( _pSet );
+ return DeactivateRC::LeavePage;
+}
+
+namespace
+{
+ bool CheckAndSave( SvtSecurityOptions::EOption _eOpt, const bool _bIsChecked, bool& _rModified )
+ {
+ bool bModified = false;
+ if ( !SvtSecurityOptions::IsReadOnly( _eOpt ) )
+ {
+ bModified = SvtSecurityOptions::IsOptionSet( _eOpt ) != _bIsChecked;
+ if ( bModified )
+ {
+ SvtSecurityOptions::SetOption( _eOpt, _bIsChecked );
+ _rModified = true;
+ }
+ }
+
+ return bModified;
+ }
+}
+
+bool SvxSecurityTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ if (m_xSecOptDlg)
+ {
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnSaveOrSend, m_xSecOptDlg->IsSaveOrSendDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnSigning, m_xSecOptDlg->IsSignDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnPrint, m_xSecOptDlg->IsPrintDocsChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnCreatePdf, m_xSecOptDlg->IsCreatePdfChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, m_xSecOptDlg->IsRemovePersInfoChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::DocWarnRecommendPassword, m_xSecOptDlg->IsRecommPasswdChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::CtrlClickHyperlink, m_xSecOptDlg->IsCtrlHyperlinkChecked(), bModified );
+ CheckAndSave( SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, m_xSecOptDlg->IsBlockUntrustedRefererLinksChecked(), bModified );
+ }
+
+ return bModified;
+}
+
+/*--------------------------------------------------------------------*/
+
+void SvxSecurityTabPage::Reset( const SfxItemSet* )
+{
+}
+
+struct SvxEMailTabPage_Impl
+{
+ SvxEMailTabPage_Impl():
+ sProgram(officecfg::Office::Common::ExternalMailer::Program::get()),
+ bROProgram(
+ officecfg::Office::Common::ExternalMailer::Program::isReadOnly()),
+ bHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::get()),
+ bROHideContent(
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::isReadOnly())
+ {}
+
+ OUString sProgram;
+ bool bROProgram;
+ bool bHideContent;
+ bool bROHideContent;
+};
+
+SvxEMailTabPage::SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optemailpage.ui", "OptEmailPage", &rSet)
+ , pImpl(new SvxEMailTabPage_Impl)
+ , m_xMailContainer(m_xBuilder->weld_container("program"))
+ , m_xMailerURLFI(m_xBuilder->weld_image("lockemail"))
+ , m_xMailerURLED(m_xBuilder->weld_entry("url"))
+ , m_xMailerURLPB(m_xBuilder->weld_button("browse"))
+ , m_xSuppressHiddenContainer(m_xBuilder->weld_container("suppressHiddenCont"))
+ , m_xSuppressHiddenFI(m_xBuilder->weld_image("lockSuppressHidden"))
+ , m_xSuppressHidden(m_xBuilder->weld_check_button("suppressHidden"))
+ , m_xDefaultFilterFT(m_xBuilder->weld_label("browsetitle"))
+{
+ m_sDefaultFilterName = m_xDefaultFilterFT->get_label();
+ m_xMailerURLPB->connect_clicked( LINK( this, SvxEMailTabPage, FileDialogHdl_Impl ) );
+}
+
+/* -------------------------------------------------------------------------*/
+
+SvxEMailTabPage::~SvxEMailTabPage()
+{
+}
+
+/* -------------------------------------------------------------------------*/
+
+std::unique_ptr<SfxTabPage> SvxEMailTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxEMailTabPage>(pPage, pController, *rAttrSet);
+}
+
+/* -------------------------------------------------------------------------*/
+
+bool SvxEMailTabPage::FillItemSet( SfxItemSet* )
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (!pImpl->bROProgram && m_xMailerURLED->get_value_changed_from_saved())
+ {
+ pImpl->sProgram = m_xMailerURLED->get_text();
+ officecfg::Office::Common::ExternalMailer::Program::set(
+ pImpl->sProgram, batch);
+ }
+ if (!pImpl->bROHideContent
+ && pImpl->bHideContent != m_xSuppressHidden->get_active())
+ {
+ pImpl->bHideContent = m_xSuppressHidden->get_active();
+ officecfg::Office::Security::HiddenContent::RemoveHiddenContent::set(
+ pImpl->bHideContent, batch);
+ }
+ batch->commit();
+ return false;
+}
+
+/* -------------------------------------------------------------------------*/
+
+void SvxEMailTabPage::Reset( const SfxItemSet* )
+{
+ m_xMailerURLED->set_sensitive(true);
+ m_xMailerURLPB->set_sensitive(true);
+
+ if (pImpl->bROProgram)
+ m_xMailerURLFI->show();
+
+ m_xMailerURLED->set_text(pImpl->sProgram);
+ m_xMailerURLED->save_value();
+
+ m_xMailContainer->set_sensitive(!pImpl->bROProgram);
+
+ if (pImpl->bROHideContent)
+ m_xSuppressHiddenFI->show();
+
+ m_xSuppressHidden->set_active(pImpl->bHideContent);
+
+ m_xSuppressHiddenContainer->set_sensitive(!pImpl->bROHideContent);
+}
+
+/* -------------------------------------------------------------------------*/
+
+IMPL_LINK_NOARG(SvxEMailTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ if (pImpl->bROProgram)
+ return;
+
+ FileDialogHelper aHelper(css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ OUString sPath = m_xMailerURLED->get_text();
+ if ( sPath.isEmpty() )
+ sPath = "/usr/bin";
+
+ OUString sUrl;
+ osl::FileBase::getFileURLFromSystemPath(sPath, sUrl);
+ aHelper.SetDisplayDirectory(sUrl);
+ aHelper.AddFilter( m_sDefaultFilterName, "*");
+
+ if ( ERRCODE_NONE == aHelper.Execute() )
+ {
+ sUrl = aHelper.GetPath();
+ if (osl::FileBase::getSystemPathFromFileURL(sUrl, sPath)
+ != osl::FileBase::E_None)
+ {
+ sPath.clear();
+ }
+ m_xMailerURLED->set_text(sPath);
+ }
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optinet2.hxx b/cui/source/options/optinet2.hxx
new file mode 100644
index 000000000..4d03d2d04
--- /dev/null
+++ b/cui/source/options/optinet2.hxx
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+namespace svx {
+ class SecurityOptionsDialog;
+}
+
+// class SvxProxyTabPage -------------------------------------------------
+class SvxProxyTabPage : public SfxTabPage
+{
+private:
+
+ std::unique_ptr<weld::ComboBox> m_xProxyModeLB;
+
+ std::unique_ptr<weld::Label> m_xHttpProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpProxyED;
+ std::unique_ptr<weld::Label> m_xHttpPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpPortED;
+
+ std::unique_ptr<weld::Label> m_xHttpsProxyFT;
+ std::unique_ptr<weld::Entry> m_xHttpsProxyED;
+ std::unique_ptr<weld::Label> m_xHttpsPortFT;
+ std::unique_ptr<weld::Entry> m_xHttpsPortED;
+
+ std::unique_ptr<weld::Label> m_xFtpProxyFT;
+ std::unique_ptr<weld::Entry> m_xFtpProxyED;
+ std::unique_ptr<weld::Label> m_xFtpPortFT;
+ std::unique_ptr<weld::Entry> m_xFtpPortED;
+
+ std::unique_ptr<weld::Label> m_xNoProxyForFT;
+ std::unique_ptr<weld::Entry> m_xNoProxyForED;
+ std::unique_ptr<weld::Label> m_xNoProxyDescFT;
+
+ css::uno::Reference< css::uno::XInterface > m_xConfigurationUpdateAccess;
+
+ void EnableControls_Impl();
+ void ReadConfigData_Impl();
+ void ReadConfigDefaults_Impl();
+ void RestoreConfigDefaults_Impl();
+
+ DECL_LINK(PortChangedHdl, weld::Entry&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, NumberOnlyTextFilterHdl, OUString&, bool);
+ DECL_STATIC_LINK(SvxProxyTabPage, NoSpaceTextFilterHdl, OUString&, bool);
+ DECL_LINK(ProxyHdl_Impl, weld::ComboBox&, void);
+ DECL_STATIC_LINK(SvxProxyTabPage, LoseFocusHdl_Impl, weld::Widget&, void);
+
+public:
+ SvxProxyTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxProxyTabPage() override;
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+// class SvxSecurityTabPage ---------------------------------------------
+
+class CertPathDialog;
+class SvxSecurityTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<svx::SecurityOptionsDialog> m_xSecOptDlg;
+
+ std::unique_ptr<CertPathDialog> mpCertPathDlg;
+
+ OUString m_sPasswordStoringDeactivateStr;
+
+ std::unique_ptr<weld::Button> m_xSecurityOptionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xSavePasswordsCB;
+ std::unique_ptr<weld::Button> m_xShowConnectionsPB;
+
+ std::unique_ptr<weld::CheckButton> m_xMasterPasswordCB;
+ std::unique_ptr<weld::Label> m_xMasterPasswordFT;
+ std::unique_ptr<weld::Button> m_xMasterPasswordPB;
+
+ std::unique_ptr<weld::Container> m_xMacroSecFrame;
+ std::unique_ptr<weld::Button> m_xMacroSecPB;
+
+ std::unique_ptr<weld::Container> m_xCertFrame;
+ std::unique_ptr<weld::Button> m_xCertPathPB;
+
+ std::unique_ptr<weld::Container> m_xTSAURLsFrame;
+ std::unique_ptr<weld::Button> m_xTSAURLsPB;
+
+ std::unique_ptr<weld::Label> m_xNoPasswordSaveFT;
+
+ DECL_LINK(SecurityOptionsHdl, weld::Button&, void);
+ DECL_LINK(SavePasswordHdl, weld::Toggleable&, void);
+ DECL_LINK(MasterPasswordHdl, weld::Button&, void);
+ DECL_LINK(MasterPasswordCBHdl, weld::Toggleable&, void);
+ DECL_LINK(ShowPasswordsHdl, weld::Button&, void);
+ DECL_LINK(MacroSecPBHdl, weld::Button&, void );
+ DECL_LINK(CertPathPBHdl, weld::Button&, void );
+ DECL_LINK(TSAURLsPBHdl, weld::Button&, void );
+
+ void InitControls();
+
+protected:
+ virtual void ActivatePage( const SfxItemSet& rSet ) override;
+ virtual DeactivateRC DeactivatePage( SfxItemSet* pSet ) override;
+
+public:
+ SvxSecurityTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+ virtual ~SvxSecurityTabPage() override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+struct SvxEMailTabPage_Impl;
+class SvxEMailTabPage : public SfxTabPage
+{
+ OUString m_sDefaultFilterName;
+
+ std::unique_ptr<SvxEMailTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::Container> m_xMailContainer;
+ std::unique_ptr<weld::Image> m_xMailerURLFI;
+ std::unique_ptr<weld::Entry> m_xMailerURLED;
+ std::unique_ptr<weld::Button> m_xMailerURLPB;
+ std::unique_ptr<weld::Container> m_xSuppressHiddenContainer;
+ std::unique_ptr<weld::Image> m_xSuppressHiddenFI;
+ std::unique_ptr<weld::CheckButton> m_xSuppressHidden;
+ std::unique_ptr<weld::Label> m_xDefaultFilterFT;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+
+public:
+ SvxEMailTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet );
+ virtual ~SvxEMailTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.cxx b/cui/source/options/optjava.cxx
new file mode 100644
index 000000000..693029822
--- /dev/null
+++ b/cui/source/options/optjava.cxx
@@ -0,0 +1,960 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include <sal/config.h>
+#include <sal/log.hxx>
+
+#include <cassert>
+#include <memory>
+
+#include <config_java.h>
+
+#include "optaboutconfig.hxx"
+#include "optjava.hxx"
+#include <treeopt.hxx>
+#include <dialmgr.hxx>
+
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+
+#include <strings.hrc>
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <vcl/weld.hxx>
+#include <unotools/pathoptions.hxx>
+#include <svtools/imagemgr.hxx>
+#include <svtools/restartdialog.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/inputdlg.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#if HAVE_FEATURE_JAVA
+#include <jvmfwk/framework.hxx>
+#endif
+
+// define ----------------------------------------------------------------
+
+#define CLASSPATH_DELIMITER SAL_PATHSEPARATOR
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::uno;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+SvxJavaOptionsPage::SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optadvancedpage.ui", "OptAdvancedPage", &rSet)
+ , m_aResetIdle("cui options SvxJavaOptionsPage Reset")
+ , xDialogListener(new ::svt::DialogClosedListener())
+ , m_xJavaEnableCB(m_xBuilder->weld_check_button("javaenabled"))
+ , m_xJavaList(m_xBuilder->weld_tree_view("javas"))
+ , m_xJavaPathText(m_xBuilder->weld_label("javapath"))
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xParameterBtn(m_xBuilder->weld_button("parameters"))
+ , m_xClassPathBtn(m_xBuilder->weld_button("classpath"))
+ , m_xExpertConfigBtn(m_xBuilder->weld_button("expertconfig"))
+ , m_xExperimentalCB(m_xBuilder->weld_check_button("experimental"))
+ , m_xMacroCB(m_xBuilder->weld_check_button("macrorecording"))
+ , m_xAddDialogText(m_xBuilder->weld_label("selectruntime"))
+ , m_xJavaFrame(m_xBuilder->weld_widget("javaframe"))
+{
+ m_sInstallText = m_xJavaPathText->get_label();
+ m_sAddDialogText = m_xAddDialogText->get_label();
+
+ m_xJavaList->set_size_request(m_xJavaList->get_approximate_digit_width() * 30,
+ m_xJavaList->get_height_rows(8));
+
+ m_xJavaList->enable_toggle_buttons(weld::ColumnToggleType::Radio);
+ m_xJavaList->connect_toggled( LINK( this, SvxJavaOptionsPage, CheckHdl_Impl ) );
+ m_xJavaList->connect_changed( LINK( this, SvxJavaOptionsPage, SelectHdl_Impl ) );
+
+ std::vector<int> aWidths
+ {
+ m_xJavaList->get_checkbox_column_width(),
+ o3tl::narrowing<int>(m_xJavaList->get_pixel_size("Sun Microsystems Inc.").Width())
+ };
+ m_xJavaList->set_column_fixed_widths(aWidths);
+
+ m_xJavaEnableCB->connect_toggled( LINK( this, SvxJavaOptionsPage, EnableHdl_Impl ) );
+ m_xAddBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, AddHdl_Impl ) );
+ m_xParameterBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ParameterHdl_Impl ) );
+ m_xClassPathBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ClassPathHdl_Impl ) );
+ m_aResetIdle.SetInvokeHandler( LINK( this, SvxJavaOptionsPage, ResetHdl_Impl ) );
+
+ m_xExpertConfigBtn->connect_clicked( LINK( this, SvxJavaOptionsPage, ExpertConfigHdl_Impl) );
+ if (!officecfg::Office::Common::Security::EnableExpertConfiguration::get())
+ m_xExpertConfigBtn->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::MacroRecorderMode::isReadOnly())
+ m_xMacroCB->set_sensitive(false);
+
+ if (officecfg::Office::Common::Misc::ExperimentalMode::isReadOnly())
+ m_xExperimentalCB->set_sensitive(false);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxJavaOptionsPage, DialogClosedHdl ) );
+
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#if HAVE_FEATURE_JAVA
+ jfw_lock();
+#else
+ m_xJavaFrame->set_sensitive(false);
+#endif
+}
+
+SvxJavaOptionsPage::~SvxJavaOptionsPage()
+{
+ ClearJavaInfo();
+#if HAVE_FEATURE_JAVA
+ m_aAddedInfos.clear();
+
+ jfw_unlock();
+#endif
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, EnableHdl_Impl, weld::Toggleable&, void)
+{
+ bool bEnable = m_xJavaFrame->get_sensitive() && m_xJavaEnableCB->get_active();
+ m_xJavaList->set_sensitive(bEnable);
+}
+
+IMPL_LINK(SvxJavaOptionsPage, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ HandleCheckEntry(m_xJavaList->get_iter_index_in_parent(rRowCol.first));
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, SelectHdl_Impl, weld::TreeView&, void)
+{
+ UpdateJavaPathText();
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, AddHdl_Impl, weld::Button&, void)
+{
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ OUString sWorkFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sWorkFolder );
+ xFolderPicker->setDescription( m_sAddDialogText );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::AddHdl_Impl()");
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ParameterHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ std::vector< OUString > aParameterList;
+ if (!m_xParamDlg)
+ {
+ m_xParamDlg.reset(new SvxJavaParameterDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getVMParameters( &m_parParameters );
+ if ( JFW_E_NONE == eErr && !m_parParameters.empty() )
+ {
+ aParameterList = m_parParameters;
+ m_xParamDlg->SetParameters( aParameterList );
+ }
+ }
+ else
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ m_xParamDlg->DisableButtons(); //disable add, edit and remove button when dialog is reopened
+ }
+
+ if (m_xParamDlg->run() == RET_OK)
+ {
+ if ( aParameterList != m_xParamDlg->GetParameters() )
+ {
+ aParameterList = m_xParamDlg->GetParameters();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_JAVAPARAMETERS );
+ }
+ }
+ }
+ else
+ m_xParamDlg->SetParameters( aParameterList );
+#else
+ (void) this; // Silence loplugin:staticmethods
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ClassPathHdl_Impl, weld::Button&, void)
+{
+#if HAVE_FEATURE_JAVA
+ OUString sClassPath;
+
+ if ( !m_xPathDlg )
+ {
+ m_xPathDlg.reset(new SvxJavaClassPathDlg(GetFrameWeld()));
+ javaFrameworkError eErr = jfw_getUserClassPath( &m_pClassPath );
+ if ( JFW_E_NONE == eErr )
+ {
+ sClassPath = m_pClassPath;
+ m_xPathDlg->SetClassPath( sClassPath );
+ }
+ }
+ else
+ sClassPath = m_xPathDlg->GetClassPath();
+
+ m_xPathDlg->SetFocus();
+ if (m_xPathDlg->run() == RET_OK)
+ {
+
+ if (m_xPathDlg->GetClassPath() != sClassPath)
+ {
+ sClassPath = m_xPathDlg->GetClassPath();
+ if ( jfw_isVMRunning() )
+ {
+ RequestRestart( svtools::RESTART_REASON_ASSIGNING_FOLDERS );
+ }
+ }
+ }
+ else
+ m_xPathDlg->SetClassPath( sClassPath );
+#else
+ (void) this;
+#endif
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ResetHdl_Impl, Timer *, void)
+{
+ LoadJREs();
+}
+
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, StartFolderPickerHdl, void*, void)
+{
+ try
+ {
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else if ( xFolderPicker.is() && xFolderPicker->execute() == ExecutableDialogResults::OK )
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxJavaOptionsPage::StartFolderPickerHdl()" );
+ }
+}
+
+IMPL_LINK( SvxJavaOptionsPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if ( RET_OK == pEvt->DialogResult )
+ {
+ DBG_ASSERT( xFolderPicker.is(), "SvxJavaOptionsPage::DialogClosedHdl(): no folder picker" );
+
+ AddFolder( xFolderPicker->getDirectory() );
+ }
+}
+
+IMPL_LINK_NOARG(SvxJavaOptionsPage, ExpertConfigHdl_Impl, weld::Button&, void)
+{
+ CuiAboutConfigTabPage aExpertConfigDlg(GetFrameWeld());
+ {
+ weld::WaitObject aWait(GetFrameWeld());
+ aExpertConfigDlg.Reset();//initialize and reset function
+ }
+
+ if (RET_OK == aExpertConfigDlg.run())
+ {
+ aExpertConfigDlg.FillItemSet();//save changes if there are any
+ }
+}
+
+void SvxJavaOptionsPage::ClearJavaInfo()
+{
+#if HAVE_FEATURE_JAVA
+ m_parJavaInfo.clear();
+#else
+ (void) this;
+#endif
+}
+
+void SvxJavaOptionsPage::LoadJREs()
+{
+#if HAVE_FEATURE_JAVA
+ weld::WaitObject aWaitObj(GetFrameWeld());
+ javaFrameworkError eErr = jfw_findAllJREs( &m_parJavaInfo );
+ if ( JFW_E_NONE == eErr )
+ {
+ for (auto const & pInfo: m_parJavaInfo)
+ {
+ AddJRE( pInfo.get() );
+ }
+ }
+
+ for (auto const & pInfo: m_aAddedInfos)
+ {
+ AddJRE( pInfo.get() );
+ }
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( !(JFW_E_NONE == eErr && pSelectedJava) )
+ return;
+
+ sal_Int32 i = 0;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pSelectedJava.get() ) )
+ {
+ HandleCheckEntry(i);
+ UpdateJavaPathText();
+ break;
+ }
+ ++i;
+ }
+#else
+ (void) this;
+#endif
+}
+
+
+void SvxJavaOptionsPage::AddJRE( JavaInfo const * _pInfo )
+{
+#if HAVE_FEATURE_JAVA
+ int nPos = m_xJavaList->n_children();
+ m_xJavaList->append();
+ m_xJavaList->set_toggle(nPos, TRISTATE_FALSE);
+ m_xJavaList->set_text(nPos, _pInfo->sVendor, 1);
+ m_xJavaList->set_text(nPos, _pInfo->sVersion, 2);
+
+ INetURLObject aLocObj(_pInfo->sLocation);
+ OUString sLocation = aLocObj.getFSysPath(FSysStyle::Detect);
+ m_xJavaList->set_id(nPos, sLocation);
+#else
+ (void) this;
+ (void)_pInfo;
+#endif
+}
+
+void SvxJavaOptionsPage::HandleCheckEntry(int nCheckedRow)
+{
+ m_xJavaList->select(nCheckedRow);
+ for (int i = 0, nCount = m_xJavaList->n_children(); i < nCount; ++i)
+ {
+ // we have radio button behavior -> so uncheck the other entries
+ m_xJavaList->set_toggle(i, i == nCheckedRow ? TRISTATE_TRUE : TRISTATE_FALSE);
+ }
+}
+
+void SvxJavaOptionsPage::UpdateJavaPathText()
+{
+ assert(m_xJavaList->get_selected_index() != -1);
+ // set installation directory info
+ OUString sLocation = m_xJavaList->get_selected_id();
+ // tdf#80646 insert LTR mark after label
+ OUString sInfo = m_sInstallText + u"\u200E" + sLocation;
+ m_xJavaPathText->set_label(sInfo);
+}
+
+void SvxJavaOptionsPage::AddFolder( const OUString& _rFolder )
+{
+#if HAVE_FEATURE_JAVA
+ bool bStartAgain = true;
+ std::unique_ptr<JavaInfo> pInfo;
+ javaFrameworkError eErr = jfw_getJavaInfoByPath( _rFolder, &pInfo );
+ if ( JFW_E_NONE == eErr && pInfo )
+ {
+ sal_Int32 nPos = 0;
+ bool bFound = false;
+ for (auto const & pCmpInfo: m_parJavaInfo)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+
+ if ( !bFound )
+ {
+ for (auto const & pCmpInfo: m_aAddedInfos)
+ {
+ if ( jfw_areEqualJavaInfo( pCmpInfo.get(), pInfo.get() ) )
+ {
+ bFound = true;
+ break;
+ }
+ ++nPos;
+ }
+ }
+
+ if ( !bFound )
+ {
+ jfw_addJRELocation( pInfo->sLocation );
+ AddJRE( pInfo.get() );
+ m_aAddedInfos.push_back( std::move(pInfo) );
+ nPos = m_xJavaList->n_children() - 1;
+ }
+
+ HandleCheckEntry(nPos);
+ UpdateJavaPathText();
+ bStartAgain = false;
+ }
+ else if ( JFW_E_NOT_RECOGNIZED == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_JRE_NOT_RECOGNIZED)));
+ xBox->run();
+ }
+ else if ( JFW_E_FAILED_VERSION == eErr )
+ {
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(GetFrameWeld(),
+ VclMessageType::Warning, VclButtonsType::Ok,
+ CuiResId(RID_CUISTR_JRE_FAILED_VERSION)));
+ xBox->run();
+ }
+
+ if ( bStartAgain )
+ {
+ xFolderPicker->setDisplayDirectory( _rFolder );
+ Application::PostUserEvent( LINK( this, SvxJavaOptionsPage, StartFolderPickerHdl ) );
+ }
+#else
+ (void) this;
+ (void)_rFolder;
+#endif
+}
+
+void SvxJavaOptionsPage::RequestRestart(svtools::RestartReason eReason)
+{
+ OfaTreeOptionsDialog* pParentDlg(static_cast<OfaTreeOptionsDialog*>(GetDialogController()));
+ if (pParentDlg)
+ pParentDlg->SetNeedsRestart(eReason);
+}
+
+std::unique_ptr<SfxTabPage> SvxJavaOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxJavaOptionsPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxJavaOptionsPage::FillItemSet( SfxItemSet* /*rCoreSet*/ )
+{
+ bool bModified = false;
+
+ if ( m_xExperimentalCB->get_state_changed_from_saved() )
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::ExperimentalMode::set( m_xExperimentalCB->get_active(), xChanges );
+ xChanges->commit();
+ bModified = true;
+ RequestRestart( svtools::RESTART_REASON_EXP_FEATURES );
+ }
+
+ if ( m_xMacroCB->get_state_changed_from_saved() )
+ {
+ std::shared_ptr< comphelper::ConfigurationChanges > xChanges(
+ comphelper::ConfigurationChanges::create());
+ officecfg::Office::Common::Misc::MacroRecorderMode::set( m_xMacroCB->get_active(), xChanges );
+ xChanges->commit();
+ bModified = true;
+ }
+
+#if HAVE_FEATURE_JAVA
+ javaFrameworkError eErr = JFW_E_NONE;
+ if (m_xParamDlg)
+ {
+ eErr = jfw_setVMParameters(m_xParamDlg->GetParameters());
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setVMParameters");
+ bModified = true;
+ }
+
+ if (m_xPathDlg)
+ {
+ OUString sPath(m_xPathDlg->GetClassPath());
+ if (m_xPathDlg->GetOldPath() != sPath)
+ {
+ eErr = jfw_setUserClassPath( sPath );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setUserClassPath");
+ bModified = true;
+ }
+ }
+
+ sal_uInt32 nCount = m_xJavaList->n_children();
+ for (sal_uInt32 i = 0; i < nCount; ++i)
+ {
+ if (m_xJavaList->get_toggle(i) == TRISTATE_TRUE)
+ {
+ JavaInfo const * pInfo;
+ if ( i < m_parJavaInfo.size() )
+ pInfo = m_parJavaInfo[i].get();
+ else
+ pInfo = m_aAddedInfos[ i - m_parJavaInfo.size() ].get();
+
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ if ( JFW_E_NONE == eErr || JFW_E_INVALID_SETTINGS == eErr )
+ {
+ if (!pSelectedJava || !jfw_areEqualJavaInfo( pInfo, pSelectedJava.get() ) )
+ {
+ if ( jfw_isVMRunning() ||
+ ( ( pInfo->nRequirements & JFW_REQUIRE_NEEDRESTART ) == JFW_REQUIRE_NEEDRESTART ) )
+ {
+ RequestRestart( svtools::RESTART_REASON_JAVA );
+ }
+
+ eErr = jfw_setSelectedJRE( pInfo );
+ SAL_WARN_IF(JFW_E_NONE != eErr, "cui.options", "SvxJavaOptionsPage::FillItemSet(): error in jfw_setSelectedJRE");
+ bModified = true;
+ }
+ }
+ break;
+ }
+ }
+
+ bool bEnabled = false;
+ eErr = jfw_getEnabled( &bEnabled );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_getEnabled" );
+ if ( bEnabled != m_xJavaEnableCB->get_active() )
+ {
+ eErr = jfw_setEnabled( m_xJavaEnableCB->get_active() );
+ DBG_ASSERT( JFW_E_NONE == eErr,
+ "SvxJavaOptionsPage::FillItemSet(): error in jfw_setEnabled" );
+ bModified = true;
+ }
+#endif
+
+ return bModified;
+}
+
+
+void SvxJavaOptionsPage::Reset( const SfxItemSet* /*rSet*/ )
+{
+ ClearJavaInfo();
+ m_xJavaList->clear();
+
+#if HAVE_FEATURE_JAVA
+ bool bEnabled = false;
+ javaFrameworkError eErr = jfw_getEnabled( &bEnabled );
+ if (eErr == JFW_E_DIRECT_MODE)
+ {
+ // direct mode disregards Java settings made here, so gray them out
+ m_xJavaFrame->set_sensitive(false);
+ // check whether a usable JRE was set
+ std::unique_ptr<JavaInfo> pSelectedJava;
+ eErr = jfw_getSelectedJRE( &pSelectedJava );
+ bEnabled = (eErr == JFW_E_NONE);
+ }
+ else if ( eErr != JFW_E_NONE )
+ bEnabled = false;
+ m_xJavaEnableCB->set_active(bEnabled);
+ EnableHdl_Impl(*m_xJavaEnableCB);
+#else
+ m_xJavaEnableCB->set_active(false);
+ m_xJavaEnableCB->set_sensitive(false);
+#endif
+
+ m_xExperimentalCB->set_active( officecfg::Office::Common::Misc::ExperimentalMode::get() );
+ m_xExperimentalCB->save_state();
+ m_xMacroCB->set_active( officecfg::Office::Common::Misc::MacroRecorderMode::get() );
+ m_xMacroCB->save_state();
+
+ m_aResetIdle.Start();
+}
+
+
+void SvxJavaOptionsPage::FillUserData()
+{
+ SetUserData( OUString() );
+}
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+SvxJavaParameterDlg::SvxJavaParameterDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javastartparametersdialog.ui",
+ "JavaStartParameters")
+ , m_xParameterEdit(m_xBuilder->weld_entry("parameterfield"))
+ , m_xAssignBtn(m_xBuilder->weld_button("assignbtn"))
+ , m_xAssignedList(m_xBuilder->weld_tree_view("assignlist"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("removebtn"))
+ , m_xEditBtn(m_xBuilder->weld_button("editbtn"))
+{
+ m_xAssignedList->set_size_request(m_xAssignedList->get_approximate_digit_width() * 54,
+ m_xAssignedList->get_height_rows(6));
+ m_xParameterEdit->connect_changed( LINK( this, SvxJavaParameterDlg, ModifyHdl_Impl ) );
+ m_xParameterEdit->connect_activate(LINK(this, SvxJavaParameterDlg, ActivateHdl_Impl));
+ m_xAssignBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, AssignHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, RemoveHdl_Impl ) );
+ m_xEditBtn->connect_clicked( LINK( this, SvxJavaParameterDlg, EditHdl_Impl ) );
+ m_xAssignedList->connect_changed( LINK( this, SvxJavaParameterDlg, SelectHdl_Impl ) );
+ m_xAssignedList->connect_row_activated( LINK( this, SvxJavaParameterDlg, DblClickHdl_Impl ) );
+
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+SvxJavaParameterDlg::~SvxJavaParameterDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, ModifyHdl_Impl, weld::Entry&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ m_xAssignBtn->set_sensitive(!sParam.isEmpty());
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, AssignHdl_Impl, weld::Button&, void)
+{
+ OUString sParam = comphelper::string::strip(m_xParameterEdit->get_text(), ' ');
+ if (sParam.isEmpty())
+ return;
+
+ int nPos = m_xAssignedList->find_text(sParam);
+ if (nPos == -1)
+ {
+ m_xAssignedList->append_text(sParam);
+ m_xAssignedList->select(m_xAssignedList->n_children() - 1);
+ }
+ else
+ m_xAssignedList->select(nPos);
+ m_xParameterEdit->set_text(OUString());
+ ModifyHdl_Impl(*m_xParameterEdit);
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, ActivateHdl_Impl, weld::Entry&, bool)
+{
+ if (m_xAssignBtn->get_sensitive())
+ {
+ AssignHdl_Impl(*m_xAssignBtn);
+ return true;
+ }
+ return false;
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, EditHdl_Impl, weld::Button&, void)
+{
+ EditParameter();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableEditButton();
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, DblClickHdl_Impl, weld::TreeView&, bool)
+{
+ EditParameter();
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxJavaParameterDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xAssignedList->remove(nPos);
+ int nCount = m_xAssignedList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xAssignedList->select(nPos);
+ }
+ else
+ {
+ DisableEditButton();
+ }
+ }
+ EnableRemoveButton();
+}
+
+void SvxJavaParameterDlg::EditParameter()
+{
+ int nPos = m_xAssignedList->get_selected_index();
+ m_xParameterEdit->set_text(OUString());
+
+ if (nPos == -1)
+ return;
+
+ InputDialog aParamEditDlg(m_xDialog.get(), CuiResId(RID_CUISTR_JAVA_START_PARAM));
+ OUString editableClassPath = m_xAssignedList->get_selected_text();
+ aParamEditDlg.SetEntryText(editableClassPath);
+ aParamEditDlg.HideHelpBtn();
+
+ if (!aParamEditDlg.run())
+ return;
+ OUString editedClassPath = comphelper::string::strip(aParamEditDlg.GetEntryText(), ' ');
+
+ if ( !editedClassPath.isEmpty() && editableClassPath != editedClassPath )
+ {
+ m_xAssignedList->remove(nPos);
+ m_xAssignedList->insert_text(nPos, editedClassPath);
+ m_xAssignedList->select(nPos);
+ }
+}
+
+short SvxJavaParameterDlg::run()
+{
+ m_xParameterEdit->grab_focus();
+ m_xAssignedList->select(-1);
+ return GenericDialogController::run();
+}
+
+std::vector< OUString > SvxJavaParameterDlg::GetParameters() const
+{
+ int nCount = m_xAssignedList->n_children();
+ std::vector< OUString > aParamList;
+ aParamList.reserve(nCount);
+ for (int i = 0; i < nCount; ++i)
+ aParamList.push_back(m_xAssignedList->get_text(i));
+ return aParamList;
+}
+
+void SvxJavaParameterDlg::DisableButtons()
+{
+ DisableAssignButton();
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+void SvxJavaParameterDlg::SetParameters( std::vector< OUString > const & rParams )
+{
+ m_xAssignedList->clear();
+ for (auto const & sParam: rParams)
+ {
+ m_xAssignedList->append_text(sParam);
+ }
+ DisableEditButton();
+ DisableRemoveButton();
+}
+
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+SvxJavaClassPathDlg::SvxJavaClassPathDlg(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/javaclasspathdialog.ui", "JavaClassPath")
+ , m_xPathList(m_xBuilder->weld_tree_view("paths"))
+ , m_xAddArchiveBtn(m_xBuilder->weld_button("archive"))
+ , m_xAddPathBtn(m_xBuilder->weld_button("folder"))
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+{
+ m_xPathList->set_size_request(m_xPathList->get_approximate_digit_width() * 54,
+ m_xPathList->get_height_rows(8));
+ m_xAddArchiveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddArchiveHdl_Impl ) );
+ m_xAddPathBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, AddPathHdl_Impl ) );
+ m_xRemoveBtn->connect_clicked( LINK( this, SvxJavaClassPathDlg, RemoveHdl_Impl ) );
+ m_xPathList->connect_changed( LINK( this, SvxJavaClassPathDlg, SelectHdl_Impl ) );
+
+ // set initial focus to path list
+ m_xPathList->grab_focus();
+}
+
+SvxJavaClassPathDlg::~SvxJavaClassPathDlg()
+{
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddArchiveHdl_Impl, weld::Button&, void)
+{
+ sfx2::FileDialogHelper aDlg(TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, m_xDialog.get());
+ aDlg.SetTitle( CuiResId( RID_CUISTR_ARCHIVE_TITLE ) );
+ aDlg.AddFilter( CuiResId( RID_CUISTR_ARCHIVE_HEADLINE ), "*.jar;*.zip" );
+ aDlg.SetContext(sfx2::FileDialogHelper::JavaClassPath);
+ OUString sFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sFolder);
+ // best effort
+ }
+ if (!sFolder.isEmpty())
+ aDlg.SetDisplayDirectory( sFolder );
+ if ( aDlg.Execute() == ERRCODE_NONE )
+ {
+ OUString sURL = aDlg.GetPath();
+ OUString sFile;
+ if (osl::FileBase::getSystemPathFromFileURL(sURL, sFile) == osl::FileBase::E_None)
+ {
+ INetURLObject aURL( sURL );
+ if ( !IsPathDuplicate( sFile ) )
+ {
+ m_xPathList->append("", sFile, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFile );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, AddPathHdl_Impl, weld::Button&, void)
+{
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference < XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_xDialog.get());
+
+ OUString sOldFolder;
+ if (m_xPathList->count_selected_rows() > 0)
+ {
+ osl::FileBase::getFileURLFromSystemPath(m_xPathList->get_selected_text(), sOldFolder);
+ // best effort
+ }
+ if (sOldFolder.isEmpty())
+ sOldFolder = SvtPathOptions().GetWorkPath();
+ xFolderPicker->setDisplayDirectory( sOldFolder );
+ if ( xFolderPicker->execute() == ExecutableDialogResults::OK )
+ {
+ OUString sFolderURL( xFolderPicker->getDirectory() );
+ INetURLObject aURL( sFolderURL );
+ OUString sNewFolder;
+ if (osl::FileBase::getSystemPathFromFileURL(sFolderURL, sNewFolder)
+ == osl::FileBase::E_None)
+ {
+ if ( !IsPathDuplicate( sNewFolder ) )
+ {
+ m_xPathList->append("", sNewFolder, SvFileInformationManager::GetImageId(aURL));
+ m_xPathList->select(m_xPathList->n_children() - 1);
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_MULTIFILE_DBL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sNewFolder );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ else
+ {
+ OUString sMsg( CuiResId( RID_CUISTR_CANNOTCONVERTURL_ERR ) );
+ sMsg = sMsg.replaceFirst( "%1", sFolderURL );
+ std::unique_ptr<weld::MessageDialog> xBox(Application::CreateMessageDialog(m_xDialog.get(),
+ VclMessageType::Warning, VclButtonsType::Ok, sMsg));
+ xBox->run();
+ }
+ }
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, RemoveHdl_Impl, weld::Button&, void)
+{
+ int nPos = m_xPathList->get_selected_index();
+ if (nPos != -1)
+ {
+ m_xPathList->remove(nPos);
+ int nCount = m_xPathList->n_children();
+ if (nCount)
+ {
+ if (nPos >= nCount)
+ nPos = nCount - 1;
+ m_xPathList->select( nPos );
+ }
+ }
+
+ EnableRemoveButton();
+}
+
+IMPL_LINK_NOARG(SvxJavaClassPathDlg, SelectHdl_Impl, weld::TreeView&, void)
+{
+ EnableRemoveButton();
+}
+
+bool SvxJavaClassPathDlg::IsPathDuplicate( std::u16string_view _rPath )
+{
+ bool bRet = false;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if ( m_xPathList->get_text(i) == _rPath )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+OUString SvxJavaClassPathDlg::GetClassPath() const
+{
+ OUStringBuffer sPath;
+ int nCount = m_xPathList->n_children();
+ for (int i = 0; i < nCount; ++i)
+ {
+ if (!sPath.isEmpty())
+ sPath.append(CLASSPATH_DELIMITER);
+ sPath.append(m_xPathList->get_text(i));
+ }
+ return sPath.makeStringAndClear();
+}
+
+void SvxJavaClassPathDlg::SetClassPath( const OUString& _rPath )
+{
+ if ( m_sOldPath.isEmpty() )
+ m_sOldPath = _rPath;
+ m_xPathList->clear();
+ if (!_rPath.isEmpty())
+ {
+ sal_Int32 nIdx = 0;
+ do
+ {
+ OUString sToken = _rPath.getToken( 0, CLASSPATH_DELIMITER, nIdx );
+ OUString sURL;
+ osl::FileBase::getFileURLFromSystemPath(sToken, sURL); // best effort
+ INetURLObject aURL( sURL );
+ m_xPathList->append("", sToken, SvFileInformationManager::GetImageId(aURL));
+ }
+ while (nIdx>=0);
+ // select first entry
+ m_xPathList->select(0);
+ }
+ SelectHdl_Impl(*m_xPathList);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjava.hxx b/cui/source/options/optjava.hxx
new file mode 100644
index 000000000..097b7ffb5
--- /dev/null
+++ b/cui/source/options/optjava.hxx
@@ -0,0 +1,206 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <config_java.h>
+
+#include <memory>
+#include <vector>
+#include <vcl/timer.hxx>
+#include <vcl/idle.hxx>
+#include <vcl/weld.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <svtools/dialogclosedlistener.hxx>
+#include <svtools/restartdialog.hxx>
+
+// forward ---------------------------------------------------------------
+
+#if HAVE_FEATURE_JAVA
+struct JavaInfo;
+#else
+typedef void* JavaInfo;
+#endif
+
+class SvxJavaParameterDlg;
+class SvxJavaClassPathDlg;
+class SvxJavaListBox;
+class OfaTreeOptionsDialog;
+
+// class SvxJavaOptionsPage ----------------------------------------------
+
+class SvxJavaOptionsPage : public SfxTabPage
+{
+private:
+#if HAVE_FEATURE_JAVA
+ std::vector<std::unique_ptr<JavaInfo>> m_parJavaInfo;
+ std::vector<OUString> m_parParameters;
+ OUString m_pClassPath;
+#endif
+ OUString m_sInstallText;
+ OUString m_sAddDialogText;
+ Idle m_aResetIdle;
+
+ std::vector<std::unique_ptr<JavaInfo>> m_aAddedInfos;
+
+ rtl::Reference< ::svt::DialogClosedListener > xDialogListener;
+ css::uno::Reference< css::ui::dialogs::XFolderPicker2 > xFolderPicker;
+
+ std::unique_ptr<weld::CheckButton> m_xJavaEnableCB;
+ std::unique_ptr<weld::TreeView> m_xJavaList;
+ std::unique_ptr<weld::Label> m_xJavaPathText;
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xParameterBtn;
+ std::unique_ptr<weld::Button> m_xClassPathBtn;
+ std::unique_ptr<weld::Button> m_xExpertConfigBtn;
+
+ std::unique_ptr<SvxJavaParameterDlg> m_xParamDlg;
+ std::unique_ptr<SvxJavaClassPathDlg> m_xPathDlg;
+
+ std::unique_ptr<weld::CheckButton> m_xExperimentalCB;
+ std::unique_ptr<weld::CheckButton> m_xMacroCB;
+
+ std::unique_ptr<weld::Label> m_xAddDialogText;
+
+ std::unique_ptr<weld::Widget> m_xJavaFrame;
+
+ DECL_LINK(EnableHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(CheckHdl_Impl, const weld::TreeView::iter_col&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(ParameterHdl_Impl, weld::Button&, void);
+ DECL_LINK(ClassPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(ResetHdl_Impl, Timer *, void);
+
+ DECL_LINK(StartFolderPickerHdl, void *, void);
+ DECL_LINK(DialogClosedHdl, css::ui::dialogs::DialogClosedEvent*, void);
+
+ DECL_LINK(ExpertConfigHdl_Impl, weld::Button&, void);
+
+ void ClearJavaInfo();
+ void LoadJREs();
+ void AddJRE( JavaInfo const * _pInfo );
+ void HandleCheckEntry(int nCheckedRow);
+ void UpdateJavaPathText();
+ void AddFolder( const OUString& _rFolder );
+ void RequestRestart( svtools::RestartReason eReason );
+
+public:
+ SvxJavaOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJavaOptionsPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+// class SvxJavaParameterDlg ---------------------------------------------
+
+class SvxJavaParameterDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Entry> m_xParameterEdit;
+ std::unique_ptr<weld::Button> m_xAssignBtn;
+ std::unique_ptr<weld::TreeView> m_xAssignedList;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xEditBtn;
+
+ DECL_LINK(ModifyHdl_Impl, weld::Entry&, void);
+ DECL_LINK(ActivateHdl_Impl, weld::Entry&, bool);
+ DECL_LINK(AssignHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+ DECL_LINK(DblClickHdl_Impl, weld::TreeView&, bool);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(EditHdl_Impl, weld::Button&, void);
+
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void EnableEditButton()
+ {
+ m_xEditBtn->set_sensitive(m_xAssignedList->get_selected_index() != -1);
+ }
+
+ void DisableAssignButton()
+ {
+ m_xAssignBtn->set_sensitive(false);
+ }
+
+ void DisableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ }
+
+ void DisableEditButton()
+ {
+ m_xEditBtn->set_sensitive(false);
+ }
+
+public:
+ explicit SvxJavaParameterDlg(weld::Window* pParent);
+ virtual ~SvxJavaParameterDlg() override;
+
+ virtual short run() override;
+
+ std::vector< OUString > GetParameters() const;
+ void SetParameters( std::vector< OUString > const & rParams );
+ void DisableButtons();
+ void EditParameter();
+};
+
+// class SvxJavaClassPathDlg ---------------------------------------------
+
+class SvxJavaClassPathDlg : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::TreeView> m_xPathList;
+ std::unique_ptr<weld::Button> m_xAddArchiveBtn;
+ std::unique_ptr<weld::Button> m_xAddPathBtn;
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+
+ OUString m_sOldPath;
+
+ DECL_LINK(AddArchiveHdl_Impl, weld::Button&, void);
+ DECL_LINK(AddPathHdl_Impl, weld::Button&, void);
+ DECL_LINK(RemoveHdl_Impl, weld::Button&, void);
+ DECL_LINK(SelectHdl_Impl, weld::TreeView&, void);
+
+ bool IsPathDuplicate(std::u16string_view _rPath);
+ void EnableRemoveButton()
+ {
+ m_xRemoveBtn->set_sensitive(m_xPathList->get_selected_index() != -1);
+ }
+
+public:
+ explicit SvxJavaClassPathDlg(weld::Window* pParent);
+ virtual ~SvxJavaClassPathDlg() override;
+
+ const OUString& GetOldPath() const { return m_sOldPath; }
+ void SetFocus() { m_xPathList->grab_focus(); }
+
+ OUString GetClassPath() const;
+ void SetClassPath( const OUString& _rPath );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.cxx b/cui/source/options/optjsearch.cxx
new file mode 100644
index 000000000..4a2c31c49
--- /dev/null
+++ b/cui/source/options/optjsearch.cxx
@@ -0,0 +1,358 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <tools/debug.hxx>
+#include <unotools/searchopt.hxx>
+#include <i18nutil/transliteration.hxx>
+#include "optjsearch.hxx"
+
+using namespace com::sun::star::i18n;
+
+
+SvxJSearchOptionsPage::SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optjsearchpage.ui", "OptJSearchPage", &rSet)
+ , m_xMatchCase(m_xBuilder->weld_check_button("matchcase"))
+ , m_xMatchFullHalfWidth(m_xBuilder->weld_check_button("matchfullhalfwidth"))
+ , m_xMatchHiraganaKatakana(m_xBuilder->weld_check_button("matchhiraganakatakana"))
+ , m_xMatchContractions(m_xBuilder->weld_check_button("matchcontractions"))
+ , m_xMatchMinusDashChoon(m_xBuilder->weld_check_button("matchminusdashchoon"))
+ , m_xMatchRepeatCharMarks(m_xBuilder->weld_check_button("matchrepeatcharmarks"))
+ , m_xMatchVariantFormKanji(m_xBuilder->weld_check_button("matchvariantformkanji"))
+ , m_xMatchOldKanaForms(m_xBuilder->weld_check_button("matcholdkanaforms"))
+ , m_xMatchDiziDuzu(m_xBuilder->weld_check_button("matchdiziduzu"))
+ , m_xMatchBavaHafa(m_xBuilder->weld_check_button("matchbavahafa"))
+ , m_xMatchTsithichiDhizi(m_xBuilder->weld_check_button("matchtsithichidhizi"))
+ , m_xMatchHyuiyuByuvyu(m_xBuilder->weld_check_button("matchhyuiyubyuvyu"))
+ , m_xMatchSesheZeje(m_xBuilder->weld_check_button("matchseshezeje"))
+ , m_xMatchIaiya(m_xBuilder->weld_check_button("matchiaiya"))
+ , m_xMatchKiku(m_xBuilder->weld_check_button("matchkiku"))
+ , m_xMatchProlongedSoundMark(m_xBuilder->weld_check_button("matchprolongedsoundmark"))
+ , m_xIgnorePunctuation(m_xBuilder->weld_check_button("ignorepunctuation"))
+ , m_xIgnoreWhitespace(m_xBuilder->weld_check_button("ignorewhitespace"))
+ , m_xIgnoreMiddleDot(m_xBuilder->weld_check_button("ignoremiddledot"))
+ , nTransliterationFlags(TransliterationFlags::NONE)
+ , bSaveOptions(true)
+{
+}
+
+SvxJSearchOptionsPage::~SvxJSearchOptionsPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxJSearchOptionsPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxJSearchOptionsPage>(pPage, pController, *rSet);
+}
+
+void SvxJSearchOptionsPage::SetTransliterationFlags( TransliterationFlags nSettings )
+{
+ bool bVal(nSettings & TransliterationFlags::IGNORE_CASE);
+ m_xMatchCase ->set_active( bVal ); //! treat as equal uppercase/lowercase
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_WIDTH);
+ m_xMatchFullHalfWidth ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::IGNORE_KANA);
+ m_xMatchHiraganaKatakana ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSize_ja_JP);
+ m_xMatchContractions ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMinusSign_ja_JP);
+ m_xMatchMinusDashChoon ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIterationMark_ja_JP);
+ m_xMatchRepeatCharMarks ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKanji_ja_JP);
+ m_xMatchVariantFormKanji ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTraditionalKana_ja_JP);
+ m_xMatchOldKanaForms ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreZiZu_ja_JP);
+ m_xMatchDiziDuzu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreBaFa_ja_JP);
+ m_xMatchBavaHafa ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreTiJi_ja_JP);
+ m_xMatchTsithichiDhizi ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreHyuByu_ja_JP);
+ m_xMatchHyuiyuByuvyu ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeZe_ja_JP);
+ m_xMatchSesheZeje ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreIandEfollowedByYa_ja_JP);
+ m_xMatchIaiya ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP);
+ m_xMatchKiku ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSeparator_ja_JP);
+ m_xIgnorePunctuation ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreSpace_ja_JP);
+ m_xIgnoreWhitespace ->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreProlongedSoundMark_ja_JP);
+ m_xMatchProlongedSoundMark->set_active( bVal );
+ bVal = bool(nSettings & TransliterationFlags::ignoreMiddleDot_ja_JP);
+ m_xIgnoreMiddleDot ->set_active( bVal );
+
+ nTransliterationFlags = nSettings;
+}
+
+TransliterationFlags SvxJSearchOptionsPage::GetTransliterationFlags_Impl()
+{
+ TransliterationFlags nTmp = TransliterationFlags::NONE;
+ if (m_xMatchCase->get_active()) //! treat as equal uppercase/lowercase
+ nTmp |= TransliterationFlags::IGNORE_CASE;
+ if (m_xMatchFullHalfWidth->get_active())
+ nTmp |= TransliterationFlags::IGNORE_WIDTH;
+ if (m_xMatchHiraganaKatakana->get_active())
+ nTmp |= TransliterationFlags::IGNORE_KANA;
+ if (m_xMatchContractions->get_active())
+ nTmp |= TransliterationFlags::ignoreSize_ja_JP;
+ if (m_xMatchMinusDashChoon->get_active())
+ nTmp |= TransliterationFlags::ignoreMinusSign_ja_JP;
+ if (m_xMatchRepeatCharMarks->get_active())
+ nTmp |= TransliterationFlags::ignoreIterationMark_ja_JP;
+ if (m_xMatchVariantFormKanji->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKanji_ja_JP;
+ if (m_xMatchOldKanaForms->get_active())
+ nTmp |= TransliterationFlags::ignoreTraditionalKana_ja_JP;
+ if (m_xMatchDiziDuzu->get_active())
+ nTmp |= TransliterationFlags::ignoreZiZu_ja_JP;
+ if (m_xMatchBavaHafa->get_active())
+ nTmp |= TransliterationFlags::ignoreBaFa_ja_JP;
+ if (m_xMatchTsithichiDhizi->get_active())
+ nTmp |= TransliterationFlags::ignoreTiJi_ja_JP;
+ if (m_xMatchHyuiyuByuvyu->get_active())
+ nTmp |= TransliterationFlags::ignoreHyuByu_ja_JP;
+ if (m_xMatchSesheZeje->get_active())
+ nTmp |= TransliterationFlags::ignoreSeZe_ja_JP;
+ if (m_xMatchIaiya->get_active())
+ nTmp |= TransliterationFlags::ignoreIandEfollowedByYa_ja_JP;
+ if (m_xMatchKiku->get_active())
+ nTmp |= TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP;
+ if (m_xIgnorePunctuation->get_active())
+ nTmp |= TransliterationFlags::ignoreSeparator_ja_JP;
+ if (m_xIgnoreWhitespace->get_active())
+ nTmp |= TransliterationFlags::ignoreSpace_ja_JP;
+ if (m_xMatchProlongedSoundMark->get_active())
+ nTmp |= TransliterationFlags::ignoreProlongedSoundMark_ja_JP;
+ if (m_xIgnoreMiddleDot->get_active())
+ nTmp |= TransliterationFlags::ignoreMiddleDot_ja_JP;
+
+ nTransliterationFlags = nTmp;
+ return nTransliterationFlags;
+}
+
+
+void SvxJSearchOptionsPage::Reset( const SfxItemSet* )
+{
+ SvtSearchOptions aOpt;
+
+ // read settings from configuration
+ m_xMatchCase ->set_active(!aOpt.IsMatchCase() ); //! treat as equal uppercase/lowercase
+ m_xMatchFullHalfWidth ->set_active( aOpt.IsMatchFullHalfWidthForms() );
+ m_xMatchHiraganaKatakana ->set_active( aOpt.IsMatchHiraganaKatakana() );
+ m_xMatchContractions ->set_active( aOpt.IsMatchContractions() );
+ m_xMatchMinusDashChoon ->set_active( aOpt.IsMatchMinusDashChoon() );
+ m_xMatchRepeatCharMarks ->set_active( aOpt.IsMatchRepeatCharMarks() );
+ m_xMatchVariantFormKanji ->set_active( aOpt.IsMatchVariantFormKanji() );
+ m_xMatchOldKanaForms ->set_active( aOpt.IsMatchOldKanaForms() );
+ m_xMatchDiziDuzu ->set_active( aOpt.IsMatchDiziDuzu() );
+ m_xMatchBavaHafa ->set_active( aOpt.IsMatchBavaHafa() );
+ m_xMatchTsithichiDhizi ->set_active( aOpt.IsMatchTsithichiDhizi() );
+ m_xMatchHyuiyuByuvyu ->set_active( aOpt.IsMatchHyuiyuByuvyu() );
+ m_xMatchSesheZeje ->set_active( aOpt.IsMatchSesheZeje() );
+ m_xMatchIaiya ->set_active( aOpt.IsMatchIaiya() );
+ m_xMatchKiku ->set_active( aOpt.IsMatchKiku() );
+ m_xIgnorePunctuation ->set_active( aOpt.IsIgnorePunctuation() );
+ m_xIgnoreWhitespace ->set_active( aOpt.IsIgnoreWhitespace() );
+ m_xMatchProlongedSoundMark ->set_active( aOpt.IsIgnoreProlongedSoundMark() );
+ m_xIgnoreMiddleDot ->set_active( aOpt.IsIgnoreMiddleDot() );
+
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ DBG_ASSERT( nTransliterationFlags == aOpt.GetTransliterationFlags(),
+ "Transliteration settings different" );
+
+ m_xMatchCase ->save_state();
+ m_xMatchFullHalfWidth ->save_state();
+ m_xMatchHiraganaKatakana ->save_state();
+ m_xMatchContractions ->save_state();
+ m_xMatchMinusDashChoon ->save_state();
+ m_xMatchRepeatCharMarks ->save_state();
+ m_xMatchVariantFormKanji ->save_state();
+ m_xMatchOldKanaForms ->save_state();
+ m_xMatchDiziDuzu ->save_state();
+ m_xMatchBavaHafa ->save_state();
+ m_xMatchTsithichiDhizi ->save_state();
+ m_xMatchHyuiyuByuvyu ->save_state();
+ m_xMatchSesheZeje ->save_state();
+ m_xMatchIaiya ->save_state();
+ m_xMatchKiku ->save_state();
+ m_xIgnorePunctuation ->save_state();
+ m_xIgnoreWhitespace ->save_state();
+ m_xMatchProlongedSoundMark ->save_state();
+ m_xIgnoreMiddleDot ->save_state();
+}
+
+
+bool SvxJSearchOptionsPage::FillItemSet( SfxItemSet* )
+{
+ TransliterationFlags nOldVal = nTransliterationFlags;
+ nTransliterationFlags = GetTransliterationFlags_Impl();
+ bool bModified = nOldVal != nTransliterationFlags;
+
+ if (!bSaveOptions)
+ return bModified;
+
+ bModified = false;
+ SvtSearchOptions aOpt;
+ bool bNewVal, bChanged;
+
+ bNewVal = m_xMatchCase->get_active(); //! treat as equal uppercase/lowercase
+ bChanged = m_xMatchCase->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchCase(!bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchFullHalfWidth->get_active();
+ bChanged = m_xMatchFullHalfWidth->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchFullHalfWidthForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHiraganaKatakana->get_active();
+ bChanged = m_xMatchHiraganaKatakana->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHiraganaKatakana( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchContractions->get_active();
+ bChanged = m_xMatchContractions->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchContractions( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchMinusDashChoon->get_active();
+ bChanged = m_xMatchMinusDashChoon->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchMinusDashChoon( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchRepeatCharMarks->get_active();
+ bChanged = m_xMatchRepeatCharMarks->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchRepeatCharMarks( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchVariantFormKanji->get_active();
+ bChanged = m_xMatchVariantFormKanji->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchVariantFormKanji( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchOldKanaForms->get_active();
+ bChanged = m_xMatchOldKanaForms->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchOldKanaForms( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchDiziDuzu->get_active();
+ bChanged = m_xMatchDiziDuzu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchDiziDuzu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchBavaHafa->get_active();
+ bChanged = m_xMatchBavaHafa->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchBavaHafa( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchTsithichiDhizi->get_active();
+ bChanged = m_xMatchTsithichiDhizi->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchTsithichiDhizi( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchHyuiyuByuvyu->get_active();
+ bChanged = m_xMatchHyuiyuByuvyu->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchHyuiyuByuvyu( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchSesheZeje->get_active();
+ bChanged = m_xMatchSesheZeje->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchSesheZeje( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchIaiya->get_active();
+ bChanged = m_xMatchIaiya->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchIaiya( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchKiku->get_active();
+ bChanged = m_xMatchKiku->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetMatchKiku( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnorePunctuation->get_active();
+ bChanged = m_xIgnorePunctuation->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnorePunctuation( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreWhitespace->get_active();
+ bChanged = m_xIgnoreWhitespace->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreWhitespace( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xMatchProlongedSoundMark->get_active();
+ bChanged = m_xMatchProlongedSoundMark->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreProlongedSoundMark( bNewVal );
+ bModified = true;
+ }
+ bNewVal = m_xIgnoreMiddleDot->get_active();
+ bChanged = m_xIgnoreMiddleDot->get_state_changed_from_saved();
+ if (bChanged)
+ {
+ aOpt.SetIgnoreMiddleDot( bNewVal );
+ bModified = true;
+ }
+
+ if (bModified)
+ aOpt.Commit();
+
+ return bModified;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optjsearch.hxx b/cui/source/options/optjsearch.hxx
new file mode 100644
index 000000000..f0da350ae
--- /dev/null
+++ b/cui/source/options/optjsearch.hxx
@@ -0,0 +1,71 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <i18nutil/transliteration.hxx>
+#include <sfx2/tabdlg.hxx>
+#include <vcl/weld.hxx>
+
+class SfxItemSet;
+
+class SvxJSearchOptionsPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::CheckButton> m_xMatchCase;
+ std::unique_ptr<weld::CheckButton> m_xMatchFullHalfWidth;
+ std::unique_ptr<weld::CheckButton> m_xMatchHiraganaKatakana;
+ std::unique_ptr<weld::CheckButton> m_xMatchContractions;
+ std::unique_ptr<weld::CheckButton> m_xMatchMinusDashChoon;
+ std::unique_ptr<weld::CheckButton> m_xMatchRepeatCharMarks;
+ std::unique_ptr<weld::CheckButton> m_xMatchVariantFormKanji;
+ std::unique_ptr<weld::CheckButton> m_xMatchOldKanaForms;
+ std::unique_ptr<weld::CheckButton> m_xMatchDiziDuzu;
+ std::unique_ptr<weld::CheckButton> m_xMatchBavaHafa;
+ std::unique_ptr<weld::CheckButton> m_xMatchTsithichiDhizi;
+ std::unique_ptr<weld::CheckButton> m_xMatchHyuiyuByuvyu;
+ std::unique_ptr<weld::CheckButton> m_xMatchSesheZeje;
+ std::unique_ptr<weld::CheckButton> m_xMatchIaiya;
+ std::unique_ptr<weld::CheckButton> m_xMatchKiku;
+ std::unique_ptr<weld::CheckButton> m_xMatchProlongedSoundMark;
+
+ std::unique_ptr<weld::CheckButton> m_xIgnorePunctuation;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreWhitespace;
+ std::unique_ptr<weld::CheckButton> m_xIgnoreMiddleDot;
+
+ TransliterationFlags nTransliterationFlags;
+ bool bSaveOptions;
+
+ TransliterationFlags GetTransliterationFlags_Impl();
+
+public:
+ SvxJSearchOptionsPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxJSearchOptionsPage() override;
+ static std::unique_ptr<SfxTabPage> Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+
+ void EnableSaveOptions( bool bVal ) { bSaveOptions = bVal; }
+
+ TransliterationFlags GetTransliterationFlags() const { return nTransliterationFlags; }
+ void SetTransliterationFlags( TransliterationFlags nSettings );
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optlanguagetool.cxx b/cui/source/options/optlanguagetool.cxx
new file mode 100644
index 000000000..38807bc33
--- /dev/null
+++ b/cui/source/options/optlanguagetool.cxx
@@ -0,0 +1,76 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "optlanguagetool.hxx"
+#include <svtools/languagetoolcfg.hxx>
+#include <sal/log.hxx>
+
+OptLanguageToolTabPage::OptLanguageToolTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/langtoolconfigpage.ui", "OptLangToolPage", &rSet)
+ , m_xBaseURLED(m_xBuilder->weld_entry("baseurl"))
+ , m_xUsernameED(m_xBuilder->weld_entry("username"))
+ , m_xApiKeyED(m_xBuilder->weld_entry("apikey"))
+ , m_xActivateBox(m_xBuilder->weld_check_button("activate"))
+ , m_xApiSettingsFrame(m_xBuilder->weld_frame("apisettings"))
+{
+ m_xActivateBox->connect_toggled(LINK(this, OptLanguageToolTabPage, CheckHdl));
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ EnableControls(rLanguageOpts.getEnabled());
+}
+
+OptLanguageToolTabPage::~OptLanguageToolTabPage() {}
+
+void OptLanguageToolTabPage::EnableControls(bool bEnable)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ rLanguageOpts.setEnabled(bEnable);
+ m_xApiSettingsFrame->set_visible(bEnable);
+ m_xActivateBox->set_active(bEnable);
+}
+
+IMPL_LINK_NOARG(OptLanguageToolTabPage, CheckHdl, weld::Toggleable&, void)
+{
+ EnableControls(m_xActivateBox->get_active());
+}
+
+void OptLanguageToolTabPage::Reset(const SfxItemSet*)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ m_xBaseURLED->set_text(rLanguageOpts.getBaseURL());
+ m_xUsernameED->set_text(rLanguageOpts.getUsername());
+ m_xApiKeyED->set_text(rLanguageOpts.getApiKey());
+}
+
+bool OptLanguageToolTabPage::FillItemSet(SfxItemSet*)
+{
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ rLanguageOpts.setBaseURL(m_xBaseURLED->get_text());
+ rLanguageOpts.setUsername(m_xUsernameED->get_text());
+ rLanguageOpts.setApiKey(m_xApiKeyED->get_text());
+ return false;
+}
+
+std::unique_ptr<SfxTabPage> OptLanguageToolTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<OptLanguageToolTabPage>(pPage, pController, *rAttrSet);
+}
diff --git a/cui/source/options/optlanguagetool.hxx b/cui/source/options/optlanguagetool.hxx
new file mode 100644
index 000000000..46a60ecbe
--- /dev/null
+++ b/cui/source/options/optlanguagetool.hxx
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+#include <sfx2/tabdlg.hxx>
+
+class OptLanguageToolTabPage : public SfxTabPage
+{
+public:
+ OptLanguageToolTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~OptLanguageToolTabPage() override;
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet);
+
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+private:
+ std::unique_ptr<weld::Entry> m_xBaseURLED;
+ std::unique_ptr<weld::Entry> m_xUsernameED;
+ std::unique_ptr<weld::Entry> m_xApiKeyED;
+ std::unique_ptr<weld::CheckButton> m_xActivateBox;
+ std::unique_ptr<weld::Frame> m_xApiSettingsFrame;
+
+ void EnableControls(bool bEnable);
+
+ DECL_LINK(CheckHdl, weld::Toggleable&, void);
+}; \ No newline at end of file
diff --git a/cui/source/options/optlingu.cxx b/cui/source/options/optlingu.cxx
new file mode 100644
index 000000000..be2b891eb
--- /dev/null
+++ b/cui/source/options/optlingu.cxx
@@ -0,0 +1,1974 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <utility>
+#include <vcl/settings.hxx>
+#include <vcl/weld.hxx>
+#include <i18nlangtag/languagetag.hxx>
+#include <i18nlangtag/mslangid.hxx>
+#include <officecfg/Office/Security.hxx>
+#include <unotools/lingucfg.hxx>
+#include <unotools/linguprops.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <sfx2/sfxsids.hrc>
+#include <tools/debug.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <comphelper/dispatchcommand.hxx>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/linguistic2/LinguServiceManager.hpp>
+#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XSpellChecker.hpp>
+#include <com/sun/star/linguistic2/XProofreader.hpp>
+#include <com/sun/star/linguistic2/XHyphenator.hpp>
+#include <com/sun/star/linguistic2/XThesaurus.hpp>
+#include <com/sun/star/linguistic2/XDictionary.hpp>
+#include <com/sun/star/linguistic2/XDictionaryList.hpp>
+#include <com/sun/star/linguistic2/XLinguProperties.hpp>
+#include <com/sun/star/lang/XServiceDisplayName.hpp>
+#include <com/sun/star/frame/XStorable.hpp>
+#include <unotools/extendedsecurityoptions.hxx>
+#include <svl/eitem.hxx>
+#include <vcl/svapp.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <svx/svxdlg.hxx>
+#include <editeng/optitems.hxx>
+#include <optlingu.hxx>
+#include <dialmgr.hxx>
+#include <strings.hrc>
+
+#include <ucbhelper/content.hxx>
+
+#include <vector>
+#include <map>
+
+using namespace ::ucbhelper;
+using namespace ::com::sun::star;
+using namespace css::lang;
+using namespace css::uno;
+using namespace css::linguistic2;
+using namespace css::beans;
+
+constexpr OUStringLiteral cSpell(SN_SPELLCHECKER);
+constexpr OUStringLiteral cGrammar(SN_GRAMMARCHECKER);
+constexpr OUStringLiteral cHyph(SN_HYPHENATOR);
+constexpr OUStringLiteral cThes(SN_THESAURUS);
+
+// static ----------------------------------------------------------------
+
+static sal_Int32 lcl_SeqGetEntryPos(
+ const Sequence< OUString > &rSeq, std::u16string_view rEntry )
+{
+ sal_Int32 i;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pItem = rSeq.getConstArray();
+ for (i = 0; i < nLen; ++i)
+ {
+ if (rEntry == pItem[i])
+ break;
+ }
+ return i < nLen ? i : -1;
+}
+
+static bool KillFile_Impl( const OUString& rURL )
+{
+ bool bRet = true;
+ try
+ {
+ Content aCnt( rURL, uno::Reference< css::ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
+ aCnt.executeCommand( "delete", Any( true ) );
+ }
+ catch( ... )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "KillFile" );
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+// 0x 0p 0t 0c nn
+// p: 1 -> parent
+// t: 1 -> spell, 2 -> hyph, 3 -> thes, 4 -> grammar
+// c: 1 -> checked 0 -> unchecked
+// n: index
+
+#define TYPE_SPELL sal_uInt8(1)
+#define TYPE_GRAMMAR sal_uInt8(2)
+#define TYPE_HYPH sal_uInt8(3)
+#define TYPE_THES sal_uInt8(4)
+
+namespace {
+
+class ModuleUserData_Impl
+{
+ bool bParent;
+ bool bIsChecked;
+ sal_uInt8 nType;
+ sal_uInt8 nIndex;
+ OUString sImplName;
+
+public:
+ ModuleUserData_Impl( OUString sImpName, bool bIsParent, bool bChecked, sal_uInt8 nSetType, sal_uInt8 nSetIndex ) :
+ bParent(bIsParent),
+ bIsChecked(bChecked),
+ nType(nSetType),
+ nIndex(nSetIndex),
+ sImplName(std::move(sImpName))
+ {
+ }
+ bool IsParent() const {return bParent;}
+ sal_uInt8 GetType() const {return nType;}
+ bool IsChecked() const {return bIsChecked;}
+ sal_uInt8 GetIndex() const {return nIndex;}
+ const OUString& GetImplName() const {return sImplName;}
+
+};
+
+
+// User for user-dictionaries (XDictionary interface)
+
+class DicUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit DicUserData(sal_uInt32 nUserData) : nVal( nUserData ) {}
+ DicUserData( sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool IsChecked() const { return static_cast<bool>((nVal >> 8) & 0x01); }
+ bool IsDeletable() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+};
+
+}
+
+DicUserData::DicUserData(
+ sal_uInt16 nEID,
+ bool bChecked, bool bEditable, bool bDeletable )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ (static_cast<sal_uInt32>(bEditable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bDeletable ? 1 : 0) << 10);
+}
+
+/*--------------------------------------------------
+ Entry IDs for options listbox of dialog
+--------------------------------------------------*/
+
+namespace {
+
+enum EID_OPTIONS
+{
+ EID_SPELL_AUTO,
+ EID_GRAMMAR_AUTO,
+ EID_CAPITAL_WORDS,
+ EID_WORDS_WITH_DIGITS,
+ EID_SPELL_SPECIAL,
+ EID_NUM_MIN_WORDLEN,
+ EID_NUM_PRE_BREAK,
+ EID_NUM_POST_BREAK,
+ EID_HYPH_AUTO,
+ EID_HYPH_SPECIAL
+};
+
+}
+
+static OUString lcl_GetPropertyName( EID_OPTIONS eEntryId )
+{
+ switch (eEntryId)
+ {
+ case EID_SPELL_AUTO: return UPN_IS_SPELL_AUTO;
+ case EID_GRAMMAR_AUTO: return UPN_IS_GRAMMAR_AUTO;
+ case EID_CAPITAL_WORDS: return UPN_IS_SPELL_UPPER_CASE;
+ case EID_WORDS_WITH_DIGITS: return UPN_IS_SPELL_WITH_DIGITS;
+ case EID_SPELL_SPECIAL: return UPN_IS_SPELL_SPECIAL;
+ case EID_NUM_MIN_WORDLEN: return UPN_HYPH_MIN_WORD_LENGTH;
+ case EID_NUM_PRE_BREAK: return UPN_HYPH_MIN_LEADING;
+ case EID_NUM_POST_BREAK: return UPN_HYPH_MIN_TRAILING;
+ case EID_HYPH_AUTO: return UPN_IS_HYPH_AUTO;
+ case EID_HYPH_SPECIAL: return UPN_IS_HYPH_SPECIAL;
+ default: assert (false); abort();
+ }
+}
+
+namespace {
+
+class OptionsBreakSet : public weld::GenericDialogController
+{
+ std::unique_ptr<weld::Widget> m_xBeforeFrame;
+ std::unique_ptr<weld::Widget> m_xAfterFrame;
+ std::unique_ptr<weld::Widget> m_xMinimalFrame;
+ std::unique_ptr<weld::SpinButton> m_xBreakNF;
+
+public:
+ OptionsBreakSet(weld::Window* pParent, sal_uInt16 nRID)
+ : GenericDialogController(pParent, "cui/ui/breaknumberoption.ui", "BreakNumberOption")
+ , m_xBeforeFrame(m_xBuilder->weld_widget("beforeframe"))
+ , m_xAfterFrame(m_xBuilder->weld_widget("afterframe"))
+ , m_xMinimalFrame(m_xBuilder->weld_widget("miniframe"))
+ {
+ assert(EID_NUM_PRE_BREAK == nRID || EID_NUM_POST_BREAK == nRID || EID_NUM_MIN_WORDLEN == nRID); //unexpected ID
+
+ if (nRID == EID_NUM_PRE_BREAK)
+ {
+ m_xBeforeFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("beforebreak");
+ }
+ else if(nRID == EID_NUM_POST_BREAK)
+ {
+ m_xAfterFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("afterbreak");
+ }
+ else if(nRID == EID_NUM_MIN_WORDLEN)
+ {
+ m_xMinimalFrame->show();
+ m_xBreakNF = m_xBuilder->weld_spin_button("wordlength");
+ }
+ }
+
+ weld::SpinButton& GetNumericFld()
+ {
+ return *m_xBreakNF;
+ }
+};
+
+// class OptionsUserData -------------------------------------------------
+
+class OptionsUserData
+{
+ sal_uInt32 nVal;
+
+public:
+ explicit OptionsUserData( sal_uInt32 nUserData ) : nVal( nUserData ) {}
+ OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked );
+
+ sal_uInt32 GetUserData() const { return nVal; }
+ sal_uInt16 GetEntryId() const { return static_cast<sal_uInt16>(nVal >> 16); }
+ bool HasNumericValue() const { return static_cast<bool>((nVal >> 10) & 0x01); }
+ sal_uInt16 GetNumericValue() const { return static_cast<sal_uInt16>(nVal & 0xFF); }
+ bool IsCheckable() const { return static_cast<bool>((nVal >> 9) & 0x01); }
+ bool IsModified() const { return static_cast<bool>((nVal >> 11) & 0x01); }
+
+ void SetNumericValue( sal_uInt8 nNumVal );
+};
+
+}
+
+OptionsUserData::OptionsUserData( sal_uInt16 nEID,
+ bool bHasNV, sal_uInt16 nNumVal,
+ bool bCheckable, bool bChecked )
+{
+ DBG_ASSERT( nEID < 65000, "Entry Id out of range" );
+ DBG_ASSERT( nNumVal < 256, "value out of range" );
+ nVal = (static_cast<sal_uInt32>(0xFFFF & nEID) << 16) |
+ (static_cast<sal_uInt32>(bHasNV ? 1 : 0) << 10) |
+ (static_cast<sal_uInt32>(bCheckable ? 1 : 0) << 9) |
+ (static_cast<sal_uInt32>(bChecked ? 1 : 0) << 8) |
+ static_cast<sal_uInt32>(0xFF & nNumVal);
+}
+
+void OptionsUserData::SetNumericValue( sal_uInt8 nNumVal )
+{
+ if (HasNumericValue() && (GetNumericValue() != nNumVal))
+ {
+ nVal &= 0xffffff00;
+ nVal |= nNumVal;
+ nVal |= sal_uInt32(1) << 11; // mark as modified
+ }
+}
+
+// ServiceInfo_Impl ----------------------------------------------------
+
+namespace {
+
+struct ServiceInfo_Impl
+{
+ OUString sDisplayName;
+ OUString sSpellImplName;
+ OUString sHyphImplName;
+ OUString sThesImplName;
+ OUString sGrammarImplName;
+ uno::Reference< XSpellChecker > xSpell;
+ uno::Reference< XHyphenator > xHyph;
+ uno::Reference< XThesaurus > xThes;
+ uno::Reference< XProofreader > xGrammar;
+ bool bConfigured;
+
+ ServiceInfo_Impl() : bConfigured(false) {}
+};
+
+}
+
+typedef std::vector< ServiceInfo_Impl > ServiceInfoArr;
+typedef std::map< LanguageType, Sequence< OUString > > LangImplNameTable;
+
+
+// SvxLinguData_Impl ----------------------------------------------------
+
+class SvxLinguData_Impl
+{
+ //contains services and implementation names sorted by implementation names
+ ServiceInfoArr aDisplayServiceArr;
+ sal_uInt32 nDisplayServices;
+
+ Sequence< Locale > aAllServiceLocales;
+ LangImplNameTable aCfgSpellTable;
+ LangImplNameTable aCfgHyphTable;
+ LangImplNameTable aCfgThesTable;
+ LangImplNameTable aCfgGrammarTable;
+ uno::Reference< XLinguServiceManager2 > xLinguSrvcMgr;
+
+
+ static bool AddRemove( Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd );
+
+public:
+ SvxLinguData_Impl();
+
+ uno::Reference<XLinguServiceManager2> & GetManager() { return xLinguSrvcMgr; }
+
+ void SetChecked( const Sequence< OUString > &rConfiguredServices );
+ void Reconfigure( std::u16string_view rDisplayName, bool bEnable );
+
+ const Sequence<Locale> & GetAllSupportedLocales() const { return aAllServiceLocales; }
+
+ LangImplNameTable & GetSpellTable() { return aCfgSpellTable; }
+ LangImplNameTable & GetHyphTable() { return aCfgHyphTable; }
+ LangImplNameTable & GetThesTable() { return aCfgThesTable; }
+ LangImplNameTable & GetGrammarTable() { return aCfgGrammarTable; }
+
+ ServiceInfoArr & GetDisplayServiceArray() { return aDisplayServiceArr; }
+
+ const sal_uInt32 & GetDisplayServiceCount() const { return nDisplayServices; }
+ void SetDisplayServiceCount( sal_uInt32 nVal ) { nDisplayServices = nVal; }
+
+ // returns the list of service implementation names for the specified
+ // language and service (TYPE_SPELL, TYPE_HYPH, TYPE_THES) sorted in
+ // the proper order for the SvxEditModulesDlg (the ones from the
+ // configuration (keeping that order!) first and then the other ones.
+ // I.e. the ones available but not configured in arbitrary order).
+ // They available ones may contain names that do not(!) support that
+ // language.
+ Sequence< OUString > GetSortedImplNames( LanguageType nLang, sal_uInt8 nType );
+
+ ServiceInfo_Impl * GetInfoByImplName( std::u16string_view rSvcImplName );
+};
+
+
+static sal_Int32 lcl_SeqGetIndex( const Sequence< OUString > &rSeq, std::u16string_view rTxt )
+{
+ sal_Int32 nRes = -1;
+ sal_Int32 nLen = rSeq.getLength();
+ const OUString *pString = rSeq.getConstArray();
+ for (sal_Int32 i = 0; i < nLen && nRes == -1; ++i)
+ {
+ if (pString[i] == rTxt)
+ nRes = i;
+ }
+ return nRes;
+}
+
+
+Sequence< OUString > SvxLinguData_Impl::GetSortedImplNames( LanguageType nLang, sal_uInt8 nType )
+{
+ LangImplNameTable *pTable = nullptr;
+ switch (nType)
+ {
+ case TYPE_SPELL : pTable = &aCfgSpellTable; break;
+ case TYPE_HYPH : pTable = &aCfgHyphTable; break;
+ case TYPE_THES : pTable = &aCfgThesTable; break;
+ case TYPE_GRAMMAR : pTable = &aCfgGrammarTable; break;
+ }
+ Sequence< OUString > aRes;
+ if (!pTable)
+ {
+ SAL_WARN( "cui.options", "unknown linguistic type" );
+ return aRes;
+ }
+ if (pTable->count( nLang ))
+ aRes = (*pTable)[ nLang ]; // add configured services
+ sal_Int32 nIdx = aRes.getLength();
+ DBG_ASSERT( static_cast<sal_Int32>(nDisplayServices) >= nIdx, "size mismatch" );
+ aRes.realloc( nDisplayServices );
+ OUString *pRes = aRes.getArray();
+
+ // add not configured services
+ for (sal_Int32 i = 0; i < static_cast<sal_Int32>(nDisplayServices); ++i)
+ {
+ const ServiceInfo_Impl &rInfo = aDisplayServiceArr[ i ];
+ OUString aImplName;
+ switch (nType)
+ {
+ case TYPE_SPELL : aImplName = rInfo.sSpellImplName; break;
+ case TYPE_HYPH : aImplName = rInfo.sHyphImplName; break;
+ case TYPE_THES : aImplName = rInfo.sThesImplName; break;
+ case TYPE_GRAMMAR : aImplName = rInfo.sGrammarImplName; break;
+ }
+
+ if (!aImplName.isEmpty() && (lcl_SeqGetIndex( aRes, aImplName) == -1)) // name not yet added
+ {
+ DBG_ASSERT( nIdx < aRes.getLength(), "index out of range" );
+ if (nIdx < aRes.getLength())
+ pRes[ nIdx++ ] = aImplName;
+ }
+ }
+ // don't forget to put aRes back to its actual size just in case you allocated too much
+ // since all of the names may have already been added
+ // otherwise you get duplicate entries in the edit dialog
+ aRes.realloc( nIdx );
+ return aRes;
+}
+
+
+ServiceInfo_Impl * SvxLinguData_Impl::GetInfoByImplName( std::u16string_view rSvcImplName )
+{
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl &rTmp = aDisplayServiceArr[ i ];
+ if (rTmp.sSpellImplName == rSvcImplName ||
+ rTmp.sHyphImplName == rSvcImplName ||
+ rTmp.sThesImplName == rSvcImplName ||
+ rTmp.sGrammarImplName == rSvcImplName)
+ {
+ return &rTmp;
+ }
+ }
+ return nullptr;
+}
+
+
+static void lcl_MergeLocales(Sequence< Locale >& aAllLocales, const Sequence< Locale >& rAdd)
+{
+ Sequence<Locale> aLocToAdd(rAdd.getLength());
+ Locale* pLocToAdd = aLocToAdd.getArray();
+ sal_Int32 nFound = 0;
+ for(const Locale& i : rAdd)
+ {
+ bool bFound = false;
+ for(const Locale& j : std::as_const(aAllLocales))
+ {
+ if (i.Language == j.Language &&
+ i.Country == j.Country &&
+ i.Variant == j.Variant)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if(!bFound)
+ {
+ pLocToAdd[nFound++] = i;
+ }
+ }
+ sal_Int32 nLength = aAllLocales.getLength();
+ aAllLocales.realloc( nLength + nFound);
+ Locale* pAllLocales2 = aAllLocales.getArray();
+ for(sal_Int32 i = 0; i < nFound; i++)
+ pAllLocales2[nLength++] = pLocToAdd[i];
+}
+
+static void lcl_MergeDisplayArray(
+ SvxLinguData_Impl &rData,
+ const ServiceInfo_Impl &rToAdd )
+{
+ sal_uInt32 nCnt = 0;
+
+ ServiceInfoArr &rSvcInfoArr = rData.GetDisplayServiceArray();
+ sal_uInt32 nEntries = rData.GetDisplayServiceCount();
+
+ for (sal_uInt32 i = 0; i < nEntries; ++i)
+ {
+ ServiceInfo_Impl& rEntry = rSvcInfoArr[i];
+ if (rEntry.sDisplayName == rToAdd.sDisplayName)
+ {
+ if(rToAdd.xSpell.is())
+ {
+ DBG_ASSERT( !rEntry.xSpell.is() &&
+ rEntry.sSpellImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sSpellImplName = rToAdd.sSpellImplName;
+ rEntry.xSpell = rToAdd.xSpell;
+ }
+ if(rToAdd.xGrammar.is())
+ {
+ DBG_ASSERT( !rEntry.xGrammar.is() &&
+ rEntry.sGrammarImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sGrammarImplName = rToAdd.sGrammarImplName;
+ rEntry.xGrammar = rToAdd.xGrammar;
+ }
+ if(rToAdd.xHyph.is())
+ {
+ DBG_ASSERT( !rEntry.xHyph.is() &&
+ rEntry.sHyphImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sHyphImplName = rToAdd.sHyphImplName;
+ rEntry.xHyph = rToAdd.xHyph;
+ }
+ if(rToAdd.xThes.is())
+ {
+ DBG_ASSERT( !rEntry.xThes.is() &&
+ rEntry.sThesImplName.isEmpty(),
+ "merge conflict" );
+ rEntry.sThesImplName = rToAdd.sThesImplName;
+ rEntry.xThes = rToAdd.xThes;
+ }
+ return ;
+ }
+ ++nCnt;
+ }
+ rData.GetDisplayServiceArray().push_back( rToAdd );
+ rData.SetDisplayServiceCount( nCnt + 1 );
+}
+
+SvxLinguData_Impl::SvxLinguData_Impl() :
+ nDisplayServices (0)
+{
+ uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ xLinguSrvcMgr = LinguServiceManager::create(xContext);
+
+ const Locale& rCurrentLocale = Application::GetSettings().GetLanguageTag().getLocale();
+ Sequence<Any> aArgs(2);//second arguments has to be empty!
+ aArgs.getArray()[0] <<= LinguMgr::GetLinguPropertySet();
+
+ //read spell checker
+ const Sequence< OUString > aSpellNames = xLinguSrvcMgr->getAvailableServices(
+ cSpell, Locale() );
+
+ for(const OUString& spellName : aSpellNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sSpellImplName = spellName;
+ aInfo.xSpell.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sSpellImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xSpell, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xSpell->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read grammar checker
+ const Sequence< OUString > aGrammarNames = xLinguSrvcMgr->getAvailableServices(
+ cGrammar, Locale() );
+ for(const OUString& grammarName : aGrammarNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sGrammarImplName = grammarName;
+ aInfo.xGrammar.set(
+ xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sGrammarImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xGrammar, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xGrammar->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read hyphenator
+ const Sequence< OUString > aHyphNames = xLinguSrvcMgr->getAvailableServices(
+ cHyph, Locale() );
+ for(const OUString& hyphName : aHyphNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sHyphImplName = hyphName;
+ aInfo.xHyph.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sHyphImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xHyph, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xHyph->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ //read thesauri
+ const Sequence< OUString > aThesNames = xLinguSrvcMgr->getAvailableServices(
+ cThes, Locale() );
+ for(const OUString& thesName : aThesNames)
+ {
+ ServiceInfo_Impl aInfo;
+ aInfo.sThesImplName = thesName;
+ aInfo.xThes.set( xContext->getServiceManager()->createInstanceWithArgumentsAndContext(aInfo.sThesImplName, aArgs, xContext), UNO_QUERY);
+
+ uno::Reference<XServiceDisplayName> xDispName(aInfo.xThes, UNO_QUERY);
+ if(xDispName.is())
+ aInfo.sDisplayName = xDispName->getServiceDisplayName( rCurrentLocale );
+
+ const Sequence< Locale > aLocales( aInfo.xThes->getLocales() );
+ //! suppress display of entries with no supported languages (see feature 110994)
+ if (aLocales.hasElements())
+ {
+ lcl_MergeLocales( aAllServiceLocales, aLocales );
+ lcl_MergeDisplayArray( *this, aInfo );
+ }
+ }
+
+ Sequence< OUString > aCfgSvcs;
+ for(auto const & locale : std::as_const(aAllServiceLocales))
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cSpell, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgSpellTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cGrammar, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgGrammarTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cHyph, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgHyphTable[ nLang ] = aCfgSvcs;
+
+ aCfgSvcs = xLinguSrvcMgr->getConfiguredServices(cThes, locale);
+ SetChecked( aCfgSvcs );
+ if (aCfgSvcs.hasElements())
+ aCfgThesTable[ nLang ] = aCfgSvcs;
+ }
+}
+
+void SvxLinguData_Impl::SetChecked(const Sequence<OUString>& rConfiguredServices)
+{
+ for(OUString const & configService : rConfiguredServices)
+ {
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rEntry = aDisplayServiceArr[i];
+ if (!rEntry.bConfigured)
+ {
+ const OUString &rSrvcImplName = configService;
+ if (!rSrvcImplName.isEmpty() &&
+ (rEntry.sSpellImplName == rSrvcImplName ||
+ rEntry.sGrammarImplName == rSrvcImplName ||
+ rEntry.sHyphImplName == rSrvcImplName ||
+ rEntry.sThesImplName == rSrvcImplName))
+ {
+ rEntry.bConfigured = true;
+ break;
+ }
+ }
+ }
+ }
+}
+
+bool SvxLinguData_Impl::AddRemove(
+ Sequence< OUString > &rConfigured,
+ const OUString &rImplName, bool bAdd )
+{
+ bool bRet = false; // modified?
+
+ sal_Int32 nEntries = rConfigured.getLength();
+ sal_Int32 nPos = lcl_SeqGetEntryPos(rConfigured, rImplName);
+ if (bAdd && nPos < 0) // add new entry
+ {
+ rConfigured.realloc( ++nEntries );
+ OUString *pConfigured = rConfigured.getArray();
+ pConfigured[nEntries - 1] = rImplName;
+ bRet = true;
+ }
+ else if (!bAdd && nPos >= 0) // remove existing entry
+ {
+ OUString *pConfigured = rConfigured.getArray();
+ for (sal_Int32 i = nPos; i < nEntries - 1; ++i)
+ pConfigured[i] = pConfigured[i + 1];
+ rConfigured.realloc(--nEntries);
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+
+void SvxLinguData_Impl::Reconfigure( std::u16string_view rDisplayName, bool bEnable )
+{
+ DBG_ASSERT( !rDisplayName.empty(), "empty DisplayName" );
+
+ ServiceInfo_Impl *pInfo = nullptr;
+ for (sal_uInt32 i = 0; i < nDisplayServices; ++i)
+ {
+ ServiceInfo_Impl& rTmp = aDisplayServiceArr[i];
+ if (rTmp.sDisplayName == rDisplayName)
+ {
+ pInfo = &rTmp;
+ break;
+ }
+ }
+ DBG_ASSERT( pInfo, "DisplayName entry not found" );
+ if (!pInfo)
+ return;
+
+ pInfo->bConfigured = bEnable;
+
+ Sequence< Locale > aLocales;
+ const Locale *pLocale = nullptr;
+ sal_Int32 nLocales = 0;
+ sal_Int32 i;
+
+ // update configured spellchecker entries
+ if (pInfo->xSpell.is())
+ {
+ aLocales = pInfo->xSpell->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgSpellTable.count( nLang ) && bEnable)
+ aCfgSpellTable[ nLang ] = Sequence< OUString >();
+ if (aCfgSpellTable.count( nLang ))
+ AddRemove( aCfgSpellTable[ nLang ], pInfo->sSpellImplName, bEnable );
+ }
+ }
+
+ // update configured grammar checker entries
+ if (pInfo->xGrammar.is())
+ {
+ aLocales = pInfo->xGrammar->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgGrammarTable.count( nLang ) && bEnable)
+ aCfgGrammarTable[ nLang ] = Sequence< OUString >();
+ if (aCfgGrammarTable.count( nLang ))
+ AddRemove( aCfgGrammarTable[ nLang ], pInfo->sGrammarImplName, bEnable );
+ }
+ }
+
+ // update configured hyphenator entries
+ if (pInfo->xHyph.is())
+ {
+ aLocales = pInfo->xHyph->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgHyphTable.count( nLang ) && bEnable)
+ aCfgHyphTable[ nLang ] = Sequence< OUString >();
+ if (aCfgHyphTable.count( nLang ))
+ AddRemove( aCfgHyphTable[ nLang ], pInfo->sHyphImplName, bEnable );
+ }
+ }
+
+ // update configured spellchecker entries
+ if (!pInfo->xThes.is())
+ return;
+
+ aLocales = pInfo->xThes->getLocales();
+ pLocale = aLocales.getConstArray();
+ nLocales = aLocales.getLength();
+ for (i = 0; i < nLocales; ++i)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pLocale[i] );
+ if (!aCfgThesTable.count( nLang ) && bEnable)
+ aCfgThesTable[ nLang ] = Sequence< OUString >();
+ if (aCfgThesTable.count( nLang ))
+ AddRemove( aCfgThesTable[ nLang ], pInfo->sThesImplName, bEnable );
+ }
+}
+
+
+// class SvxLinguTabPage -------------------------------------------------
+
+SvxLinguTabPage::SvxLinguTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optlingupage.ui", "OptLinguPage", &rSet)
+ , sCapitalWords (CuiResId(RID_CUISTR_CAPITAL_WORDS))
+ , sWordsWithDigits(CuiResId(RID_CUISTR_WORDS_WITH_DIGITS))
+ , sSpellSpecial (CuiResId(RID_CUISTR_SPELL_SPECIAL))
+ , sSpellAuto (CuiResId(RID_CUISTR_SPELL_AUTO))
+ , sGrammarAuto (CuiResId(RID_CUISTR_GRAMMAR_AUTO))
+ , sNumMinWordlen (CuiResId(RID_CUISTR_NUM_MIN_WORDLEN))
+ , sNumPreBreak (CuiResId(RID_CUISTR_NUM_PRE_BREAK))
+ , sNumPostBreak (CuiResId(RID_CUISTR_NUM_POST_BREAK))
+ , sHyphAuto (CuiResId(RID_CUISTR_HYPH_AUTO))
+ , sHyphSpecial (CuiResId(RID_CUISTR_HYPH_SPECIAL))
+ , nUPN_HYPH_MIN_WORD_LENGTH(-1)
+ , nUPN_HYPH_MIN_LEADING(-1)
+ , nUPN_HYPH_MIN_TRAILING(-1)
+ , m_nDlbClickEventId(nullptr)
+ , m_xLinguModulesFT(m_xBuilder->weld_label("lingumodulesft"))
+ , m_xLinguModulesCLB(m_xBuilder->weld_tree_view("lingumodules"))
+ , m_xLinguModulesEditPB(m_xBuilder->weld_button("lingumodulesedit"))
+ , m_xLinguDicsFT(m_xBuilder->weld_label("lingudictsft"))
+ , m_xLinguDicsCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xLinguDicsNewPB(m_xBuilder->weld_button("lingudictsnew"))
+ , m_xLinguDicsEditPB(m_xBuilder->weld_button("lingudictsedit"))
+ , m_xLinguDicsDelPB(m_xBuilder->weld_button("lingudictsdelete"))
+ , m_xLinguOptionsCLB(m_xBuilder->weld_tree_view("linguoptions"))
+ , m_xLinguOptionsEditPB(m_xBuilder->weld_button("linguoptionsedit"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+{
+ m_xLinguModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xLinguDicsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ m_xLinguOptionsCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ m_xLinguModulesCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguModulesCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+ m_xLinguModulesCLB->connect_toggled(LINK(this, SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl));
+
+ m_xLinguModulesEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguOptionsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguDicsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguDicsCLB->connect_toggled(LINK(this, SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl));
+
+ m_xLinguDicsNewPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsEditPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+ m_xLinguDicsDelPB->connect_clicked( LINK( this, SvxLinguTabPage, ClickHdl_Impl ));
+
+ m_xLinguOptionsCLB->connect_changed( LINK( this, SvxLinguTabPage, SelectHdl_Impl ));
+ m_xLinguOptionsCLB->connect_row_activated(LINK(this, SvxLinguTabPage, BoxDoubleClickHdl_Impl));
+
+ m_xMoreDictsLink->connect_activate_link(LINK(this, SvxLinguTabPage, OnLinkClick));
+ if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
+ m_xMoreDictsLink->hide();
+
+ xProp = LinguMgr::GetLinguPropertySet();
+ xDicList.set( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ // keep references to all **currently** available dictionaries,
+ // since the diclist may get changed meanwhile (e.g. through the API).
+ // We want the dialog to operate on the same set of dictionaries it
+ // was started with.
+ // Also we have to take care to not lose the last reference when
+ // someone else removes a dictionary from the list.
+ // removed dics will be replaced by NULL new entries be added to the end
+ // Thus we may use indices as consistent references.
+ aDics = xDicList->getDictionaries();
+
+ UpdateDicBox_Impl();
+ }
+ else
+ {
+ m_xLinguDicsFT->set_sensitive(false);
+ m_xLinguDicsCLB->set_sensitive(false);
+ m_xLinguDicsNewPB->set_sensitive(false);
+ m_xLinguDicsEditPB->set_sensitive(false);
+ m_xLinguDicsDelPB->set_sensitive(false);
+ }
+}
+
+SvxLinguTabPage::~SvxLinguTabPage()
+{
+ if (m_nDlbClickEventId)
+ {
+ Application::RemoveUserEvent(m_nDlbClickEventId);
+ m_nDlbClickEventId = nullptr;
+ }
+ pLinguData.reset();
+}
+
+std::unique_ptr<SfxTabPage> SvxLinguTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxLinguTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxLinguTabPage::FillItemSet( SfxItemSet* rCoreSet )
+{
+ bool bModified = true; // !!!!
+
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ DBG_ASSERT( pLinguData, "pLinguData not yet initialized" );
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ // update spellchecker configuration entries
+ const LangImplNameTable *pTable = &pLinguData->GetSpellTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cSpell, aLocale, aImplNames );
+ }
+
+ // update grammar checker configuration entries
+ pTable = &pLinguData->GetGrammarTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cGrammar, aLocale, aImplNames );
+ }
+
+ // update hyphenator configuration entries
+ pTable = &pLinguData->GetHyphTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cHyph, aLocale, aImplNames );
+ }
+
+ // update thesaurus configuration entries
+ pTable = &pLinguData->GetThesTable();
+ for (auto const& elem : *pTable)
+ {
+ LanguageType nLang = elem.first;
+ const Sequence< OUString > aImplNames(elem.second);
+ uno::Reference< XLinguServiceManager2 > xMgr( pLinguData->GetManager() );
+ Locale aLocale( LanguageTag::convertToLocale(nLang) );
+ if (xMgr.is())
+ xMgr->setConfiguredServices( cThes, aLocale, aImplNames );
+ }
+ }
+
+
+ // activate dictionaries according to checkbox state
+
+ Sequence< OUString > aActiveDics;
+ sal_Int32 nActiveDics = 0;
+ int nEntries = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nEntries; ++i)
+ {
+ sal_Int32 nDics = aDics.getLength();
+
+ aActiveDics.realloc( nDics );
+ OUString *pActiveDic = aActiveDics.getArray();
+
+ DicUserData aData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aData.GetEntryId() < nDics)
+ {
+ bool bChecked = m_xLinguDicsCLB->get_toggle(i) == TRISTATE_TRUE;
+ uno::Reference< XDictionary > xDic( aDics.getConstArray()[ i ] );
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ bChecked = true;
+ xDic->setActive( bChecked );
+
+ if (bChecked)
+ {
+ OUString aDicName( xDic->getName() );
+ pActiveDic[ nActiveDics++ ] = aDicName;
+ }
+ }
+ }
+ }
+
+ aActiveDics.realloc( nActiveDics );
+ Any aTmp;
+ aTmp <<= aActiveDics;
+ SvtLinguConfig aLngCfg;
+ aLngCfg.SetProperty( UPH_ACTIVE_DICTIONARIES, aTmp );
+
+
+ nEntries = m_xLinguOptionsCLB->n_children();
+ for (int j = 0; j < nEntries; ++j)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(j).toUInt32());
+ OUString aPropName( lcl_GetPropertyName( static_cast<EID_OPTIONS>(aData.GetEntryId()) ) );
+
+ Any aAny;
+ if (aData.IsCheckable())
+ {
+ bool bChecked = m_xLinguOptionsCLB->get_toggle(j) == TRISTATE_TRUE;
+ aAny <<= bChecked;
+ }
+ else if (aData.HasNumericValue())
+ {
+ sal_Int16 nVal = aData.GetNumericValue();
+ aAny <<= nVal;
+ }
+
+ if (xProp.is())
+ xProp->setPropertyValue( aPropName, aAny );
+ aLngCfg.SetProperty( aPropName, aAny );
+ }
+
+ OptionsUserData aPreBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_PRE_BREAK).toUInt32());
+ OptionsUserData aPostBreakData(m_xLinguOptionsCLB->get_id(EID_NUM_POST_BREAK).toUInt32());
+ if ( aPreBreakData.IsModified() || aPostBreakData.IsModified() )
+ {
+ SfxHyphenRegionItem aHyp( SID_ATTR_HYPHENREGION );
+ aHyp.GetMinLead() = static_cast<sal_uInt8>(aPreBreakData.GetNumericValue());
+ aHyp.GetMinTrail() = static_cast<sal_uInt8>(aPostBreakData.GetNumericValue());
+ rCoreSet->Put( aHyp );
+ }
+
+ // automatic spell checking
+ bool bNewAutoCheck = m_xLinguOptionsCLB->get_toggle(EID_SPELL_AUTO) == TRISTATE_TRUE;
+ const SfxPoolItem* pOld = GetOldItem( *rCoreSet, SID_AUTOSPELL_CHECK );
+ if ( !pOld || static_cast<const SfxBoolItem*>(pOld)->GetValue() != bNewAutoCheck )
+ {
+ rCoreSet->Put( SfxBoolItem( SID_AUTOSPELL_CHECK, bNewAutoCheck ) );
+ bModified = true;
+ }
+
+ return bModified;
+}
+
+sal_uInt32 SvxLinguTabPage::GetDicUserData( const uno::Reference< XDictionary > &rxDic, sal_uInt16 nIdx )
+{
+ sal_uInt32 nRes = 0;
+ DBG_ASSERT( rxDic.is(), "dictionary not supplied" );
+ if (rxDic.is())
+ {
+ uno::Reference< frame::XStorable > xStor( rxDic, UNO_QUERY );
+
+ bool bChecked = rxDic->isActive();
+ bool bEditable = !xStor.is() || !xStor->isReadonly();
+ bool bDeletable = bEditable;
+
+ nRes = DicUserData( nIdx,
+ bChecked, bEditable, bDeletable ).GetUserData();
+ }
+ return nRes;
+}
+
+
+void SvxLinguTabPage::AddDicBoxEntry(
+ const uno::Reference< XDictionary > &rxDic,
+ sal_uInt16 nIdx )
+{
+ m_xLinguDicsCLB->freeze();
+
+ OUString aTxt( ::GetDicInfoStr( rxDic->getName(),
+ LanguageTag( rxDic->getLocale() ).getLanguageType(),
+ DictionaryType_NEGATIVE == rxDic->getDictionaryType() ) );
+ m_xLinguDicsCLB->append(); // append at end
+ int nEntry = m_xLinguDicsCLB->n_children() - 1;
+ DicUserData aData( GetDicUserData( rxDic, nIdx ) );
+ m_xLinguDicsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ m_xLinguDicsCLB->set_toggle(nEntry, aData.IsChecked() ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguDicsCLB->set_text(nEntry, aTxt, 0); // append at end
+
+ m_xLinguDicsCLB->thaw();
+}
+
+void SvxLinguTabPage::UpdateDicBox_Impl()
+{
+ m_xLinguDicsCLB->freeze();
+ m_xLinguDicsCLB->clear();
+
+ sal_Int32 nDics = aDics.getLength();
+ const uno::Reference< XDictionary > *pDic = aDics.getConstArray();
+ for (sal_Int32 i = 0; i < nDics; ++i)
+ {
+ const uno::Reference< XDictionary > &rDic = pDic[i];
+ if (rDic.is())
+ AddDicBoxEntry( rDic, static_cast<sal_uInt16>(i) );
+ }
+
+ m_xLinguDicsCLB->thaw();
+ if (m_xLinguDicsCLB->n_children())
+ {
+ m_xLinguDicsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguDicsCLB);
+ }
+}
+
+void SvxLinguTabPage::UpdateModulesBox_Impl()
+{
+ if (!pLinguData)
+ return;
+
+ const ServiceInfoArr &rAllDispSrvcArr = pLinguData->GetDisplayServiceArray();
+ const sal_uInt32 nDispSrvcCount = pLinguData->GetDisplayServiceCount();
+
+ m_xLinguModulesCLB->clear();
+
+ for (sal_uInt32 i = 0; i < nDispSrvcCount; ++i)
+ {
+ const ServiceInfo_Impl &rInfo = rAllDispSrvcArr[i];
+ m_xLinguModulesCLB->append();
+ m_xLinguModulesCLB->set_id(i, weld::toId(&rInfo));
+ m_xLinguModulesCLB->set_toggle(i, rInfo.bConfigured ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguModulesCLB->set_text(i, rInfo.sDisplayName, 0);
+ }
+ if (nDispSrvcCount)
+ {
+ m_xLinguModulesCLB->select(0);
+ SelectHdl_Impl(*m_xLinguModulesCLB);
+ }
+ m_xLinguModulesEditPB->set_sensitive( nDispSrvcCount > 0 );
+}
+
+void SvxLinguTabPage::Reset( const SfxItemSet* rSet )
+{
+ // if not HideGroups was called with GROUP_MODULES...
+ if (m_xLinguModulesCLB->get_visible())
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+ UpdateModulesBox_Impl();
+ }
+
+
+ // get data from configuration
+ SvtLinguConfig aLngCfg;
+
+ m_xLinguOptionsCLB->freeze();
+ m_xLinguOptionsCLB->clear();
+
+ sal_Int16 nVal = 0;
+ bool bVal = false;
+ sal_uInt32 nUserData = 0;
+
+ m_xLinguOptionsCLB->append();
+ int nEntry = 0;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_AUTO ) >>= bVal;
+ const SfxPoolItem* pItem = GetItem( *rSet, SID_AUTOSPELL_CHECK );
+ if (pItem)
+ bVal = static_cast<const SfxBoolItem *>(pItem)->GetValue();
+ nUserData = OptionsUserData( EID_SPELL_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_GRAMMAR_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_GRAMMAR_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sGrammarAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_UPPER_CASE ) >>= bVal;
+ nUserData = OptionsUserData( EID_CAPITAL_WORDS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sCapitalWords, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_WITH_DIGITS ) >>= bVal;
+ nUserData = OptionsUserData( EID_WORDS_WITH_DIGITS, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sWordsWithDigits, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_SPELL_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_SPELL_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sSpellSpecial, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_WORD_LENGTH ) >>= nVal;
+ nUserData = OptionsUserData( EID_NUM_MIN_WORDLEN, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_WORD_LENGTH = nEntry;
+
+ const SfxHyphenRegionItem *pHyp = nullptr;
+ if ( rSet->GetItemState( SID_ATTR_HYPHENREGION, false ) == SfxItemState::SET )
+ pHyp = & rSet->Get( SID_ATTR_HYPHENREGION );
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_LEADING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinLead());
+ nUserData = OptionsUserData( EID_NUM_PRE_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_LEADING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_HYPH_MIN_TRAILING ) >>= nVal;
+ if (pHyp)
+ nVal = static_cast<sal_Int16>(pHyp->GetMinTrail());
+ nUserData = OptionsUserData( EID_NUM_POST_BREAK, true, static_cast<sal_uInt16>(nVal), false, false).GetUserData();
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+ nUPN_HYPH_MIN_TRAILING = nEntry;
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_AUTO ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_AUTO, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphAuto, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->append();
+ ++nEntry;
+
+ aLngCfg.GetProperty( UPN_IS_HYPH_SPECIAL ) >>= bVal;
+ nUserData = OptionsUserData( EID_HYPH_SPECIAL, false, 0, true, bVal).GetUserData();
+ m_xLinguOptionsCLB->set_toggle(nEntry, bVal ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xLinguOptionsCLB->set_text(nEntry, sHyphSpecial, 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(nUserData));
+
+ m_xLinguOptionsCLB->thaw();
+
+ m_xLinguOptionsCLB->select(0);
+ SelectHdl_Impl(*m_xLinguOptionsCLB);
+
+ m_xLinguModulesCLB->set_size_request(m_xLinguModulesCLB->get_preferred_size().Width(),
+ m_xLinguModulesCLB->get_height_rows(3));
+ m_xLinguDicsCLB->set_size_request(m_xLinguDicsCLB->get_preferred_size().Width(),
+ m_xLinguDicsCLB->get_height_rows(5));
+ m_xLinguOptionsCLB->set_size_request(m_xLinguOptionsCLB->get_preferred_size().Width(),
+ m_xLinguOptionsCLB->get_height_rows(5));
+}
+
+IMPL_LINK(SvxLinguTabPage, BoxDoubleClickHdl_Impl, weld::TreeView&, rBox, bool)
+{
+ if (&rBox == m_xLinguModulesCLB.get() && !m_nDlbClickEventId)
+ {
+ //! in order to avoid a bug causing a GPF when double clicking
+ //! on a module entry and exiting the "Edit Modules" dialog
+ //! after that.
+ m_nDlbClickEventId = Application::PostUserEvent(LINK(this, SvxLinguTabPage, PostDblClickHdl_Impl));
+ }
+ else if (&rBox == m_xLinguOptionsCLB.get())
+ {
+ ClickHdl_Impl(*m_xLinguOptionsEditPB);
+ }
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxLinguTabPage, PostDblClickHdl_Impl, void*, void)
+{
+ m_nDlbClickEventId = nullptr;
+ ClickHdl_Impl(*m_xLinguModulesEditPB);
+}
+
+IMPL_LINK(SvxLinguTabPage, ModulesBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ if (!pLinguData)
+ return;
+ pLinguData->Reconfigure(m_xLinguModulesCLB->get_text(rRowCol.first),
+ m_xLinguModulesCLB->get_toggle(rRowCol.first) == TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxLinguTabPage, DicsBoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
+{
+ const uno::Reference<XDictionary> &rDic = aDics.getConstArray()[m_xLinguDicsCLB->get_iter_index_in_parent(rRowCol.first)];
+ if (LinguMgr::GetIgnoreAllList() == rDic)
+ m_xLinguDicsCLB->set_toggle(rRowCol.first, TRISTATE_TRUE);
+}
+
+IMPL_LINK(SvxLinguTabPage, ClickHdl_Impl, weld::Button&, rBtn, void)
+{
+ if (m_xLinguModulesEditPB.get() == &rBtn)
+ {
+ if (!pLinguData)
+ pLinguData.reset( new SvxLinguData_Impl );
+
+ SvxLinguData_Impl aOldLinguData( *pLinguData );
+ SvxEditModulesDlg aDlg(GetFrameWeld(), *pLinguData);
+ if (aDlg.run() != RET_OK)
+ *pLinguData = aOldLinguData;
+
+ // evaluate new status of 'bConfigured' flag
+ sal_uInt32 nLen = pLinguData->GetDisplayServiceCount();
+ for (sal_uInt32 i = 0; i < nLen; ++i)
+ pLinguData->GetDisplayServiceArray()[i].bConfigured = false;
+ const Locale* pAllLocales = pLinguData->GetAllSupportedLocales().getConstArray();
+ sal_Int32 nLocales = pLinguData->GetAllSupportedLocales().getLength();
+ for (sal_Int32 k = 0; k < nLocales; ++k)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( pAllLocales[k] );
+ if (pLinguData->GetSpellTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetSpellTable()[ nLang ] );
+ if (pLinguData->GetGrammarTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetGrammarTable()[ nLang ] );
+ if (pLinguData->GetHyphTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetHyphTable()[ nLang ] );
+ if (pLinguData->GetThesTable().count( nLang ))
+ pLinguData->SetChecked( pLinguData->GetThesTable()[ nLang ] );
+ }
+
+ // show new status of modules
+ UpdateModulesBox_Impl();
+ }
+ else if (m_xLinguDicsNewPB.get() == &rBtn)
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNewDictionaryDialog> aDlg(pFact->CreateSvxNewDictionaryDialog(GetFrameWeld()));
+ uno::Reference< XDictionary > xNewDic;
+ if ( aDlg->Execute() == RET_OK )
+ xNewDic = aDlg->GetNewDictionary();
+ if ( xNewDic.is() )
+ {
+ // add new dics to the end
+ sal_Int32 nLen = aDics.getLength();
+ aDics.realloc( nLen + 1 );
+
+ aDics.getArray()[ nLen ] = xNewDic;
+
+ AddDicBoxEntry( xNewDic, static_cast<sal_uInt16>(nLen) );
+ }
+ }
+ else if (m_xLinguDicsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<VclAbstractDialog> aDlg(pFact->CreateSvxEditDictionaryDialog(GetFrameWeld(), xDic->getName()));
+ aDlg->Execute();
+ }
+ }
+ }
+ }
+ else if (m_xLinguDicsDelPB.get() == &rBtn)
+ {
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(GetFrameWeld(), "cui/ui/querydeletedictionarydialog.ui"));
+ std::unique_ptr<weld::MessageDialog> xQuery(xBuilder->weld_message_dialog("QueryDeleteDictionaryDialog"));
+ if (RET_NO == xQuery->run())
+ return;
+
+ int nEntry = m_xLinguDicsCLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(m_xLinguDicsCLB->get_id(nEntry).toUInt32());
+ sal_uInt16 nDicPos = aData.GetEntryId();
+ sal_Int32 nDics = aDics.getLength();
+ if (nDicPos < nDics)
+ {
+ uno::Reference< XDictionary > xDic = aDics.getConstArray()[ nDicPos ];
+ if (xDic.is())
+ {
+ if (LinguMgr::GetIgnoreAllList() == xDic)
+ xDic->clear();
+ else
+ {
+ if (xDicList.is())
+ xDicList->removeDictionary( xDic );
+
+ uno::Reference< frame::XStorable > xStor( xDic, UNO_QUERY );
+ if ( xStor->hasLocation() && !xStor->isReadonly() )
+ {
+ OUString sURL = xStor->getLocation();
+ INetURLObject aObj(sURL);
+ DBG_ASSERT( aObj.GetProtocol() == INetProtocol::File,
+ "non-file URLs cannot be deleted" );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ {
+ KillFile_Impl( aObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+ }
+ }
+
+ aDics.getArray()[ nDicPos ] = nullptr;
+
+ // remove entry from checklistbox
+ int nCnt = m_xLinguDicsCLB->n_children();
+ for (int i = 0; i < nCnt; ++i)
+ {
+ DicUserData aDicData(m_xLinguDicsCLB->get_id(i).toUInt32());
+ if (aDicData.GetEntryId() == nDicPos )
+ {
+ m_xLinguDicsCLB->remove(i);
+ break;
+ }
+ }
+ DBG_ASSERT( nCnt > m_xLinguDicsCLB->n_children(),
+ "remove failed ?");
+ }
+ }
+ }
+ }
+ }
+ else if (m_xLinguOptionsEditPB.get() == &rBtn)
+ {
+ int nEntry = m_xLinguOptionsCLB->get_selected_index();
+ DBG_ASSERT(nEntry != -1, "no entry selected");
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(m_xLinguOptionsCLB->get_id(nEntry).toUInt32());
+ if (aData.HasNumericValue())
+ {
+ sal_uInt16 nRID = aData.GetEntryId();
+ OptionsBreakSet aDlg(GetFrameWeld(), nRID);
+ aDlg.GetNumericFld().set_value(aData.GetNumericValue());
+ if (RET_OK == aDlg.run())
+ {
+ int nVal = aDlg.GetNumericFld().get_value();
+ if (-1 != nVal && aData.GetNumericValue() != nVal)
+ {
+ aData.SetNumericValue( static_cast<sal_uInt8>(nVal) ); //! sets IsModified !
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ if (nEntry == nUPN_HYPH_MIN_WORD_LENGTH)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumMinWordlen + " " + OUString::number(nVal), 0);
+ else if (nEntry == nUPN_HYPH_MIN_LEADING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPreBreak + " " + OUString::number(nVal), 0);
+ else if (nEntry == nUPN_HYPH_MIN_TRAILING)
+ m_xLinguOptionsCLB->set_text(nEntry, sNumPostBreak + " " + OUString::number(nVal), 0);
+ m_xLinguOptionsCLB->set_id(nEntry, OUString::number(aData.GetUserData()));
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBtn unexpected value" );
+ }
+}
+
+IMPL_LINK(SvxLinguTabPage, SelectHdl_Impl, weld::TreeView&, rBox, void)
+{
+ if (m_xLinguModulesCLB.get() == &rBox)
+ {
+ }
+ else if (m_xLinguDicsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ DicUserData aData(rBox.get_id(nEntry).toUInt32());
+
+ // always allow to edit (i.e. at least view the content of the dictionary)
+ m_xLinguDicsEditPB->set_sensitive( true );
+ m_xLinguDicsDelPB->set_sensitive( aData.IsDeletable() );
+ }
+ }
+ else if (m_xLinguOptionsCLB.get() == &rBox)
+ {
+ int nEntry = rBox.get_selected_index();
+ if (nEntry != -1)
+ {
+ OptionsUserData aData(rBox.get_id(nEntry).toUInt32());
+ m_xLinguOptionsEditPB->set_sensitive( aData.HasNumericValue() );
+ }
+ }
+ else
+ {
+ OSL_FAIL( "rBox unexpected value" );
+ }
+}
+
+void SvxLinguTabPage::HideGroups( sal_uInt16 nGrp )
+{
+ if ( 0 != ( GROUP_MODULES & nGrp ) )
+ {
+ m_xLinguModulesFT->hide();
+ m_xLinguModulesCLB->hide();
+ m_xLinguModulesEditPB->hide();
+
+ if (officecfg::Office::Security::Hyperlinks::Open::get() != SvtExtendedSecurityOptions::OPEN_NEVER)
+ {
+ m_xMoreDictsLink->show();
+ }
+ }
+}
+
+IMPL_STATIC_LINK_NOARG(SvxLinguTabPage, OnLinkClick, weld::LinkButton&, bool)
+{
+ comphelper::dispatchCommand(".uno:MoreDictionaries", {});
+ return true;
+}
+
+SvxEditModulesDlg::SvxEditModulesDlg(weld::Window* pParent, SvxLinguData_Impl& rData)
+ : GenericDialogController(pParent, "cui/ui/editmodulesdialog.ui", "EditModulesDialog")
+ , sSpell(CuiResId(RID_CUISTR_SPELL))
+ , sHyph(CuiResId(RID_CUISTR_HYPH))
+ , sThes(CuiResId(RID_CUISTR_THES))
+ , sGrammar(CuiResId(RID_CUISTR_GRAMMAR))
+ , rLinguData(rData)
+ , m_xModulesCLB(m_xBuilder->weld_tree_view("lingudicts"))
+ , m_xPrioUpPB(m_xBuilder->weld_button("up"))
+ , m_xPrioDownPB(m_xBuilder->weld_button("down"))
+ , m_xBackPB(m_xBuilder->weld_button("back"))
+ , m_xMoreDictsLink(m_xBuilder->weld_link_button("moredictslink"))
+ , m_xClosePB(m_xBuilder->weld_button("close"))
+ , m_xLanguageLB(new SvxLanguageBox(m_xBuilder->weld_combo_box("language")))
+{
+ m_xModulesCLB->set_size_request(m_xModulesCLB->get_approximate_digit_width() * 40,
+ m_xModulesCLB->get_height_rows(12));
+
+ m_xModulesCLB->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ pDefaultLinguData.reset( new SvxLinguData_Impl( rLinguData ) );
+
+ m_xModulesCLB->connect_changed( LINK( this, SvxEditModulesDlg, SelectHdl_Impl ));
+ m_xModulesCLB->connect_toggled(LINK(this, SvxEditModulesDlg, BoxCheckButtonHdl_Impl));
+
+ m_xClosePB->connect_clicked( LINK( this, SvxEditModulesDlg, ClickHdl_Impl ));
+ m_xPrioUpPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xPrioDownPB->connect_clicked( LINK( this, SvxEditModulesDlg, UpDownHdl_Impl ));
+ m_xBackPB->connect_clicked( LINK( this, SvxEditModulesDlg, BackHdl_Impl ));
+ // in case of not installed language modules
+ m_xPrioUpPB->set_sensitive( false );
+ m_xPrioDownPB->set_sensitive( false );
+
+ m_xMoreDictsLink->connect_activate_link(LINK(this, SvxEditModulesDlg, OnLinkClick));
+ if (officecfg::Office::Security::Hyperlinks::Open::get() == SvtExtendedSecurityOptions::OPEN_NEVER)
+ m_xMoreDictsLink->hide();
+
+ // set that we want the checkbox shown if spellchecking is available
+ m_xLanguageLB->SetLanguageList(SvxLanguageListFlags::EMPTY, false, false, true);
+
+ //fill language box
+ const Sequence< Locale >& rLoc = rLinguData.GetAllSupportedLocales();
+ for (Locale const & locale : rLoc)
+ {
+ LanguageType nLang = LanguageTag::convertToLanguageType( locale );
+ m_xLanguageLB->InsertLanguage(nLang);
+ }
+ LanguageType eSysLang = MsLangId::getConfiguredSystemLanguage();
+ m_xLanguageLB->set_active_id( eSysLang );
+ if (m_xLanguageLB->get_active_id() != eSysLang)
+ m_xLanguageLB->set_active(0);
+
+ m_xLanguageLB->connect_changed( LINK( this, SvxEditModulesDlg, LangSelectListBoxHdl_Impl ));
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+SvxEditModulesDlg::~SvxEditModulesDlg()
+{
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+}
+
+IMPL_LINK( SvxEditModulesDlg, SelectHdl_Impl, weld::TreeView&, rBox, void )
+{
+ int nCurPos = rBox.get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ bool bDisableUp = true;
+ bool bDisableDown = true;
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos));
+ if (!pData->IsParent() && pData->GetType() != TYPE_HYPH)
+ {
+ if (nCurPos < rBox.n_children() - 1)
+ {
+ bDisableDown = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos + 1))->IsParent();
+ }
+ if (nCurPos > 1)
+ {
+ bDisableUp = weld::fromId<ModuleUserData_Impl*>(rBox.get_id(nCurPos - 1))->IsParent();
+ }
+ }
+ m_xPrioUpPB->set_sensitive(!bDisableUp);
+ m_xPrioDownPB->set_sensitive(!bDisableDown);
+}
+
+IMPL_LINK( SvxEditModulesDlg, BoxCheckButtonHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void )
+{
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(rRowCol.first));
+ if (pData->IsParent() || pData->GetType() != TYPE_HYPH)
+ return;
+
+ // make hyphenator checkboxes function as radio-buttons
+ // (at most one box may be checked)
+ auto nPos = m_xModulesCLB->get_iter_index_in_parent(rRowCol.first);
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ if (!pData->IsParent() && pData->GetType() == TYPE_HYPH && i != nPos)
+ {
+ m_xModulesCLB->set_toggle(i, TRISTATE_FALSE);
+ }
+ }
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, LangSelectListBoxHdl_Impl, weld::ComboBox&, void)
+{
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+}
+
+void SvxEditModulesDlg::LangSelectHdl_Impl(const SvxLanguageBox* pBox)
+{
+ LanguageType eCurLanguage = m_xLanguageLB->get_active_id();
+ static Locale aLastLocale;
+ Locale aCurLocale( LanguageTag::convertToLocale( eCurLanguage));
+
+ if (pBox)
+ {
+ // save old probably changed settings
+ // before switching to new language entries
+
+ LanguageType nLang = LanguageTag::convertToLanguageType( aLastLocale );
+
+ sal_Int32 nStart = 0, nLocalIndex = 0;
+ Sequence< OUString > aChange;
+ bool bChanged = false;
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ {
+ ModuleUserData_Impl* pData = weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ if (pData->IsParent())
+ {
+ if (bChanged)
+ {
+ LangImplNameTable *pTable = nullptr;
+ sal_uInt8 nType = pData->GetType();
+ switch (nType - 1)
+ {
+ case TYPE_SPELL : pTable = &rLinguData.GetSpellTable(); break;
+ case TYPE_GRAMMAR : pTable = &rLinguData.GetGrammarTable(); break;
+ case TYPE_HYPH : pTable = &rLinguData.GetHyphTable(); break;
+ case TYPE_THES : pTable = &rLinguData.GetThesTable(); break;
+ }
+ if (pTable)
+ {
+ aChange.realloc(nStart);
+ (*pTable)[ nLang ] = aChange;
+ }
+ }
+ nLocalIndex = nStart = 0;
+ aChange.realloc(nEntryCount);
+ bChanged = false;
+ }
+ else
+ {
+ OUString* pChange = aChange.getArray();
+ pChange[nStart] = pData->GetImplName();
+ bChanged |= pData->GetIndex() != nLocalIndex ||
+ static_cast<TriState>(pData->IsChecked()) != m_xModulesCLB->get_toggle(i);
+ if (m_xModulesCLB->get_toggle(i))
+ nStart++;
+ ++nLocalIndex;
+ }
+ }
+ if(bChanged)
+ {
+ aChange.realloc(nStart);
+ rLinguData.GetThesTable()[ nLang ] = aChange;
+ }
+ }
+
+ for (int i = 0, nEntryCount = m_xModulesCLB->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<ModuleUserData_Impl*>(m_xModulesCLB->get_id(i));
+ m_xModulesCLB->clear();
+
+ // display entries for new selected language
+
+ if (LANGUAGE_DONTKNOW != eCurLanguage)
+ {
+ sal_Int32 n;
+ ServiceInfo_Impl* pInfo;
+
+ int nRow = 0;
+ // spellchecker entries
+
+ ModuleUserData_Impl* pUserData = new ModuleUserData_Impl(
+ OUString(), true, false, TYPE_SPELL, 0 );
+ OUString sId(weld::toId(pUserData));
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sSpell, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ Sequence< OUString > aNames( rLinguData.GetSortedImplNames( eCurLanguage, TYPE_SPELL ) );
+ const OUString *pName = aNames.getConstArray();
+ sal_Int32 nNames = aNames.getLength();
+ sal_Int32 nLocalIndex = 0; // index relative to parent
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xSpell.is() &&
+ pInfo->xSpell->hasLocale( aCurLocale );
+ aImplName = pInfo->sSpellImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetSpellTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_SPELL, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // grammar checker entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_GRAMMAR, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sGrammar, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_GRAMMAR );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xGrammar.is() &&
+ pInfo->xGrammar->hasLocale( aCurLocale );
+ aImplName = pInfo->sGrammarImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetGrammarTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_GRAMMAR, static_cast<sal_uInt8>(nLocalIndex++) );
+
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // hyphenator entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_HYPH, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sHyph, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_HYPH );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xHyph.is() &&
+ pInfo->xHyph->hasLocale( aCurLocale );
+ aImplName = pInfo->sHyphImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetHyphTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_HYPH, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+
+ // thesaurus entries
+
+ pUserData = new ModuleUserData_Impl( OUString(), true, false, TYPE_THES, 0 );
+ sId = weld::toId(pUserData);
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_text(nRow, sThes, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, true, 0);
+ ++nRow;
+
+ aNames = rLinguData.GetSortedImplNames( eCurLanguage, TYPE_THES );
+ pName = aNames.getConstArray();
+ nNames = aNames.getLength();
+ nLocalIndex = 0;
+ for (n = 0; n < nNames; ++n)
+ {
+ OUString aImplName;
+ bool bIsSuppLang = false;
+
+ pInfo = rLinguData.GetInfoByImplName( pName[n] );
+ if (pInfo)
+ {
+ bIsSuppLang = pInfo->xThes.is() &&
+ pInfo->xThes->hasLocale( aCurLocale );
+ aImplName = pInfo->sThesImplName;
+ }
+ if (!aImplName.isEmpty() && bIsSuppLang)
+ {
+ OUString aTxt( pInfo->sDisplayName );
+
+ LangImplNameTable &rTable = rLinguData.GetThesTable();
+ const bool bHasLang = rTable.count( eCurLanguage );
+ if (!bHasLang)
+ {
+ SAL_INFO( "cui.options", "language entry missing" ); // only relevant if all languages found should be supported
+ }
+ const bool bCheck = bHasLang && lcl_SeqGetEntryPos( rTable[ eCurLanguage ], aImplName ) >= 0;
+ pUserData = new ModuleUserData_Impl( aImplName, false,
+ bCheck, TYPE_THES, static_cast<sal_uInt8>(nLocalIndex++) );
+ sId = weld::toId(pUserData);
+
+ m_xModulesCLB->append(nullptr);
+ m_xModulesCLB->set_id(nRow, sId);
+ m_xModulesCLB->set_toggle(nRow, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ m_xModulesCLB->set_text(nRow, aTxt, 0);
+ m_xModulesCLB->set_text_emphasis(nRow, false, 0);
+ ++nRow;
+ }
+ }
+ }
+ aLastLocale = aCurLocale;
+}
+
+IMPL_LINK( SvxEditModulesDlg, UpDownHdl_Impl, weld::Button&, rBtn, void )
+{
+ bool bUp = m_xPrioUpPB.get() == &rBtn;
+ int nCurPos = m_xModulesCLB->get_selected_index();
+ if (nCurPos == -1)
+ return;
+
+ m_xModulesCLB->freeze();
+
+ OUString sId(m_xModulesCLB->get_id(nCurPos));
+ OUString sStr(m_xModulesCLB->get_text(nCurPos));
+ bool bIsChecked = m_xModulesCLB->get_toggle(nCurPos);
+
+ m_xModulesCLB->remove(nCurPos);
+
+ int nDestPos = bUp ? nCurPos - 1 : nCurPos + 1;
+
+ m_xModulesCLB->insert_text(nDestPos, sStr);
+ m_xModulesCLB->set_id(nDestPos, sId);
+ m_xModulesCLB->set_toggle(nDestPos, bIsChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
+
+ m_xModulesCLB->thaw();
+
+ m_xModulesCLB->select(nDestPos);
+ SelectHdl_Impl(*m_xModulesCLB);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, ClickHdl_Impl, weld::Button&, void)
+{
+ // store language config
+ LangSelectHdl_Impl(m_xLanguageLB.get());
+ m_xDialog->response(RET_OK);
+}
+
+IMPL_LINK_NOARG(SvxEditModulesDlg, BackHdl_Impl, weld::Button&, void)
+{
+ rLinguData = *pDefaultLinguData;
+ LangSelectHdl_Impl(nullptr);
+}
+
+IMPL_STATIC_LINK_NOARG(SvxEditModulesDlg, OnLinkClick, weld::LinkButton&, bool)
+{
+ comphelper::dispatchCommand(".uno:MoreDictionaries", {});
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.cxx b/cui/source/options/optopencl.cxx
new file mode 100644
index 000000000..e85ef1d7e
--- /dev/null
+++ b/cui/source/options/optopencl.cxx
@@ -0,0 +1,88 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/weld.hxx>
+#include <opencl/openclconfig.hxx>
+#include <opencl/openclwrapper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <svtools/restartdialog.hxx>
+
+#include "optopencl.hxx"
+
+SvxOpenCLTabPage::SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optopenclpage.ui", "OptOpenCLPage", &rSet)
+ , maConfig(OpenCLConfig::get())
+ , mxUseOpenCL(m_xBuilder->weld_check_button("useopencl"))
+ , mxOclUsed(m_xBuilder->weld_label("openclused"))
+ , mxOclNotUsed(m_xBuilder->weld_label("openclnotused"))
+{
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->set_sensitive(!officecfg::Office::Common::Misc::UseOpenCL::isReadOnly());
+
+ bool bCLUsed = openclwrapper::GPUEnv::isOpenCLEnabled();
+ mxOclUsed->set_visible(bCLUsed);
+ mxOclNotUsed->set_visible(!bCLUsed);
+}
+
+SvxOpenCLTabPage::~SvxOpenCLTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxOpenCLTabPage::Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxOpenCLTabPage>(pPage, pController, *rAttrSet);
+}
+
+bool SvxOpenCLTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ if (mxUseOpenCL->get_state_changed_from_saved())
+ maConfig.mbUseOpenCL = mxUseOpenCL->get_active();
+
+ if (maConfig != OpenCLConfig::get())
+ {
+ maConfig.set();
+ bModified = true;
+ }
+
+ if (bModified)
+ {
+ batch->commit();
+ SolarMutexGuard aGuard;
+ if (svtools::executeRestartDialog(comphelper::getProcessComponentContext(), nullptr,
+ svtools::RESTART_REASON_OPENCL))
+ GetDialogController()->response(RET_OK);
+ }
+
+ return bModified;
+}
+
+void SvxOpenCLTabPage::Reset( const SfxItemSet* )
+{
+ maConfig = OpenCLConfig::get();
+
+ mxUseOpenCL->set_active(maConfig.mbUseOpenCL);
+ mxUseOpenCL->save_state();
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optopencl.hxx b/cui/source/options/optopencl.hxx
new file mode 100644
index 000000000..f7097d3fd
--- /dev/null
+++ b/cui/source/options/optopencl.hxx
@@ -0,0 +1,42 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <opencl/openclconfig.hxx>
+#include <sfx2/tabdlg.hxx>
+
+class SvxOpenCLTabPage : public SfxTabPage
+{
+private:
+ OpenCLConfig maConfig;
+
+ std::unique_ptr<weld::CheckButton> mxUseOpenCL;
+ std::unique_ptr<weld::Label> mxOclUsed;
+ std::unique_ptr<weld::Label> mxOclNotUsed;
+
+public:
+ SvxOpenCLTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOpenCLTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optpath.cxx b/cui/source/options/optpath.cxx
new file mode 100644
index 000000000..18c3e32a1
--- /dev/null
+++ b/cui/source/options/optpath.cxx
@@ -0,0 +1,697 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/svxdlg.hxx>
+#include <sfx2/filedlghelper.hxx>
+#include <sfx2/app.hxx>
+#include <tools/urlobj.hxx>
+#include <unotools/defaultoptions.hxx>
+#include <unotools/pathoptions.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/viewoptions.hxx>
+
+#include <bitmaps.hlst>
+#include <dialmgr.hxx>
+#include <optpath.hxx>
+#include <strings.hrc>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <com/sun/star/uno/Exception.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/util/thePathSettings.hpp>
+#include <tools/diagnose_ex.h>
+#include <sal/log.hxx>
+#include <o3tl/string_view.hxx>
+
+using namespace css;
+using namespace css::beans;
+using namespace css::lang;
+using namespace css::ui::dialogs;
+using namespace css::uno;
+using namespace svx;
+
+// define ----------------------------------------------------------------
+
+constexpr OUStringLiteral POSTFIX_INTERNAL = u"_internal";
+constexpr OUStringLiteral POSTFIX_USER = u"_user";
+constexpr OUStringLiteral POSTFIX_WRITABLE = u"_writable";
+constexpr OUStringLiteral VAR_ONE = u"%1";
+constexpr OUStringLiteral IODLG_CONFIGNAME = u"FilePicker_Save";
+
+// struct OptPath_Impl ---------------------------------------------------
+
+struct OptPath_Impl
+{
+ OUString m_sMultiPathDlg;
+ Reference< css::util::XPathSettings > m_xPathSettings;
+
+ OptPath_Impl()
+ : m_sMultiPathDlg(CuiResId(RID_CUISTR_EDIT_PATHS))
+ {
+ }
+};
+
+namespace {
+
+struct PathUserData_Impl
+{
+ SvtPathOptions::Paths nRealId;
+ bool bItemStateSet;
+ OUString sUserPath;
+ OUString sWritablePath;
+ bool bReadOnly;
+
+ explicit PathUserData_Impl(SvtPathOptions::Paths nId)
+ : nRealId(nId)
+ , bItemStateSet(false)
+ , bReadOnly(false)
+ {
+ }
+};
+
+struct Handle2CfgNameMapping_Impl
+{
+ SvtPathOptions::Paths m_nHandle;
+ const char* m_pCfgName;
+};
+
+}
+
+Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
+{
+ { SvtPathOptions::Paths::AutoCorrect, "AutoCorrect" },
+ { SvtPathOptions::Paths::AutoText, "AutoText" },
+ { SvtPathOptions::Paths::Backup, "Backup" },
+ { SvtPathOptions::Paths::Gallery, "Gallery" },
+ { SvtPathOptions::Paths::Graphic, "Graphic" },
+ { SvtPathOptions::Paths::Temp, "Temp" },
+ { SvtPathOptions::Paths::Template, "Template" },
+ { SvtPathOptions::Paths::Work, "Work" },
+ { SvtPathOptions::Paths::Dictionary, "Dictionary" },
+ { SvtPathOptions::Paths::Classification, "Classification" },
+#if OSL_DEBUG_LEVEL > 1
+ { SvtPathOptions::Paths::Linguistic, "Linguistic" },
+#endif
+ { SvtPathOptions::Paths::LAST, nullptr }
+};
+
+static OUString getCfgName_Impl( SvtPathOptions::Paths _nHandle )
+{
+ OUString sCfgName;
+ sal_uInt16 nIndex = 0;
+ while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != SvtPathOptions::Paths::LAST )
+ {
+ if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
+ {
+ // config name found
+ sCfgName = OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
+ break;
+ }
+ ++nIndex;
+ }
+
+ return sCfgName;
+}
+
+#define MULTIPATH_DELIMITER ';'
+
+static OUString Convert_Impl( std::u16string_view rValue )
+{
+ if (rValue.empty())
+ return OUString();
+
+ sal_Int32 nPos = 0;
+ OUStringBuffer aReturn;
+ for (;;)
+ {
+ OUString aValue( o3tl::getToken(rValue, 0, MULTIPATH_DELIMITER, nPos ) );
+ INetURLObject aObj( aValue );
+ if ( aObj.GetProtocol() == INetProtocol::File )
+ aReturn.append(aObj.PathToFileName());
+ if ( nPos < 0 )
+ break;
+ aReturn.append(MULTIPATH_DELIMITER);
+ }
+
+ return aReturn.makeStringAndClear();
+}
+
+// functions -------------------------------------------------------------
+
+static bool IsMultiPath_Impl( const SvtPathOptions::Paths nIndex )
+{
+#if OSL_DEBUG_LEVEL > 1
+ return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
+ SvtPathOptions::Paths::AutoText == nIndex ||
+ SvtPathOptions::Paths::Basic == nIndex ||
+ SvtPathOptions::Paths::Gallery == nIndex ||
+ SvtPathOptions::Paths::Template == nIndex );
+#else
+ return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
+ SvtPathOptions::Paths::AutoText == nIndex ||
+ SvtPathOptions::Paths::Basic == nIndex ||
+ SvtPathOptions::Paths::Gallery == nIndex ||
+ SvtPathOptions::Paths::Template == nIndex ||
+ SvtPathOptions::Paths::Linguistic == nIndex ||
+ SvtPathOptions::Paths::Dictionary == nIndex );
+#endif
+}
+
+// class SvxPathTabPage --------------------------------------------------
+
+SvxPathTabPage::SvxPathTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optpathspage.ui", "OptPathsPage", &rSet)
+ , pImpl(new OptPath_Impl)
+ , xDialogListener ( new ::svt::DialogClosedListener() )
+ , m_xStandardBtn(m_xBuilder->weld_button("default"))
+ , m_xPathBtn(m_xBuilder->weld_button("edit"))
+ , m_xPathBox(m_xBuilder->weld_tree_view("paths"))
+{
+ m_xStandardBtn->connect_clicked(LINK(this, SvxPathTabPage, StandardHdl_Impl));
+ m_xPathBtn->connect_clicked( LINK( this, SvxPathTabPage, PathHdl_Impl ) );
+
+ m_xPathBox->set_size_request(m_xPathBox->get_approximate_digit_width() * 60,
+ m_xPathBox->get_height_rows(20));
+
+ m_xPathBox->connect_row_activated( LINK( this, SvxPathTabPage, DoubleClickPathHdl_Impl ) );
+ m_xPathBox->connect_column_clicked(LINK(this, SvxPathTabPage, HeaderBarClick));
+ m_xPathBox->connect_changed( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
+ m_xPathBox->set_selection_mode(SelectionMode::Multiple);
+
+ xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
+}
+
+IMPL_LINK(SvxPathTabPage, HeaderBarClick, int, nColumn, void)
+{
+ bool bSortAtoZ = !m_xPathBox->get_sort_order();
+ m_xPathBox->set_sort_order(bSortAtoZ);
+ m_xPathBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
+}
+
+SvxPathTabPage::~SvxPathTabPage()
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ delete weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
+}
+
+std::unique_ptr<SfxTabPage> SvxPathTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxPathTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxPathTabPage::FillItemSet( SfxItemSet* )
+{
+ for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
+ {
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
+ SvtPathOptions::Paths nRealId = pPathImpl->nRealId;
+ if (pPathImpl->bItemStateSet )
+ SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
+ }
+ return true;
+}
+
+void SvxPathTabPage::Reset( const SfxItemSet* )
+{
+ m_xPathBox->clear();
+ m_xPathBox->make_unsorted();
+
+ std::unique_ptr<weld::TreeIter> xIter = m_xPathBox->make_iterator();
+ for( sal_uInt16 i = 0; i <= sal_uInt16(SvtPathOptions::Paths::Classification); ++i )
+ {
+ // only writer uses autotext
+ if ( static_cast<SvtPathOptions::Paths>(i) == SvtPathOptions::Paths::AutoText
+ && !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ continue;
+
+ TranslateId pId;
+
+ switch (static_cast<SvtPathOptions::Paths>(i))
+ {
+ case SvtPathOptions::Paths::AutoCorrect:
+ pId = RID_CUISTR_KEY_AUTOCORRECT_DIR;
+ break;
+ case SvtPathOptions::Paths::AutoText:
+ pId = RID_CUISTR_KEY_GLOSSARY_PATH;
+ break;
+ case SvtPathOptions::Paths::Backup:
+ pId = RID_CUISTR_KEY_BACKUP_PATH;
+ break;
+ case SvtPathOptions::Paths::Gallery:
+ pId = RID_CUISTR_KEY_GALLERY_DIR;
+ break;
+ case SvtPathOptions::Paths::Graphic:
+ pId = RID_CUISTR_KEY_GRAPHICS_PATH;
+ break;
+ case SvtPathOptions::Paths::Temp:
+ pId = RID_CUISTR_KEY_TEMP_PATH;
+ break;
+ case SvtPathOptions::Paths::Template:
+ pId = RID_CUISTR_KEY_TEMPLATE_PATH;
+ break;
+ case SvtPathOptions::Paths::Dictionary:
+ pId = RID_CUISTR_KEY_DICTIONARY_PATH;
+ break;
+ case SvtPathOptions::Paths::Classification:
+ pId = RID_CUISTR_KEY_CLASSIFICATION_PATH;
+ break;
+#if OSL_DEBUG_LEVEL > 1
+ case SvtPathOptions::Paths::Linguistic:
+ pId = RID_CUISTR_KEY_LINGUISTIC_DIR;
+ break;
+#endif
+ case SvtPathOptions::Paths::Work:
+ pId = RID_CUISTR_KEY_WORK_PATH;
+ break;
+ default: break;
+ }
+
+ if (pId)
+ {
+ m_xPathBox->append(xIter.get());
+
+ OUString aStr(CuiResId(pId));
+ m_xPathBox->set_text(*xIter, aStr, 0);
+
+ OUString sInternal, sUser, sWritable;
+ bool bReadOnly = false;
+ GetPathList( static_cast<SvtPathOptions::Paths>(i), sInternal, sUser, sWritable, bReadOnly );
+
+ if (bReadOnly)
+ m_xPathBox->set_image(*xIter, RID_SVXBMP_LOCK);
+
+ OUString sTmpPath = sUser;
+ if ( !sTmpPath.isEmpty() && !sWritable.isEmpty() )
+ sTmpPath += OUStringChar(MULTIPATH_DELIMITER);
+ sTmpPath += sWritable;
+ const OUString aValue = Convert_Impl( sTmpPath );
+
+ m_xPathBox->set_text(*xIter, aValue, 1);
+
+ const OUString aValueInternal = Convert_Impl( sInternal );
+
+ m_xPathBox->set_text(*xIter, aValueInternal, 2);
+
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 0);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 1);
+ m_xPathBox->set_sensitive(*xIter, !bReadOnly, 2);
+
+ PathUserData_Impl* pPathImpl = new PathUserData_Impl(static_cast<SvtPathOptions::Paths>(i));
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ pPathImpl->bReadOnly = bReadOnly;
+
+ OUString sId = weld::toId(pPathImpl);
+ m_xPathBox->set_id(*xIter, sId);
+ }
+ }
+
+ m_xPathBox->columns_autosize();
+ m_xPathBox->make_sorted();
+ PathSelect_Impl(*m_xPathBox);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl, weld::TreeView&, void)
+{
+ bool bEnable = false;
+ int nEntry = m_xPathBox->get_selected_index();
+ if (nEntry != -1)
+ {
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
+ bEnable = !pPathImpl->bReadOnly;
+ }
+ sal_uInt16 nSelCount = m_xPathBox->count_selected_rows();
+ m_xPathBtn->set_sensitive(1 == nSelCount && bEnable);
+ m_xStandardBtn->set_sensitive(nSelCount > 0 && bEnable);
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl, weld::Button&, void)
+{
+ m_xPathBox->selected_foreach([this](weld::TreeIter& rEntry){
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(rEntry));
+ OUString aOldPath = SvtDefaultOptions::GetDefaultPath( pPathImpl->nRealId );
+
+ if ( !aOldPath.isEmpty() )
+ {
+ OUString sInternal, sUser, sWritable, sTemp;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+
+ sal_Int32 nOldPos = 0;
+ do
+ {
+ bool bFound = false;
+ const std::u16string_view sOnePath = o3tl::getToken(aOldPath, 0, MULTIPATH_DELIMITER, nOldPos );
+ if ( !sInternal.isEmpty() )
+ {
+ sal_Int32 nInternalPos = 0;
+ do
+ {
+ if ( o3tl::getToken(sInternal, 0, MULTIPATH_DELIMITER, nInternalPos ) == sOnePath )
+ bFound = true;
+ }
+ while ( !bFound && nInternalPos >= 0 );
+ }
+ if ( !bFound )
+ {
+ if ( !sTemp.isEmpty() )
+ sTemp += OUStringChar(MULTIPATH_DELIMITER);
+ sTemp += sOnePath;
+ }
+ }
+ while ( nOldPos >= 0 );
+
+ OUString sWritablePath;
+ OUStringBuffer sUserPath;
+ if ( !sTemp.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken = sTemp.getToken( 0, MULTIPATH_DELIMITER, nNextPos );
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritablePath = sToken;
+ break;
+ }
+ if ( !sUserPath.isEmpty() )
+ sUserPath.append(MULTIPATH_DELIMITER);
+ sUserPath.append(sToken);
+ }
+ }
+ m_xPathBox->set_text(rEntry, Convert_Impl(sTemp), 1);
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sUserPath = sUserPath.makeStringAndClear();
+ pPathImpl->sWritablePath = sWritablePath;
+ }
+ return false;
+ });
+}
+
+void SvxPathTabPage::ChangeCurrentEntry( const OUString& _rFolder )
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ if (nEntry == -1)
+ {
+ SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
+ return;
+ }
+
+ OUString sInternal, sUser, sWritable;
+ PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+
+ // old path is a URL?
+ INetURLObject aObj( sWritable );
+ bool bURL = ( aObj.GetProtocol() != INetProtocol::NotValid );
+ INetURLObject aNewObj( _rFolder );
+ aNewObj.removeFinalSlash();
+
+ // then the new path also a URL else system path
+ OUString sNewPathStr = bURL ? _rFolder : aNewObj.getFSysPath( FSysStyle::Detect );
+
+ bool bChanged =
+#ifdef UNX
+// Unix is case sensitive
+ ( sNewPathStr != sWritable );
+#else
+ !sNewPathStr.equalsIgnoreAsciiCase( sWritable );
+#endif
+
+ if ( !bChanged )
+ return;
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sNewPathStr), 1);
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sWritablePath = sNewPathStr;
+ if ( SvtPathOptions::Paths::Work == pPathImpl->nRealId )
+ {
+ // Remove view options entry so the new work path
+ // will be used for the next open dialog.
+ SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
+ aDlgOpt.Delete();
+ // Reset also last used dir in the sfx application instance
+ SfxApplication *pSfxApp = SfxGetpApp();
+ pSfxApp->ResetLastDir();
+ }
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, DoubleClickPathHdl_Impl, weld::TreeView&, bool)
+{
+ PathHdl_Impl(*m_xPathBtn);
+ return true;
+}
+
+IMPL_LINK_NOARG(SvxPathTabPage, PathHdl_Impl, weld::Button&, void)
+{
+ int nEntry = m_xPathBox->get_cursor_index();
+ PathUserData_Impl* pPathImpl = nEntry != -1 ? weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry)) : nullptr;
+ if (!pPathImpl || pPathImpl->bReadOnly)
+ return;
+
+ SvtPathOptions::Paths nPos = pPathImpl->nRealId;
+ OUString sInternal, sUser, sWritable;
+ bool bPickFile = false;
+ bool bReadOnly = false;
+ GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
+ sUser = pPathImpl->sUserPath;
+ sWritable = pPathImpl->sWritablePath;
+ bPickFile = pPathImpl->nRealId == SvtPathOptions::Paths::Classification;
+
+ if (IsMultiPath_Impl(nPos))
+ {
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxMultiPathDialog> pMultiDlg(
+ pFact->CreateSvxMultiPathDialog(GetFrameWeld()));
+
+ OUString sPath( sUser );
+ if ( !sPath.isEmpty() )
+ sPath += OUStringChar(MULTIPATH_DELIMITER);
+ sPath += sWritable;
+ pMultiDlg->SetPath( sPath );
+
+ const OUString sPathName = m_xPathBox->get_text(nEntry, 0);
+ const OUString sNewTitle = pImpl->m_sMultiPathDlg.replaceFirst( VAR_ONE, sPathName );
+ pMultiDlg->SetTitle( sNewTitle );
+
+ if (pMultiDlg->Execute() == RET_OK)
+ {
+ sUser.clear();
+ sWritable.clear();
+ OUString sFullPath;
+ OUString sNewPath = pMultiDlg->GetPath();
+ if ( !sNewPath.isEmpty() )
+ {
+ sal_Int32 nNextPos = 0;
+ for (;;)
+ {
+ const OUString sToken(sNewPath.getToken( 0, MULTIPATH_DELIMITER, nNextPos ));
+ if ( nNextPos<0 )
+ {
+ // Last token need a different handling
+ sWritable = sToken;
+ break;
+ }
+ if ( !sUser.isEmpty() )
+ sUser += OUStringChar(MULTIPATH_DELIMITER);
+ sUser += sToken;
+ }
+ sFullPath = sUser;
+ if ( !sFullPath.isEmpty() )
+ sFullPath += OUStringChar(MULTIPATH_DELIMITER);
+ sFullPath += sWritable;
+ }
+
+ m_xPathBox->set_text(nEntry, Convert_Impl(sFullPath), 1);
+ // save modified flag
+ pPathImpl->bItemStateSet = true;
+ pPathImpl->sUserPath = sUser;
+ pPathImpl->sWritablePath = sWritable;
+ }
+ }
+ else if (!bPickFile)
+ {
+ try
+ {
+ Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ INetURLObject aURL( sWritable, INetProtocol::File );
+ xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
+ if ( xAsyncDlg.is() )
+ xAsyncDlg->startExecuteModal( xDialogListener );
+ else
+ {
+ short nRet = xFolderPicker->execute();
+ if (ExecutableDialogResults::OK != nRet)
+ return;
+
+ OUString sFolder(xFolderPicker->getDirectory());
+ ChangeCurrentEntry(sFolder);
+ }
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
+ }
+ }
+ else
+ {
+ try
+ {
+ sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
+ uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = aHelper.GetFilePicker();
+ xFilePicker->appendFilter(OUString(), "*.xml");
+ if (xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
+ {
+ uno::Sequence<OUString> aPathSeq(xFilePicker->getSelectedFiles());
+ ChangeCurrentEntry(aPathSeq[0]);
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ DBG_UNHANDLED_EXCEPTION("cui.options", "exception from file picker");
+ }
+ }
+}
+
+IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
+{
+ if (RET_OK == pEvt->DialogResult)
+ {
+ assert(xFolderPicker.is() && "SvxPathTabPage::DialogClosedHdl(): no folder picker");
+ OUString sURL = xFolderPicker->getDirectory();
+ ChangeCurrentEntry( sURL );
+ }
+}
+
+void SvxPathTabPage::GetPathList(
+ SvtPathOptions::Paths _nPathHandle, OUString& _rInternalPath,
+ OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // load internal paths
+ Any aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_INTERNAL);
+ Sequence< OUString > aPathSeq;
+ if ( aAny >>= aPathSeq )
+ {
+ tools::Long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rInternalPath.isEmpty() )
+ _rInternalPath += ";";
+ _rInternalPath += pPaths[i];
+ }
+ }
+ // load user paths
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_USER);
+ if ( aAny >>= aPathSeq )
+ {
+ tools::Long i, nCount = aPathSeq.getLength();
+ const OUString* pPaths = aPathSeq.getConstArray();
+
+ for ( i = 0; i < nCount; ++i )
+ {
+ if ( !_rUserPath.isEmpty() )
+ _rUserPath += ";";
+ _rUserPath += pPaths[i];
+ }
+ }
+ // then the writable path
+ aAny = pImpl->m_xPathSettings->getPropertyValue(
+ sCfgName + POSTFIX_WRITABLE);
+ OUString sWritablePath;
+ if ( aAny >>= sWritablePath )
+ _rWritablePath = sWritablePath;
+
+ // and the readonly flag
+ Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
+ Property aProp = xInfo->getPropertyByName(sCfgName);
+ _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::GetPathList()" );
+ }
+}
+
+
+void SvxPathTabPage::SetPathList(
+ SvtPathOptions::Paths _nPathHandle, std::u16string_view _rUserPath, const OUString& _rWritablePath )
+{
+ OUString sCfgName = getCfgName_Impl( _nPathHandle );
+
+ try
+ {
+ // load PathSettings service if necessary
+ if ( !pImpl->m_xPathSettings.is() )
+ {
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
+ }
+
+ // save user paths
+ const sal_Int32 nCount = comphelper::string::getTokenCount(_rUserPath, MULTIPATH_DELIMITER);
+ Sequence< OUString > aPathSeq( nCount );
+ OUString* pArray = aPathSeq.getArray();
+ sal_Int32 nPos = 0;
+ for ( sal_Int32 i = 0; i < nCount; ++i )
+ pArray[i] = o3tl::getToken(_rUserPath, 0, MULTIPATH_DELIMITER, nPos );
+ Any aValue( aPathSeq );
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_USER, aValue);
+
+ // then the writable path
+ aValue <<= _rWritablePath;
+ pImpl->m_xPathSettings->setPropertyValue(
+ sCfgName + POSTFIX_WRITABLE, aValue);
+ }
+ catch( const Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.cxx b/cui/source/options/optsave.cxx
new file mode 100644
index 000000000..43468715c
--- /dev/null
+++ b/cui/source/options/optsave.cxx
@@ -0,0 +1,635 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <o3tl/string_view.hxx>
+#include <svl/eitem.hxx>
+#include <svl/intitem.hxx>
+#include "optsave.hxx"
+#include <treeopt.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <comphelper/processfactory.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/saveopt.hxx>
+#include <comphelper/sequenceashashmap.hxx>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XContainerQuery.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <sfx2/sfxsids.hrc>
+#include <sfx2/docfilt.hxx>
+#include <svtools/restartdialog.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <officecfg/Office/Recovery.hxx>
+
+#include <sfx2/fcontnr.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace comphelper;
+
+#define CFG_PAGE_AND_GROUP u"General", u"LoadSave"
+
+
+struct SvxSaveTabPage_Impl
+{
+ Reference< XNameContainer > xFact;
+ std::vector< OUString > aFilterArr[APP_COUNT];
+ std::vector< bool > aODFArr[APP_COUNT];
+ std::vector< OUString > aUIFilterArr[APP_COUNT];
+ OUString aDefaultArr[APP_COUNT];
+ bool aDefaultReadonlyArr[APP_COUNT];
+ bool bInitialized;
+
+ SvxSaveTabPage_Impl();
+};
+
+SvxSaveTabPage_Impl::SvxSaveTabPage_Impl() : bInitialized( false )
+{
+}
+
+// class SvxSaveTabPage --------------------------------------------------
+
+SvxSaveTabPage::SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet)
+ : SfxTabPage( pPage, pController, "cui/ui/optsavepage.ui", "OptSavePage", &rCoreSet )
+ , pImpl(new SvxSaveTabPage_Impl)
+ , m_xLoadUserSettingsCB(m_xBuilder->weld_check_button("load_settings"))
+ , m_xLoadDocPrinterCB(m_xBuilder->weld_check_button("load_docprinter"))
+ , m_xDocInfoCB(m_xBuilder->weld_check_button("docinfo"))
+ , m_xBackupCB(m_xBuilder->weld_check_button("backup"))
+ , m_xAutoSaveCB(m_xBuilder->weld_check_button("autosave"))
+ , m_xAutoSaveEdit(m_xBuilder->weld_spin_button("autosave_spin"))
+ , m_xMinuteFT(m_xBuilder->weld_label("autosave_mins"))
+ , m_xUserAutoSaveCB(m_xBuilder->weld_check_button("userautosave"))
+ , m_xRelativeFsysCB(m_xBuilder->weld_check_button("relative_fsys"))
+ , m_xRelativeInetCB(m_xBuilder->weld_check_button("relative_inet"))
+ , m_xODFVersionLB(m_xBuilder->weld_combo_box("odfversion"))
+ , m_xWarnAlienFormatCB(m_xBuilder->weld_check_button("warnalienformat"))
+ , m_xDocTypeLB(m_xBuilder->weld_combo_box("doctype"))
+ , m_xSaveAsFT(m_xBuilder->weld_label("saveas_label"))
+ , m_xSaveAsLB(m_xBuilder->weld_combo_box("saveas"))
+ , m_xODFWarningFI(m_xBuilder->weld_widget("odfwarning_image"))
+ , m_xODFWarningFT(m_xBuilder->weld_label("odfwarning_label"))
+{
+ m_xAutoSaveEdit->set_max_length(2);
+
+ m_xODFVersionLB->set_id(0, OUString::number(SvtSaveOptions::ODFVER_011)); // 1.0/1.1
+ m_xODFVersionLB->set_id(1, OUString::number(SvtSaveOptions::ODFVER_012)); // 1.2
+ m_xODFVersionLB->set_id(2, OUString::number(SvtSaveOptions::ODFVER_012_EXT_COMPAT)); // 1.2 Extended (compatibility mode)
+ m_xODFVersionLB->set_id(3, OUString::number(SvtSaveOptions::ODFVER_012_EXTENDED)); // 1.2 Extended
+ m_xODFVersionLB->set_id(4, OUString::number(SvtSaveOptions::ODFVER_013)); // 1.3
+ m_xODFVersionLB->set_id(5, OUString::number(SvtSaveOptions::ODFVER_LATEST)); // 1.3 Extended (recommended)
+
+ m_xDocTypeLB->set_id(0, OUString::number(APP_WRITER) );
+ m_xDocTypeLB->set_id(1, OUString::number(APP_WRITER_WEB) );
+ m_xDocTypeLB->set_id(2, OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->set_id(3, OUString::number(APP_CALC) );
+ m_xDocTypeLB->set_id(4, OUString::number(APP_IMPRESS) );
+ m_xDocTypeLB->set_id(5, OUString::number(APP_DRAW) );
+ m_xDocTypeLB->set_id(6, OUString::number(APP_MATH) );
+
+ m_xAutoSaveCB->connect_toggled( LINK( this, SvxSaveTabPage, AutoClickHdl_Impl ) );
+
+ SvtModuleOptions aModuleOpt;
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_MATH));
+ m_xDocTypeLB->remove_id(OUString::number(APP_MATH));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_MATH] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH);
+ pImpl->aDefaultReadonlyArr[APP_MATH] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::MATH);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_DRAW));
+ m_xDocTypeLB->remove_id(OUString::number(APP_DRAW));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_DRAW] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW);
+ pImpl->aDefaultReadonlyArr[APP_DRAW] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::DRAW);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_IMPRESS));
+ m_xDocTypeLB->remove_id(OUString::number(APP_IMPRESS));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_IMPRESS] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS);
+ pImpl->aDefaultReadonlyArr[APP_IMPRESS] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::IMPRESS);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_CALC));
+ m_xDocTypeLB->remove_id(OUString::number(APP_CALC));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_CALC] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC);
+ pImpl->aDefaultReadonlyArr[APP_CALC] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::CALC);
+ }
+
+ if ( !aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xSaveAsLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_WEB));
+ m_xDocTypeLB->remove_id(OUString::number(APP_WRITER_GLOBAL));
+ }
+ else
+ {
+ pImpl->aDefaultArr[APP_WRITER] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultArr[APP_WRITER_WEB] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] = aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ pImpl->aDefaultReadonlyArr[APP_WRITER] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITER);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_WEB] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERWEB);
+ pImpl->aDefaultReadonlyArr[APP_WRITER_GLOBAL] = aModuleOpt.IsDefaultFilterReadonly(SvtModuleOptions::EFactory::WRITERGLOBAL);
+ }
+
+ Link<weld::ComboBox&,void> aLink = LINK( this, SvxSaveTabPage, ODFVersionHdl_Impl );
+ m_xODFVersionLB->connect_changed( aLink );
+ aLink = LINK( this, SvxSaveTabPage, FilterHdl_Impl );
+ m_xDocTypeLB->connect_changed( aLink );
+ m_xSaveAsLB->connect_changed( aLink );
+
+ DetectHiddenControls();
+}
+
+SvxSaveTabPage::~SvxSaveTabPage()
+{
+}
+
+std::unique_ptr<SfxTabPage> SvxSaveTabPage::Create(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet* rAttrSet)
+{
+ return std::make_unique<SvxSaveTabPage>(pPage, pController, *rAttrSet);
+}
+
+void SvxSaveTabPage::DetectHiddenControls()
+{
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"Backup", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "Backup"
+ m_xBackupCB->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"AutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "AutoSave"
+ m_xAutoSaveCB->hide();
+ m_xAutoSaveEdit->hide();
+ m_xMinuteFT->hide();
+ }
+
+ if ( aOptionsDlgOpt.IsOptionHidden( u"UserAutoSave", CFG_PAGE_AND_GROUP ) )
+ {
+ // hide controls of "UserAutoSave"
+ m_xUserAutoSaveCB->hide();
+ }
+
+}
+
+bool SvxSaveTabPage::FillItemSet( SfxItemSet* rSet )
+{
+ auto xChanges = comphelper::ConfigurationChanges::create();
+ bool bModified = false, bRequestRestart = false;
+ if(m_xLoadUserSettingsCB->get_state_changed_from_saved())
+ officecfg::Office::Common::Load::UserDefinedSettings::set(m_xLoadUserSettingsCB->get_active(), xChanges);
+
+ if ( m_xLoadDocPrinterCB->get_state_changed_from_saved() )
+ officecfg::Office::Common::Save::Document::LoadPrinter::set(m_xLoadDocPrinterCB->get_active(), xChanges);
+
+ if ( m_xODFVersionLB->get_value_changed_from_saved() )
+ {
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ SetODFDefaultVersion( SvtSaveOptions::ODFDefaultVersion( nVersion ), xChanges );
+ }
+
+ if ( m_xDocInfoCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_DOCINFO,
+ m_xDocInfoCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xBackupCB->get_sensitive() && m_xBackupCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_BACKUP, m_xBackupCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_AUTOSAVE,
+ m_xAutoSaveCB->get_active() ) );
+ bModified = bRequestRestart = true;
+ }
+ if ( m_xWarnAlienFormatCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_WARNALIENFORMAT,
+ m_xWarnAlienFormatCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xAutoSaveEdit->get_value_changed_from_saved() )
+ {
+ rSet->Put( SfxUInt16Item( SID_ATTR_AUTOSAVEMINUTE,
+ static_cast<sal_uInt16>(m_xAutoSaveEdit->get_value()) ) );
+ bModified = bRequestRestart = true;
+ }
+
+ if ( m_xUserAutoSaveCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_ATTR_USERAUTOSAVE,
+ m_xUserAutoSaveCB->get_active() ) );
+ bModified = true;
+ }
+ // save relatively
+ if ( m_xRelativeFsysCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_SAVEREL_FSYS,
+ m_xRelativeFsysCB->get_active() ) );
+ bModified = true;
+ }
+
+ if ( m_xRelativeInetCB->get_state_changed_from_saved() )
+ {
+ rSet->Put( SfxBoolItem( SID_SAVEREL_INET,
+ m_xRelativeInetCB->get_active() ) );
+ bModified = true;
+ }
+
+ SvtModuleOptions aModuleOpt;
+ if(!pImpl->aDefaultArr[APP_MATH].isEmpty() &&
+ pImpl->aDefaultArr[APP_MATH] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::MATH, pImpl->aDefaultArr[APP_MATH]);
+
+ if( !pImpl->aDefaultArr[APP_DRAW].isEmpty() &&
+ pImpl->aDefaultArr[APP_DRAW] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::DRAW, pImpl->aDefaultArr[APP_DRAW]);
+
+ if(!pImpl->aDefaultArr[APP_IMPRESS].isEmpty() &&
+ pImpl->aDefaultArr[APP_IMPRESS] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::IMPRESS, pImpl->aDefaultArr[APP_IMPRESS]);
+
+ if(!pImpl->aDefaultArr[APP_CALC].isEmpty() &&
+ pImpl->aDefaultArr[APP_CALC] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::CALC, pImpl->aDefaultArr[APP_CALC]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITER, pImpl->aDefaultArr[APP_WRITER]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_WEB].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_WEB] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERWEB, pImpl->aDefaultArr[APP_WRITER_WEB]);
+
+ if(!pImpl->aDefaultArr[APP_WRITER_GLOBAL].isEmpty() &&
+ pImpl->aDefaultArr[APP_WRITER_GLOBAL] != aModuleOpt.GetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL))
+ aModuleOpt.SetFactoryDefaultFilter(SvtModuleOptions::EFactory::WRITERGLOBAL, pImpl->aDefaultArr[APP_WRITER_GLOBAL]);
+
+ xChanges->commit();
+
+ if (bRequestRestart)
+ {
+ OfaTreeOptionsDialog* pParentDlg(static_cast<OfaTreeOptionsDialog*>(GetDialogController()));
+ if (pParentDlg)
+ pParentDlg->SetNeedsRestart(svtools::RESTART_REASON_SAVE);
+ }
+
+ return bModified;
+}
+
+static bool isODFFormat( std::u16string_view sFilter )
+{
+ static const char* aODFFormats[] =
+ {
+ "writer8",
+ "writer8_template",
+ "writerglobal8",
+ "writerglobal8_writer",
+ "calc8",
+ "calc8_template",
+ "draw8",
+ "draw8_template",
+ "impress8",
+ "impress8_template",
+ "impress8_draw",
+ "chart8",
+ "math8",
+ nullptr
+ };
+
+ bool bRet = false;
+ int i = 0;
+ while ( aODFFormats[i] != nullptr )
+ {
+ if ( o3tl::equalsAscii( sFilter, aODFFormats[i++] ) )
+ {
+ bRet = true;
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+void SvxSaveTabPage::Reset( const SfxItemSet* )
+{
+ m_xLoadUserSettingsCB->set_active(officecfg::Office::Common::Load::UserDefinedSettings::get());
+ m_xLoadUserSettingsCB->save_state();
+ m_xLoadUserSettingsCB->set_sensitive(!officecfg::Office::Common::Load::UserDefinedSettings::isReadOnly());
+ m_xLoadDocPrinterCB->set_active( officecfg::Office::Common::Save::Document::LoadPrinter::get() );
+ m_xLoadDocPrinterCB->save_state();
+ m_xLoadDocPrinterCB->set_sensitive(!officecfg::Office::Common::Save::Document::LoadPrinter::isReadOnly());
+
+ if ( !pImpl->bInitialized )
+ {
+ try
+ {
+ Reference< XMultiServiceFactory > xMSF = comphelper::getProcessServiceFactory();
+ pImpl->xFact.set(xMSF->createInstance("com.sun.star.document.FilterFactory"), UNO_QUERY);
+
+ DBG_ASSERT(pImpl->xFact.is(), "service com.sun.star.document.FilterFactory unavailable");
+ Reference< XContainerQuery > xQuery(pImpl->xFact, UNO_QUERY);
+ if(xQuery.is())
+ {
+ for (sal_Int32 n = 0, nEntryCount = m_xDocTypeLB->get_count(); n < nEntryCount; ++n)
+ {
+ unsigned int nData = m_xDocTypeLB->get_id(n).toUInt32();
+ OUString sCommand = "getSortedFilterList():module=%1:iflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::IMPORT|SfxFilterFlags::EXPORT)) +
+ ":eflags=" +
+ OUString::number(static_cast<int>(SfxFilterFlags::NOTINFILEDLG));
+ OUString sReplace;
+ switch(nData)
+ {
+ case APP_WRITER : sReplace = "com.sun.star.text.TextDocument"; break;
+ case APP_WRITER_WEB : sReplace = "com.sun.star.text.WebDocument"; break;
+ case APP_WRITER_GLOBAL : sReplace = "com.sun.star.text.GlobalDocument"; break;
+ case APP_CALC : sReplace = "com.sun.star.sheet.SpreadsheetDocument";break;
+ case APP_IMPRESS : sReplace = "com.sun.star.presentation.PresentationDocument";break;
+ case APP_DRAW : sReplace = "com.sun.star.drawing.DrawingDocument";break;
+ case APP_MATH : sReplace = "com.sun.star.formula.FormulaProperties";break;
+ default: OSL_FAIL("illegal user data");
+ }
+ sCommand = sCommand.replaceFirst("%1", sReplace);
+ Reference< XEnumeration > xList = xQuery->createSubSetEnumerationByQuery(sCommand);
+ std::vector< OUString > lList;
+ std::vector<bool> lODFList;
+ while(xList->hasMoreElements())
+ {
+ SequenceAsHashMap aFilter(xList->nextElement());
+ OUString sFilter = aFilter.getUnpackedValueOrDefault("Name",OUString());
+ if (!sFilter.isEmpty())
+ {
+ lList.push_back(sFilter);
+ lODFList.push_back( isODFFormat( sFilter ) );
+ }
+ }
+ pImpl->aFilterArr[nData] = lList;
+ pImpl->aODFArr[nData] = lODFList;
+ }
+ }
+ m_xDocTypeLB->set_active(0);
+ FilterHdl_Impl(*m_xDocTypeLB);
+ }
+ catch(Exception const &)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "exception in FilterFactory access" );
+ }
+
+ pImpl->bInitialized = true;
+ }
+
+ m_xDocInfoCB->set_active(officecfg::Office::Common::Save::Document::EditProperty::get());
+ m_xDocInfoCB->set_sensitive(!officecfg::Office::Common::Save::Document::EditProperty::isReadOnly());
+
+ m_xBackupCB->set_active(officecfg::Office::Common::Save::Document::CreateBackup::get());
+ m_xBackupCB->set_sensitive(!officecfg::Office::Common::Save::Document::CreateBackup::isReadOnly());
+
+ m_xAutoSaveCB->set_active(officecfg::Office::Common::Save::Document::AutoSave::get());
+ m_xAutoSaveCB->set_sensitive(!officecfg::Office::Common::Save::Document::AutoSave::isReadOnly());
+
+ m_xUserAutoSaveCB->set_active(officecfg::Office::Recovery::AutoSave::UserAutoSaveEnabled::get());
+ m_xUserAutoSaveCB->set_sensitive(!officecfg::Office::Recovery::AutoSave::UserAutoSaveEnabled::isReadOnly());
+
+ m_xWarnAlienFormatCB->set_active(officecfg::Office::Common::Save::Document::WarnAlienFormat::get());
+ m_xWarnAlienFormatCB->set_sensitive(!officecfg::Office::Common::Save::Document::WarnAlienFormat::isReadOnly());
+
+ m_xAutoSaveEdit->set_value(officecfg::Office::Common::Save::Document::AutoSaveTimeIntervall::get());
+ m_xAutoSaveEdit->set_sensitive(!officecfg::Office::Common::Save::Document::AutoSaveTimeIntervall::isReadOnly());
+
+ // save relatively
+ m_xRelativeFsysCB->set_active(officecfg::Office::Common::Save::URL::FileSystem::get());
+ m_xRelativeFsysCB->set_sensitive(!officecfg::Office::Common::Save::URL::FileSystem::isReadOnly());
+
+ m_xRelativeInetCB->set_active(officecfg::Office::Common::Save::URL::Internet::get());
+ m_xRelativeInetCB->set_sensitive(!officecfg::Office::Common::Save::URL::Internet::isReadOnly());
+
+ sal_Int32 nDefaultVersion = GetODFDefaultVersion();
+ m_xODFVersionLB->set_active_id(OUString::number(nDefaultVersion));
+ m_xODFVersionLB->set_sensitive(!officecfg::Office::Common::Save::ODF::DefaultVersion::isReadOnly());
+
+ AutoClickHdl_Impl(*m_xAutoSaveCB);
+ ODFVersionHdl_Impl(*m_xODFVersionLB);
+
+ m_xDocInfoCB->save_state();
+ m_xBackupCB->save_state();
+ m_xWarnAlienFormatCB->save_state();
+ m_xAutoSaveCB->save_state();
+ m_xAutoSaveEdit->save_value();
+
+ m_xUserAutoSaveCB->save_state();
+
+ m_xRelativeFsysCB->save_state();
+ m_xRelativeInetCB->save_state();
+ m_xODFVersionLB->save_value();
+}
+
+IMPL_LINK(SvxSaveTabPage, AutoClickHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ if (&rBox != m_xAutoSaveCB.get())
+ return;
+
+ if (m_xAutoSaveCB->get_active())
+ {
+ m_xAutoSaveEdit->set_sensitive(true);
+ m_xMinuteFT->set_sensitive(true);
+ m_xUserAutoSaveCB->set_sensitive(true);
+ }
+ else
+ {
+ m_xAutoSaveEdit->set_sensitive(false);
+ m_xMinuteFT->set_sensitive(false);
+ m_xUserAutoSaveCB->set_sensitive(false);
+ }
+}
+
+static OUString lcl_ExtracUIName(const Sequence<PropertyValue> &rProperties, std::u16string_view rExtension)
+{
+ OUString sName;
+ const PropertyValue* pPropVal = rProperties.getConstArray();
+ const PropertyValue* const pEnd = pPropVal + rProperties.getLength();
+ for( ; pPropVal != pEnd; pPropVal++ )
+ {
+ const OUString &rName = pPropVal->Name;
+ if (rName == "UIName")
+ {
+ OUString sUIName;
+ if ( ( pPropVal->Value >>= sUIName ) && sUIName.getLength() )
+ {
+ if (!rExtension.empty())
+ {
+ return sUIName + " (" + rExtension + ")";
+ }
+ else
+ {
+ return sUIName;
+ }
+ }
+ }
+ else if (rName == "Name")
+ {
+ pPropVal->Value >>= sName;
+ }
+ }
+
+ OSL_ENSURE( false, "Filter without UIName!" );
+
+ return sName;
+}
+
+IMPL_LINK( SvxSaveTabPage, FilterHdl_Impl, weld::ComboBox&, rBox, void )
+{
+ const int nCurPos = m_xDocTypeLB->get_active();
+
+ int nData = -1;
+ if (nCurPos < APP_COUNT)
+ nData = m_xDocTypeLB->get_id(nCurPos).toInt32();
+
+ if ( nData >= 0 && nData < APP_COUNT )
+ {
+ if(m_xDocTypeLB.get() == &rBox)
+ {
+ m_xSaveAsLB->clear();
+ auto & rFilters = pImpl->aFilterArr[nData];
+ if(pImpl->aUIFilterArr[nData].empty())
+ {
+ pImpl->aUIFilterArr[nData].resize(pImpl->aFilterArr[nData].size());
+ auto & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t nFilter = 0; nFilter < pImpl->aFilterArr[nData].size(); nFilter++)
+ {
+ Any aProps = pImpl->xFact->getByName(rFilters[nFilter]);
+ // get the extension of the filter
+ OUString extension;
+ SfxFilterMatcher matcher;
+ std::shared_ptr<const SfxFilter> pFilter = matcher.GetFilter4FilterName(rFilters[nFilter]);
+ if (pFilter)
+ {
+ extension = pFilter->GetWildcard().getGlob().getToken(0, ';');
+ }
+ Sequence<PropertyValue> aProperties;
+ aProps >>= aProperties;
+ rUIFilters[nFilter] = lcl_ExtracUIName(aProperties, extension);
+ }
+ }
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ OUString sSelect;
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ {
+ OUString sId;
+ if (pImpl->aODFArr[nData][i])
+ sId = weld::toId(pImpl.get());
+ m_xSaveAsLB->append(sId, rUIFilters[i]);
+ if (rFilters[i] == pImpl->aDefaultArr[nData])
+ sSelect = rUIFilters[i];
+ }
+ if (!sSelect.isEmpty())
+ {
+ m_xSaveAsLB->set_active_text(sSelect);
+ }
+
+ m_xSaveAsFT->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ m_xSaveAsLB->set_sensitive(!pImpl->aDefaultReadonlyArr[nData]);
+ }
+ else
+ {
+ OUString sSelect = rBox.get_active_text();
+ auto const & rFilters = pImpl->aFilterArr[nData];
+ auto const & rUIFilters = pImpl->aUIFilterArr[nData];
+ for(size_t i = 0; i < pImpl->aUIFilterArr[nData].size(); i++)
+ if(rUIFilters[i] == sSelect)
+ {
+ sSelect = rFilters[i];
+ break;
+ }
+
+ pImpl->aDefaultArr[nData] = sSelect;
+ }
+ }
+
+ ODFVersionHdl_Impl( *m_xSaveAsLB );
+}
+
+IMPL_LINK_NOARG(SvxSaveTabPage, ODFVersionHdl_Impl, weld::ComboBox&, void)
+{
+ sal_Int32 nVersion = m_xODFVersionLB->get_active_id().toInt32();
+ bool bShown = SvtSaveOptions::ODFDefaultVersion(nVersion) != SvtSaveOptions::ODFVER_LATEST;
+ if ( bShown )
+ {
+ bool bHasODFFormat = false;
+ const int nCount = m_xSaveAsLB->get_count();
+ for (int i = 0; i < nCount; ++i )
+ {
+ if ( m_xSaveAsLB->get_id(i).toInt64() != 0 )
+ {
+ bHasODFFormat = true;
+ break;
+ }
+ }
+
+ bShown = !bHasODFFormat
+ || ( m_xSaveAsLB->get_active_id().toInt64() != 0);
+ }
+
+ m_xODFWarningFI->set_visible(bShown);
+ m_xODFWarningFT->set_visible(bShown);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optsave.hxx b/cui/source/options/optsave.hxx
new file mode 100644
index 000000000..4ec3b1dda
--- /dev/null
+++ b/cui/source/options/optsave.hxx
@@ -0,0 +1,78 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <memory>
+#include <sfx2/tabdlg.hxx>
+
+#define APP_WRITER 0
+#define APP_WRITER_WEB 1
+#define APP_WRITER_GLOBAL 2
+#define APP_CALC 3
+#define APP_IMPRESS 4
+#define APP_DRAW 5
+#define APP_MATH 6
+#define APP_COUNT 7
+
+namespace com::sun::star::beans { struct PropertyValue; }
+
+// class SvxSaveTabPage --------------------------------------------------
+
+struct SvxSaveTabPage_Impl;
+
+class SvxSaveTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<SvxSaveTabPage_Impl> pImpl;
+
+ std::unique_ptr<weld::CheckButton> m_xLoadUserSettingsCB;
+ std::unique_ptr<weld::CheckButton> m_xLoadDocPrinterCB;
+ std::unique_ptr<weld::CheckButton> m_xDocInfoCB;
+ std::unique_ptr<weld::CheckButton> m_xBackupCB;
+ std::unique_ptr<weld::CheckButton> m_xAutoSaveCB;
+ std::unique_ptr<weld::SpinButton> m_xAutoSaveEdit;
+ std::unique_ptr<weld::Label> m_xMinuteFT;
+ std::unique_ptr<weld::CheckButton> m_xUserAutoSaveCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeFsysCB;
+ std::unique_ptr<weld::CheckButton> m_xRelativeInetCB;
+ std::unique_ptr<weld::ComboBox> m_xODFVersionLB;
+ std::unique_ptr<weld::CheckButton> m_xWarnAlienFormatCB;
+ std::unique_ptr<weld::ComboBox> m_xDocTypeLB;
+ std::unique_ptr<weld::Label> m_xSaveAsFT;
+ std::unique_ptr<weld::ComboBox> m_xSaveAsLB;
+ std::unique_ptr<weld::Widget> m_xODFWarningFI;
+ std::unique_ptr<weld::Label> m_xODFWarningFT;
+
+ DECL_LINK( AutoClickHdl_Impl, weld::Toggleable&, void );
+ DECL_LINK( FilterHdl_Impl, weld::ComboBox&, void );
+ DECL_LINK(ODFVersionHdl_Impl, weld::ComboBox&, void );
+
+ void DetectHiddenControls();
+
+public:
+ SvxSaveTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ virtual ~SvxSaveTabPage() override;
+
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet );
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.cxx b/cui/source/options/optupdt.cxx
new file mode 100644
index 000000000..754fb5fdc
--- /dev/null
+++ b/cui/source/options/optupdt.cxx
@@ -0,0 +1,405 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include "optupdt.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/configuration/theDefaultProvider.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/deployment/UpdateInformationProvider.hpp>
+#include <com/sun/star/ucb/XWebDAVCommandEnvironment.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/XDispatchProvider.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <com/sun/star/util/URLTransformer.hpp>
+#include <com/sun/star/util/XURLTransformer.hpp>
+#include <com/sun/star/setup/UpdateCheckConfig.hpp>
+#include <com/sun/star/configuration/ReadWriteAccess.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/NamedValue.hpp>
+#include <sfx2/filedlghelper.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <osl/file.hxx>
+#include <osl/security.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+
+using namespace ::css;
+
+SvxOnlineUpdateTabPage::SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/optonlineupdatepage.ui", "OptOnlineUpdatePage", &rSet)
+ , m_xNeverChecked(m_xBuilder->weld_label("neverchecked"))
+ , m_xAutoCheckCheckBox(m_xBuilder->weld_check_button("autocheck"))
+ , m_xEveryDayButton(m_xBuilder->weld_radio_button("everyday"))
+ , m_xEveryWeekButton(m_xBuilder->weld_radio_button("everyweek"))
+ , m_xEveryMonthButton(m_xBuilder->weld_radio_button("everymonth"))
+ , m_xCheckNowButton(m_xBuilder->weld_button("checknow"))
+ , m_xAutoDownloadCheckBox(m_xBuilder->weld_check_button("autodownload"))
+ , m_xDestPathLabel(m_xBuilder->weld_label("destpathlabel"))
+ , m_xDestPath(m_xBuilder->weld_label("destpath"))
+ , m_xChangePathButton(m_xBuilder->weld_button("changepath"))
+ , m_xLastChecked(m_xBuilder->weld_label("lastchecked"))
+ , m_xExtrasCheckBox(m_xBuilder->weld_check_button("extrabits"))
+ , m_xUserAgentLabel(m_xBuilder->weld_label("useragent"))
+ , m_xPrivacyPolicyButton(m_xBuilder->weld_link_button("btnPrivacyPolicy"))
+{
+ m_aNeverChecked = m_xNeverChecked->get_label();
+
+ m_xAutoCheckCheckBox->connect_toggled( LINK( this, SvxOnlineUpdateTabPage, AutoCheckHdl_Impl ) );
+ m_xExtrasCheckBox->connect_toggled( LINK( this, SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl ) );
+ m_xCheckNowButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, CheckNowHdl_Impl ) );
+ m_xChangePathButton->connect_clicked( LINK( this, SvxOnlineUpdateTabPage, FileDialogHdl_Impl ) );
+ m_xPrivacyPolicyButton->set_uri(
+ officecfg::Office::Common::Menus::PrivacyPolicyURL::get()
+ + "?type=updatecheck&LOvers=" + utl::ConfigManager::getProductVersion()
+ + "&LOlocale=" + LanguageTag(utl::ConfigManager::getUILocale()).getBcp47());
+
+
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+
+ m_xUpdateAccess = setup::UpdateCheckConfig::create( xContext );
+ m_xReadWriteAccess = css::configuration::ReadWriteAccess::create(xContext, "*");
+
+ bool bDownloadSupported = false;
+ m_xUpdateAccess->getByName( "DownloadSupported" ) >>= bDownloadSupported;
+
+ m_xAutoDownloadCheckBox->set_visible(bDownloadSupported);
+ m_xDestPathLabel->set_visible(bDownloadSupported);
+ m_xDestPath->set_visible(bDownloadSupported);
+ m_xChangePathButton->set_visible(bDownloadSupported);
+
+ m_aLastCheckedTemplate = m_xLastChecked->get_label();
+
+ UpdateLastCheckedText();
+ UpdateUserAgent();
+}
+
+SvxOnlineUpdateTabPage::~SvxOnlineUpdateTabPage()
+{
+}
+
+void SvxOnlineUpdateTabPage::UpdateLastCheckedText()
+{
+ OUString aText;
+ sal_Int64 lastChecked = 0;
+
+ m_xUpdateAccess->getByName("LastCheck") >>= lastChecked;
+
+ if( lastChecked == 0 ) // never checked
+ {
+ aText = m_aNeverChecked;
+ }
+ else
+ {
+ TimeValue lastCheckedTV;
+ oslDateTime lastCheckedDT;
+
+ Date aDate( Date::EMPTY );
+ tools::Time aTime( tools::Time::EMPTY );
+
+ lastCheckedTV.Seconds = static_cast<sal_uInt32>(lastChecked);
+ osl_getLocalTimeFromSystemTime( &lastCheckedTV, &lastCheckedTV );
+
+ if ( osl_getDateTimeFromTimeValue( &lastCheckedTV, &lastCheckedDT ) )
+ {
+ aDate = Date( lastCheckedDT.Day, lastCheckedDT.Month, lastCheckedDT.Year );
+ aTime = ::tools::Time( lastCheckedDT.Hours, lastCheckedDT.Minutes );
+ }
+
+ LanguageType eUILang = Application::GetSettings().GetUILanguageTag().getLanguageType();
+ std::optional<SvNumberFormatter> pNumberFormatter( std::in_place, ::comphelper::getProcessComponentContext(), eUILang );
+ const Color* pColor = nullptr;
+ const Date& rNullDate = pNumberFormatter->GetNullDate();
+ sal_uInt32 nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::DATE, eUILang );
+
+ OUString aDateStr;
+ pNumberFormatter->GetOutputString( aDate - rNullDate, nFormat, aDateStr, &pColor );
+
+ nFormat = pNumberFormatter->GetStandardFormat( SvNumFormatType::TIME, eUILang );
+ OUString aTimeStr;
+ pNumberFormatter->GetOutputString( aTime.GetTimeInDays(), nFormat, aTimeStr, &pColor );
+
+ pNumberFormatter.reset();
+
+ aText = m_aLastCheckedTemplate;
+ sal_Int32 nIndex = aText.indexOf( "%DATE%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aDateStr );
+
+ nIndex = aText.indexOf( "%TIME%" );
+ if ( nIndex != -1 )
+ aText = aText.replaceAt( nIndex, 6, aTimeStr );
+ }
+
+ m_xLastChecked->set_label(aText);
+}
+
+void SvxOnlineUpdateTabPage::UpdateUserAgent()
+{
+ try {
+ uno::Reference< ucb::XWebDAVCommandEnvironment > xDav(
+ css::deployment::UpdateInformationProvider::create(
+ ::comphelper::getProcessComponentContext() ),
+ css::uno::UNO_QUERY_THROW );
+
+ OUString aPseudoURL = "useragent:normal";
+ if( m_xExtrasCheckBox->get_active() )
+ aPseudoURL = "useragent:extended";
+ const uno::Sequence< beans::StringPair > aHeaders
+ = xDav->getUserRequestHeaders( aPseudoURL, ucb::WebDAVHTTPMethod(0) );
+
+ for (const css::beans::StringPair & aHeader : aHeaders)
+ {
+ if ( aHeader.First == "User-Agent" )
+ {
+ OUString aText = aHeader.Second;
+ aText = aText.replaceAll(";", ";\n");
+ aText = aText.replaceAll("(", "\n(");
+ m_xUserAgentLabel->set_label(aText);
+ break;
+ }
+ }
+ } catch (const uno::Exception &) {
+ TOOLS_WARN_EXCEPTION( "cui.options", "Unexpected exception fetching User Agent" );
+ }
+}
+
+std::unique_ptr<SfxTabPage> SvxOnlineUpdateTabPage::Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rAttrSet )
+{
+ return std::make_unique<SvxOnlineUpdateTabPage>( pPage, pController, *rAttrSet );
+}
+
+bool SvxOnlineUpdateTabPage::FillItemSet( SfxItemSet* )
+{
+ bool bModified = false;
+
+ bool bValue;
+ sal_Int64 nValue;
+
+ if( m_xAutoCheckCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoCheckCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoCheckEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ nValue = 0;
+ if( m_xEveryDayButton->get_active() )
+ {
+ if( !m_xEveryDayButton->get_saved_state() )
+ nValue = 86400;
+ }
+ else if( m_xEveryWeekButton->get_active() )
+ {
+ if( !m_xEveryWeekButton->get_saved_state() )
+ nValue = 604800;
+ }
+ else if( m_xEveryMonthButton->get_active() )
+ {
+ if( !m_xEveryMonthButton->get_saved_state() )
+ nValue = 2592000;
+ }
+
+ if( nValue > 0 )
+ {
+ m_xUpdateAccess->replaceByName( "CheckInterval", uno::Any( nValue ) );
+ bModified = true;
+ }
+
+ if( m_xAutoDownloadCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xAutoDownloadCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "AutoDownloadEnabled", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ OUString sValue, aURL;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+
+ if( ( osl::FileBase::E_None == osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) ) &&
+ ( aURL != sValue ) )
+ {
+ m_xUpdateAccess->replaceByName( "DownloadDestination", uno::Any( aURL ) );
+ bModified = true;
+ }
+
+ if( m_xExtrasCheckBox->get_state_changed_from_saved() )
+ {
+ bValue = m_xExtrasCheckBox->get_active();
+ m_xUpdateAccess->replaceByName( "ExtendedUserAgent", uno::Any( bValue ) );
+ bModified = true;
+ }
+
+ uno::Reference< util::XChangesBatch > xChangesBatch(m_xUpdateAccess, uno::UNO_QUERY);
+ if( xChangesBatch.is() && xChangesBatch->hasPendingChanges() )
+ xChangesBatch->commitChanges();
+
+ return bModified;
+}
+
+void SvxOnlineUpdateTabPage::Reset( const SfxItemSet* )
+{
+ bool bValue = false;
+ m_xUpdateAccess->getByName( "AutoCheckEnabled" ) >>= bValue;
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoCheckEnabled");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+
+ m_xAutoCheckCheckBox->set_active(bValue);
+ m_xAutoCheckCheckBox->set_sensitive(!bReadOnly);
+
+ sal_Int64 nValue = 0;
+ m_xUpdateAccess->getByName( "CheckInterval" ) >>= nValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly2 = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryWeekButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+ m_xEveryMonthButton->set_sensitive(bValue && !(bReadOnly || bReadOnly2));
+
+ if( nValue == 86400 )
+ m_xEveryDayButton->set_active(true);
+ else if( nValue == 604800 )
+ m_xEveryWeekButton->set_active(true);
+ else
+ m_xEveryMonthButton->set_active(true);
+
+ m_xAutoCheckCheckBox->save_state();
+ m_xEveryDayButton->save_state();
+ m_xEveryWeekButton->save_state();
+ m_xEveryMonthButton->save_state();
+
+ m_xUpdateAccess->getByName( "AutoDownloadEnabled" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/AutoDownloadEnabled");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xAutoDownloadCheckBox->set_active(bValue);
+ m_xAutoDownloadCheckBox->set_sensitive(!bReadOnly);
+ m_xDestPathLabel->set_sensitive(true);
+ m_xDestPath->set_sensitive(true);
+
+ OUString sValue, aPath;
+ m_xUpdateAccess->getByName( "DownloadDestination" ) >>= sValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/DownloadDestination");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xChangePathButton->set_sensitive(!bReadOnly);
+
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sValue, aPath) )
+ m_xDestPath->set_label(aPath);
+
+ m_xUpdateAccess->getByName( "ExtendedUserAgent" ) >>= bValue;
+ aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/ExtendedUserAgent");
+ bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xExtrasCheckBox->set_active(bValue);
+ m_xExtrasCheckBox->set_sensitive(!bReadOnly);
+ m_xExtrasCheckBox->save_state();
+ UpdateUserAgent();
+
+ m_xAutoDownloadCheckBox->save_state();
+}
+
+void SvxOnlineUpdateTabPage::FillUserData()
+{
+}
+
+IMPL_LINK(SvxOnlineUpdateTabPage, AutoCheckHdl_Impl, weld::Toggleable&, rBox, void)
+{
+ bool bEnabled = rBox.get_active();
+ beans::Property aProperty = m_xReadWriteAccess->getPropertyByHierarchicalName("/org.openoffice.Office.Jobs/Jobs/org.openoffice.Office.Jobs:Job['UpdateCheck']/Arguments/CheckInterval");
+ bool bReadOnly = (aProperty.Attributes & beans::PropertyAttribute::READONLY) != 0;
+ m_xEveryDayButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryWeekButton->set_sensitive(bEnabled && !bReadOnly);
+ m_xEveryMonthButton->set_sensitive(bEnabled && !bReadOnly);
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, ExtrasCheckHdl_Impl, weld::Toggleable&, void)
+{
+ UpdateUserAgent();
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, FileDialogHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
+
+ OUString aURL;
+ if( osl::FileBase::E_None != osl::FileBase::getFileURLFromSystemPath(m_xDestPath->get_label(), aURL) )
+ osl::Security().getHomeDir(aURL);
+
+ xFolderPicker->setDisplayDirectory( aURL );
+ sal_Int16 nRet = xFolderPicker->execute();
+
+ if ( ui::dialogs::ExecutableDialogResults::OK == nRet )
+ {
+ OUString aFolder;
+ if( osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(xFolderPicker->getDirectory(), aFolder))
+ m_xDestPath->set_label(aFolder);
+ }
+}
+
+IMPL_LINK_NOARG(SvxOnlineUpdateTabPage, CheckNowHdl_Impl, weld::Button&, void)
+{
+ uno::Reference < uno::XComponentContext> xContext( ::comphelper::getProcessComponentContext() );
+
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xConfigProvider(
+ css::configuration::theDefaultProvider::get( xContext ) );
+
+ beans::NamedValue aProperty;
+ aProperty.Name = "nodepath";
+ aProperty.Value <<= OUString("org.openoffice.Office.Addons/AddonUI/OfficeHelp/UpdateCheckJob");
+
+ uno::Sequence< uno::Any > aArgumentList{ uno::Any(aProperty) };
+
+ uno::Reference< container::XNameAccess > xNameAccess(
+ xConfigProvider->createInstanceWithArguments(
+ "com.sun.star.configuration.ConfigurationAccess", aArgumentList ),
+ uno::UNO_QUERY_THROW );
+
+ util::URL aURL;
+ xNameAccess->getByName("URL") >>= aURL.Complete;
+
+ uno::Reference < util::XURLTransformer > xTransformer( util::URLTransformer::create( xContext ) );
+
+ xTransformer->parseStrict(aURL);
+
+ uno::Reference < frame::XDesktop2 > xDesktop = frame::Desktop::create( xContext );
+
+ uno::Reference< frame::XDispatchProvider > xDispatchProvider(
+ xDesktop->getCurrentFrame(), uno::UNO_QUERY );
+
+ uno::Reference< frame::XDispatch > xDispatch;
+ if( xDispatchProvider.is() )
+ xDispatch = xDispatchProvider->queryDispatch(aURL, OUString(), 0);
+
+ if( xDispatch.is() )
+ xDispatch->dispatch(aURL, uno::Sequence< beans::PropertyValue > ());
+
+ UpdateLastCheckedText();
+ }
+ catch( const uno::Exception& )
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "Caught exception, thread terminated");
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/optupdt.hxx b/cui/source/options/optupdt.hxx
new file mode 100644
index 000000000..7143bf333
--- /dev/null
+++ b/cui/source/options/optupdt.hxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/configuration/XReadWriteAccess.hpp>
+
+// class SvxPathTabPage --------------------------------------------------
+
+class SvxOnlineUpdateTabPage : public SfxTabPage
+{
+private:
+ OUString m_aNeverChecked;
+ OUString m_aLastCheckedTemplate;
+
+ css::uno::Reference< css::container::XNameReplace > m_xUpdateAccess;
+ css::uno::Reference<css::configuration::XReadWriteAccess> m_xReadWriteAccess;
+
+ std::unique_ptr<weld::Label> m_xNeverChecked;
+ std::unique_ptr<weld::CheckButton> m_xAutoCheckCheckBox;
+ std::unique_ptr<weld::RadioButton> m_xEveryDayButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryWeekButton;
+ std::unique_ptr<weld::RadioButton> m_xEveryMonthButton;
+ std::unique_ptr<weld::Button> m_xCheckNowButton;
+ std::unique_ptr<weld::CheckButton> m_xAutoDownloadCheckBox;
+ std::unique_ptr<weld::Label> m_xDestPathLabel;
+ std::unique_ptr<weld::Label> m_xDestPath;
+ std::unique_ptr<weld::Button> m_xChangePathButton;
+ std::unique_ptr<weld::Label> m_xLastChecked;
+ std::unique_ptr<weld::CheckButton> m_xExtrasCheckBox;
+ std::unique_ptr<weld::Label> m_xUserAgentLabel;
+ std::unique_ptr<weld::LinkButton> m_xPrivacyPolicyButton;
+
+ DECL_LINK(FileDialogHdl_Impl, weld::Button&, void);
+ DECL_LINK(CheckNowHdl_Impl, weld::Button&, void);
+ DECL_LINK(AutoCheckHdl_Impl, weld::Toggleable&, void);
+ DECL_LINK(ExtrasCheckHdl_Impl, weld::Toggleable&, void);
+
+ void UpdateLastCheckedText();
+ void UpdateUserAgent();
+
+public:
+ SvxOnlineUpdateTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet);
+ static std::unique_ptr<SfxTabPage> Create( weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet );
+ virtual ~SvxOnlineUpdateTabPage() override;
+
+ virtual bool FillItemSet( SfxItemSet* rSet ) override;
+ virtual void Reset( const SfxItemSet* rSet ) override;
+ virtual void FillUserData() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.cxx b/cui/source/options/personalization.cxx
new file mode 100644
index 000000000..ec62fb105
--- /dev/null
+++ b/cui/source/options/personalization.cxx
@@ -0,0 +1,166 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_folders.h>
+
+#include "personalization.hxx"
+
+#include <comphelper/processfactory.hxx>
+#include <officecfg/Office/Common.hxx>
+#include <rtl/bootstrap.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/stream.hxx>
+#include <vcl/event.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/graphicfilter.hxx>
+#include <vcl/virdev.hxx>
+
+using namespace com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::beans;
+
+// persona
+SvxPersonalizationTabPage::SvxPersonalizationTabPage(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet& rSet)
+ : SfxTabPage(pPage, pController, "cui/ui/personalization_tab.ui", "PersonalizationTabPage",
+ &rSet)
+ , m_xNoPersona(m_xBuilder->weld_radio_button("no_persona"))
+ , m_xDefaultPersona(m_xBuilder->weld_radio_button("default_persona"))
+{
+ for (sal_uInt32 i = 0; i < MAX_DEFAULT_PERSONAS; ++i)
+ {
+ OString sDefaultId("default" + OString::number(i));
+ m_vDefaultPersonaImages[i] = m_xBuilder->weld_toggle_button(sDefaultId);
+ m_vDefaultPersonaImages[i]->connect_clicked(
+ LINK(this, SvxPersonalizationTabPage, DefaultPersona));
+ }
+
+ LoadDefaultImages();
+}
+
+SvxPersonalizationTabPage::~SvxPersonalizationTabPage() {}
+
+std::unique_ptr<SfxTabPage> SvxPersonalizationTabPage::Create(weld::Container* pPage,
+ weld::DialogController* pController,
+ const SfxItemSet* rSet)
+{
+ return std::make_unique<SvxPersonalizationTabPage>(pPage, pController, *rSet);
+}
+
+bool SvxPersonalizationTabPage::FillItemSet(SfxItemSet*)
+{
+ // persona
+ OUString aPersona("default");
+ if (m_xNoPersona->get_active())
+ aPersona = "no";
+
+ bool bModified = false;
+ if (aPersona != officecfg::Office::Common::Misc::Persona::get()
+ || m_aPersonaSettings != officecfg::Office::Common::Misc::PersonaSettings::get())
+ {
+ bModified = true;
+ }
+
+ // write
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+ if (aPersona == "no")
+ m_aPersonaSettings.clear();
+ officecfg::Office::Common::Misc::Persona::set(aPersona, batch);
+ officecfg::Office::Common::Misc::PersonaSettings::set(m_aPersonaSettings, batch);
+ batch->commit();
+
+ if (bModified)
+ {
+ // broadcast the change
+ DataChangedEvent aDataChanged(DataChangedEventType::SETTINGS, nullptr,
+ AllSettingsFlags::STYLE);
+ Application::NotifyAllWindows(aDataChanged);
+ }
+
+ return bModified;
+}
+
+void SvxPersonalizationTabPage::Reset(const SfxItemSet*)
+{
+ // persona
+ OUString aPersona = officecfg::Office::Common::Misc::Persona::get();
+ m_aPersonaSettings = officecfg::Office::Common::Misc::PersonaSettings::get();
+
+ if (aPersona == "no")
+ m_xNoPersona->set_active(true);
+ else
+ m_xDefaultPersona->set_active(true);
+}
+
+void SvxPersonalizationTabPage::LoadDefaultImages()
+{
+ // Load the pre saved personas
+
+ OUString gallery = "$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/gallery/personas/";
+ rtl::Bootstrap::expandMacros(gallery);
+ OUString aPersonasList = gallery + "personas_list.txt";
+ SvFileStream aStream(aPersonasList, StreamMode::READ);
+ GraphicFilter aFilter;
+ Graphic aGraphic;
+ sal_Int32 nIndex = 0;
+ bool foundOne = false;
+
+ OStringBuffer aLine;
+ while (aStream.IsOpen() && !aStream.eof() && nIndex < MAX_DEFAULT_PERSONAS)
+ {
+ OUString aPersonaSetting, aPreviewFile, aName;
+ sal_Int32 nParseIndex = 0;
+
+ aStream.ReadLine(aLine);
+ aPersonaSetting = OStringToOUString(aLine, RTL_TEXTENCODING_UTF8);
+ aName = aPersonaSetting.getToken(1, ';', nParseIndex);
+ aPreviewFile = aPersonaSetting.getToken(0, ';', nParseIndex);
+
+ if (aPreviewFile.isEmpty())
+ break;
+
+ m_vDefaultPersonaSettings.push_back(aPersonaSetting);
+
+ INetURLObject aURLObj(rtl::OUStringConcatenation(gallery + aPreviewFile));
+ aFilter.ImportGraphic(aGraphic, aURLObj);
+
+ Size aSize(aGraphic.GetSizePixel());
+ aSize.setWidth(aSize.Width() / 4);
+ aSize.setHeight(aSize.Height() / 1.5);
+ ScopedVclPtr<VirtualDevice> xVirDev
+ = m_vDefaultPersonaImages[nIndex]->create_virtual_device();
+ xVirDev->SetOutputSizePixel(aSize);
+ aGraphic.Draw(*xVirDev, Point(0, 0));
+ m_vDefaultPersonaImages[nIndex]->set_image(xVirDev.get());
+ xVirDev.disposeAndClear();
+
+ m_vDefaultPersonaImages[nIndex]->set_tooltip_text(aName);
+ m_vDefaultPersonaImages[nIndex++]->show();
+ foundOne = true;
+ }
+
+ m_xDefaultPersona->set_sensitive(foundOne);
+}
+
+IMPL_LINK(SvxPersonalizationTabPage, DefaultPersona, weld::Button&, rButton, void)
+{
+ m_xDefaultPersona->set_active(true);
+ for (sal_Int32 nIndex = 0; nIndex < MAX_DEFAULT_PERSONAS; ++nIndex)
+ {
+ if (&rButton == m_vDefaultPersonaImages[nIndex].get())
+ m_aPersonaSettings = m_vDefaultPersonaSettings[nIndex];
+ else
+ m_vDefaultPersonaImages[nIndex]->set_active(false);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/personalization.hxx b/cui/source/options/personalization.hxx
new file mode 100644
index 000000000..671f194c2
--- /dev/null
+++ b/cui/source/options/personalization.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <sfx2/tabdlg.hxx>
+#include <vector>
+
+#define MAX_DEFAULT_PERSONAS 6 // Maximum number of default personas
+
+class SvxPersonalizationTabPage : public SfxTabPage
+{
+private:
+ std::unique_ptr<weld::RadioButton> m_xNoPersona; ///< Just the default look, without any bitmap
+ std::unique_ptr<weld::RadioButton> m_xDefaultPersona; ///< Use the built-in bitmap
+ std::unique_ptr<weld::ToggleButton> m_vDefaultPersonaImages
+ [MAX_DEFAULT_PERSONAS]; ///< Buttons to show the default persona images
+ OUString m_aPersonaSettings; ///< Header and footer images + color to be set in the settings.
+
+ std::vector<OUString> m_vDefaultPersonaSettings;
+
+public:
+ SvxPersonalizationTabPage(weld::Container* pPage, weld::DialogController* pController,
+ const SfxItemSet& rSet);
+ virtual ~SvxPersonalizationTabPage() override;
+
+ static std::unique_ptr<SfxTabPage>
+ Create(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet* rSet);
+
+ /// Apply the settings ([OK] button).
+ virtual bool FillItemSet(SfxItemSet* rSet) override;
+
+ /// Reset to default settings ([Revert] button).
+ virtual void Reset(const SfxItemSet* rSet) override;
+
+ /*
+ * Loads the default personas from the shared personas directory
+ * which resides in the shared gallery.
+ * There needs to be a separate subdirectory for each default persona,
+ * which includes the preview, header, and footer images.
+ * And there needs to be a personas_list.txt file in the personas directory
+ * which keeps the index/info of the default personas, one persona per line.
+ * A line should look like this:
+ * persona_slug;Persona Name;subdir/preview.jpg;subdir/header.jpg;subdir/footer.jpg;#textcolor
+ * (It is recommended to keep the subdir name the same as the slug)
+ * Example line:
+ * abstract;Abstract;abstract/preview.jpg;abstract/Header2.jpg;abstract/Footer2.jpg;#ffffff
+ */
+ void LoadDefaultImages();
+
+private:
+ /// Handle the default Persona selection
+ DECL_LINK(DefaultPersona, weld::Button&, void);
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.cxx b/cui/source/options/sdbcdriverenum.cxx
new file mode 100644
index 000000000..629fb7056
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.cxx
@@ -0,0 +1,99 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "sdbcdriverenum.hxx"
+#include <comphelper/processfactory.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/sdbc/DriverManager.hpp>
+
+
+namespace offapp
+{
+
+
+ using namespace css::uno;
+ using namespace css::lang;
+ using namespace css::container;
+ using namespace css::sdbc;
+
+ class ODriverEnumerationImpl
+ {
+ protected:
+ std::vector< OUString > m_aImplNames;
+
+ public:
+ ODriverEnumerationImpl();
+
+ const std::vector< OUString >& getDriverImplNames() const { return m_aImplNames; }
+ };
+
+
+ ODriverEnumerationImpl::ODriverEnumerationImpl()
+ {
+ try
+ {
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XDriverManager2 > xEnumAccess = DriverManager::create( xContext );
+
+ Reference< XEnumeration > xEnumDrivers = xEnumAccess->createEnumeration();
+ OSL_ENSURE(xEnumDrivers.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: invalid enumeration object!");
+
+ Reference< XServiceInfo > xDriverSI;
+ while (xEnumDrivers->hasMoreElements())
+ {
+ xEnumDrivers->nextElement() >>= xDriverSI;
+ OSL_ENSURE(xDriverSI.is(), "ODriverEnumerationImpl::ODriverEnumerationImpl: driver without service info!");
+ if (xDriverSI.is())
+ m_aImplNames.push_back(xDriverSI->getImplementationName());
+ }
+ }
+ catch(const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ODriverEnumerationImpl::ODriverEnumerationImpl: caught an exception while enumerating the drivers!");
+ }
+ }
+
+ ODriverEnumeration::ODriverEnumeration() noexcept
+ :m_pImpl(new ODriverEnumerationImpl)
+ {
+ }
+
+
+ ODriverEnumeration::~ODriverEnumeration() noexcept
+ {
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::begin() const noexcept
+ {
+ return m_pImpl->getDriverImplNames().begin();
+ }
+
+
+ ODriverEnumeration::const_iterator ODriverEnumeration::end() const noexcept
+ {
+ return m_pImpl->getDriverImplNames().end();
+ }
+
+} // namespace offapp
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/sdbcdriverenum.hxx b/cui/source/options/sdbcdriverenum.hxx
new file mode 100644
index 000000000..852648893
--- /dev/null
+++ b/cui/source/options/sdbcdriverenum.hxx
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+
+#include <vector>
+#include <memory>
+
+
+namespace offapp
+{
+
+ class ODriverEnumerationImpl;
+ /** simple class for accessing SDBC drivers registered within the office
+ <p>Rather small, introduced to not contaminate other instances with the
+ exception handling (code-size-bloating) implementations here.
+ </p>
+ */
+ class ODriverEnumeration
+ {
+ private:
+ std::unique_ptr<ODriverEnumerationImpl> m_pImpl;
+
+ public:
+ ODriverEnumeration() noexcept;
+ ~ODriverEnumeration() noexcept;
+ typedef std::vector< OUString >::const_iterator const_iterator;
+
+ const_iterator begin() const noexcept;
+ const_iterator end() const noexcept;
+ };
+
+
+} // namespace offapp
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.cxx b/cui/source/options/securityoptions.cxx
new file mode 100644
index 000000000..4b00176ab
--- /dev/null
+++ b/cui/source/options/securityoptions.cxx
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <unotools/securityoptions.hxx>
+#include "securityoptions.hxx"
+
+namespace
+{
+ bool enableAndSet(SvtSecurityOptions::EOption eOption,
+ weld::CheckButton& rCheckBox, weld::Widget& rFixedImage)
+ {
+ bool bEnable = !SvtSecurityOptions::IsReadOnly(eOption);
+ rCheckBox.set_sensitive(bEnable);
+ rFixedImage.set_visible(!bEnable);
+ rCheckBox.set_active(SvtSecurityOptions::IsOptionSet(eOption));
+ return bEnable;
+ }
+}
+
+namespace svx
+{
+
+SecurityOptionsDialog::SecurityOptionsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/securityoptionsdialog.ui", "SecurityOptionsDialog")
+ , m_xSaveOrSendDocsCB(m_xBuilder->weld_check_button("savesenddocs"))
+ , m_xSaveOrSendDocsImg(m_xBuilder->weld_widget("locksavesenddocs"))
+ , m_xSignDocsCB(m_xBuilder->weld_check_button("whensigning"))
+ , m_xSignDocsImg(m_xBuilder->weld_widget("lockwhensigning"))
+ , m_xPrintDocsCB(m_xBuilder->weld_check_button("whenprinting"))
+ , m_xPrintDocsImg(m_xBuilder->weld_widget("lockwhenprinting"))
+ , m_xCreatePdfCB(m_xBuilder->weld_check_button("whenpdf"))
+ , m_xCreatePdfImg(m_xBuilder->weld_widget("lockwhenpdf"))
+ , m_xRemovePersInfoCB(m_xBuilder->weld_check_button("removepersonal"))
+ , m_xRemovePersInfoImg(m_xBuilder->weld_widget("lockremovepersonal"))
+ , m_xRecommPasswdCB(m_xBuilder->weld_check_button("password"))
+ , m_xRecommPasswdImg(m_xBuilder->weld_widget("lockpassword"))
+ , m_xCtrlHyperlinkCB(m_xBuilder->weld_check_button("ctrlclick"))
+ , m_xCtrlHyperlinkImg(m_xBuilder->weld_widget("lockctrlclick"))
+ , m_xBlockUntrustedRefererLinksCB(m_xBuilder->weld_check_button("blockuntrusted"))
+ , m_xBlockUntrustedRefererLinksImg(m_xBuilder->weld_widget("lockblockuntrusted"))
+{
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnSaveOrSend, *m_xSaveOrSendDocsCB,
+ *m_xSaveOrSendDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnSigning, *m_xSignDocsCB,
+ *m_xSignDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnPrint, *m_xPrintDocsCB,
+ *m_xPrintDocsImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnCreatePdf, *m_xCreatePdfCB,
+ *m_xCreatePdfImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo, *m_xRemovePersInfoCB,
+ *m_xRemovePersInfoImg);
+ enableAndSet(SvtSecurityOptions::EOption::DocWarnRecommendPassword, *m_xRecommPasswdCB,
+ *m_xRecommPasswdImg);
+ enableAndSet(SvtSecurityOptions::EOption::CtrlClickHyperlink, *m_xCtrlHyperlinkCB,
+ *m_xCtrlHyperlinkImg);
+ enableAndSet(SvtSecurityOptions::EOption::BlockUntrustedRefererLinks, *m_xBlockUntrustedRefererLinksCB,
+ *m_xBlockUntrustedRefererLinksImg);
+}
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/securityoptions.hxx b/cui/source/options/securityoptions.hxx
new file mode 100644
index 000000000..dc05f5bb8
--- /dev/null
+++ b/cui/source/options/securityoptions.hxx
@@ -0,0 +1,61 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+namespace svx
+{
+
+ class SecurityOptionsDialog : public weld::GenericDialogController
+ {
+ private:
+ std::unique_ptr<weld::CheckButton> m_xSaveOrSendDocsCB;
+ std::unique_ptr<weld::Widget> m_xSaveOrSendDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xSignDocsCB;
+ std::unique_ptr<weld::Widget> m_xSignDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xPrintDocsCB;
+ std::unique_ptr<weld::Widget> m_xPrintDocsImg;
+ std::unique_ptr<weld::CheckButton> m_xCreatePdfCB;
+ std::unique_ptr<weld::Widget> m_xCreatePdfImg;
+
+ std::unique_ptr<weld::CheckButton> m_xRemovePersInfoCB;
+ std::unique_ptr<weld::Widget> m_xRemovePersInfoImg;
+ std::unique_ptr<weld::CheckButton> m_xRecommPasswdCB;
+ std::unique_ptr<weld::Widget> m_xRecommPasswdImg;
+ std::unique_ptr<weld::CheckButton> m_xCtrlHyperlinkCB;
+ std::unique_ptr<weld::Widget> m_xCtrlHyperlinkImg;
+ std::unique_ptr<weld::CheckButton> m_xBlockUntrustedRefererLinksCB;
+ std::unique_ptr<weld::Widget> m_xBlockUntrustedRefererLinksImg;
+
+ public:
+ SecurityOptionsDialog(weld::Window* pParent);
+
+ bool IsSaveOrSendDocsChecked() const { return m_xSaveOrSendDocsCB->get_active(); }
+ bool IsSignDocsChecked() const { return m_xSignDocsCB->get_active(); }
+ bool IsPrintDocsChecked() const { return m_xPrintDocsCB->get_active(); }
+ bool IsCreatePdfChecked() const { return m_xCreatePdfCB->get_active(); }
+ bool IsRemovePersInfoChecked() const { return m_xRemovePersInfoCB->get_active(); }
+ bool IsRecommPasswdChecked() const { return m_xRecommPasswdCB->get_active(); }
+ bool IsCtrlHyperlinkChecked() const { return m_xCtrlHyperlinkCB->get_active(); }
+ bool IsBlockUntrustedRefererLinksChecked() const { return m_xBlockUntrustedRefererLinksCB->get_active(); }
+ };
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/treeopt.cxx b/cui/source/options/treeopt.cxx
new file mode 100644
index 000000000..5973f422a
--- /dev/null
+++ b/cui/source/options/treeopt.cxx
@@ -0,0 +1,2115 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <memory>
+#include <string_view>
+
+#include <config_features.h>
+#include <config_feature_opencl.h>
+#include <config_feature_desktop.h>
+#include <config_gpgme.h>
+
+#include <officecfg/Office/Common.hxx>
+
+#include <svx/dialogs.hrc>
+#include <svx/svxids.hrc>
+
+#include <treeopt.hrc>
+#include <helpids.h>
+
+#include "cfgchart.hxx"
+#include "connpoolconfig.hxx"
+#include "connpooloptions.hxx"
+#include <cuioptgenrl.hxx>
+#include <dbregister.hxx>
+#include "dbregisterednamesconfig.hxx"
+#include <dialmgr.hxx>
+#include "fontsubs.hxx"
+#include "optaccessibility.hxx"
+#include <optasian.hxx>
+#include "optchart.hxx"
+#include "optcolor.hxx"
+#include "optctl.hxx"
+#include "optfltr.hxx"
+#include "optgdlg.hxx"
+#include "opthtml.hxx"
+#include "optinet2.hxx"
+#include "optjava.hxx"
+#include "optjsearch.hxx"
+#include <optlingu.hxx>
+#if HAVE_FEATURE_OPENCL
+#include "optopencl.hxx"
+#endif
+#include <optpath.hxx>
+#include "optsave.hxx"
+#include "optupdt.hxx"
+#include "personalization.hxx"
+#include <treeopt.hxx>
+#include "optbasic.hxx"
+#include "optlanguagetool.hxx"
+
+#include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
+#include <com/sun/star/awt/ContainerWindowProvider.hpp>
+#include <com/sun/star/awt/XControl.hpp>
+#include <com/sun/star/awt/PosSize.hpp>
+#include <com/sun/star/frame/Desktop.hpp>
+#include <com/sun/star/frame/ModuleManager.hpp>
+#include <com/sun/star/frame/UnknownModuleException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/linguistic2/LinguProperties.hpp>
+#include <com/sun/star/setup/UpdateCheck.hpp>
+#include <comphelper/getexpandeduri.hxx>
+#include <comphelper/processfactory.hxx>
+#include <editeng/langitem.hxx>
+#include <editeng/optitems.hxx>
+#include <editeng/unolingu.hxx>
+#include <linguistic/misc.hxx>
+#include <officecfg/Office/OptionsDialog.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/dispatch.hxx>
+#include <sfx2/module.hxx>
+#include <sfx2/printopt.hxx>
+#include <sfx2/shell.hxx>
+#include <sfx2/viewsh.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <svl/flagitem.hxx>
+#include <svl/intitem.hxx>
+#include <svl/cjkoptions.hxx>
+#include <svl/ctloptions.hxx>
+#include <svx/databaseregistrationui.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/urlobj.hxx>
+#include <tools/diagnose_ex.h>
+#include <unotools/configmgr.hxx>
+#include <unotools/moduleoptions.hxx>
+#include <unotools/optionsdlg.hxx>
+#include <unotools/viewoptions.hxx>
+#include <utility>
+#include <vcl/help.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/weldutils.hxx>
+#include <vcl/window.hxx>
+#include <sal/log.hxx>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::frame;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::linguistic2;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+
+LastPageSaver* OfaTreeOptionsDialog::pLastPageSaver = nullptr;
+
+// some stuff for easier changes for SvtViewOptions
+constexpr OUStringLiteral VIEWOPT_DATANAME = u"page data";
+
+static void SetViewOptUserItem( SvtViewOptions& rOpt, const OUString& rData )
+{
+ rOpt.SetUserItem( VIEWOPT_DATANAME, Any( rData ) );
+}
+
+static OUString GetViewOptUserItem( const SvtViewOptions& rOpt )
+{
+ Any aAny( rOpt.GetUserItem( VIEWOPT_DATANAME ) );
+ OUString aUserData;
+ aAny >>= aUserData;
+
+ return aUserData;
+}
+
+namespace {
+
+struct ModuleToGroupNameMap_Impl
+{
+ std::u16string_view m_pModule;
+ OUString m_sGroupName;
+ sal_uInt16 m_nNodeId;
+};
+}
+
+static ModuleToGroupNameMap_Impl ModuleMap[] =
+{
+ { u"ProductName", OUString(), SID_GENERAL_OPTIONS },
+ { u"LanguageSettings", OUString(), SID_LANGUAGE_OPTIONS },
+ { u"Internet", OUString(), SID_INET_DLG },
+ { u"LoadSave", OUString(), SID_FILTER_DLG },
+ { u"Writer", OUString(), SID_SW_EDITOPTIONS },
+ { u"WriterWeb", OUString(), SID_SW_ONLINEOPTIONS },
+ { u"Math", OUString(), SID_SM_EDITOPTIONS },
+ { u"Calc", OUString(), SID_SC_EDITOPTIONS },
+ { u"Impress", OUString(), SID_SD_EDITOPTIONS },
+ { u"Draw", OUString(), SID_SD_GRAPHIC_OPTIONS },
+ { u"Charts", OUString(), SID_SCH_EDITOPTIONS },
+ { u"Base", OUString(), SID_SB_STARBASEOPTIONS },
+};
+
+static void setGroupName( std::u16string_view rModule, const OUString& rGroupName )
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ rEntry.m_sGroupName = rGroupName;
+ break;
+ }
+ }
+}
+
+static OUString getGroupName( std::u16string_view rModule, bool bForced )
+{
+ OUString sGroupName;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ sGroupName = rEntry.m_sGroupName;
+ break;
+ }
+ }
+
+ if ( sGroupName.isEmpty() && bForced )
+ {
+ if ( rModule == u"Writer" )
+ sGroupName = CuiResId(SID_SW_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"WriterWeb" )
+ sGroupName = CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first);
+ else if ( rModule == u"Calc" )
+ sGroupName = CuiResId(SID_SC_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Impress" )
+ sGroupName = CuiResId(SID_SD_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Draw" )
+ sGroupName = CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first);
+ else if ( rModule == u"Math" )
+ sGroupName = CuiResId(SID_SM_EDITOPTIONS_RES[0].first);
+ else if ( rModule == u"Base" )
+ sGroupName = CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first);
+ }
+ return sGroupName;
+}
+
+static void deleteGroupNames()
+{
+ for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ rEntry.m_sGroupName.clear();
+}
+
+static sal_uInt16 getGroupNodeId( std::u16string_view rModule )
+{
+ sal_uInt16 nNodeId = 0xFFFF;
+ for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
+ {
+ if ( rEntry.m_pModule == rModule )
+ {
+ nNodeId = rEntry.m_nNodeId;
+ break;
+ }
+ }
+
+ return nNodeId;
+}
+
+namespace {
+
+class MailMergeCfg_Impl : public utl::ConfigItem
+{
+private:
+ // variables
+ bool bIsEmailSupported;
+
+ virtual void ImplCommit() override;
+
+public:
+ MailMergeCfg_Impl();
+
+ virtual void Notify( const css::uno::Sequence< OUString >& _rPropertyNames) override;
+
+ bool IsEmailSupported() const {return bIsEmailSupported;}
+
+};
+
+}
+
+MailMergeCfg_Impl::MailMergeCfg_Impl() :
+ utl::ConfigItem("Office.Writer/MailMergeWizard"),
+ bIsEmailSupported(false)
+{
+ Sequence<OUString> aNames { "EMailSupported" };
+ const Sequence< Any > aValues = GetProperties(aNames);
+ const Any* pValues = aValues.getConstArray();
+ if(aValues.hasElements() && pValues[0].hasValue())
+ pValues[0] >>= bIsEmailSupported;
+}
+
+void MailMergeCfg_Impl::ImplCommit()
+{
+}
+
+void MailMergeCfg_Impl::Notify( const css::uno::Sequence< OUString >& )
+{
+}
+
+//typedef SfxTabPage* (*FNCreateTabPage)(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet);
+static std::unique_ptr<SfxTabPage> CreateGeneralTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
+{
+ CreateTabPage fnCreate = nullptr;
+ switch(nId)
+ {
+ case RID_SFXPAGE_SAVE: fnCreate = &SvxSaveTabPage::Create; break;
+ case RID_SFXPAGE_PATH: fnCreate = &SvxPathTabPage::Create; break;
+ case RID_SFXPAGE_GENERAL: fnCreate = &SvxGeneralTabPage::Create; break;
+ case RID_SFXPAGE_PRINTOPTIONS: fnCreate = &SfxCommonPrintOptionsTabPage::Create; break;
+ case OFA_TP_LANGUAGES: fnCreate = &OfaLanguagesTabPage::Create; break;
+ case RID_SFXPAGE_LINGU: fnCreate = &SvxLinguTabPage::Create; break;
+ case OFA_TP_VIEW: fnCreate = &OfaViewTabPage::Create; break;
+ case OFA_TP_MISC: fnCreate = &OfaMiscTabPage::Create; break;
+ case RID_SVXPAGE_ASIAN_LAYOUT: fnCreate = &SvxAsianLayoutPage::Create; break;
+ case RID_SVX_FONT_SUBSTITUTION: fnCreate = &SvxFontSubstTabPage::Create; break;
+ case RID_SVXPAGE_INET_PROXY: fnCreate = &SvxProxyTabPage::Create; break;
+ case RID_SVXPAGE_INET_SECURITY: fnCreate = &SvxSecurityTabPage::Create; break;
+ case RID_SVXPAGE_INET_MAIL: fnCreate = &SvxEMailTabPage::Create; break;
+#if HAVE_FEATURE_DESKTOP
+ case RID_SVXPAGE_PERSONALIZATION: fnCreate = &SvxPersonalizationTabPage::Create; break;
+#endif
+ case RID_SVXPAGE_COLORCONFIG: fnCreate = &SvxColorOptionsTabPage::Create; break;
+ case RID_OFAPAGE_HTMLOPT: fnCreate = &OfaHtmlTabPage::Create; break;
+ case SID_OPTFILTER_MSOFFICE: fnCreate = &OfaMSFilterTabPage::Create; break;
+ case RID_OFAPAGE_MSFILTEROPT2: fnCreate = &OfaMSFilterTabPage2::Create; break;
+ case RID_SVXPAGE_JSEARCH_OPTIONS: fnCreate = &SvxJSearchOptionsPage::Create ; break;
+ case SID_SB_CONNECTIONPOOLING: fnCreate = &::offapp::ConnectionPoolOptionsPage::Create; break;
+ case SID_SB_DBREGISTEROPTIONS: fnCreate = &svx::DbRegistrationOptionsPage::Create; break;
+ case RID_SVXPAGE_ACCESSIBILITYCONFIG: fnCreate = &SvxAccessibilityOptionsTabPage::Create; break;
+ case RID_SVXPAGE_OPTIONS_CTL: fnCreate = &SvxCTLOptionsPage::Create ; break;
+ case RID_SVXPAGE_LANGTOOL_OPTIONS: fnCreate = &OptLanguageToolTabPage::Create ; break;
+ case RID_SVXPAGE_OPTIONS_JAVA: fnCreate = &SvxJavaOptionsPage::Create ; break;
+#if HAVE_FEATURE_OPENCL
+ case RID_SVXPAGE_OPENCL: fnCreate = &SvxOpenCLTabPage::Create ; break;
+#endif
+ case RID_SVXPAGE_ONLINEUPDATE: fnCreate = &SvxOnlineUpdateTabPage::Create; break;
+ case RID_OPTPAGE_CHART_DEFCOLORS: fnCreate = &SvxDefaultColorOptPage::Create; break;
+#if HAVE_FEATURE_SCRIPTING
+ case RID_SVXPAGE_BASICIDE_OPTIONS: fnCreate = &SvxBasicIDEOptionsPage::Create; break;
+#endif
+ }
+
+ return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
+}
+
+namespace {
+
+struct OptionsMapping_Impl
+{
+ const char* m_pGroupName;
+ const char* m_pPageName;
+ sal_uInt16 m_nPageId;
+};
+
+}
+
+OptionsMapping_Impl const OptionsMap_Impl[] =
+{
+// GROUP PAGE PAGE-ID
+ { "ProductName", nullptr, SID_GENERAL_OPTIONS },
+ { "ProductName", "UserData", RID_SFXPAGE_GENERAL },
+ { "ProductName", "General", OFA_TP_MISC },
+ { "ProductName", "View", OFA_TP_VIEW },
+ { "ProductName", "Print", RID_SFXPAGE_PRINTOPTIONS },
+ { "ProductName", "Paths", RID_SFXPAGE_PATH },
+ { "ProductName", "Fonts", RID_SVX_FONT_SUBSTITUTION },
+ { "ProductName", "Security", RID_SVXPAGE_INET_SECURITY },
+ { "ProductName", "Personalization", RID_SVXPAGE_PERSONALIZATION },
+ { "ProductName", "Appearance", RID_SVXPAGE_COLORCONFIG },
+ { "ProductName", "Accessibility", RID_SVXPAGE_ACCESSIBILITYCONFIG },
+ { "ProductName", "Java", RID_SVXPAGE_OPTIONS_JAVA },
+ { "ProductName", "BasicIDEOptions", RID_SVXPAGE_BASICIDE_OPTIONS },
+ { "ProductName", "OnlineUpdate", RID_SVXPAGE_ONLINEUPDATE },
+ { "LanguageSettings", nullptr, SID_LANGUAGE_OPTIONS },
+ { "LanguageSettings", "Languages", OFA_TP_LANGUAGES },
+ { "LanguageSettings", "WritingAids", RID_SFXPAGE_LINGU },
+ { "LanguageSettings", "SearchingInJapanese", RID_SVXPAGE_JSEARCH_OPTIONS },
+ { "LanguageSettings", "AsianLayout", RID_SVXPAGE_ASIAN_LAYOUT },
+ { "LanguageSettings", "ComplexTextLayout", RID_SVXPAGE_OPTIONS_CTL },
+ { "Internet", nullptr, SID_INET_DLG },
+ { "Internet", "Proxy", RID_SVXPAGE_INET_PROXY },
+ { "Internet", "Email", RID_SVXPAGE_INET_MAIL },
+ { "LoadSave", nullptr, SID_FILTER_DLG },
+ { "LoadSave", "General", RID_SFXPAGE_SAVE },
+ { "LoadSave", "VBAProperties", SID_OPTFILTER_MSOFFICE },
+ { "LoadSave", "MicrosoftOffice", RID_OFAPAGE_MSFILTEROPT2 },
+ { "LoadSave", "HTMLCompatibility", RID_OFAPAGE_HTMLOPT },
+ { "Writer", nullptr, SID_SW_EDITOPTIONS },
+ { "Writer", "General", RID_SW_TP_OPTLOAD_PAGE },
+ { "Writer", "View", RID_SW_TP_CONTENT_OPT },
+ { "Writer", "FormattingAids", RID_SW_TP_OPTSHDWCRSR },
+ { "Writer", "Grid", RID_SVXPAGE_GRID },
+ { "Writer", "BasicFontsWestern", RID_SW_TP_STD_FONT },
+ { "Writer", "BasicFontsAsian", RID_SW_TP_STD_FONT_CJK },
+ { "Writer", "BasicFontsCTL", RID_SW_TP_STD_FONT_CTL },
+ { "Writer", "Print", RID_SW_TP_OPTPRINT_PAGE },
+ { "Writer", "Table", RID_SW_TP_OPTTABLE_PAGE },
+ { "Writer", "Changes", RID_SW_TP_REDLINE_OPT },
+ { "Writer", "Comparison", RID_SW_TP_COMPARISON_OPT },
+ { "Writer", "Compatibility", RID_SW_TP_OPTCOMPATIBILITY_PAGE },
+ { "Writer", "AutoCaption", RID_SW_TP_OPTCAPTION_PAGE },
+ { "Writer", "MailMerge", RID_SW_TP_MAILCONFIG },
+ { "WriterWeb", nullptr, SID_SW_ONLINEOPTIONS },
+ { "WriterWeb", "View", RID_SW_TP_HTML_CONTENT_OPT },
+ { "WriterWeb", "FormattingAids", RID_SW_TP_HTML_OPTSHDWCRSR },
+ { "WriterWeb", "Grid", RID_SW_TP_HTML_OPTGRID_PAGE },
+ { "WriterWeb", "Print", RID_SW_TP_HTML_OPTPRINT_PAGE },
+ { "WriterWeb", "Table", RID_SW_TP_HTML_OPTTABLE_PAGE },
+ { "WriterWeb", "Background", RID_SW_TP_BACKGROUND },
+ { "Math", nullptr, SID_SM_EDITOPTIONS },
+ { "Math", "Settings", SID_SM_TP_PRINTOPTIONS },
+ { "Calc", nullptr, SID_SC_EDITOPTIONS },
+ { "Calc", "General", SID_SC_TP_LAYOUT },
+ { "Calc", "View", SID_SC_TP_CONTENT },
+ { "Calc", "Calculate", SID_SC_TP_CALC },
+ { "Calc", "Formula", SID_SC_TP_FORMULA },
+ { "Calc", "SortLists", SID_SC_TP_USERLISTS },
+ { "Calc", "Changes", SID_SC_TP_CHANGES },
+ { "Calc", "Compatibility", SID_SC_TP_COMPATIBILITY },
+ { "Calc", "Grid", SID_SC_TP_GRID },
+ { "Calc", "Print", RID_SC_TP_PRINT },
+ { "Impress", nullptr, SID_SD_EDITOPTIONS },
+ { "Impress", "General", SID_SI_TP_MISC },
+ { "Impress", "View", SID_SI_TP_CONTENTS },
+ { "Impress", "Grid", SID_SI_TP_SNAP },
+ { "Impress", "Print", SID_SI_TP_PRINT },
+ { "Draw", nullptr, SID_SD_GRAPHIC_OPTIONS },
+ { "Draw", "General", SID_SD_TP_MISC },
+ { "Draw", "View", SID_SD_TP_CONTENTS },
+ { "Draw", "Grid", SID_SD_TP_SNAP },
+ { "Draw", "Print", SID_SD_TP_PRINT },
+ { "Charts", nullptr, SID_SCH_EDITOPTIONS },
+ { "Charts", "DefaultColors", RID_OPTPAGE_CHART_DEFCOLORS },
+ { "Base", nullptr, SID_SB_STARBASEOPTIONS },
+ { "Base", "Connections", SID_SB_CONNECTIONPOOLING },
+ { "Base", "Databases", SID_SB_DBREGISTEROPTIONS },
+ { nullptr, nullptr, 0 }
+};
+
+static bool lcl_getStringFromID( sal_uInt16 _nPageId, OUString& _rGroupName, OUString& _rPageName )
+{
+ bool bRet = false;
+
+ sal_uInt16 nIdx = 0;
+ while ( OptionsMap_Impl[nIdx].m_pGroupName != nullptr )
+ {
+ if ( _nPageId == OptionsMap_Impl[nIdx].m_nPageId )
+ {
+ bRet = true;
+ _rGroupName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pGroupName );
+ if ( OptionsMap_Impl[nIdx].m_pPageName != nullptr )
+ _rPageName = OUString::createFromAscii( OptionsMap_Impl[nIdx].m_pPageName );
+ break;
+ }
+ ++nIdx;
+ }
+
+ return bRet;
+}
+
+static bool lcl_isOptionHidden( sal_uInt16 _nPageId, const SvtOptionsDialogOptions& _rOptOptions )
+{
+ bool bIsHidden = false;
+ OUString sGroupName, sPageName;
+ if ( lcl_getStringFromID( _nPageId, sGroupName, sPageName ) )
+ {
+ if ( sPageName.isEmpty() )
+ bIsHidden = _rOptOptions.IsGroupHidden( sGroupName );
+ else
+ bIsHidden = _rOptOptions.IsPageHidden( sPageName, sGroupName );
+ }
+ return bIsHidden;
+}
+
+struct OptionsPageInfo
+{
+ std::unique_ptr<SfxTabPage> m_xPage;
+ sal_uInt16 m_nPageId;
+ OUString m_sPageURL;
+ OUString m_sEventHdl;
+ std::unique_ptr<ExtensionsTabPage> m_xExtPage;
+
+ explicit OptionsPageInfo( sal_uInt16 nId ) : m_nPageId( nId ) {}
+};
+
+struct OptionsGroupInfo
+{
+ std::optional<SfxItemSet> m_pInItemSet;
+ std::unique_ptr<SfxItemSet> m_pOutItemSet;
+ SfxShell* m_pShell; // used to create the page
+ SfxModule* m_pModule; // used to create the ItemSet
+ sal_uInt16 m_nDialogId; // Id of the former dialog
+
+ OptionsGroupInfo( SfxShell* pSh, SfxModule* pMod, sal_uInt16 nId ) :
+ m_pShell( pSh ),
+ m_pModule( pMod ), m_nDialogId( nId ) {}
+};
+
+#define INI_LIST() \
+ , m_pParent ( pParent )\
+ , sTitle ( m_xDialog->get_title() )\
+ , bForgetSelection ( false )\
+ , bIsFromExtensionManager( false ) \
+ , bIsForSetDocumentLanguage( false ) \
+ , bNeedsRestart ( false ) \
+ , eRestartReason( svtools::RESTART_REASON_NONE )
+
+void OfaTreeOptionsDialog::InitWidgets()
+{
+ xOkPB = m_xBuilder->weld_button("ok");
+ xApplyPB = m_xBuilder->weld_button("apply");
+ xBackPB = m_xBuilder->weld_button("revert");
+ xTreeLB = m_xBuilder->weld_tree_view("pages");
+ xTabBox = m_xBuilder->weld_container("box");
+ Size aSize(xTreeLB->get_approximate_digit_width() * 82, xTreeLB->get_height_rows(30));
+#if HAVE_FEATURE_GPGME
+ // tdf#115015: make enough space for crypto settings (approx. 14 text edits + padding)
+ aSize.setHeight((weld::GetMinimumEditHeight() + 6) * 14);
+#endif
+ xTabBox->set_size_request(aSize.Width(), aSize.Height());
+ xTreeLB->set_size_request(xTreeLB->get_approximate_digit_width() * 35, aSize.Height());
+}
+
+// Ctor() with Frame -----------------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, const Reference< XFrame >& _xFrame, bool bActivateLastSelection)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ InitTreeAndHandler();
+ Initialize( _xFrame );
+ LoadExtensionOptions( u"" );
+ if (bActivateLastSelection)
+ ActivateLastSelection();
+
+ xTreeLB->set_accessible_name(m_xDialog->get_title());
+}
+
+// Ctor() with ExtensionId -----------------------------------------------
+OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, std::u16string_view rExtensionId)
+ : SfxOkDialogController(pParent, "cui/ui/optionsdialog.ui", "OptionsDialog")
+ INI_LIST()
+{
+ InitWidgets();
+
+ bIsFromExtensionManager = ( !rExtensionId.empty() );
+ InitTreeAndHandler();
+ LoadExtensionOptions( rExtensionId );
+ ActivateLastSelection();
+}
+
+OfaTreeOptionsDialog::~OfaTreeOptionsDialog()
+{
+ xCurrentPageEntry.reset();
+
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ // first children
+ while (bEntry)
+ {
+ // if Child (has parent), then OptionsPageInfo
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ if(pPageInfo->m_xPage)
+ {
+ pPageInfo->m_xPage->FillUserData();
+ OUString aPageData(pPageInfo->m_xPage->GetUserData());
+ if ( !aPageData.isEmpty() )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ SetViewOptUserItem( aTabPageOpt, aPageData );
+ }
+ pPageInfo->m_xPage.reset();
+ }
+
+ if (pPageInfo->m_nPageId == RID_SFXPAGE_LINGU)
+ {
+ // write personal dictionaries
+ Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
+ if (xDicList.is())
+ {
+ linguistic::SaveDictionaries( xDicList );
+ }
+ }
+
+ pPageInfo->m_xExtPage.reset();
+
+ delete pPageInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+
+ // and parents
+ bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
+ delete pGroupInfo;
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ deleteGroupNames();
+}
+
+OptionsPageInfo* OfaTreeOptionsDialog::AddTabPage(
+ sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup )
+{
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xParent))
+ return nullptr;
+ xTreeLB->iter_nth_sibling(*xParent, nGroup);
+
+ OptionsPageInfo* pPageInfo = new OptionsPageInfo( nId );
+ OUString sId(weld::toId(pPageInfo));
+ xTreeLB->insert(xParent.get(), -1, &rPageName, &sId, nullptr, nullptr, false, nullptr);
+ return pPageInfo;
+}
+
+// the ItemSet* is passed on to the dialog's ownership
+sal_uInt16 OfaTreeOptionsDialog::AddGroup(const OUString& rGroupName,
+ SfxShell* pCreateShell,
+ SfxModule* pCreateModule,
+ sal_uInt16 nDialogId )
+{
+ OptionsGroupInfo* pInfo =
+ new OptionsGroupInfo( pCreateShell, pCreateModule, nDialogId );
+ OUString sId(weld::toId(pInfo));
+ xTreeLB->append(sId, rGroupName);
+
+ sal_uInt16 nRet = 0;
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ nRet++;
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+ return nRet - 1;
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, ShowPageHdl_Impl, weld::TreeView&, void)
+{
+ SelectHdl_Impl();
+}
+
+void OfaTreeOptionsDialog::ResetCurrentPageFromConfig()
+{
+ if (!(xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry)))
+ return;
+
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if (pPageInfo->m_xPage)
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
+ }
+ else if ( pPageInfo->m_xExtPage )
+ pPageInfo->m_xExtPage->ResetPage();
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, BackHdl_Impl, weld::Button&, void)
+{
+ ResetCurrentPageFromConfig();
+}
+
+void OfaTreeOptionsDialog::ApplyOptions()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ if ( pPageInfo->m_xPage && !pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xEntry.get());
+ xTreeLB->iter_parent(*xParent);
+ OptionsGroupInfo* pGroupInfo =
+ weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ pPageInfo->m_xPage->FillItemSet(pGroupInfo->m_pOutItemSet.get());
+ }
+
+ if ( pPageInfo->m_xExtPage )
+ {
+ pPageInfo->m_xExtPage->DeactivatePage();
+ pPageInfo->m_xExtPage->SavePage();
+ }
+ if ( pPageInfo->m_xPage && RID_OPTPAGE_CHART_DEFCOLORS == pPageInfo->m_nPageId )
+ {
+ SvxDefaultColorOptPage* pPage = static_cast<SvxDefaultColorOptPage *>(pPageInfo->m_xPage.get());
+ pPage->SaveChartOptions();
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+IMPL_LINK_NOARG(OfaTreeOptionsDialog, HelpHdl_Impl, weld::Widget&, bool)
+{
+ Help* pHelp = Application::GetHelp();
+ if (pHelp && xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if (pPageInfo->m_xPage)
+ {
+ OString sHelpId(pPageInfo->m_xPage->GetHelpId());
+ pHelp->Start(OStringToOUString(sHelpId, RTL_TEXTENCODING_UTF8), m_xDialog.get());
+ return false;
+ }
+ }
+ return true;
+}
+
+IMPL_LINK(OfaTreeOptionsDialog, ApplyHdl_Impl, weld::Button&, rButton, void)
+{
+ bool bOkPressed = &rButton == xOkPB.get();
+
+ OptionsGroupInfo* pGroupInfo = nullptr;
+
+ if (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
+ if ( pPageInfo->m_xPage )
+ {
+ std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
+ xTreeLB->iter_parent(*xParent);
+
+ pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId
+ && pPageInfo->m_xPage->HasExchangeSupport() )
+ {
+ DeactivateRC nLeave = pPageInfo->m_xPage->DeactivatePage(pGroupInfo->m_pOutItemSet.get());
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // the page mustn't be left, so return early
+ assert(xTreeLB->is_selected(*xCurrentPageEntry)); // presumably this must be true here
+ if (bOkPressed)
+ return;
+ }
+ }
+ }
+ }
+
+ ApplyOptions();
+ ApplyItemSets();
+ utl::ConfigManager::storeConfigItems();
+
+ if (bOkPressed)
+ m_xDialog->response(RET_OK);
+ else
+ {
+ // tdf#137930 rebuild the in and out itemsets to reflect the current
+ // post-apply state
+ if (pGroupInfo && pGroupInfo->m_pInItemSet)
+ {
+ // tdf#138596 seeing as the SfxTabPages keep pointers to the m_pInItemSet
+ // we update the contents of the existing SfxItemSets to match
+ // the current settings, rather than create new ones
+ auto xInItemSet = pGroupInfo->m_pShell
+ ? pGroupInfo->m_pShell->CreateItemSet( pGroupInfo->m_nDialogId )
+ : CreateItemSet( pGroupInfo->m_nDialogId );
+ pGroupInfo->m_pInItemSet->Set(*xInItemSet, false);
+ pGroupInfo->m_pOutItemSet->ClearItem();
+ }
+
+ // for the Apply case, now that the settings are saved to config,
+ // reload the current page so it knows what the config now states
+ ResetCurrentPageFromConfig();
+ // reselect it to undo possible DeactivatePage above
+ xCurrentPageEntry.reset();
+ SelectHdl_Impl();
+ }
+
+ if (!bNeedsRestart)
+ return;
+
+ SolarMutexGuard aGuard;
+ weld::Window* pParent;
+ if (!bOkPressed)
+ pParent = m_xDialog.get();
+ else
+ {
+ m_xDialog->hide();
+ pParent = m_pParent;
+ }
+ bool bRestart = ::svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
+ pParent, eRestartReason);
+ if (bRestart && !bOkPressed)
+ m_xDialog->response(RET_OK);
+}
+
+void OfaTreeOptionsDialog::ApplyItemSets()
+{
+ std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
+ bool bEntry = xTreeLB->get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!xTreeLB->get_iter_depth(*xEntry))
+ {
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
+ if(pGroupInfo->m_pOutItemSet)
+ {
+ if(pGroupInfo->m_pShell)
+ pGroupInfo->m_pShell->ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ else
+ ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
+ }
+ }
+ bEntry = xTreeLB->iter_next(*xEntry);
+ }
+}
+
+void OfaTreeOptionsDialog::InitTreeAndHandler()
+{
+ xTreeLB->set_help_id(HID_OFADLG_TREELISTBOX);
+ xTreeLB->connect_changed( LINK( this, OfaTreeOptionsDialog, ShowPageHdl_Impl ) );
+ xBackPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, BackHdl_Impl ) );
+ xApplyPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, ApplyHdl_Impl ) );
+ xOkPB->connect_clicked( LINK( this, OfaTreeOptionsDialog, ApplyHdl_Impl ) );
+ m_xDialog->connect_help( LINK( this, OfaTreeOptionsDialog, HelpHdl_Impl ) );
+}
+
+void OfaTreeOptionsDialog::ActivatePage( sal_uInt16 nResId )
+{
+ bIsForSetDocumentLanguage = false;
+ if ( nResId == OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE )
+ {
+ bIsForSetDocumentLanguage = true;
+ nResId = OFA_TP_LANGUAGES;
+ }
+
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ sal_uInt16 nTemp = pLastPageSaver->m_nLastPageId;
+ pLastPageSaver->m_nLastPageId = nResId;
+ ActivateLastSelection();
+ pLastPageSaver->m_nLastPageId = nTemp;
+}
+
+void OfaTreeOptionsDialog::ActivatePage( const OUString& rPageURL )
+{
+ DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ bForgetSelection = true;
+ pLastPageSaver->m_nLastPageId = 0;
+ pLastPageSaver->m_sLastPageURL_Tools = rPageURL;
+ ActivateLastSelection();
+}
+
+void OfaTreeOptionsDialog::ActivateLastSelection()
+{
+ std::unique_ptr<weld::TreeIter> xEntry;
+
+ if (pLastPageSaver)
+ {
+ OUString sLastURL = bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ if ( sLastURL.isEmpty() )
+ {
+ sLastURL = !bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
+ : pLastPageSaver->m_sLastPageURL_Tools;
+ }
+
+ bool bMustExpand = ( INetURLObject( sLastURL ).GetProtocol() == INetProtocol::File );
+
+ std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
+ bool bTemp = xTreeLB->get_iter_first(*xTemp);
+ while (bTemp)
+ {
+ // restore only selection of a leaf
+ if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
+ {
+ OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xTemp));
+ OUString sPageURL = pPageInfo->m_sPageURL;
+ if ( bMustExpand )
+ {
+ sPageURL = comphelper::getExpandedUri(
+ comphelper::getProcessComponentContext(), sPageURL);
+ }
+
+ if ( ( !bIsFromExtensionManager
+ && pPageInfo->m_nPageId && pPageInfo->m_nPageId == pLastPageSaver->m_nLastPageId )
+ || ( !pPageInfo->m_nPageId && sLastURL == sPageURL ) )
+ {
+ xEntry = xTreeLB->make_iterator(xTemp.get());
+ break;
+ }
+ }
+ bTemp = xTreeLB->iter_next(*xTemp);
+ }
+ }
+
+ if (!xEntry)
+ {
+ xEntry = xTreeLB->make_iterator();
+ if (!xTreeLB->get_iter_first(*xEntry) || !xTreeLB->iter_next(*xEntry))
+ xEntry.reset();
+ }
+
+ if (!xEntry)
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ xTreeLB->iter_parent(*xParent);
+ xTreeLB->expand_row(*xParent);
+ xTreeLB->scroll_to_row(*xParent);
+ xTreeLB->scroll_to_row(*xEntry);
+ xTreeLB->set_cursor(*xEntry);
+ xTreeLB->select(*xEntry);
+ xTreeLB->grab_focus();
+ SelectHdl_Impl();
+}
+
+void OfaTreeOptionsDialog::InitItemSets(OptionsGroupInfo& rGroupInfo)
+{
+ if (!rGroupInfo.m_pInItemSet)
+ rGroupInfo.m_pInItemSet.emplace( rGroupInfo.m_pShell
+ ? *rGroupInfo.m_pShell->CreateItemSet( rGroupInfo.m_nDialogId )
+ : *CreateItemSet( rGroupInfo.m_nDialogId ) );
+ if (!rGroupInfo.m_pOutItemSet)
+ rGroupInfo.m_pOutItemSet = std::make_unique<SfxItemSet>(
+ *rGroupInfo.m_pInItemSet->GetPool(),
+ rGroupInfo.m_pInItemSet->GetRanges());
+}
+
+void OfaTreeOptionsDialog::SelectHdl_Impl()
+{
+ std::unique_ptr<weld::TreeIter> xEntry(xTreeLB->make_iterator());
+
+ if (!xTreeLB->get_cursor(xEntry.get()))
+ return;
+
+ if (xCurrentPageEntry && xCurrentPageEntry->equal(*xEntry))
+ return;
+
+ std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
+ bool bParent = xTreeLB->iter_parent(*xParent);
+
+ // If the user has selected a category, automatically switch to a suitable
+ // default sub-page instead.
+ if (!bParent)
+ return;
+
+ BuilderPage* pNewPage = nullptr;
+ OptionsPageInfo* pOptPageInfo = (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
+ ? weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry)) : nullptr;
+
+ if (pOptPageInfo && pOptPageInfo->m_xPage && pOptPageInfo->m_xPage->IsVisible())
+ {
+ std::unique_ptr<weld::TreeIter> xCurParent(xTreeLB->make_iterator(xCurrentPageEntry.get()));
+ xTreeLB->iter_parent(*xCurParent);
+
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xCurParent));
+ DeactivateRC nLeave = DeactivateRC::LeavePage;
+ if ( RID_SVXPAGE_COLOR != pOptPageInfo->m_nPageId && pOptPageInfo->m_xPage->HasExchangeSupport() )
+ nLeave = pOptPageInfo->m_xPage->DeactivatePage( pGroupInfo->m_pOutItemSet.get() );
+
+ if ( nLeave == DeactivateRC::KeepPage )
+ {
+ // we cannot leave this page, this is may be from a user clicking a different entry
+ // in the tree so reselect the current page
+ xTreeLB->select(*xCurrentPageEntry);
+ return;
+ }
+ else
+ pOptPageInfo->m_xPage->set_visible(false);
+ }
+ else if ( pOptPageInfo && pOptPageInfo->m_xExtPage )
+ {
+ pOptPageInfo->m_xExtPage->Hide();
+ pOptPageInfo->m_xExtPage->DeactivatePage();
+ }
+
+ OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
+ OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
+ if(!pPageInfo->m_xPage && pPageInfo->m_nPageId > 0)
+ {
+ InitItemSets(*pGroupInfo);
+
+ pPageInfo->m_xPage = ::CreateGeneralTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ if(!pPageInfo->m_xPage && pGroupInfo->m_pModule)
+ pPageInfo->m_xPage = pGroupInfo->m_pModule->CreateTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
+
+ DBG_ASSERT( pPageInfo->m_xPage, "tabpage could not created");
+ if ( pPageInfo->m_xPage )
+ {
+ SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
+ pPageInfo->m_xPage->SetUserData( GetViewOptUserItem( aTabPageOpt ) );
+ pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
+ }
+ }
+ else if ( 0 == pPageInfo->m_nPageId && !pPageInfo->m_xExtPage )
+ {
+ if ( !m_xContainerWinProvider.is() )
+ {
+ m_xContainerWinProvider = awt::ContainerWindowProvider::create( ::comphelper::getProcessComponentContext() );
+ }
+
+ pPageInfo->m_xExtPage = std::make_unique<ExtensionsTabPage>(
+ xTabBox.get(), pPageInfo->m_sPageURL, pPageInfo->m_sEventHdl, m_xContainerWinProvider);
+ }
+
+ if ( pPageInfo->m_xPage )
+ {
+ if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId &&
+ pPageInfo->m_xPage->HasExchangeSupport())
+ {
+ pPageInfo->m_xPage->ActivatePage(*pGroupInfo->m_pOutItemSet);
+ }
+ pPageInfo->m_xPage->set_visible(true);
+ }
+ else if ( pPageInfo->m_xExtPage )
+ {
+ pPageInfo->m_xExtPage->Show();
+ pPageInfo->m_xExtPage->ActivatePage();
+ }
+
+ {
+ OUString sTitleText = sTitle
+ + " - " + xTreeLB->get_text(*xParent)
+ + " - " + xTreeLB->get_text(*xEntry);
+ m_xDialog->set_title(sTitleText);
+ }
+
+ xCurrentPageEntry = std::move(xEntry);
+
+ if ( !bForgetSelection )
+ {
+ if ( !pLastPageSaver )
+ pLastPageSaver = new LastPageSaver;
+ if ( !bIsFromExtensionManager )
+ pLastPageSaver->m_nLastPageId = pPageInfo->m_nPageId;
+ if ( pPageInfo->m_xExtPage )
+ {
+ if ( bIsFromExtensionManager )
+ pLastPageSaver->m_sLastPageURL_ExtMgr = pPageInfo->m_sPageURL;
+ else
+ pLastPageSaver->m_sLastPageURL_Tools = pPageInfo->m_sPageURL;
+ }
+ }
+ pNewPage = pPageInfo->m_xPage.get();
+
+ // fdo#58170 use current page's layout child HelpId, unless there isn't a current page
+ OString sHelpId(pNewPage ? pNewPage->GetHelpId() : OString());
+ if (sHelpId.isEmpty())
+ sHelpId = HID_OFADLG_TREELISTBOX;
+ xTreeLB->set_help_id(sHelpId);
+}
+
+std::optional<SfxItemSet> OfaTreeOptionsDialog::CreateItemSet( sal_uInt16 nId )
+{
+ Reference< XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
+ std::optional<SfxItemSet> pRet;
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_HTML_MODE, SID_HTML_MODE,
+ SID_ATTR_METRIC, SID_ATTR_METRIC,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER,
+ SID_ATTR_YEAR2000, SID_ATTR_YEAR2000> );
+
+ SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet( SfxGetpApp()->GetPool() );
+ SfxApplication::GetOptions(aOptSet);
+ pRet->Put(aOptSet);
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SfxUInt16Item* pItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+
+ // miscellaneous - Year2000
+ if( SfxItemState::DEFAULT <= pDispatch->QueryState( SID_ATTR_YEAR2000, pItem ) )
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, pItem->GetValue() ) );
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
+ }
+ else
+ pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
+
+
+ // miscellaneous - Tabulator
+ pRet->Put(SfxBoolItem(SID_PRINTER_NOTFOUND_WARN, officecfg::Office::Common::Print::Warning::NotFound::get()));
+
+ SfxPrinterChangeFlags nFlag = officecfg::Office::Common::Print::Warning::PaperSize::get() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE;
+ nFlag |= officecfg::Office::Common::Print::Warning::PaperOrientation::get() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE;
+ pRet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlag) ));
+
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_CHAR_CJK_LANGUAGE, SID_ATTR_CHAR_CJK_LANGUAGE,
+ SID_ATTR_CHAR_CTL_LANGUAGE, SID_ATTR_CHAR_CTL_LANGUAGE,
+ SID_SET_DOCUMENT_LANGUAGE, SID_SET_DOCUMENT_LANGUAGE,
+ SID_ATTR_LANGUAGE, SID_ATTR_LANGUAGE,
+ SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
+ SID_OPT_LOCALE_CHANGED, SID_OPT_LOCALE_CHANGED>);
+
+ // for linguistic
+ SfxHyphenRegionItem aHyphen( SID_ATTR_HYPHENREGION );
+
+ sal_Int16 nMinLead = 2,
+ nMinTrail = 2;
+ if (xProp.is())
+ {
+ nMinLead = xProp->getHyphMinLeading();
+ nMinTrail = xProp->getHyphMinTrailing();
+ }
+ aHyphen.GetMinLead() = static_cast<sal_uInt8>(nMinLead);
+ aHyphen.GetMinTrail() = static_cast<sal_uInt8>(nMinTrail);
+
+ SfxViewFrame* pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ const SvxLanguageItem* pLangItem = nullptr;
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_LANGUAGE);
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CJK_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_CHAR_CJK_LANGUAGE);
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_ATTR_CHAR_CTL_LANGUAGE, pLangItem))
+ pRet->Put(*pLangItem, SID_ATTR_CHAR_CTL_LANGUAGE);
+
+ pRet->Put(aHyphen);
+ const SfxPoolItem* pItem = nullptr;
+ if(SfxItemState::DEFAULT <= pDispatch->QueryState(SID_AUTOSPELL_CHECK, pItem))
+ {
+ pRet->Put(std::unique_ptr<SfxPoolItem>(pItem->Clone()));
+ }
+ else
+ {
+ bool bVal = false;
+ if (xProp.is())
+ {
+ bVal = xProp->getIsSpellAuto();
+ }
+
+ pRet->Put(SfxBoolItem(SID_AUTOSPELL_CHECK, bVal));
+ }
+ }
+ pRet->Put( SfxBoolItem( SID_SET_DOCUMENT_LANGUAGE, bIsForSetDocumentLanguage ) );
+ }
+ break;
+ case SID_INET_DLG :
+ pRet.emplace( SfxGetpApp()->GetPool(),
+ svl::Items<
+ //SID_OPTIONS_START - ..END
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_INET_NOPROXY, SID_INET_FTP_PROXY_PORT,
+ SID_SECURE_URL, SID_SECURE_URL> );
+ SfxApplication::GetOptions(*pRet);
+ break;
+ case SID_FILTER_DLG:
+ pRet.emplace(
+ SfxGetpApp()->GetPool(),
+ svl::Items<
+ SID_ATTR_WARNALIENFORMAT, SID_ATTR_WARNALIENFORMAT,
+ SID_ATTR_DOCINFO, SID_ATTR_AUTOSAVEMINUTE,
+ SID_SAVEREL_INET, SID_SAVEREL_FSYS,
+ SID_ATTR_PRETTYPRINTING, SID_ATTR_PRETTYPRINTING> );
+ SfxApplication::GetOptions(*pRet);
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ pRet.emplace( SfxGetpApp()->GetPool(),
+ svl::Items<SID_SB_POOLING_ENABLED, SID_SB_DB_REGISTER> );
+ ::offapp::ConnectionPoolConfig::GetOptions(*pRet);
+ svx::DbRegisteredNamesConfig::GetOptions(*pRet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ {
+ SvxChartOptions aChartOpt;
+ pRet.emplace( SfxGetpApp()->GetPool(), svl::Items<SID_SCH_EDITOPTIONS, SID_SCH_EDITOPTIONS> );
+ pRet->Put( SvxChartColorTableItem( SID_SCH_EDITOPTIONS, aChartOpt.GetDefaultColors() ) );
+ break;
+ }
+ }
+ return pRet;
+}
+
+void OfaTreeOptionsDialog::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
+{
+ switch(nId)
+ {
+ case SID_GENERAL_OPTIONS:
+ {
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
+
+ SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet(SfxGetpApp()->GetPool());
+ aOptSet.Put(rSet);
+ if(aOptSet.Count())
+ SfxGetpApp()->SetOptions( aOptSet );
+ // get dispatcher anew, because SetOptions() might have destroyed the dispatcher
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+
+// evaluate Year2000
+ sal_uInt16 nY2K = USHRT_MAX;
+ const SfxUInt16Item* pYearItem = rSet.GetItemIfSet( SID_ATTR_YEAR2000, false );
+ if( pYearItem )
+ nY2K = pYearItem->GetValue();
+ if( USHRT_MAX != nY2K )
+ {
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pDispatch->ExecuteList(SID_ATTR_YEAR2000,
+ SfxCallMode::ASYNCHRON, { pYearItem });
+ }
+ officecfg::Office::Common::DateFormat::TwoDigitYear::set(nY2K, batch);
+ }
+
+// evaluate print
+ if(const SfxBoolItem* pWarnItem = rSet.GetItemIfSet(SID_PRINTER_NOTFOUND_WARN, false))
+ officecfg::Office::Common::Print::Warning::NotFound::set(pWarnItem->GetValue(), batch);
+
+ if(const SfxFlagItem* pFlag = rSet.GetItemIfSet(SID_PRINTER_CHANGESTODOC, false))
+ {
+ bool bPaperSizeWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
+ officecfg::Office::Common::Print::Warning::PaperSize::set(bPaperSizeWarning, batch);
+ bool bPaperOrientationWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
+ officecfg::Office::Common::Print::Warning::PaperOrientation::set(bPaperOrientationWarning, batch);
+ }
+
+// evaluate help options
+ bool bHelpTips = officecfg::Office::Common::Help::Tip::get();
+ if ( bHelpTips != Help::IsQuickHelpEnabled() )
+ bHelpTips ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
+ bool bExtendedHelp = officecfg::Office::Common::Help::ExtendedTip::get();
+ if ( bExtendedHelp != Help::IsBalloonHelpEnabled() )
+ bExtendedHelp ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
+
+ batch->commit();
+ }
+ break;
+ case SID_LANGUAGE_OPTIONS :
+ {
+ OfaTreeOptionsDialog::ApplyLanguageOptions(rSet);
+ }
+ break;
+ case SID_INET_DLG :
+ case SID_FILTER_DLG:
+ SfxGetpApp()->SetOptions( rSet );
+ break;
+
+ case SID_SB_STARBASEOPTIONS:
+ ::offapp::ConnectionPoolConfig::SetOptions( rSet );
+ svx::DbRegisteredNamesConfig::SetOptions(rSet);
+ break;
+
+ case SID_SCH_EDITOPTIONS:
+ // nothing to do. Chart options only apply to newly created charts
+ break;
+
+ default:
+ {
+ OSL_FAIL( "Unhandled option in ApplyItemSet" );
+ }
+ break;
+ }
+
+}
+void OfaTreeOptionsDialog::ApplyLanguageOptions(const SfxItemSet& rSet)
+{
+ bool bSaveSpellCheck = false;
+ const SfxPoolItem* pItem = nullptr;
+
+ Reference< XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
+ Reference< XLinguProperties > xProp = LinguProperties::create( xContext );
+ if ( const SfxHyphenRegionItem* pHyphenItem = rSet.GetItemIfSet(SID_ATTR_HYPHENREGION, false ) )
+ {
+ xProp->setHyphMinLeading( static_cast<sal_Int16>(pHyphenItem->GetMinLead()) );
+ xProp->setHyphMinTrailing( static_cast<sal_Int16>(pHyphenItem->GetMinTrail()) );
+ bSaveSpellCheck = true;
+ }
+
+ SfxViewFrame *pViewFrame = SfxViewFrame::Current();
+ if ( pViewFrame )
+ {
+ SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
+ pItem = nullptr;
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CTL_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+ if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CJK_LANGUAGE, false, &pItem ))
+ {
+ pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
+ bSaveSpellCheck = true;
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_AUTOSPELL_CHECK, false, &pItem ))
+ {
+ bool bOnlineSpelling = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+ pDispatch->ExecuteList(SID_AUTOSPELL_CHECK,
+ SfxCallMode::ASYNCHRON|SfxCallMode::RECORD, { pItem });
+
+ xProp->setIsSpellAuto( bOnlineSpelling );
+ }
+
+ if( bSaveSpellCheck )
+ {
+ //! the config item has changed since we modified the
+ //! property set it uses
+ pDispatch->Execute(SID_SPELLCHECKER_CHANGED, SfxCallMode::ASYNCHRON);
+ }
+ }
+
+ if( SfxItemState::SET == rSet.GetItemState(SID_OPT_LOCALE_CHANGED, false, &pItem ))
+ {
+ SfxViewFrame* _pViewFrame = SfxViewFrame::GetFirst();
+ while ( _pViewFrame )
+ {
+ _pViewFrame->GetDispatcher()->ExecuteList(pItem->Which(),
+ SfxCallMode::ASYNCHRON, { pItem });
+ _pViewFrame = SfxViewFrame::GetNext( *_pViewFrame );
+ }
+ }
+}
+
+static OUString getCurrentFactory_Impl( const Reference< XFrame >& _xFrame )
+{
+ OUString sIdentifier;
+ Reference < XFrame > xCurrentFrame( _xFrame );
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(::comphelper::getProcessComponentContext());
+ if ( !xCurrentFrame.is() )
+ {
+ Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sIdentifier = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "getActiveModule_Impl(): exception of XModuleManager::identify()" );
+ }
+ }
+
+ return sIdentifier;
+}
+
+void OfaTreeOptionsDialog::Initialize( const Reference< XFrame >& _xFrame )
+{
+ sal_uInt16 nGroup = 0;
+
+ SvtOptionsDialogOptions aOptionsDlgOpt;
+ sal_uInt16 nPageId;
+
+ // %PRODUCTNAME options
+ if ( !lcl_isOptionHidden( SID_GENERAL_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName(u"ProductName", CuiResId(SID_GENERAL_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_GENERAL_OPTIONS_RES[0].first), nullptr, nullptr, SID_GENERAL_OPTIONS );
+ const sal_uInt16 nEnd = static_cast<sal_uInt16>(std::size(SID_GENERAL_OPTIONS_RES));
+
+ for (sal_uInt16 i = 1; i < nEnd; ++i)
+ {
+ OUString sNewTitle = CuiResId(SID_GENERAL_OPTIONS_RES[i].first);
+ nPageId = SID_GENERAL_OPTIONS_RES[i].second;
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ // Disable Online Update page if service not installed
+ if( RID_SVXPAGE_ONLINEUPDATE == nPageId )
+ {
+ try
+ {
+ Reference < XInterface > xService( setup::UpdateCheck::create( ::comphelper::getProcessComponentContext() ) );
+ if( ! xService.is() )
+ continue;
+ }
+ catch ( css::uno::DeploymentException& )
+ {
+ continue;
+ }
+ }
+
+ // Disable Basic IDE options, if experimental features are not enabled
+ if( RID_SVXPAGE_BASICIDE_OPTIONS == nPageId )
+ {
+ if( ! officecfg::Office::Common::Misc::ExperimentalMode::get() )
+ continue;
+ }
+
+ AddTabPage( nPageId, sNewTitle, nGroup );
+ }
+ }
+
+ // Load and Save options
+ if ( !lcl_isOptionHidden( SID_FILTER_DLG, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"LoadSave", CuiResId(SID_FILTER_DLG_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_FILTER_DLG_RES[0].first), nullptr, nullptr, SID_FILTER_DLG );
+ for ( size_t i = 1; i < std::size(SID_FILTER_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_FILTER_DLG_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_FILTER_DLG_RES[i].first), nGroup );
+ }
+ }
+
+ // Language options
+ SvtCTLOptions aCTLLanguageOptions;
+ if ( !lcl_isOptionHidden( SID_LANGUAGE_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName(u"LanguageSettings", CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first), nullptr, nullptr, SID_LANGUAGE_OPTIONS );
+ for (size_t i = 1; i < std::size(SID_LANGUAGE_OPTIONS_RES); ++i)
+ {
+ nPageId = static_cast<sal_uInt16>(SID_LANGUAGE_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SVXPAGE_JSEARCH_OPTIONS != nPageId || SvtCJKOptions::IsJapaneseFindEnabled() ) &&
+ ( RID_SVXPAGE_ASIAN_LAYOUT != nPageId || SvtCJKOptions::IsAsianTypographyEnabled() ) &&
+ ( RID_SVXPAGE_OPTIONS_CTL != nPageId || aCTLLanguageOptions.IsCTLFontEnabled() ) )
+ AddTabPage(nPageId, CuiResId(SID_LANGUAGE_OPTIONS_RES[i].first), nGroup);
+ }
+ }
+
+ OUString aFactory = getCurrentFactory_Impl( _xFrame );
+ DBG_ASSERT( GetModuleIdentifier( _xFrame ) == aFactory, "S H I T!!!" );
+
+ // Writer and Writer/Web options
+ SvtModuleOptions aModuleOpt;
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
+ {
+ // text document
+ if ( aFactory == "com.sun.star.text.TextDocument"
+ || aFactory == "com.sun.star.text.WebDocument"
+ || aFactory == "com.sun.star.text.GlobalDocument" )
+ {
+ SfxModule* pSwMod = SfxApplication::GetModule(SfxToolsModule::Writer);
+ if ( !lcl_isOptionHidden( SID_SW_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ if ( aFactory == "com.sun.star.text.WebDocument" )
+ setGroupName( u"WriterWeb", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ else
+ setGroupName( u"Writer", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SW_EDITOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SW_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+ if ( ( RID_SW_TP_STD_FONT_CJK != nPageId || SvtCJKOptions::IsCJKFontEnabled() ) &&
+ ( RID_SW_TP_STD_FONT_CTL != nPageId || aCTLLanguageOptions.IsCTLFontEnabled() ) &&
+ ( RID_SW_TP_MAILCONFIG != nPageId || MailMergeCfg_Impl().IsEmailSupported() ) )
+ AddTabPage( nPageId, CuiResId(SID_SW_EDITOPTIONS_RES[i].first), nGroup );
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+
+ // HTML documents
+ if ( !lcl_isOptionHidden( SID_SW_ONLINEOPTIONS, aOptionsDlgOpt ) )
+ {
+ nGroup = AddGroup(CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_ONLINEOPTIONS );
+ for( size_t i = 1; i < std::size(SID_SW_ONLINEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SW_ONLINEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage(nPageId, CuiResId(SID_SW_ONLINEOPTIONS_RES[i].first), nGroup);
+ }
+#ifdef DBG_UTIL
+ AddTabPage( RID_SW_TP_OPTTEST_PAGE, "Internal Test", nGroup );
+#endif
+ }
+ }
+ }
+
+ // Calc options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC ) )
+ {
+ if ( aFactory == "com.sun.star.sheet.SpreadsheetDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SC_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pScMod = SfxApplication::GetModule( SfxToolsModule::Calc );
+ setGroupName( u"Calc", CuiResId(SID_SC_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SC_EDITOPTIONS_RES[0].first), pScMod, pScMod, SID_SC_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SC_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SC_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SC_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Impress options
+ SfxModule* pSdMod = SfxApplication::GetModule( SfxToolsModule::Draw );
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::IMPRESS ) )
+ {
+ if ( aFactory == "com.sun.star.presentation.PresentationDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Impress", CuiResId(SID_SD_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_EDITOPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_EDITOPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SD_EDITOPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_EDITOPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Draw options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DRAW ) )
+ {
+ if ( aFactory == "com.sun.star.drawing.DrawingDocument" )
+ {
+ if ( !lcl_isOptionHidden( SID_SD_GRAPHIC_OPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Draw", CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_GRAPHIC_OPTIONS );
+ const sal_uInt16 nCount = static_cast<sal_uInt16>(std::size(SID_SD_GRAPHIC_OPTIONS_RES));
+ for ( sal_uInt16 i = 1; i < nCount; ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SD_GRAPHIC_OPTIONS_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+
+ AddTabPage( nPageId, CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Math options
+ if ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::MATH ) )
+ {
+ if ( aFactory == "com.sun.star.formula.FormulaProperties" )
+ {
+ if ( !lcl_isOptionHidden( SID_SM_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ SfxModule* pSmMod = SfxApplication::GetModule(SfxToolsModule::Math);
+ setGroupName( u"Math", CuiResId(SID_SM_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup(CuiResId(SID_SM_EDITOPTIONS_RES[0].first), pSmMod, pSmMod, SID_SM_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SM_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SM_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SM_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+ }
+ }
+
+ // Database - needed only if there is an application which integrates with databases
+ if ( !lcl_isOptionHidden( SID_SB_STARBASEOPTIONS, aOptionsDlgOpt ) &&
+ ( aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::DATABASE )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::WRITER )
+ || aModuleOpt.IsModuleInstalled( SvtModuleOptions::EModule::CALC )
+ ) )
+ {
+ setGroupName( u"Base", CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first), nullptr, nullptr, SID_SB_STARBASEOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SB_STARBASEOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SB_STARBASEOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SB_STARBASEOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Chart options (always installed and active)
+ if ( !lcl_isOptionHidden( SID_SCH_EDITOPTIONS, aOptionsDlgOpt ) )
+ {
+ setGroupName( u"Charts", CuiResId(SID_SCH_EDITOPTIONS_RES[0].first) );
+ nGroup = AddGroup( CuiResId(SID_SCH_EDITOPTIONS_RES[0].first), nullptr, nullptr, SID_SCH_EDITOPTIONS );
+ for ( size_t i = 1; i < std::size(SID_SCH_EDITOPTIONS_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_SCH_EDITOPTIONS_RES[i].second);
+ if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ AddTabPage( nPageId, CuiResId(SID_SCH_EDITOPTIONS_RES[i].first), nGroup );
+ }
+ }
+
+ // Internet options
+ if ( lcl_isOptionHidden( SID_INET_DLG, aOptionsDlgOpt ) )
+ return;
+
+ setGroupName(u"Internet", CuiResId(SID_INET_DLG_RES[0].first));
+ nGroup = AddGroup(CuiResId(SID_INET_DLG_RES[0].first), nullptr, nullptr, SID_INET_DLG );
+
+ for ( size_t i = 1; i < std::size(SID_INET_DLG_RES); ++i )
+ {
+ nPageId = static_cast<sal_uInt16>(SID_INET_DLG_RES[i].second);
+ if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
+ continue;
+#if defined(_WIN32)
+ // Disable E-mail tab-page on Windows
+ if ( nPageId == RID_SVXPAGE_INET_MAIL )
+ continue;
+#endif
+ AddTabPage( nPageId, CuiResId(SID_INET_DLG_RES[i].first), nGroup );
+ }
+}
+
+static bool isNodeActive( OptionsNode const * pNode, Module* pModule )
+{
+ if ( !pNode )
+ return false;
+
+ // Node for all modules active?
+ if ( pNode->m_bAllModules )
+ return true;
+
+ // OOo-Nodes (Writer, Calc, Impress...) are active if node is already inserted
+ if ( !getGroupName( pNode->m_sId, false ).isEmpty() )
+ return true;
+
+ // no module -> not active
+ if ( !pModule )
+ return false;
+
+ // search node in active module
+ if ( pModule->m_bActive )
+ {
+ for (auto const& j : pModule->m_aNodeList)
+ if ( j->m_sId == pNode->m_sId )
+ return true;
+ }
+ return false;
+}
+
+void OfaTreeOptionsDialog::LoadExtensionOptions( std::u16string_view rExtensionId )
+{
+ std::unique_ptr<Module> pModule;
+
+ // when called by Tools - Options then load nodes of active module
+ if ( rExtensionId.empty() )
+ {
+ pModule = LoadModule( GetModuleIdentifier( Reference< XFrame >() ) );
+ }
+
+ VectorOfNodes aNodeList = LoadNodes( pModule.get(), rExtensionId );
+ InsertNodes( aNodeList );
+}
+
+OUString OfaTreeOptionsDialog::GetModuleIdentifier( const Reference< XFrame >& rFrame )
+{
+ OUString sModule;
+ Reference < XFrame > xCurrentFrame( rFrame );
+ Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
+ Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
+
+ if ( !xCurrentFrame.is() )
+ {
+ Reference < XDesktop2 > xDesktop = Desktop::create( xContext );
+ xCurrentFrame = xDesktop->getCurrentFrame();
+ }
+
+ if ( xCurrentFrame.is() )
+ {
+ try
+ {
+ sModule = xModuleManager->identify( xCurrentFrame );
+ }
+ catch ( css::frame::UnknownModuleException& )
+ {
+ SAL_INFO( "cui.options", "unknown module" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "OfaTreeOptionsDialog::GetModuleIdentifier(): exception of XModuleManager::identify()");
+ }
+ }
+ return sModule;
+}
+
+std::unique_ptr<Module> OfaTreeOptionsDialog::LoadModule(
+ std::u16string_view rModuleIdentifier )
+{
+ std::unique_ptr<Module> pModule;
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Modules::get());
+
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+ for ( const OUString& rModule : seqNames )
+ {
+ if ( rModuleIdentifier == rModule )
+ {
+ // current active module found
+ pModule.reset(new Module);
+ pModule->m_bActive = true;
+
+ Reference< XNameAccess > xModAccess;
+ xSet->getByName( rModule ) >>= xModAccess;
+ if ( xModAccess.is() )
+ {
+ // load the nodes of this module
+ Reference< XNameAccess > xNodeAccess;
+ xModAccess->getByName( "Nodes" ) >>= xNodeAccess;
+ if ( xNodeAccess.is() )
+ {
+ const Sequence< OUString > xTemp = xNodeAccess->getElementNames();
+ Reference< XNameAccess > xAccess;
+ sal_Int32 nIndex = -1;
+ for ( const OUString& rNode : xTemp)
+ {
+ xNodeAccess->getByName( rNode ) >>= xAccess;
+ if ( xAccess.is() )
+ {
+ xAccess->getByName( "Index" ) >>= nIndex;
+ if ( nIndex < 0 )
+ // append nodes with index < 0
+ pModule->m_aNodeList.push_back(
+ std::unique_ptr<OrderedEntry>(new OrderedEntry(nIndex, rNode)));
+ else
+ {
+ // search position of the node
+ std::vector<OrderedEntry *>::size_type y = 0;
+ for ( ; y < pModule->m_aNodeList.size(); ++y )
+ {
+ sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
+ if ( nNodeIdx < 0 || nNodeIdx > nIndex )
+ break;
+ }
+ // and insert the node on this position
+ pModule->m_aNodeList.insert(
+ pModule->m_aNodeList.begin() + y,
+ std::unique_ptr<OrderedEntry>(new OrderedEntry( nIndex, rNode )) );
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ }
+ return pModule;
+}
+
+VectorOfNodes OfaTreeOptionsDialog::LoadNodes(
+ Module* pModule, std::u16string_view rExtensionId)
+{
+ VectorOfNodes aOutNodeList;
+
+ Reference< XNameAccess > xSet(
+ officecfg::Office::OptionsDialog::Nodes::get());
+ VectorOfNodes aNodeList;
+ const Sequence< OUString > seqNames = xSet->getElementNames();
+
+ for ( OUString const & sGroupName : seqNames )
+ {
+ Reference< XNameAccess > xNodeAccess;
+ xSet->getByName( sGroupName ) >>= xNodeAccess;
+
+ if ( xNodeAccess.is() )
+ {
+ OUString sNodeId, sLabel, sPageURL;
+ bool bAllModules = false;
+
+ sNodeId = sGroupName;
+ xNodeAccess->getByName( "Label" ) >>= sLabel;
+ xNodeAccess->getByName( "OptionsPage" ) >>= sPageURL;
+ xNodeAccess->getByName( "AllModules" ) >>= bAllModules;
+
+ if ( sLabel.isEmpty() )
+ sLabel = sGroupName;
+ OUString sTemp = getGroupName( sLabel, !rExtensionId.empty() );
+ if ( !sTemp.isEmpty() )
+ sLabel = sTemp;
+ std::unique_ptr<OptionsNode> pNode(new OptionsNode(sNodeId, sLabel, bAllModules));
+
+ if ( rExtensionId.empty() && !isNodeActive( pNode.get(), pModule ) )
+ {
+ continue;
+ }
+
+ Reference< XNameAccess > xLeavesSet;
+ xNodeAccess->getByName( "Leaves" ) >>= xLeavesSet;
+ if ( xLeavesSet.is() )
+ {
+ const Sequence< OUString > seqLeaves = xLeavesSet->getElementNames();
+ for ( OUString const & leafName : seqLeaves )
+ {
+ Reference< XNameAccess > xLeaveAccess;
+ xLeavesSet->getByName( leafName ) >>= xLeaveAccess;
+
+ if ( xLeaveAccess.is() )
+ {
+ OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
+ sal_Int32 nLeafGrpIdx = 0;
+
+ xLeaveAccess->getByName( "Id" ) >>= sId;
+ xLeaveAccess->getByName( "Label" ) >>= sLeafLabel;
+ xLeaveAccess->getByName( "OptionsPage" ) >>= sLeafURL;
+ xLeaveAccess->getByName( "EventHandlerService" ) >>= sEventHdl;
+ xLeaveAccess->getByName( "GroupId" ) >>= sLeafGrpId;
+ xLeaveAccess->getByName( "GroupIndex" ) >>= nLeafGrpIdx;
+
+ if ( rExtensionId.empty() || sId == rExtensionId )
+ {
+ std::unique_ptr<OptionsLeaf> pLeaf(new OptionsLeaf(
+ sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx ));
+
+ if ( !sLeafGrpId.isEmpty() )
+ {
+ bool bAlreadyOpened = false;
+ if ( !pNode->m_aGroupedLeaves.empty() )
+ {
+ for (auto & rGroup : pNode->m_aGroupedLeaves)
+ {
+ if ( !rGroup.empty() &&
+ rGroup[0]->m_sGroupId == sLeafGrpId )
+ {
+ std::vector<std::unique_ptr<OptionsLeaf>>::size_type l = 0;
+ for ( ; l < rGroup.size(); ++l )
+ {
+ if ( rGroup[l]->m_nGroupIndex >= nLeafGrpIdx )
+ break;
+ }
+ rGroup.insert( rGroup.begin() + l, std::move(pLeaf) );
+ bAlreadyOpened = true;
+ break;
+ }
+ }
+ }
+ if ( !bAlreadyOpened )
+ {
+ std::vector< std::unique_ptr<OptionsLeaf> > aGroupedLeaves;
+ aGroupedLeaves.push_back( std::move(pLeaf) );
+ pNode->m_aGroupedLeaves.push_back( std::move(aGroupedLeaves) );
+ }
+ }
+ else
+ pNode->m_aLeaves.push_back( std::move(pLeaf) );
+ }
+ }
+ }
+ }
+
+ // do not insert nodes without leaves
+ if ( !pNode->m_aLeaves.empty() || !pNode->m_aGroupedLeaves.empty() )
+ {
+ pModule ? aNodeList.push_back( std::move(pNode) ) : aOutNodeList.push_back( std::move(pNode) );
+ }
+ }
+ }
+
+ if ( pModule && !aNodeList.empty() )
+ {
+ for ( auto const & i: pModule->m_aNodeList )
+ {
+ OUString sNodeId = i->m_sId;
+ for ( auto j = aNodeList.begin(); j != aNodeList.end(); ++j )
+ {
+ if ( (*j)->m_sId == sNodeId )
+ {
+ aOutNodeList.push_back( std::move(*j) );
+ aNodeList.erase( j );
+ break;
+ }
+ }
+ }
+
+ for ( auto & i: aNodeList )
+ aOutNodeList.push_back( std::move(i) );
+ }
+ return aOutNodeList;
+}
+
+static sal_uInt16 lcl_getGroupId( std::u16string_view rGroupName, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nRet = 0;
+
+ std::unique_ptr<weld::TreeIter> xEntry = rTreeLB.make_iterator();
+ bool bEntry = rTreeLB.get_iter_first(*xEntry);
+ while (bEntry)
+ {
+ if (!rTreeLB.get_iter_depth(*xEntry))
+ {
+ OUString sTemp(rTreeLB.get_text(*xEntry));
+ if (sTemp == rGroupName)
+ return nRet;
+ nRet++;
+ }
+ bEntry = rTreeLB.iter_next(*xEntry);
+ }
+
+ return USHRT_MAX;
+}
+
+static void lcl_insertLeaf(
+ OfaTreeOptionsDialog* pDlg, OptionsNode const * pNode, OptionsLeaf const * pLeaf, const weld::TreeView& rTreeLB )
+{
+ sal_uInt16 nGrpId = lcl_getGroupId( pNode->m_sLabel, rTreeLB );
+ if ( USHRT_MAX == nGrpId )
+ {
+ sal_uInt16 nNodeGrpId = getGroupNodeId( pNode->m_sId );
+ nGrpId = pDlg->AddGroup( pNode->m_sLabel, nullptr, nullptr, nNodeGrpId );
+ }
+ OptionsPageInfo* pInfo = pDlg->AddTabPage( 0, pLeaf->m_sLabel, nGrpId );
+ pInfo->m_sPageURL = pLeaf->m_sPageURL;
+ pInfo->m_sEventHdl = pLeaf->m_sEventHdl;
+}
+
+void OfaTreeOptionsDialog::InsertNodes( const VectorOfNodes& rNodeList )
+{
+ for (auto const& node : rNodeList)
+ {
+ if ( !node->m_aLeaves.empty() || !node->m_aGroupedLeaves.empty() )
+ {
+ for ( auto const & j: node->m_aGroupedLeaves )
+ {
+ for ( size_t k = 0; k < j.size(); ++k )
+ {
+ lcl_insertLeaf( this, node.get(), j[k].get(), *xTreeLB );
+ }
+ }
+
+ for ( auto const & j: node->m_aLeaves )
+ {
+ lcl_insertLeaf( this, node.get(), j.get(), *xTreeLB );
+ }
+ }
+ }
+}
+
+void OfaTreeOptionsDialog::SetNeedsRestart( svtools::RestartReason eReason)
+{
+ bNeedsRestart = true;
+ eRestartReason = eReason;
+}
+
+short OfaTreeOptionsDialog::run()
+{
+ std::unique_ptr< SvxDicListChgClamp > pClamp;
+ if ( !bIsFromExtensionManager )
+ {
+ // collect all DictionaryList Events while the dialog is executed
+ Reference<css::linguistic2::XSearchableDictionaryList> xDictionaryList(LinguMgr::GetDictionaryList());
+ pClamp.reset( new SvxDicListChgClamp( xDictionaryList ) );
+ }
+
+ return SfxOkDialogController::run();
+}
+
+// class ExtensionsTabPage -----------------------------------------------
+ExtensionsTabPage::ExtensionsTabPage(
+ weld::Container* pParent, OUString aPageURL,
+ OUString aEvtHdl, const Reference< awt::XContainerWindowProvider >& rProvider )
+ : m_pContainer(pParent)
+ , m_sPageURL(std::move(aPageURL))
+ , m_sEventHdl(std::move(aEvtHdl))
+ , m_xWinProvider(rProvider)
+{
+}
+
+ExtensionsTabPage::~ExtensionsTabPage()
+{
+ Hide();
+ DeactivatePage();
+
+ if ( m_xPage.is() )
+ {
+ try
+ {
+ m_xPage->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPage.clear();
+ }
+
+ if ( m_xPageParent.is() )
+ {
+ try
+ {
+ m_xPageParent->dispose();
+ }
+ catch (const Exception&)
+ {
+ }
+ m_xPageParent.clear();
+ }
+}
+
+void ExtensionsTabPage::CreateDialogWithHandler()
+{
+ try
+ {
+ bool bWithHandler = !m_sEventHdl.isEmpty();
+ if ( bWithHandler )
+ {
+ Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
+ m_xEventHdl.set( xFactory->createInstance( m_sEventHdl ), UNO_QUERY );
+ }
+
+ if ( !bWithHandler || m_xEventHdl.is() )
+ {
+ m_xPageParent = m_pContainer->CreateChildFrame();
+ Reference<awt::XWindowPeer> xParent(m_xPageParent, UNO_QUERY);
+ m_xPage =
+ m_xWinProvider->createContainerWindow(
+ m_sPageURL, OUString(), xParent, m_xEventHdl );
+
+ Reference< awt::XControl > xPageControl( m_xPage, UNO_QUERY );
+ if ( xPageControl.is() )
+ {
+ Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
+ if ( xWinPeer.is() )
+ {
+ VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWinPeer );
+ if ( pWindow )
+ pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
+ }
+ }
+ }
+ }
+ catch (const Exception&)
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::CreateDialogWithHandler(): exception of XDialogProvider2::createDialogWithHandler()");
+ }
+}
+
+bool ExtensionsTabPage::DispatchAction( const OUString& rAction )
+{
+ bool bRet = false;
+ if ( m_xEventHdl.is() )
+ {
+ try
+ {
+ bRet = m_xEventHdl->callHandlerMethod( m_xPage, Any( rAction ), "external_event" );
+ }
+ catch ( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::DispatchAction(): exception of XDialogEventHandler::callHandlerMethod()" );
+ }
+ }
+ return bRet;
+}
+
+void ExtensionsTabPage::Show()
+{
+ if (!m_xPageParent.is())
+ return;
+
+ VclPtr<vcl::Window> xPageParent = VCLUnoHelper::GetWindow(m_xPageParent);
+ if (xPageParent)
+ {
+ // NoActivate otherwise setVisible will call Window::Show which will grab
+ // focus to the page by default
+ xPageParent->Show(true, ShowFlags::NoActivate);
+ }
+
+ m_xPageParent->setVisible(true);
+}
+
+void ExtensionsTabPage::Hide()
+{
+ if (!m_xPageParent.is())
+ return;
+ m_xPageParent->setVisible(false);
+}
+
+void ExtensionsTabPage::ActivatePage()
+{
+ if ( !m_xPage.is() )
+ {
+ CreateDialogWithHandler();
+
+ if ( m_xPage.is() )
+ {
+ auto aWindowRect = m_xPageParent->getPosSize();
+ m_xPage->setPosSize(0, 0, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POSSIZE);
+ if ( !m_sEventHdl.isEmpty() )
+ DispatchAction( "initialize" );
+ }
+ }
+
+ if ( m_xPage.is() )
+ {
+ m_xPage->setVisible( true );
+ }
+}
+
+void ExtensionsTabPage::DeactivatePage()
+{
+ if ( m_xPage.is() )
+ m_xPage->setVisible( false );
+}
+
+void ExtensionsTabPage::ResetPage()
+{
+ DispatchAction( "back" );
+ ActivatePage();
+}
+
+void ExtensionsTabPage::SavePage()
+{
+ DispatchAction( "ok" );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.cxx b/cui/source/options/tsaurls.cxx
new file mode 100644
index 000000000..5c01e1c5b
--- /dev/null
+++ b/cui/source/options/tsaurls.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <officecfg/Office/Common.hxx>
+#include <svx/svxdlg.hxx>
+#include <comphelper/sequence.hxx>
+#include <tools/diagnose_ex.h>
+
+#include "tsaurls.hxx"
+
+using namespace ::com::sun::star;
+
+TSAURLsDialog::TSAURLsDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/tsaurldialog.ui", "TSAURLDialog")
+ , m_xAddBtn(m_xBuilder->weld_button("add"))
+ , m_xDeleteBtn(m_xBuilder->weld_button("delete"))
+ , m_xOKBtn(m_xBuilder->weld_button("ok"))
+ , m_xURLListBox(m_xBuilder->weld_tree_view("urls"))
+ , m_xEnterAUrl(m_xBuilder->weld_label("enteraurl"))
+{
+ m_xURLListBox->set_size_request(m_xURLListBox->get_approximate_digit_width() * 28,
+ m_xURLListBox->get_height_rows(8));
+ m_xOKBtn->set_sensitive(false);
+
+ m_xAddBtn->connect_clicked(LINK(this, TSAURLsDialog, AddHdl_Impl));
+ m_xDeleteBtn->connect_clicked(LINK(this, TSAURLsDialog, DeleteHdl_Impl));
+ m_xOKBtn->connect_clicked(LINK(this, TSAURLsDialog, OKHdl_Impl));
+ m_xURLListBox->connect_changed(LINK(this, TSAURLsDialog, SelectHdl));
+
+ try
+ {
+ std::optional<css::uno::Sequence<OUString>> aUserSetTSAURLs(
+ officecfg::Office::Common::Security::Scripting::TSAURLs::get());
+ if (aUserSetTSAURLs)
+ {
+ const css::uno::Sequence<OUString>& rUserSetTSAURLs = *aUserSetTSAURLs;
+ for (auto const& userSetTSAURL : rUserSetTSAURLs)
+ {
+ AddTSAURL(userSetTSAURL);
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ TOOLS_WARN_EXCEPTION("cui.options", "TSAURLsDialog::TSAURLsDialog()");
+ }
+
+ if (m_xURLListBox->get_selected_index() == -1)
+ {
+ m_xDeleteBtn->set_sensitive(false);
+ }
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, OKHdl_Impl, weld::Button&, void)
+{
+ std::shared_ptr<comphelper::ConfigurationChanges> batch(
+ comphelper::ConfigurationChanges::create());
+
+ officecfg::Office::Common::Security::Scripting::TSAURLs::set(
+ comphelper::containerToSequence(m_aURLs), batch);
+ batch->commit();
+
+ m_xDialog->response(RET_OK);
+}
+
+TSAURLsDialog::~TSAURLsDialog() {}
+
+void TSAURLsDialog::AddTSAURL(const OUString& rURL)
+{
+ m_aURLs.insert(rURL);
+
+ m_xURLListBox->freeze();
+ m_xURLListBox->clear();
+
+ for (auto const& url : m_aURLs)
+ {
+ m_xURLListBox->append_text(url);
+ }
+
+ m_xURLListBox->thaw();
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, AddHdl_Impl, weld::Button&, void)
+{
+ OUString aURL;
+ OUString aDesc(m_xEnterAUrl->get_label());
+
+ SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
+ ScopedVclPtr<AbstractSvxNameDialog> pDlg(
+ pFact->CreateSvxNameDialog(m_xDialog.get(), aURL, aDesc));
+
+ if (pDlg->Execute() == RET_OK)
+ {
+ pDlg->GetName(aURL);
+ AddTSAURL(aURL);
+ m_xOKBtn->set_sensitive(true);
+ }
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, SelectHdl, weld::TreeView&, void)
+{
+ m_xDeleteBtn->set_sensitive(true);
+}
+
+IMPL_LINK_NOARG(TSAURLsDialog, DeleteHdl_Impl, weld::Button&, void)
+{
+ int nSel = m_xURLListBox->get_selected_index();
+ if (nSel == -1)
+ return;
+
+ m_aURLs.erase(m_xURLListBox->get_text(nSel));
+ m_xURLListBox->remove(nSel);
+ m_xURLListBox->unselect_all();
+ // After operations in a ListBox we have nothing selected
+ m_xDeleteBtn->set_sensitive(false);
+ m_xOKBtn->set_sensitive(true);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/tsaurls.hxx b/cui/source/options/tsaurls.hxx
new file mode 100644
index 000000000..8fb1d0490
--- /dev/null
+++ b/cui/source/options/tsaurls.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <vcl/weld.hxx>
+
+#include <set>
+
+class TSAURLsDialog : public weld::GenericDialogController
+{
+private:
+ std::unique_ptr<weld::Button> m_xAddBtn;
+ std::unique_ptr<weld::Button> m_xDeleteBtn;
+ std::unique_ptr<weld::Button> m_xOKBtn;
+ std::unique_ptr<weld::TreeView> m_xURLListBox;
+ std::unique_ptr<weld::Label> m_xEnterAUrl;
+
+ DECL_LINK(AddHdl_Impl, weld::Button&, void);
+ DECL_LINK(DeleteHdl_Impl, weld::Button&, void);
+ DECL_LINK(OKHdl_Impl, weld::Button&, void);
+ // After operations in a TreeView we have nothing selected
+ // Is Selected element handler for the TreeView
+ DECL_LINK(SelectHdl, weld::TreeView&, void);
+
+ std::set<OUString> m_aURLs;
+
+ void AddTSAURL(const OUString& rURL);
+
+public:
+ explicit TSAURLsDialog(weld::Window* pParent);
+ virtual ~TSAURLsDialog() override;
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.cxx b/cui/source/options/webconninfo.cxx
new file mode 100644
index 000000000..d9acbd18f
--- /dev/null
+++ b/cui/source/options/webconninfo.cxx
@@ -0,0 +1,229 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <o3tl/safeint.hxx>
+#include "webconninfo.hxx"
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/task/PasswordContainer.hpp>
+#include <com/sun/star/task/UrlRecord.hpp>
+#include <com/sun/star/task/XPasswordContainer2.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/docpasswordrequest.hxx>
+
+using namespace ::com::sun::star;
+
+
+namespace svx
+{
+
+// class WebConnectionInfoDialog -----------------------------------------
+
+WebConnectionInfoDialog::WebConnectionInfoDialog(weld::Window* pParent)
+ : GenericDialogController(pParent, "cui/ui/storedwebconnectiondialog.ui", "StoredWebConnectionDialog")
+ , m_nPos( -1 )
+ , m_xRemoveBtn(m_xBuilder->weld_button("remove"))
+ , m_xRemoveAllBtn(m_xBuilder->weld_button("removeall"))
+ , m_xChangeBtn(m_xBuilder->weld_button("change"))
+ , m_xPasswordsLB(m_xBuilder->weld_tree_view("logins"))
+{
+ std::vector<int> aWidths
+ {
+ o3tl::narrowing<int>(m_xPasswordsLB->get_approximate_digit_width() * 50)
+ };
+ m_xPasswordsLB->set_column_fixed_widths(aWidths);
+ m_xPasswordsLB->set_size_request(m_xPasswordsLB->get_approximate_digit_width() * 70,
+ m_xPasswordsLB->get_height_rows(8));
+
+ m_xPasswordsLB->connect_column_clicked(LINK(this, WebConnectionInfoDialog, HeaderBarClickedHdl));
+
+ FillPasswordList();
+
+ m_xRemoveBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemovePasswordHdl ) );
+ m_xRemoveAllBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, RemoveAllPasswordsHdl ) );
+ m_xChangeBtn->connect_clicked( LINK( this, WebConnectionInfoDialog, ChangePasswordHdl ) );
+ m_xPasswordsLB->connect_changed( LINK( this, WebConnectionInfoDialog, EntrySelectedHdl ) );
+
+ m_xRemoveBtn->set_sensitive( false );
+ m_xChangeBtn->set_sensitive( false );
+
+ m_xPasswordsLB->make_sorted();
+}
+
+WebConnectionInfoDialog::~WebConnectionInfoDialog()
+{
+}
+
+IMPL_LINK(WebConnectionInfoDialog, HeaderBarClickedHdl, int, nColumn, void)
+{
+ if (nColumn == 0) // only the first column is sorted
+ {
+ m_xPasswordsLB->set_sort_order(!m_xPasswordsLB->get_sort_order());
+ }
+}
+
+void WebConnectionInfoDialog::FillPasswordList()
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xMasterPasswd(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ if ( xMasterPasswd->isPersistentStoringAllowed() )
+ {
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), nullptr);
+
+ const uno::Sequence< task::UrlRecord > aURLEntries = xMasterPasswd->getAllPersistent( xInteractionHandler );
+ sal_Int32 nCount = 0;
+ for ( task::UrlRecord const & urlEntry : aURLEntries )
+ {
+ for ( auto const & user : urlEntry.UserList )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), urlEntry.Url);
+ m_xPasswordsLB->set_text(nCount, user.UserName, 1);
+ ++nCount;
+ }
+ }
+
+ // remember pos of first url container entry.
+ m_nPos = nCount;
+
+ const uno::Sequence< OUString > aUrls
+ = xMasterPasswd->getUrls( true /* OnlyPersistent */ );
+
+ for ( OUString const & url : aUrls )
+ {
+ m_xPasswordsLB->append(OUString::number(nCount), url);
+ m_xPasswordsLB->set_text(nCount, "*");
+ ++nCount;
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemovePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ if ( nPos < m_nPos )
+ {
+ xPasswdContainer->removePersistent( aURL, aUserName );
+ }
+ else
+ {
+ xPasswdContainer->removeUrl( aURL );
+ }
+
+ m_xPasswordsLB->remove(nEntry);
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, RemoveAllPasswordsHdl, weld::Button&, void)
+{
+ try
+ {
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+
+ // should the master password be requested before?
+ xPasswdContainer->removeAllPersistent();
+
+ const uno::Sequence< OUString > aUrls
+ = xPasswdContainer->getUrls( true /* OnlyPersistent */ );
+ for ( OUString const & url : aUrls )
+ xPasswdContainer->removeUrl( url );
+
+ m_xPasswordsLB->clear();
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, ChangePasswordHdl, weld::Button&, void)
+{
+ try
+ {
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry != -1)
+ {
+ OUString aURL = m_xPasswordsLB->get_text(nEntry, 0);
+ OUString aUserName = m_xPasswordsLB->get_text(nEntry, 1);
+
+ rtl::Reference<::comphelper::SimplePasswordRequest> pPasswordRequest
+ = new ::comphelper::SimplePasswordRequest;
+
+ uno::Reference< task::XInteractionHandler > xInteractionHandler =
+ task::InteractionHandler::createWithParent(comphelper::getProcessComponentContext(), m_xDialog->GetXWindow());
+ xInteractionHandler->handle( pPasswordRequest );
+
+ if ( pPasswordRequest->isPassword() )
+ {
+ OUString aNewPass = pPasswordRequest->getPassword();
+ uno::Sequence<OUString> aPasswd { aNewPass };
+
+ uno::Reference< task::XPasswordContainer2 > xPasswdContainer(
+ task::PasswordContainer::create(comphelper::getProcessComponentContext()));
+ xPasswdContainer->addPersistent(
+ aURL, aUserName, aPasswd, xInteractionHandler );
+ }
+ }
+ }
+ catch( uno::Exception& )
+ {}
+}
+
+
+IMPL_LINK_NOARG(WebConnectionInfoDialog, EntrySelectedHdl, weld::TreeView&, void)
+{
+ int nEntry = m_xPasswordsLB->get_selected_index();
+ if (nEntry == -1)
+ {
+ m_xRemoveBtn->set_sensitive(false);
+ m_xChangeBtn->set_sensitive(false);
+ }
+ else
+ {
+ m_xRemoveBtn->set_sensitive(true);
+
+ // url container entries (-> use system credentials) have
+ // no password
+ int nPos = m_xPasswordsLB->get_id(nEntry).toInt32();
+ m_xChangeBtn->set_sensitive(nPos < m_nPos);
+ }
+}
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/cui/source/options/webconninfo.hxx b/cui/source/options/webconninfo.hxx
new file mode 100644
index 000000000..6c52d2163
--- /dev/null
+++ b/cui/source/options/webconninfo.hxx
@@ -0,0 +1,51 @@
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#pragma once
+
+#include <vcl/weld.hxx>
+
+namespace svx
+{
+ class WebConnectionInfoDialog : public weld::GenericDialogController
+ {
+ private:
+ sal_Int32 m_nPos;
+
+ std::unique_ptr<weld::Button> m_xRemoveBtn;
+ std::unique_ptr<weld::Button> m_xRemoveAllBtn;
+ std::unique_ptr<weld::Button> m_xChangeBtn;
+ std::unique_ptr<weld::TreeView> m_xPasswordsLB;
+
+ DECL_LINK( HeaderBarClickedHdl, int, void );
+ DECL_LINK( RemovePasswordHdl, weld::Button&, void );
+ DECL_LINK( RemoveAllPasswordsHdl, weld::Button&, void );
+ DECL_LINK( ChangePasswordHdl, weld::Button&, void );
+ DECL_LINK( EntrySelectedHdl, weld::TreeView&, void );
+
+ void FillPasswordList();
+
+ public:
+ explicit WebConnectionInfoDialog(weld::Window* pParent);
+ virtual ~WebConnectionInfoDialog() override;
+ };
+
+
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */