Use correct object
[LibreOffice.git] / cui / source / options / treeopt.cxx
blob32dd79d90a5cc9aa25c7eeb024d07b1081518342
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <string_view>
23 #include <config_features.h>
24 #include <config_feature_opencl.h>
25 #include <config_feature_desktop.h>
26 #include <config_gpgme.h>
28 #include <officecfg/Office/Common.hxx>
29 #include <officecfg/Office/Writer.hxx>
31 #include <svx/dialogs.hrc>
32 #include <svx/svxids.hrc>
34 #include <treeopt.hrc>
35 #include <helpids.h>
37 #include "cfgchart.hxx"
38 #include "connpoolconfig.hxx"
39 #include "connpooloptions.hxx"
40 #include <cuioptgenrl.hxx>
41 #include <dbregister.hxx>
42 #include "dbregisterednamesconfig.hxx"
43 #include <dialmgr.hxx>
44 #include "fontsubs.hxx"
45 #include "optaccessibility.hxx"
46 #include <optasian.hxx>
47 #include "optchart.hxx"
48 #include "optcolor.hxx"
49 #include "optctl.hxx"
50 #include "optfltr.hxx"
51 #include "optgdlg.hxx"
52 #include "opthtml.hxx"
53 #include "optinet2.hxx"
54 #include "optjava.hxx"
55 #include "optjsearch.hxx"
56 #include <optlingu.hxx>
57 #if HAVE_FEATURE_OPENCL
58 #include "optopencl.hxx"
59 #endif
60 #include <optpath.hxx>
61 #include "optsave.hxx"
62 #include "optupdt.hxx"
63 #include "personalization.hxx"
64 #include <treeopt.hxx>
65 #include "optbasic.hxx"
66 #include "optlanguagetool.hxx"
67 #include "optdeepl.hxx"
69 // include search util
70 #include <com/sun/star/util/SearchFlags.hpp>
71 #include <com/sun/star/util/SearchAlgorithms2.hpp>
72 #include <unotools/textsearch.hxx>
74 #include <com/sun/star/awt/XContainerWindowEventHandler.hpp>
75 #include <com/sun/star/awt/ContainerWindowProvider.hpp>
76 #include <com/sun/star/awt/XControl.hpp>
77 #include <com/sun/star/awt/PosSize.hpp>
78 #include <com/sun/star/frame/Desktop.hpp>
79 #include <com/sun/star/frame/ModuleManager.hpp>
80 #include <com/sun/star/frame/UnknownModuleException.hpp>
81 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
82 #include <com/sun/star/linguistic2/LinguProperties.hpp>
83 #include <comphelper/getexpandeduri.hxx>
84 #include <comphelper/processfactory.hxx>
85 #include <editeng/langitem.hxx>
86 #include <editeng/optitems.hxx>
87 #include <editeng/unolingu.hxx>
88 #include <linguistic/misc.hxx>
89 #include <o3tl/deleter.hxx>
90 #include <officecfg/Office/OptionsDialog.hxx>
91 #include <sfx2/app.hxx>
92 #include <sfx2/dispatch.hxx>
93 #include <sfx2/module.hxx>
94 #include <sfx2/printopt.hxx>
95 #include <sfx2/shell.hxx>
96 #include <sfx2/viewsh.hxx>
97 #include <sfx2/viewfrm.hxx>
98 #include <svl/flagitem.hxx>
99 #include <svl/intitem.hxx>
100 #include <svl/cjkoptions.hxx>
101 #include <svl/ctloptions.hxx>
102 #include <svx/databaseregistrationui.hxx>
103 #include <toolkit/helper/vclunohelper.hxx>
104 #include <tools/urlobj.hxx>
105 #include <comphelper/diagnose_ex.hxx>
106 #include <unotools/configmgr.hxx>
107 #include <unotools/moduleoptions.hxx>
108 #include <unotools/optionsdlg.hxx>
109 #include <unotools/viewoptions.hxx>
110 #include <utility>
111 #include <vcl/help.hxx>
112 #include <vcl/svapp.hxx>
113 #include <vcl/weldutils.hxx>
114 #include <vcl/window.hxx>
115 #include <sal/log.hxx>
117 using namespace ::com::sun::star;
118 using namespace ::com::sun::star::container;
119 using namespace ::com::sun::star::frame;
120 using namespace ::com::sun::star::lang;
121 using namespace ::com::sun::star::linguistic2;
122 using namespace ::com::sun::star::uno;
123 using namespace ::com::sun::star::util;
125 LastPageSaver* OfaTreeOptionsDialog::pLastPageSaver = nullptr;
127 // some stuff for easier changes for SvtViewOptions
128 constexpr OUString VIEWOPT_DATANAME = u"page data"_ustr;
130 static void SetViewOptUserItem( SvtViewOptions& rOpt, const OUString& rData )
132 rOpt.SetUserItem( VIEWOPT_DATANAME, Any( rData ) );
135 static OUString GetViewOptUserItem( const SvtViewOptions& rOpt )
137 Any aAny( rOpt.GetUserItem( VIEWOPT_DATANAME ) );
138 OUString aUserData;
139 aAny >>= aUserData;
141 return aUserData;
144 namespace {
146 struct ModuleToGroupNameMap_Impl
148 std::u16string_view m_pModule;
149 OUString m_sGroupName;
150 sal_uInt16 m_nNodeId;
154 static ModuleToGroupNameMap_Impl ModuleMap[] =
156 { u"ProductName", OUString(), SID_GENERAL_OPTIONS },
157 { u"LanguageSettings", OUString(), SID_LANGUAGE_OPTIONS },
158 { u"Internet", OUString(), SID_INET_DLG },
159 { u"LoadSave", OUString(), SID_FILTER_DLG },
160 { u"Writer", OUString(), SID_SW_EDITOPTIONS },
161 { u"WriterWeb", OUString(), SID_SW_ONLINEOPTIONS },
162 { u"Math", OUString(), SID_SM_EDITOPTIONS },
163 { u"Calc", OUString(), SID_SC_EDITOPTIONS },
164 { u"Impress", OUString(), SID_SD_EDITOPTIONS },
165 { u"Draw", OUString(), SID_SD_GRAPHIC_OPTIONS },
166 { u"Charts", OUString(), SID_SCH_EDITOPTIONS },
167 { u"Base", OUString(), SID_SB_STARBASEOPTIONS },
170 static void setGroupName( std::u16string_view rModule, const OUString& rGroupName )
172 for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
174 if ( rEntry.m_pModule == rModule )
176 rEntry.m_sGroupName = rGroupName;
177 break;
182 static OUString getGroupName( std::u16string_view rModule, bool bForced )
184 OUString sGroupName;
185 for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
187 if ( rEntry.m_pModule == rModule )
189 sGroupName = rEntry.m_sGroupName;
190 break;
194 if ( sGroupName.isEmpty() && bForced )
196 if ( rModule == u"Writer" )
197 sGroupName = CuiResId(SID_SW_EDITOPTIONS_RES[0].first);
198 else if ( rModule == u"WriterWeb" )
199 sGroupName = CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first);
200 else if ( rModule == u"Calc" )
201 sGroupName = CuiResId(SID_SC_EDITOPTIONS_RES[0].first);
202 else if ( rModule == u"Impress" )
203 sGroupName = CuiResId(SID_SD_EDITOPTIONS_RES[0].first);
204 else if ( rModule == u"Draw" )
205 sGroupName = CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first);
206 else if ( rModule == u"Math" )
207 sGroupName = CuiResId(SID_SM_EDITOPTIONS_RES[0].first);
208 else if ( rModule == u"Base" )
209 sGroupName = CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first);
211 return sGroupName;
214 static void deleteGroupNames()
216 for (ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
217 rEntry.m_sGroupName.clear();
220 static sal_uInt16 getGroupNodeId( std::u16string_view rModule )
222 sal_uInt16 nNodeId = 0xFFFF;
223 for (const ModuleToGroupNameMap_Impl& rEntry : ModuleMap)
225 if ( rEntry.m_pModule == rModule )
227 nNodeId = rEntry.m_nNodeId;
228 break;
232 return nNodeId;
235 namespace {
237 bool MailMergeCfgIsEmailSupported()
239 std::optional<bool> b = officecfg::Office::Writer::MailMergeWizard::EMailSupported::get();
240 return b.has_value() && *b;
245 //typedef SfxTabPage* (*FNCreateTabPage)(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet &rAttrSet);
246 static std::unique_ptr<SfxTabPage> CreateGeneralTabPage(sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
248 CreateTabPage fnCreate = nullptr;
249 switch(nId)
251 case RID_SFXPAGE_SAVE: fnCreate = &SvxSaveTabPage::Create; break;
252 case RID_SFXPAGE_PATH: fnCreate = &SvxPathTabPage::Create; break;
253 case RID_SFXPAGE_GENERAL: fnCreate = &SvxGeneralTabPage::Create; break;
254 case RID_SFXPAGE_PRINTOPTIONS: fnCreate = &SfxCommonPrintOptionsTabPage::Create; break;
255 case OFA_TP_LANGUAGES: fnCreate = &OfaLanguagesTabPage::Create; break;
256 case RID_SFXPAGE_LINGU: fnCreate = &SvxLinguTabPage::Create; break;
257 case OFA_TP_VIEW: fnCreate = &OfaViewTabPage::Create; break;
258 case OFA_TP_MISC: fnCreate = &OfaMiscTabPage::Create; break;
259 case RID_SVXPAGE_ASIAN_LAYOUT: fnCreate = &SvxAsianLayoutPage::Create; break;
260 case RID_SVX_FONT_SUBSTITUTION: fnCreate = &SvxFontSubstTabPage::Create; break;
261 case RID_SVXPAGE_INET_PROXY: fnCreate = &SvxProxyTabPage::Create; break;
262 case RID_SVXPAGE_INET_SECURITY: fnCreate = &SvxSecurityTabPage::Create; break;
263 case RID_SVXPAGE_INET_MAIL: fnCreate = &SvxEMailTabPage::Create; break;
264 #if HAVE_FEATURE_DESKTOP
265 case RID_SVXPAGE_PERSONALIZATION: fnCreate = &SvxPersonalizationTabPage::Create; break;
266 #endif
267 case RID_SVXPAGE_COLORCONFIG: fnCreate = &SvxColorOptionsTabPage::Create; break;
268 case RID_OFAPAGE_HTMLOPT: fnCreate = &OfaHtmlTabPage::Create; break;
269 case SID_OPTFILTER_MSOFFICE: fnCreate = &OfaMSFilterTabPage::Create; break;
270 case RID_OFAPAGE_MSFILTEROPT2: fnCreate = &OfaMSFilterTabPage2::Create; break;
271 case RID_SVXPAGE_JSEARCH_OPTIONS: fnCreate = &SvxJSearchOptionsPage::Create ; break;
272 case SID_SB_CONNECTIONPOOLING: fnCreate = &::offapp::ConnectionPoolOptionsPage::Create; break;
273 case SID_SB_DBREGISTEROPTIONS: fnCreate = &svx::DbRegistrationOptionsPage::Create; break;
274 case RID_SVXPAGE_ACCESSIBILITYCONFIG: fnCreate = &SvxAccessibilityOptionsTabPage::Create; break;
275 case RID_SVXPAGE_OPTIONS_CTL: fnCreate = &SvxCTLOptionsPage::Create ; break;
276 case RID_SVXPAGE_LANGTOOL_OPTIONS: fnCreate = &OptLanguageToolTabPage::Create ; break;
277 case RID_SVXPAGE_DEEPL_OPTIONS: fnCreate = &OptDeeplTabPage::Create ; break;
278 case RID_SVXPAGE_OPTIONS_JAVA: fnCreate = &SvxJavaOptionsPage::Create ; break;
279 #if HAVE_FEATURE_OPENCL
280 case RID_SVXPAGE_OPENCL: fnCreate = &SvxOpenCLTabPage::Create ; break;
281 #endif
282 case RID_SVXPAGE_ONLINEUPDATE: fnCreate = &SvxOnlineUpdateTabPage::Create; break;
283 case RID_OPTPAGE_CHART_DEFCOLORS: fnCreate = &SvxDefaultColorOptPage::Create; break;
284 #if HAVE_FEATURE_SCRIPTING
285 case RID_SVXPAGE_BASICIDE_OPTIONS: fnCreate = &SvxBasicIDEOptionsPage::Create; break;
286 #endif
289 return fnCreate ? (*fnCreate)( pPage, pController, &rSet ) : nullptr;
292 namespace {
294 struct OptionsMapping_Impl
296 OUString m_aGroupName;
297 OUString m_aPageName;
298 sal_uInt16 m_nPageId;
303 constexpr OptionsMapping_Impl OptionsMap_Impl[]
305 // GROUP PAGE PAGE-ID
306 { u"ProductName"_ustr, u""_ustr, SID_GENERAL_OPTIONS },
307 { u"ProductName"_ustr, u"UserData"_ustr, RID_SFXPAGE_GENERAL },
308 { u"ProductName"_ustr, u"General"_ustr, OFA_TP_MISC },
309 { u"ProductName"_ustr, u"View"_ustr, OFA_TP_VIEW },
310 { u"ProductName"_ustr, u"Print"_ustr, RID_SFXPAGE_PRINTOPTIONS },
311 { u"ProductName"_ustr, u"Paths"_ustr, RID_SFXPAGE_PATH },
312 { u"ProductName"_ustr, u"Fonts"_ustr, RID_SVX_FONT_SUBSTITUTION },
313 { u"ProductName"_ustr, u"Security"_ustr, RID_SVXPAGE_INET_SECURITY },
314 { u"ProductName"_ustr, u"Personalization"_ustr, RID_SVXPAGE_PERSONALIZATION },
315 { u"ProductName"_ustr, u"Appearance"_ustr, RID_SVXPAGE_COLORCONFIG },
316 { u"ProductName"_ustr, u"Accessibility"_ustr, RID_SVXPAGE_ACCESSIBILITYCONFIG },
317 { u"ProductName"_ustr, u"Java"_ustr, RID_SVXPAGE_OPTIONS_JAVA },
318 { u"ProductName"_ustr, u"BasicIDEOptions"_ustr, RID_SVXPAGE_BASICIDE_OPTIONS },
319 { u"ProductName"_ustr, u"OnlineUpdate"_ustr, RID_SVXPAGE_ONLINEUPDATE },
320 { u"LanguageSettings"_ustr, u""_ustr, SID_LANGUAGE_OPTIONS },
321 { u"LanguageSettings"_ustr, u"Languages"_ustr, OFA_TP_LANGUAGES },
322 { u"LanguageSettings"_ustr, u"WritingAids"_ustr, RID_SFXPAGE_LINGU },
323 { u"LanguageSettings"_ustr, u"SearchingInJapanese"_ustr, RID_SVXPAGE_JSEARCH_OPTIONS },
324 { u"LanguageSettings"_ustr, u"AsianLayout"_ustr, RID_SVXPAGE_ASIAN_LAYOUT },
325 { u"LanguageSettings"_ustr, u"ComplexTextLayout"_ustr, RID_SVXPAGE_OPTIONS_CTL },
326 { u"Internet"_ustr, u""_ustr, SID_INET_DLG },
327 { u"Internet"_ustr, u"Proxy"_ustr, RID_SVXPAGE_INET_PROXY },
328 { u"Internet"_ustr, u"Email"_ustr, RID_SVXPAGE_INET_MAIL },
329 { u"LoadSave"_ustr, u""_ustr, SID_FILTER_DLG },
330 { u"LoadSave"_ustr, u"General"_ustr, RID_SFXPAGE_SAVE },
331 { u"LoadSave"_ustr, u"VBAProperties"_ustr, SID_OPTFILTER_MSOFFICE },
332 { u"LoadSave"_ustr, u"MicrosoftOffice"_ustr, RID_OFAPAGE_MSFILTEROPT2 },
333 { u"LoadSave"_ustr, u"HTMLCompatibility"_ustr, RID_OFAPAGE_HTMLOPT },
334 { u"Writer"_ustr, u""_ustr, SID_SW_EDITOPTIONS },
335 { u"Writer"_ustr, u"General"_ustr, RID_SW_TP_OPTLOAD_PAGE },
336 { u"Writer"_ustr, u"View"_ustr, RID_SW_TP_CONTENT_OPT },
337 { u"Writer"_ustr, u"FormattingAids"_ustr, RID_SW_TP_OPTSHDWCRSR },
338 { u"Writer"_ustr, u"Grid"_ustr, RID_SVXPAGE_GRID },
339 { u"Writer"_ustr, u"BasicFontsWestern"_ustr, RID_SW_TP_STD_FONT },
340 { u"Writer"_ustr, u"BasicFontsAsian"_ustr, RID_SW_TP_STD_FONT_CJK },
341 { u"Writer"_ustr, u"BasicFontsCTL"_ustr, RID_SW_TP_STD_FONT_CTL },
342 { u"Writer"_ustr, u"Print"_ustr, RID_SW_TP_OPTPRINT_PAGE },
343 { u"Writer"_ustr, u"Table"_ustr, RID_SW_TP_OPTTABLE_PAGE },
344 { u"Writer"_ustr, u"Changes"_ustr, RID_SW_TP_REDLINE_OPT },
345 { u"Writer"_ustr, u"Comparison"_ustr, RID_SW_TP_COMPARISON_OPT },
346 { u"Writer"_ustr, u"Compatibility"_ustr, RID_SW_TP_OPTCOMPATIBILITY_PAGE },
347 { u"Writer"_ustr, u"AutoCaption"_ustr, RID_SW_TP_OPTCAPTION_PAGE },
348 { u"Writer"_ustr, u"MailMerge"_ustr, RID_SW_TP_MAILCONFIG },
349 { u"WriterWeb"_ustr, u""_ustr, SID_SW_ONLINEOPTIONS },
350 { u"WriterWeb"_ustr, u"View"_ustr, RID_SW_TP_HTML_CONTENT_OPT },
351 { u"WriterWeb"_ustr, u"FormattingAids"_ustr, RID_SW_TP_HTML_OPTSHDWCRSR },
352 { u"WriterWeb"_ustr, u"Grid"_ustr, RID_SW_TP_HTML_OPTGRID_PAGE },
353 { u"WriterWeb"_ustr, u"Print"_ustr, RID_SW_TP_HTML_OPTPRINT_PAGE },
354 { u"WriterWeb"_ustr, u"Table"_ustr, RID_SW_TP_HTML_OPTTABLE_PAGE },
355 { u"WriterWeb"_ustr, u"Background"_ustr, RID_SW_TP_BACKGROUND },
356 { u"Math"_ustr, u""_ustr, SID_SM_EDITOPTIONS },
357 { u"Math"_ustr, u"Settings"_ustr, SID_SM_TP_PRINTOPTIONS },
358 { u"Calc"_ustr, u""_ustr, SID_SC_EDITOPTIONS },
359 { u"Calc"_ustr, u"General"_ustr, SID_SC_TP_LAYOUT },
360 { u"Calc"_ustr, u"View"_ustr, SID_SC_TP_CONTENT },
361 { u"Calc"_ustr, u"Calculate"_ustr, SID_SC_TP_CALC },
362 { u"Calc"_ustr, u"Formula"_ustr, SID_SC_TP_FORMULA },
363 { u"Calc"_ustr, u"SortLists"_ustr, SID_SC_TP_USERLISTS },
364 { u"Calc"_ustr, u"Changes"_ustr, SID_SC_TP_CHANGES },
365 { u"Calc"_ustr, u"Compatibility"_ustr, SID_SC_TP_COMPATIBILITY },
366 { u"Calc"_ustr, u"Grid"_ustr, SID_SC_TP_GRID },
367 { u"Calc"_ustr, u"Print"_ustr, RID_SC_TP_PRINT },
368 { u"Impress"_ustr, u""_ustr, SID_SD_EDITOPTIONS },
369 { u"Impress"_ustr, u"General"_ustr, SID_SI_TP_MISC },
370 { u"Impress"_ustr, u"View"_ustr, SID_SI_TP_CONTENTS },
371 { u"Impress"_ustr, u"Grid"_ustr, SID_SI_TP_SNAP },
372 { u"Impress"_ustr, u"Print"_ustr, SID_SI_TP_PRINT },
373 { u"Draw"_ustr, u""_ustr, SID_SD_GRAPHIC_OPTIONS },
374 { u"Draw"_ustr, u"General"_ustr, SID_SD_TP_MISC },
375 { u"Draw"_ustr, u"View"_ustr, SID_SD_TP_CONTENTS },
376 { u"Draw"_ustr, u"Grid"_ustr, SID_SD_TP_SNAP },
377 { u"Draw"_ustr, u"Print"_ustr, SID_SD_TP_PRINT },
378 { u"Charts"_ustr, u""_ustr, SID_SCH_EDITOPTIONS },
379 { u"Charts"_ustr, u"DefaultColors"_ustr, RID_OPTPAGE_CHART_DEFCOLORS },
380 { u"Base"_ustr, u""_ustr, SID_SB_STARBASEOPTIONS },
381 { u"Base"_ustr, u"Connections"_ustr, SID_SB_CONNECTIONPOOLING },
382 { u"Base"_ustr, u"Databases"_ustr, SID_SB_DBREGISTEROPTIONS },
385 static bool lcl_getStringFromID( sal_uInt16 _nPageId, OUString& _rGroupName, OUString& _rPageName )
387 bool bRet = false;
389 for (const auto & rMapping : OptionsMap_Impl )
391 if ( _nPageId == rMapping.m_nPageId )
393 bRet = true;
394 _rGroupName = rMapping.m_aGroupName;
395 if ( !rMapping.m_aPageName.isEmpty() )
396 _rPageName = rMapping.m_aPageName;
397 break;
401 return bRet;
404 static bool lcl_isOptionHidden( sal_uInt16 _nPageId, const SvtOptionsDialogOptions& _rOptOptions )
406 bool bIsHidden = false;
407 OUString sGroupName, sPageName;
408 if ( lcl_getStringFromID( _nPageId, sGroupName, sPageName ) )
410 if ( sPageName.isEmpty() )
411 bIsHidden = _rOptOptions.IsGroupHidden( sGroupName );
412 else
413 bIsHidden = _rOptOptions.IsPageHidden( sPageName, sGroupName );
415 return bIsHidden;
418 struct OptionsPageInfo
420 std::unique_ptr<SfxTabPage> m_xPage;
421 sal_uInt16 m_nPageId;
422 OUString m_sPageURL;
423 OUString m_sEventHdl;
424 std::unique_ptr<ExtensionsTabPage> m_xExtPage;
426 explicit OptionsPageInfo( sal_uInt16 nId ) : m_nPageId( nId ) {}
429 struct OptionsGroupInfo
431 std::optional<SfxItemSet> m_pInItemSet;
432 std::unique_ptr<SfxItemSet> m_pOutItemSet;
433 SfxShell* m_pShell; // used to create the page
434 SfxModule* m_pModule; // used to create the ItemSet
435 sal_uInt16 m_nDialogId; // Id of the former dialog
437 OptionsGroupInfo( SfxShell* pSh, SfxModule* pMod, sal_uInt16 nId ) :
438 m_pShell( pSh ),
439 m_pModule( pMod ), m_nDialogId( nId ) {}
442 struct OptionsPageIdInfo
444 OUString m_sParentName;
445 OUString m_sPageName;
446 sal_uInt16 m_nParentId;
447 sal_uInt16 m_nPageId;
449 OptionsPageIdInfo(OUString sParentName, OUString sPageName, sal_uInt16 nParentId,
450 sal_uInt16 nPageId)
451 : m_sParentName(std::move(sParentName))
452 , m_sPageName(std::move(sPageName))
453 , m_nParentId(nParentId)
454 , m_nPageId(nPageId)
459 // Basic ctor with common initialization
460 OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, bool fromExtensionManager)
461 : SfxOkDialogController(pParent, u"cui/ui/optionsdialog.ui"_ustr, u"OptionsDialog"_ustr)
462 , xOkPB(m_xBuilder->weld_button(u"ok"_ustr))
463 , xApplyPB(m_xBuilder->weld_button(u"apply"_ustr))
464 , xBackPB(m_xBuilder->weld_button(u"revert"_ustr))
465 , xTreeLB(m_xBuilder->weld_tree_view(u"pages"_ustr))
466 , xTabBox(m_xBuilder->weld_container(u"box"_ustr))
467 , m_xSearchEdit(m_xBuilder->weld_entry(u"searchEntry"_ustr))
468 , m_pParent(pParent)
469 , m_aUpdateDataTimer("OfaTreeOptionsDialog UpdateDataTimer")
470 , bIsFirtsInitialize(true)
471 , sTitle(m_xDialog->get_title())
472 , bForgetSelection(false)
473 , bIsFromExtensionManager(fromExtensionManager)
474 , bIsForSetDocumentLanguage(false)
475 , bNeedsRestart(false)
476 , eRestartReason(svtools::RESTART_REASON_NONE)
478 Size aSize(xTreeLB->get_approximate_digit_width() * 100, xTreeLB->get_height_rows(30));
479 xTabBox->set_size_request(aSize.Width(), aSize.Height());
480 xTreeLB->set_size_request(xTreeLB->get_approximate_digit_width() * 35, aSize.Height());
482 // Init tree and handler
483 xTreeLB->set_help_id(HID_OFADLG_TREELISTBOX);
484 xTreeLB->connect_selection_changed(LINK(this, OfaTreeOptionsDialog, ShowPageHdl_Impl));
485 xBackPB->connect_clicked(LINK(this, OfaTreeOptionsDialog, BackHdl_Impl));
486 xApplyPB->connect_clicked(LINK(this, OfaTreeOptionsDialog, ApplyHdl_Impl));
487 xOkPB->connect_clicked(LINK(this, OfaTreeOptionsDialog, ApplyHdl_Impl));
488 m_xSearchEdit->connect_changed(LINK(this, OfaTreeOptionsDialog, SearchUpdateHdl));
489 m_xSearchEdit->connect_focus_out(LINK(this, OfaTreeOptionsDialog, FocusOut_Impl));
490 m_xDialog->connect_help(LINK(this, OfaTreeOptionsDialog, HelpHdl_Impl));
492 m_aUpdateDataTimer.SetInvokeHandler(LINK(this, OfaTreeOptionsDialog, ImplUpdateDataHdl));
493 m_aUpdateDataTimer.SetTimeout(EDIT_UPDATEDATA_TIMEOUT);
495 // Initialize search util
496 m_options.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
497 m_options.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
498 m_options.searchFlag
499 |= (util::SearchFlags::REG_NOT_BEGINOFLINE | util::SearchFlags::REG_NOT_ENDOFLINE);
501 xTreeLB->set_accessible_name(sTitle);
504 // Ctor() with Frame -----------------------------------------------------
505 OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, const Reference< XFrame >& _xFrame, bool bActivateLastSelection)
506 : OfaTreeOptionsDialog(pParent, false)
508 Initialize( _xFrame );
509 LoadExtensionOptions( u"" );
510 if (bActivateLastSelection)
511 ActivateLastSelection();
514 // Ctor() with ExtensionId -----------------------------------------------
515 OfaTreeOptionsDialog::OfaTreeOptionsDialog(weld::Window* pParent, std::u16string_view rExtensionId)
516 : OfaTreeOptionsDialog(pParent, !rExtensionId.empty())
518 LoadExtensionOptions( rExtensionId );
519 ActivateLastSelection();
522 void OfaTreeOptionsDialog::ImplDestroy()
524 xCurrentPageEntry.reset();
526 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
527 bool bEntry = xTreeLB->get_iter_first(*xEntry);
528 // first children
529 while (bEntry)
531 // if Child (has parent), then OptionsPageInfo
532 if (xTreeLB->get_iter_depth(*xEntry))
534 OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
535 if(pPageInfo->m_xPage)
537 pPageInfo->m_xPage->FillUserData();
538 OUString aPageData(pPageInfo->m_xPage->GetUserData());
539 if ( !aPageData.isEmpty() )
541 SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
542 SetViewOptUserItem( aTabPageOpt, aPageData );
544 pPageInfo->m_xPage.reset();
547 if (pPageInfo->m_nPageId == RID_SFXPAGE_LINGU)
549 // write personal dictionaries
550 Reference< XSearchableDictionaryList > xDicList( LinguMgr::GetDictionaryList() );
551 if (xDicList.is())
553 linguistic::SaveDictionaries( xDicList );
557 pPageInfo->m_xExtPage.reset();
559 delete pPageInfo;
561 bEntry = xTreeLB->iter_next(*xEntry);
564 // and parents
565 bEntry = xTreeLB->get_iter_first(*xEntry);
566 while (bEntry)
568 if (!xTreeLB->get_iter_depth(*xEntry))
570 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
571 delete pGroupInfo;
573 bEntry = xTreeLB->iter_next(*xEntry);
575 deleteGroupNames();
578 OfaTreeOptionsDialog::~OfaTreeOptionsDialog()
580 suppress_fun_call_w_exception(ImplDestroy());
583 OptionsPageInfo* OfaTreeOptionsDialog::AddTabPage(
584 sal_uInt16 nId, const OUString& rPageName, sal_uInt16 nGroup )
586 std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator();
587 if (!xTreeLB->get_iter_first(*xParent))
588 return nullptr;
589 xTreeLB->iter_nth_sibling(*xParent, nGroup);
591 OptionsPageInfo* pPageInfo = new OptionsPageInfo( nId );
592 OUString sId(weld::toId(pPageInfo));
593 xTreeLB->insert(xParent.get(), -1, &rPageName, &sId, nullptr, nullptr, false, nullptr);
594 return pPageInfo;
597 // the ItemSet* is passed on to the dialog's ownership
598 sal_uInt16 OfaTreeOptionsDialog::AddGroup(const OUString& rGroupName,
599 SfxShell* pCreateShell,
600 SfxModule* pCreateModule,
601 sal_uInt16 nDialogId )
603 OptionsGroupInfo* pInfo =
604 new OptionsGroupInfo( pCreateShell, pCreateModule, nDialogId );
605 OUString sId(weld::toId(pInfo));
606 xTreeLB->append(sId, rGroupName);
608 sal_uInt16 nRet = 0;
609 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
610 bool bEntry = xTreeLB->get_iter_first(*xEntry);
611 while (bEntry)
613 if (!xTreeLB->get_iter_depth(*xEntry))
614 nRet++;
615 bEntry = xTreeLB->iter_next(*xEntry);
617 return nRet - 1;
620 IMPL_LINK_NOARG(OfaTreeOptionsDialog, ShowPageHdl_Impl, weld::TreeView&, void)
622 SelectHdl_Impl();
625 void OfaTreeOptionsDialog::ResetCurrentPageFromConfig()
627 if (!(xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry)))
628 return;
630 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
631 if (pPageInfo->m_xPage)
633 std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
634 xTreeLB->iter_parent(*xParent);
635 OptionsGroupInfo* pGroupInfo =
636 weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
637 pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
639 else if ( pPageInfo->m_xExtPage )
640 pPageInfo->m_xExtPage->ResetPage();
643 IMPL_LINK_NOARG(OfaTreeOptionsDialog, BackHdl_Impl, weld::Button&, void)
645 ResetCurrentPageFromConfig();
648 void OfaTreeOptionsDialog::ApplyOptions()
650 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
651 bool bEntry = xTreeLB->get_iter_first(*xEntry);
652 while (bEntry)
654 if (xTreeLB->get_iter_depth(*xEntry))
656 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
657 if ( pPageInfo->m_xPage && !pPageInfo->m_xPage->HasExchangeSupport() )
659 std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xEntry.get());
660 xTreeLB->iter_parent(*xParent);
661 OptionsGroupInfo* pGroupInfo =
662 weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
663 pPageInfo->m_xPage->FillItemSet(pGroupInfo->m_pOutItemSet.get());
666 if ( pPageInfo->m_xExtPage )
668 pPageInfo->m_xExtPage->DeactivatePage();
669 pPageInfo->m_xExtPage->SavePage();
671 if ( pPageInfo->m_xPage && RID_OPTPAGE_CHART_DEFCOLORS == pPageInfo->m_nPageId )
673 SvxDefaultColorOptPage* pPage = static_cast<SvxDefaultColorOptPage *>(pPageInfo->m_xPage.get());
674 pPage->SaveChartOptions();
677 bEntry = xTreeLB->iter_next(*xEntry);
681 IMPL_LINK_NOARG(OfaTreeOptionsDialog, HelpHdl_Impl, weld::Widget&, bool)
683 Help* pHelp = Application::GetHelp();
684 if (pHelp && xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
686 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
687 if (pPageInfo->m_xPage)
689 OUString sHelpId(pPageInfo->m_xPage->GetHelpId());
690 pHelp->Start(sHelpId, m_xDialog.get());
691 return false;
694 return true;
697 IMPL_LINK(OfaTreeOptionsDialog, ApplyHdl_Impl, weld::Button&, rButton, void)
699 bool bOkPressed = &rButton == xOkPB.get();
701 OptionsGroupInfo* pGroupInfo = nullptr;
703 if (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
705 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry));
706 if ( pPageInfo->m_xPage )
708 std::unique_ptr<weld::TreeIter> xParent = xTreeLB->make_iterator(xCurrentPageEntry.get());
709 xTreeLB->iter_parent(*xParent);
711 pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
712 if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId
713 && pPageInfo->m_xPage->HasExchangeSupport() )
715 DeactivateRC nLeave = pPageInfo->m_xPage->DeactivatePage(pGroupInfo->m_pOutItemSet.get());
716 if ( nLeave == DeactivateRC::KeepPage )
718 // the page mustn't be left, so return early
719 assert(xTreeLB->is_selected(*xCurrentPageEntry)); // presumably this must be true here
720 if (bOkPressed)
721 return;
727 ApplyOptions();
728 ApplyItemSets();
729 utl::ConfigManager::storeConfigItems();
731 if (bOkPressed)
732 m_xDialog->response(RET_OK);
733 else
735 // tdf#137930 rebuild the in and out itemsets to reflect the current
736 // post-apply state
737 if (pGroupInfo && pGroupInfo->m_pInItemSet)
739 // tdf#138596 seeing as the SfxTabPages keep pointers to the m_pInItemSet
740 // we update the contents of the existing SfxItemSets to match
741 // the current settings, rather than create new ones
742 auto xInItemSet = pGroupInfo->m_pShell
743 ? pGroupInfo->m_pShell->CreateItemSet( pGroupInfo->m_nDialogId )
744 : CreateItemSet( pGroupInfo->m_nDialogId );
745 pGroupInfo->m_pInItemSet->Set(*xInItemSet, false);
746 pGroupInfo->m_pOutItemSet->ClearItem();
749 // for the Apply case, now that the settings are saved to config,
750 // reload the current page so it knows what the config now states
751 ResetCurrentPageFromConfig();
752 // reselect it to undo possible DeactivatePage above
753 xCurrentPageEntry.reset();
754 SelectHdl_Impl();
757 if (!bNeedsRestart)
758 return;
760 SolarMutexGuard aGuard;
761 weld::Window* pParent;
762 if (!bOkPressed)
763 pParent = m_xDialog.get();
764 else
766 m_xDialog->hide();
767 pParent = m_pParent;
769 bool bRestart = ::svtools::executeRestartDialog(comphelper::getProcessComponentContext(),
770 pParent, eRestartReason);
771 if (bRestart && !bOkPressed)
772 m_xDialog->response(RET_OK);
775 IMPL_LINK_NOARG(OfaTreeOptionsDialog, FocusOut_Impl, weld::Widget&, void)
777 if (m_aUpdateDataTimer.IsActive())
779 m_aUpdateDataTimer.Stop();
780 m_aUpdateDataTimer.Invoke();
784 IMPL_LINK_NOARG(OfaTreeOptionsDialog, SearchUpdateHdl, weld::Entry&, void)
786 m_aUpdateDataTimer.Start();
789 IMPL_LINK_NOARG(OfaTreeOptionsDialog, ImplUpdateDataHdl, Timer*, void)
791 // initializeAllDialogs() can take a long time, show wait cursor and disable input
792 m_xSearchEdit->set_editable(false);
793 m_xSearchEdit->set_busy_cursor(true);
795 // Pause redraw
796 xTreeLB->freeze();
798 if (bIsFirtsInitialize)
800 m_xSearchEdit->freeze();
801 xTreeLB->hide();
803 initializeAllDialogs();
805 m_xSearchEdit->thaw();
806 xTreeLB->show();
807 bIsFirtsInitialize = false;
810 // Apply the search filter
811 OUString aSearchTerm(m_xSearchEdit->get_text());
812 int nMatchFound = applySearchFilter(aSearchTerm);
814 // Resume redraw
815 xTreeLB->thaw();
817 // select first child of first node after the search done
818 if (nMatchFound != -1)
819 selectFirstEntry();
821 m_xSearchEdit->set_editable(true);
822 m_xSearchEdit->set_busy_cursor(false);
825 void OfaTreeOptionsDialog::selectFirstEntry()
827 std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
828 bool bTemp = xTreeLB->get_iter_first(*xTemp);
830 while (bTemp)
832 // select only the first child
833 if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
835 std::unique_ptr<weld::TreeIter> xEntry(xTreeLB->make_iterator(xTemp.get()));
837 std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
838 xTreeLB->iter_parent(*xParent);
839 xTreeLB->expand_row(*xParent);
840 xTreeLB->scroll_to_row(*xParent);
841 xTreeLB->scroll_to_row(*xEntry);
842 xTreeLB->set_cursor(*xEntry);
843 xTreeLB->select(*xEntry);
844 SelectHdl_Impl();
846 break;
848 bTemp = xTreeLB->iter_next(*xTemp);
852 void OfaTreeOptionsDialog::initializeAllDialogs()
854 std::unique_ptr<weld::TreeIter> xEntry;
856 std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
857 bool bTemp = xTreeLB->get_iter_first(*xTemp);
859 while (bTemp)
861 if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
863 if (!(xEntry = xTreeLB->make_iterator(xTemp.get())))
865 xEntry = xTreeLB->make_iterator();
866 if (!xTreeLB->get_iter_first(*xEntry) || !xTreeLB->iter_next(*xEntry))
867 xEntry.reset();
870 if (!xEntry)
871 return;
873 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
874 if (TreeOptHelper::getStringsFromDialog(pPageInfo->m_nPageId).isEmpty())
876 SolarMutexGuard aGuard;
877 initializeCurrentDialog(pPageInfo, xEntry);
881 bTemp = xTreeLB->iter_next(*xTemp);
885 void OfaTreeOptionsDialog::clearOptionsDialog()
887 // clear and reset
888 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
889 bool bEntry = xTreeLB->get_iter_first(*xEntry);
891 while (bEntry)
893 if (xTreeLB->get_iter_depth(*xEntry))
895 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
896 if (pPageInfo->m_xPage)
897 pPageInfo->m_xPage.reset();
899 bEntry = xTreeLB->iter_next(*xEntry);
901 xCurrentPageEntry.reset();
904 // store Options tree with their page names
905 void OfaTreeOptionsDialog::storeOptionsTree()
907 m_aTreePageIds.clear();
909 sal_uInt16 aParentId = 0;
910 OUString sParentName;
912 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
913 bool bEntry = xTreeLB->get_iter_first(*xEntry);
915 while (bEntry)
917 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
918 bool bIsParentNode = !xTreeLB->get_iter_depth(*xEntry);
920 if (bIsParentNode)
922 // Parent node
923 sParentName = xTreeLB->get_text(*xEntry);
924 aParentId = pGroupInfo->m_nDialogId;
925 m_aTreePageIds.push_back(new OptionsPageIdInfo(sParentName, sParentName, aParentId, 0));
927 else
929 // Child node
930 OUString sChildName = xTreeLB->get_text(*xEntry);
931 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
932 m_aTreePageIds.push_back(
933 new OptionsPageIdInfo(sParentName, sChildName, aParentId, pPageInfo->m_nPageId));
935 bEntry = xTreeLB->iter_next(*xEntry);
939 int OfaTreeOptionsDialog::applySearchFilter(const OUString& rSearchTerm)
941 if (rSearchTerm.isEmpty())
943 clearOptionsDialog();
944 xTreeLB->clear();
945 Initialize(m_xFrame);
947 return 0;
950 m_options.searchString = rSearchTerm;
951 utl::TextSearch textSearch(m_options);
953 clearOptionsDialog();
955 if (xTreeLB->n_children() > 0)
956 xTreeLB->clear();
958 std::vector<std::pair<sal_uInt16, std::vector<sal_uInt16>>> aFoundIdsVector;
960 for (std::size_t i = 0; i < m_aTreePageIds.size(); ++i)
962 const OUString sParentName = m_aTreePageIds[i]->m_sParentName;
963 const OUString sPageName = m_aTreePageIds[i]->m_sPageName;
964 const sal_uInt16 nParentId = m_aTreePageIds[i]->m_nParentId;
965 const sal_uInt16 nPageId = m_aTreePageIds[i]->m_nPageId;
967 const OUString sPageStrings = TreeOptHelper::getStringsFromDialog(nPageId);
968 const OUString sPageNameAndStrings = sParentName + " " + sPageName + " " + sPageStrings;
970 sal_Int32 aStartPos = 0;
971 sal_Int32 aEndPos = sPageNameAndStrings.getLength();
973 // check if rSearchTerm matches with sPageNameAndStrings
974 if (textSearch.SearchForward(sPageNameAndStrings, &aStartPos, &aEndPos))
976 bool isFound = false;
977 for (auto& aEntryId : aFoundIdsVector)
979 if (aEntryId.first == nParentId)
981 isFound = true;
982 aEntryId.second.push_back(nPageId);
986 if (!isFound)
987 aFoundIdsVector.push_back({ nParentId, { nPageId } });
991 showDialog(aFoundIdsVector);
993 // if treeview is empty, return -1
994 return xTreeLB->n_children() ? 0 : -1;
997 void OfaTreeOptionsDialog::showDialog(VectorOfMatchedIds& pSearchIds)
1000 // void generalOptions(); // SID_GENERAL_OPTIONS
1001 // void loadAndSaveOptions(); // SID_FILTER_DLG
1002 // void languageOptions(); // SID_LANGUAGE_OPTIONS
1003 // void writerOptions(); // SID_SW_EDITOPTIONS
1004 // void writerWebOptions(); // SID_SW_ONLINEOPTIONS
1005 // void calcOptions(); // SID_SC_EDITOPTIONS
1006 // void impressOptions(); // SID_SD_EDITOPTIONS
1007 // void drawOptions(); // SID_SD_GRAPHIC_OPTIONS
1008 // void mathOptions(); // SID_SM_EDITOPTIONS
1009 // void databaseOptions(); // SID_SB_STARBASEOPTIONS
1010 // void chartOptions(); // SID_SCH_EDITOPTIONS
1011 // void internetOptions(); // SID_INET_DLG
1014 for (auto& aEntryId : pSearchIds)
1016 switch (aEntryId.first)
1018 case SID_GENERAL_OPTIONS:
1019 generalOptions(aEntryId.second);
1020 break;
1022 case SID_FILTER_DLG:
1023 loadAndSaveOptions(aEntryId.second);
1024 break;
1026 case SID_LANGUAGE_OPTIONS:
1027 languageOptions(aEntryId.second);
1028 break;
1030 case SID_SW_EDITOPTIONS:
1031 writerOptions(aEntryId.second);
1032 break;
1034 case SID_SW_ONLINEOPTIONS:
1035 writerWebOptions(aEntryId.second);
1036 break;
1038 case SID_SC_EDITOPTIONS:
1039 calcOptions(aEntryId.second);
1040 break;
1042 case SID_SD_EDITOPTIONS:
1043 impressOptions(aEntryId.second);
1044 break;
1046 case SID_SD_GRAPHIC_OPTIONS:
1047 drawOptions(aEntryId.second);
1048 break;
1050 case SID_SM_EDITOPTIONS:
1051 mathOptions(aEntryId.second);
1052 break;
1054 case SID_SB_STARBASEOPTIONS:
1055 databaseOptions(aEntryId.second);
1056 break;
1058 case SID_SCH_EDITOPTIONS:
1059 chartOptions(aEntryId.second);
1060 break;
1062 case SID_INET_DLG:
1063 internetOptions(aEntryId.second);
1064 break;
1066 default:
1067 break;
1072 void OfaTreeOptionsDialog::ApplyItemSets()
1074 std::unique_ptr<weld::TreeIter> xEntry = xTreeLB->make_iterator();
1075 bool bEntry = xTreeLB->get_iter_first(*xEntry);
1076 while (bEntry)
1078 if (!xTreeLB->get_iter_depth(*xEntry))
1080 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xEntry));
1081 if(pGroupInfo->m_pOutItemSet)
1083 if(pGroupInfo->m_pShell)
1084 pGroupInfo->m_pShell->ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
1085 else
1086 ApplyItemSet( pGroupInfo->m_nDialogId, *pGroupInfo->m_pOutItemSet);
1089 bEntry = xTreeLB->iter_next(*xEntry);
1093 void OfaTreeOptionsDialog::ActivatePage( sal_uInt16 nResId )
1095 bIsForSetDocumentLanguage = false;
1096 if ( nResId == OFA_TP_LANGUAGES_FOR_SET_DOCUMENT_LANGUAGE )
1098 bIsForSetDocumentLanguage = true;
1099 nResId = OFA_TP_LANGUAGES;
1102 DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
1103 if ( !pLastPageSaver )
1104 pLastPageSaver = new LastPageSaver;
1105 bForgetSelection = true;
1106 sal_uInt16 nTemp = pLastPageSaver->m_nLastPageId;
1107 pLastPageSaver->m_nLastPageId = nResId;
1108 ActivateLastSelection();
1109 pLastPageSaver->m_nLastPageId = nTemp;
1112 void OfaTreeOptionsDialog::ActivatePage( const OUString& rPageURL )
1114 DBG_ASSERT( !bIsFromExtensionManager, "OfaTreeOptionsDialog::ActivatePage(): call from extension manager" );
1115 if ( !pLastPageSaver )
1116 pLastPageSaver = new LastPageSaver;
1117 bForgetSelection = true;
1118 pLastPageSaver->m_nLastPageId = 0;
1119 pLastPageSaver->m_sLastPageURL_Tools = rPageURL;
1120 ActivateLastSelection();
1123 void OfaTreeOptionsDialog::ActivateLastSelection()
1125 std::unique_ptr<weld::TreeIter> xEntry;
1127 if (pLastPageSaver)
1129 OUString sLastURL = bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
1130 : pLastPageSaver->m_sLastPageURL_Tools;
1131 if ( sLastURL.isEmpty() )
1133 sLastURL = !bIsFromExtensionManager ? pLastPageSaver->m_sLastPageURL_ExtMgr
1134 : pLastPageSaver->m_sLastPageURL_Tools;
1137 bool bMustExpand = ( INetURLObject( sLastURL ).GetProtocol() == INetProtocol::File );
1139 std::unique_ptr<weld::TreeIter> xTemp = xTreeLB->make_iterator();
1140 bool bTemp = xTreeLB->get_iter_first(*xTemp);
1141 while (bTemp)
1143 // restore only selection of a leaf
1144 if (xTreeLB->get_iter_depth(*xTemp) && xTreeLB->get_id(*xTemp).toInt64())
1146 OptionsPageInfo* pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xTemp));
1147 OUString sPageURL = pPageInfo->m_sPageURL;
1148 if ( bMustExpand )
1150 sPageURL = comphelper::getExpandedUri(
1151 comphelper::getProcessComponentContext(), sPageURL);
1154 if ( ( !bIsFromExtensionManager
1155 && pPageInfo->m_nPageId && pPageInfo->m_nPageId == pLastPageSaver->m_nLastPageId )
1156 || ( !pPageInfo->m_nPageId && sLastURL == sPageURL ) )
1158 xEntry = xTreeLB->make_iterator(xTemp.get());
1159 break;
1162 bTemp = xTreeLB->iter_next(*xTemp);
1166 if (!xEntry)
1168 xEntry = xTreeLB->make_iterator();
1169 if (!xTreeLB->get_iter_first(*xEntry) || !xTreeLB->iter_next(*xEntry))
1170 xEntry.reset();
1173 if (!xEntry)
1174 return;
1176 std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
1177 xTreeLB->iter_parent(*xParent);
1178 xTreeLB->expand_row(*xParent);
1179 xTreeLB->scroll_to_row(*xParent);
1180 xTreeLB->scroll_to_row(*xEntry);
1181 xTreeLB->set_cursor(*xEntry);
1182 xTreeLB->select(*xEntry);
1183 m_xSearchEdit->grab_focus();
1184 SelectHdl_Impl();
1187 void OfaTreeOptionsDialog::InitItemSets(OptionsGroupInfo& rGroupInfo)
1189 if (!rGroupInfo.m_pInItemSet)
1190 rGroupInfo.m_pInItemSet.emplace( rGroupInfo.m_pShell
1191 ? *rGroupInfo.m_pShell->CreateItemSet( rGroupInfo.m_nDialogId )
1192 : *CreateItemSet( rGroupInfo.m_nDialogId ) );
1193 if (!rGroupInfo.m_pOutItemSet)
1194 rGroupInfo.m_pOutItemSet = std::make_unique<SfxItemSet>(
1195 *rGroupInfo.m_pInItemSet->GetPool(),
1196 rGroupInfo.m_pInItemSet->GetRanges());
1199 void OfaTreeOptionsDialog::initializeCurrentDialog(OptionsPageInfo*& pPageInfo,
1200 std::unique_ptr<weld::TreeIter>& xEntry)
1202 std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
1203 bool bParent = xTreeLB->iter_parent(*xParent);
1205 if (!bParent)
1206 return;
1208 if (pPageInfo->m_xPage)
1210 TreeOptHelper::storeStringsOfDialog(pPageInfo->m_nPageId,
1211 pPageInfo->m_xPage->GetAllStrings());
1212 return;
1215 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
1217 if (!pPageInfo->m_xPage && pPageInfo->m_nPageId > 0)
1219 InitItemSets(*pGroupInfo);
1221 pPageInfo->m_xPage = ::CreateGeneralTabPage(pPageInfo->m_nPageId, xTabBox.get(), this,
1222 *pGroupInfo->m_pInItemSet);
1224 if (!pPageInfo->m_xPage && pGroupInfo->m_pModule)
1225 pPageInfo->m_xPage = pGroupInfo->m_pModule->CreateTabPage(
1226 pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
1228 DBG_ASSERT(pPageInfo->m_xPage, "tabpage could not created");
1229 if (pPageInfo->m_xPage)
1231 SvtViewOptions aTabPageOpt(EViewType::TabPage, OUString::number(pPageInfo->m_nPageId));
1232 pPageInfo->m_xPage->SetUserData(GetViewOptUserItem(aTabPageOpt));
1233 pPageInfo->m_xPage->SetFrame(m_xFrame);
1234 pPageInfo->m_xPage->Reset(&*pGroupInfo->m_pInItemSet);
1237 TreeOptHelper::storeStringsOfDialog(pPageInfo->m_nPageId,
1238 pPageInfo->m_xPage->GetAllStrings());
1240 pPageInfo->m_xPage->set_visible(false);
1242 else if (0 == pPageInfo->m_nPageId && !pPageInfo->m_xExtPage)
1244 if (!m_xContainerWinProvider.is())
1245 m_xContainerWinProvider
1246 = awt::ContainerWindowProvider::create(::comphelper::getProcessComponentContext());
1248 pPageInfo->m_xExtPage = std::make_unique<ExtensionsTabPage>(
1249 xTabBox.get(), pPageInfo->m_sPageURL, pPageInfo->m_sEventHdl, m_xContainerWinProvider);
1251 pPageInfo->m_xExtPage->Hide();
1254 BuilderPage* pNewPage = pPageInfo->m_xPage.get();
1256 // fdo#58170 use current page's layout child HelpId, unless there isn't a current page
1257 OUString sHelpId(pNewPage ? pNewPage->GetHelpId() : OUString());
1258 if (sHelpId.isEmpty())
1259 sHelpId = HID_OFADLG_TREELISTBOX;
1260 xTreeLB->set_help_id(sHelpId);
1263 void OfaTreeOptionsDialog::SelectHdl_Impl()
1265 std::unique_ptr<weld::TreeIter> xEntry(xTreeLB->make_iterator());
1267 if (!xTreeLB->get_cursor(xEntry.get()))
1268 return;
1270 if (xCurrentPageEntry && xCurrentPageEntry->equal(*xEntry))
1271 return;
1273 std::unique_ptr<weld::TreeIter> xParent(xTreeLB->make_iterator(xEntry.get()));
1274 bool bParent = xTreeLB->iter_parent(*xParent);
1276 // If the user has selected a category, automatically switch to a suitable
1277 // default sub-page instead.
1278 if (!bParent)
1279 return;
1281 BuilderPage* pNewPage = nullptr;
1282 OptionsPageInfo* pOptPageInfo = (xCurrentPageEntry && xTreeLB->get_iter_depth(*xCurrentPageEntry))
1283 ? weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xCurrentPageEntry)) : nullptr;
1285 if (pOptPageInfo && pOptPageInfo->m_xPage && pOptPageInfo->m_xPage->IsVisible())
1287 std::unique_ptr<weld::TreeIter> xCurParent(xTreeLB->make_iterator(xCurrentPageEntry.get()));
1288 xTreeLB->iter_parent(*xCurParent);
1290 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xCurParent));
1291 DeactivateRC nLeave = DeactivateRC::LeavePage;
1292 if ( RID_SVXPAGE_COLOR != pOptPageInfo->m_nPageId && pOptPageInfo->m_xPage->HasExchangeSupport() )
1293 nLeave = pOptPageInfo->m_xPage->DeactivatePage( pGroupInfo->m_pOutItemSet.get() );
1295 if ( nLeave == DeactivateRC::KeepPage )
1297 // we cannot leave this page, this is may be from a user clicking a different entry
1298 // in the tree so reselect the current page
1299 xTreeLB->select(*xCurrentPageEntry);
1300 return;
1302 else
1303 pOptPageInfo->m_xPage->set_visible(false);
1305 else if ( pOptPageInfo && pOptPageInfo->m_xExtPage )
1307 pOptPageInfo->m_xExtPage->Hide();
1308 pOptPageInfo->m_xExtPage->DeactivatePage();
1311 OptionsPageInfo *pPageInfo = weld::fromId<OptionsPageInfo*>(xTreeLB->get_id(*xEntry));
1312 OptionsGroupInfo* pGroupInfo = weld::fromId<OptionsGroupInfo*>(xTreeLB->get_id(*xParent));
1313 if(!pPageInfo->m_xPage && pPageInfo->m_nPageId > 0)
1315 InitItemSets(*pGroupInfo);
1317 pPageInfo->m_xPage = ::CreateGeneralTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
1319 if(!pPageInfo->m_xPage && pGroupInfo->m_pModule)
1320 pPageInfo->m_xPage = pGroupInfo->m_pModule->CreateTabPage(pPageInfo->m_nPageId, xTabBox.get(), this, *pGroupInfo->m_pInItemSet);
1322 DBG_ASSERT( pPageInfo->m_xPage, "tabpage could not created");
1323 if ( pPageInfo->m_xPage )
1325 SvtViewOptions aTabPageOpt( EViewType::TabPage, OUString::number( pPageInfo->m_nPageId) );
1326 pPageInfo->m_xPage->SetUserData( GetViewOptUserItem( aTabPageOpt ) );
1327 pPageInfo->m_xPage->SetFrame( m_xFrame );
1328 pPageInfo->m_xPage->Reset( &*pGroupInfo->m_pInItemSet );
1331 else if ( 0 == pPageInfo->m_nPageId && !pPageInfo->m_xExtPage )
1333 if ( !m_xContainerWinProvider.is() )
1335 m_xContainerWinProvider = awt::ContainerWindowProvider::create( ::comphelper::getProcessComponentContext() );
1338 pPageInfo->m_xExtPage = std::make_unique<ExtensionsTabPage>(
1339 xTabBox.get(), pPageInfo->m_sPageURL, pPageInfo->m_sEventHdl, m_xContainerWinProvider);
1342 if ( pPageInfo->m_xPage )
1344 if ( RID_SVXPAGE_COLOR != pPageInfo->m_nPageId &&
1345 pPageInfo->m_xPage->HasExchangeSupport())
1347 pPageInfo->m_xPage->ActivatePage(*pGroupInfo->m_pOutItemSet);
1349 pPageInfo->m_xPage->set_visible(true);
1351 else if ( pPageInfo->m_xExtPage )
1353 pPageInfo->m_xExtPage->Show();
1354 pPageInfo->m_xExtPage->ActivatePage();
1358 OUString sTitleText = sTitle
1359 + " - " + xTreeLB->get_text(*xParent)
1360 + " - " + xTreeLB->get_text(*xEntry);
1361 m_xDialog->set_title(sTitleText);
1364 xCurrentPageEntry = std::move(xEntry);
1366 if ( !bForgetSelection )
1368 if ( !pLastPageSaver )
1369 pLastPageSaver = new LastPageSaver;
1370 if ( !bIsFromExtensionManager )
1371 pLastPageSaver->m_nLastPageId = pPageInfo->m_nPageId;
1372 if ( pPageInfo->m_xExtPage )
1374 if ( bIsFromExtensionManager )
1375 pLastPageSaver->m_sLastPageURL_ExtMgr = pPageInfo->m_sPageURL;
1376 else
1377 pLastPageSaver->m_sLastPageURL_Tools = pPageInfo->m_sPageURL;
1380 pNewPage = pPageInfo->m_xPage.get();
1382 // fdo#58170 use current page's layout child HelpId, unless there isn't a current page
1383 OUString sHelpId(pNewPage ? pNewPage->GetHelpId() : OUString());
1384 if (sHelpId.isEmpty())
1385 sHelpId = HID_OFADLG_TREELISTBOX;
1386 xTreeLB->set_help_id(sHelpId);
1389 std::optional<SfxItemSet> OfaTreeOptionsDialog::CreateItemSet( sal_uInt16 nId )
1391 Reference< XLinguProperties > xProp( LinguMgr::GetLinguPropertySet() );
1392 std::optional<SfxItemSet> pRet;
1393 switch(nId)
1395 case SID_GENERAL_OPTIONS:
1397 pRet.emplace(
1398 SfxGetpApp()->GetPool(),
1399 svl::Items<
1400 SID_HTML_MODE, SID_HTML_MODE,
1401 SID_ATTR_METRIC, SID_ATTR_METRIC,
1402 SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
1403 SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER,
1404 SID_ATTR_YEAR2000, SID_ATTR_YEAR2000> );
1406 SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet( SfxGetpApp()->GetPool() );
1407 SfxApplication::GetOptions(aOptSet);
1408 pRet->Put(aOptSet);
1410 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1411 if ( pViewFrame )
1413 SfxPoolItemHolder aResult;
1414 const SfxItemState aState(pViewFrame->GetDispatcher()->QueryState(SID_ATTR_YEAR2000, aResult));
1415 const SfxUInt16Item* pItem(static_cast<const SfxUInt16Item*>(aResult.getItem()));
1417 // miscellaneous - Year2000
1418 if(SfxItemState::DEFAULT <= aState && nullptr != pItem)
1419 pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, pItem->GetValue() ) );
1420 else
1421 pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
1423 else
1424 pRet->Put( SfxUInt16Item( SID_ATTR_YEAR2000, officecfg::Office::Common::DateFormat::TwoDigitYear::get() ) );
1427 // miscellaneous - Tabulator
1428 pRet->Put(SfxBoolItem(SID_PRINTER_NOTFOUND_WARN, officecfg::Office::Common::Print::Warning::NotFound::get()));
1430 SfxPrinterChangeFlags nFlag = officecfg::Office::Common::Print::Warning::PaperSize::get() ? SfxPrinterChangeFlags::CHG_SIZE : SfxPrinterChangeFlags::NONE;
1431 nFlag |= officecfg::Office::Common::Print::Warning::PaperOrientation::get() ? SfxPrinterChangeFlags::CHG_ORIENTATION : SfxPrinterChangeFlags::NONE;
1432 pRet->Put( SfxFlagItem( SID_PRINTER_CHANGESTODOC, static_cast<int>(nFlag) ));
1435 break;
1436 case SID_LANGUAGE_OPTIONS :
1438 pRet.emplace(
1439 SfxGetpApp()->GetPool(),
1440 svl::Items<
1441 SID_ATTR_CHAR_CJK_LANGUAGE, SID_ATTR_CHAR_CJK_LANGUAGE,
1442 SID_ATTR_CHAR_CTL_LANGUAGE, SID_ATTR_CHAR_CTL_LANGUAGE,
1443 SID_SET_DOCUMENT_LANGUAGE, SID_SET_DOCUMENT_LANGUAGE,
1444 SID_ATTR_LANGUAGE, SID_ATTR_LANGUAGE,
1445 SID_AUTOSPELL_CHECK, SID_AUTOSPELL_CHECK,
1446 SID_OPT_LOCALE_CHANGED, SID_OPT_LOCALE_CHANGED>);
1448 // for linguistic
1449 SfxHyphenRegionItem aHyphen( SID_ATTR_HYPHENREGION );
1451 sal_Int16 nMinLead = 2,
1452 nMinTrail = 2;
1453 if (xProp.is())
1455 nMinLead = xProp->getHyphMinLeading();
1456 nMinTrail = xProp->getHyphMinTrailing();
1458 aHyphen.GetMinLead() = static_cast<sal_uInt8>(nMinLead);
1459 aHyphen.GetMinTrail() = static_cast<sal_uInt8>(nMinTrail);
1461 SfxViewFrame* pViewFrame = SfxViewFrame::Current();
1462 if ( pViewFrame )
1464 SfxPoolItemHolder aResult;
1465 SfxDispatcher* pDispatch(pViewFrame->GetDispatcher());
1467 SfxItemState aState(pDispatch->QueryState(SID_ATTR_LANGUAGE, aResult));
1468 if(SfxItemState::DEFAULT <= aState)
1469 pRet->Put(*aResult.getItem());
1471 aState = pDispatch->QueryState(SID_ATTR_CHAR_CJK_LANGUAGE, aResult);
1472 if(SfxItemState::DEFAULT <= aState)
1473 pRet->Put(*aResult.getItem());
1475 aState = pDispatch->QueryState(SID_ATTR_CHAR_CTL_LANGUAGE, aResult);
1476 if(SfxItemState::DEFAULT <= aState)
1477 pRet->Put(*aResult.getItem());
1479 pRet->Put(aHyphen);
1481 aState = pDispatch->QueryState(SID_AUTOSPELL_CHECK, aResult);
1482 if(SfxItemState::DEFAULT <= aState)
1484 pRet->Put(*aResult.getItem()); // allow share/refcounting
1485 // pRet->Put(std::unique_ptr<SfxPoolItem>(aResult.getItem()->Clone()));
1487 else
1489 bool bVal = false;
1490 if (xProp.is())
1492 bVal = xProp->getIsSpellAuto();
1495 pRet->Put(SfxBoolItem(SID_AUTOSPELL_CHECK, bVal));
1498 pRet->Put( SfxBoolItem( SID_SET_DOCUMENT_LANGUAGE, bIsForSetDocumentLanguage ) );
1500 break;
1501 case SID_INET_DLG :
1502 pRet.emplace( SfxGetpApp()->GetPool(),
1503 svl::Items<
1504 //SID_OPTIONS_START - ..END
1505 SID_SAVEREL_INET, SID_SAVEREL_FSYS,
1506 SID_INET_NOPROXY, SID_INET_HTTP_PROXY_PORT,
1507 SID_SECURE_URL, SID_SECURE_URL> );
1508 SfxApplication::GetOptions(*pRet);
1509 break;
1510 case SID_FILTER_DLG:
1511 pRet.emplace(
1512 SfxGetpApp()->GetPool(),
1513 svl::Items<
1514 SID_ATTR_WARNALIENFORMAT, SID_ATTR_WARNALIENFORMAT,
1515 SID_ATTR_DOCINFO, SID_ATTR_AUTOSAVEMINUTE,
1516 SID_SAVEREL_INET, SID_SAVEREL_FSYS,
1517 SID_ATTR_PRETTYPRINTING, SID_ATTR_PRETTYPRINTING> );
1518 SfxApplication::GetOptions(*pRet);
1519 break;
1521 case SID_SB_STARBASEOPTIONS:
1522 pRet.emplace( SfxGetpApp()->GetPool(),
1523 svl::Items<SID_SB_POOLING_ENABLED, SID_SB_DB_REGISTER> );
1524 ::offapp::ConnectionPoolConfig::GetOptions(*pRet);
1525 svx::DbRegisteredNamesConfig::GetOptions(*pRet);
1526 break;
1528 case SID_SCH_EDITOPTIONS:
1530 pRet.emplace( SfxGetpApp()->GetPool(), svl::Items<SID_SCH_EDITOPTIONS, SID_SCH_EDITOPTIONS> );
1531 pRet->Put( SvxChartColorTableItem( SID_SCH_EDITOPTIONS, SvxChartOptions::GetDefaultColors() ) );
1532 break;
1535 return pRet;
1538 void OfaTreeOptionsDialog::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet )
1540 switch(nId)
1542 case SID_GENERAL_OPTIONS:
1544 std::shared_ptr<comphelper::ConfigurationChanges> batch(comphelper::ConfigurationChanges::create());
1546 SfxItemSetFixed<SID_ATTR_QUICKLAUNCHER, SID_ATTR_QUICKLAUNCHER> aOptSet(SfxGetpApp()->GetPool());
1547 aOptSet.Put(rSet);
1548 if(aOptSet.Count())
1549 SfxApplication::SetOptions( aOptSet );
1550 // get dispatcher anew, because SetOptions() might have destroyed the dispatcher
1551 SfxViewFrame *pViewFrame = SfxViewFrame::Current();
1553 // evaluate Year2000
1554 sal_uInt16 nY2K = USHRT_MAX;
1555 const SfxUInt16Item* pYearItem = rSet.GetItemIfSet( SID_ATTR_YEAR2000, false );
1556 if( pYearItem )
1557 nY2K = pYearItem->GetValue();
1558 if( USHRT_MAX != nY2K )
1560 if ( pViewFrame )
1562 SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
1563 pDispatch->ExecuteList(SID_ATTR_YEAR2000,
1564 SfxCallMode::ASYNCHRON, { pYearItem });
1566 officecfg::Office::Common::DateFormat::TwoDigitYear::set(nY2K, batch);
1569 // evaluate print
1570 if(const SfxBoolItem* pWarnItem = rSet.GetItemIfSet(SID_PRINTER_NOTFOUND_WARN, false))
1571 officecfg::Office::Common::Print::Warning::NotFound::set(pWarnItem->GetValue(), batch);
1573 if(const SfxFlagItem* pFlag = rSet.GetItemIfSet(SID_PRINTER_CHANGESTODOC, false))
1575 bool bPaperSizeWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_SIZE);
1576 officecfg::Office::Common::Print::Warning::PaperSize::set(bPaperSizeWarning, batch);
1577 bool bPaperOrientationWarning = bool(static_cast<SfxPrinterChangeFlags>(pFlag->GetValue()) & SfxPrinterChangeFlags::CHG_ORIENTATION);
1578 officecfg::Office::Common::Print::Warning::PaperOrientation::set(bPaperOrientationWarning, batch);
1581 // evaluate help options
1582 bool bHelpTips = officecfg::Office::Common::Help::Tip::get();
1583 if ( bHelpTips != Help::IsQuickHelpEnabled() )
1584 bHelpTips ? Help::EnableQuickHelp() : Help::DisableQuickHelp();
1585 bool bExtendedHelp = officecfg::Office::Common::Help::ExtendedTip::get();
1586 if ( bExtendedHelp != Help::IsBalloonHelpEnabled() )
1587 bExtendedHelp ? Help::EnableBalloonHelp() : Help::DisableBalloonHelp();
1589 batch->commit();
1591 break;
1592 case SID_LANGUAGE_OPTIONS :
1594 OfaTreeOptionsDialog::ApplyLanguageOptions(rSet);
1596 break;
1597 case SID_INET_DLG :
1598 case SID_FILTER_DLG:
1599 SfxApplication::SetOptions( rSet );
1600 break;
1602 case SID_SB_STARBASEOPTIONS:
1603 ::offapp::ConnectionPoolConfig::SetOptions( rSet );
1604 svx::DbRegisteredNamesConfig::SetOptions(rSet);
1605 break;
1607 case SID_SCH_EDITOPTIONS:
1608 // nothing to do. Chart options only apply to newly created charts
1609 break;
1611 default:
1613 SAL_WARN("cui.options", "Unhandled option in ApplyItemSet");
1615 break;
1619 void OfaTreeOptionsDialog::ApplyLanguageOptions(const SfxItemSet& rSet)
1621 bool bSaveSpellCheck = false;
1622 const SfxPoolItem* pItem = nullptr;
1624 const Reference< XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
1625 Reference< XLinguProperties > xProp = LinguProperties::create( xContext );
1626 if ( const SfxHyphenRegionItem* pHyphenItem = rSet.GetItemIfSet(SID_ATTR_HYPHENREGION, false ) )
1628 xProp->setHyphMinLeading( static_cast<sal_Int16>(pHyphenItem->GetMinLead()) );
1629 xProp->setHyphMinTrailing( static_cast<sal_Int16>(pHyphenItem->GetMinTrail()) );
1630 bSaveSpellCheck = true;
1633 SfxViewFrame *pViewFrame = SfxViewFrame::Current();
1634 if ( pViewFrame )
1636 SfxDispatcher* pDispatch = pViewFrame->GetDispatcher();
1637 pItem = nullptr;
1638 if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_LANGUAGE, false, &pItem ))
1640 pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
1641 bSaveSpellCheck = true;
1643 if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CTL_LANGUAGE, false, &pItem ))
1645 pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
1646 bSaveSpellCheck = true;
1648 if(SfxItemState::SET == rSet.GetItemState( SID_ATTR_CHAR_CJK_LANGUAGE, false, &pItem ))
1650 pDispatch->ExecuteList(pItem->Which(), SfxCallMode::SYNCHRON, { pItem });
1651 bSaveSpellCheck = true;
1654 if( SfxItemState::SET == rSet.GetItemState(SID_AUTOSPELL_CHECK, false, &pItem ))
1656 bool bOnlineSpelling = static_cast<const SfxBoolItem*>(pItem)->GetValue();
1657 pDispatch->ExecuteList(SID_AUTOSPELL_CHECK,
1658 SfxCallMode::ASYNCHRON|SfxCallMode::RECORD, { pItem });
1660 xProp->setIsSpellAuto( bOnlineSpelling );
1663 if( bSaveSpellCheck )
1665 //! the config item has changed since we modified the
1666 //! property set it uses
1667 pDispatch->Execute(SID_SPELLCHECKER_CHANGED, SfxCallMode::ASYNCHRON);
1671 if( SfxItemState::SET == rSet.GetItemState(SID_OPT_LOCALE_CHANGED, false, &pItem ))
1673 SfxViewFrame* _pViewFrame = SfxViewFrame::GetFirst();
1674 while ( _pViewFrame )
1676 _pViewFrame->GetDispatcher()->ExecuteList(pItem->Which(),
1677 SfxCallMode::ASYNCHRON, { pItem });
1678 _pViewFrame = SfxViewFrame::GetNext( *_pViewFrame );
1683 OUString OfaTreeOptionsDialog::getCurrentFactory_Impl( const Reference< XFrame >& _xFrame )
1685 OUString sIdentifier;
1686 Reference < XFrame > xCurrentFrame( _xFrame );
1687 Reference < XModuleManager2 > xModuleManager = ModuleManager::create(::comphelper::getProcessComponentContext());
1688 if ( !xCurrentFrame.is() )
1690 Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
1691 xCurrentFrame = xDesktop->getCurrentFrame();
1694 if ( xCurrentFrame.is() )
1698 sIdentifier = xModuleManager->identify( xCurrentFrame );
1700 catch ( css::frame::UnknownModuleException& )
1702 SAL_INFO( "cui.options", "unknown module" );
1704 catch ( Exception const & )
1706 TOOLS_WARN_EXCEPTION( "cui.options", "getActiveModule_Impl(): exception of XModuleManager::identify()" );
1710 return sIdentifier;
1713 void OfaTreeOptionsDialog::generalOptions(const std::vector<sal_uInt16>& vPageId)
1715 SvtOptionsDialogOptions aOptionsDlgOpt;
1716 if ( !lcl_isOptionHidden( SID_GENERAL_OPTIONS, aOptionsDlgOpt ) )
1718 setGroupName(u"ProductName", CuiResId(SID_GENERAL_OPTIONS_RES[0].first));
1719 sal_uInt16 nGroup = AddGroup(CuiResId(SID_GENERAL_OPTIONS_RES[0].first), nullptr, nullptr, SID_GENERAL_OPTIONS );
1721 for (size_t i = 1; i < std::size(SID_GENERAL_OPTIONS_RES); ++i)
1723 OUString sNewTitle = CuiResId(SID_GENERAL_OPTIONS_RES[i].first);
1724 sal_uInt16 nPageId = SID_GENERAL_OPTIONS_RES[i].second;
1725 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1726 continue;
1728 // Disable Online Update page if neither mode is available
1729 if( RID_SVXPAGE_ONLINEUPDATE == nPageId
1730 && !(SvxOnlineUpdateTabPage::isTraditionalOnlineUpdateAvailable()
1731 || SvxOnlineUpdateTabPage::isMarOnlineUpdateAvailable()) )
1733 continue;
1736 if (!vPageId.empty())
1738 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1739 AddTabPage(nPageId, sNewTitle, nGroup);
1741 else
1742 AddTabPage(nPageId, sNewTitle, nGroup);
1747 void OfaTreeOptionsDialog::loadAndSaveOptions(const std::vector<sal_uInt16>& vPageId)
1749 SvtOptionsDialogOptions aOptionsDlgOpt;
1750 if ( !lcl_isOptionHidden( SID_FILTER_DLG, aOptionsDlgOpt ) )
1752 setGroupName( u"LoadSave", CuiResId(SID_FILTER_DLG_RES[0].first) );
1753 sal_uInt16 nGroup = AddGroup( CuiResId(SID_FILTER_DLG_RES[0].first), nullptr, nullptr, SID_FILTER_DLG );
1754 for ( size_t i = 1; i < std::size(SID_FILTER_DLG_RES); ++i )
1756 sal_uInt16 nPageId = SID_FILTER_DLG_RES[i].second;
1757 if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1759 if (!vPageId.empty())
1761 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1762 AddTabPage(nPageId, CuiResId(SID_FILTER_DLG_RES[i].first), nGroup);
1764 else
1765 AddTabPage(nPageId, CuiResId(SID_FILTER_DLG_RES[i].first), nGroup);
1771 void OfaTreeOptionsDialog::languageOptions(const std::vector<sal_uInt16>& vPageId)
1773 SvtOptionsDialogOptions aOptionsDlgOpt;
1774 if ( !lcl_isOptionHidden( SID_LANGUAGE_OPTIONS, aOptionsDlgOpt ) )
1776 setGroupName(u"LanguageSettings", CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first));
1777 sal_uInt16 nGroup = AddGroup(CuiResId(SID_LANGUAGE_OPTIONS_RES[0].first), nullptr, nullptr, SID_LANGUAGE_OPTIONS );
1778 for (size_t i = 1; i < std::size(SID_LANGUAGE_OPTIONS_RES); ++i)
1780 sal_uInt16 nPageId = SID_LANGUAGE_OPTIONS_RES[i].second;
1781 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1782 continue;
1784 // Disable DeepL translation settings, if experimental mode is not enabled
1785 if( RID_SVXPAGE_DEEPL_OPTIONS == nPageId )
1787 if( ! officecfg::Office::Common::Misc::ExperimentalMode::get() )
1788 continue;
1791 if ( ( RID_SVXPAGE_JSEARCH_OPTIONS != nPageId || SvtCJKOptions::IsJapaneseFindEnabled() ) &&
1792 ( RID_SVXPAGE_ASIAN_LAYOUT != nPageId || SvtCJKOptions::IsAsianTypographyEnabled() ) &&
1793 ( RID_SVXPAGE_OPTIONS_CTL != nPageId || SvtCTLOptions::IsCTLFontEnabled() ) )
1795 if (!vPageId.empty())
1797 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1798 AddTabPage(nPageId, CuiResId(SID_LANGUAGE_OPTIONS_RES[i].first), nGroup);
1800 else
1801 AddTabPage(nPageId, CuiResId(SID_LANGUAGE_OPTIONS_RES[i].first), nGroup);
1807 void OfaTreeOptionsDialog::writerOptions(const std::vector<sal_uInt16>& vPageId)
1809 if (SvtModuleOptions().IsWriterInstalled())
1811 // text document
1812 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
1813 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
1814 if ( aFactory == "com.sun.star.text.TextDocument"
1815 || aFactory == "com.sun.star.text.WebDocument"
1816 || aFactory == "com.sun.star.text.GlobalDocument" )
1818 SvtOptionsDialogOptions aOptionsDlgOpt;
1819 if ( !lcl_isOptionHidden( SID_SW_EDITOPTIONS, aOptionsDlgOpt ) )
1821 if ( aFactory == "com.sun.star.text.WebDocument" )
1822 setGroupName( u"WriterWeb", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
1823 else
1824 setGroupName( u"Writer", CuiResId(SID_SW_EDITOPTIONS_RES[0].first) );
1825 SfxModule* pSwMod = SfxApplication::GetModule(SfxToolsModule::Writer);
1826 sal_uInt16 nGroup = AddGroup(CuiResId(SID_SW_EDITOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_EDITOPTIONS );
1827 SvtCTLOptions aCTLLanguageOptions;
1828 for ( size_t i = 1; i < std::size(SID_SW_EDITOPTIONS_RES); ++i )
1830 sal_uInt16 nPageId = SID_SW_EDITOPTIONS_RES[i].second;
1831 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1832 continue;
1833 if ( ( RID_SW_TP_STD_FONT_CJK != nPageId || SvtCJKOptions::IsCJKFontEnabled() ) &&
1834 ( RID_SW_TP_STD_FONT_CTL != nPageId || SvtCTLOptions::IsCTLFontEnabled() ) &&
1835 ( RID_SW_TP_MAILCONFIG != nPageId || MailMergeCfgIsEmailSupported() ) )
1837 if (!vPageId.empty())
1839 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1840 AddTabPage(nPageId, CuiResId(SID_SW_EDITOPTIONS_RES[i].first),
1841 nGroup);
1843 else
1844 AddTabPage(nPageId, CuiResId(SID_SW_EDITOPTIONS_RES[i].first), nGroup);
1847 #ifdef DBG_UTIL
1848 if (!vPageId.empty())
1850 if (std::find(vPageId.begin(), vPageId.end(), RID_SW_TP_OPTTEST_PAGE)
1851 != vPageId.end())
1852 AddTabPage(RID_SW_TP_OPTTEST_PAGE, u"Internal Test"_ustr, nGroup);
1854 else
1855 AddTabPage(RID_SW_TP_OPTTEST_PAGE, u"Internal Test"_ustr, nGroup);
1856 #endif
1862 void OfaTreeOptionsDialog::writerWebOptions(const std::vector<sal_uInt16>& vPageId)
1864 if (SvtModuleOptions().IsWriterInstalled())
1866 // text document
1867 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
1868 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
1869 if ( aFactory == "com.sun.star.text.TextDocument"
1870 || aFactory == "com.sun.star.text.WebDocument"
1871 || aFactory == "com.sun.star.text.GlobalDocument" )
1873 // HTML documents
1874 SvtOptionsDialogOptions aOptionsDlgOpt;
1875 if ( !lcl_isOptionHidden( SID_SW_ONLINEOPTIONS, aOptionsDlgOpt ) )
1877 SfxModule* pSwMod = SfxApplication::GetModule(SfxToolsModule::Writer);
1878 sal_uInt16 nGroup = AddGroup(CuiResId(SID_SW_ONLINEOPTIONS_RES[0].first), pSwMod, pSwMod, SID_SW_ONLINEOPTIONS );
1879 for( size_t i = 1; i < std::size(SID_SW_ONLINEOPTIONS_RES); ++i )
1881 sal_uInt16 nPageId = SID_SW_ONLINEOPTIONS_RES[i].second;
1882 if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1884 if (!vPageId.empty())
1886 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1887 AddTabPage(nPageId, CuiResId(SID_SW_ONLINEOPTIONS_RES[i].first),
1888 nGroup);
1890 else
1891 AddTabPage(nPageId, CuiResId(SID_SW_ONLINEOPTIONS_RES[i].first),
1892 nGroup);
1895 #ifdef DBG_UTIL
1896 if (!vPageId.empty())
1898 if (std::find(vPageId.begin(), vPageId.end(), RID_SW_TP_OPTTEST_PAGE)
1899 != vPageId.end())
1900 AddTabPage(RID_SW_TP_OPTTEST_PAGE, u"Internal Test"_ustr, nGroup);
1902 else
1903 AddTabPage(RID_SW_TP_OPTTEST_PAGE, u"Internal Test"_ustr, nGroup);
1904 #endif
1910 void OfaTreeOptionsDialog::calcOptions(const std::vector<sal_uInt16>& vPageId)
1912 // Calc options
1913 if (SvtModuleOptions().IsCalcInstalled())
1915 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
1916 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
1917 if ( aFactory == "com.sun.star.sheet.SpreadsheetDocument" )
1919 SvtOptionsDialogOptions aOptionsDlgOpt;
1920 if ( !lcl_isOptionHidden( SID_SC_EDITOPTIONS, aOptionsDlgOpt ) )
1922 SfxModule* pScMod = SfxApplication::GetModule( SfxToolsModule::Calc );
1923 setGroupName( u"Calc", CuiResId(SID_SC_EDITOPTIONS_RES[0].first) );
1924 sal_uInt16 nGroup = AddGroup( CuiResId(SID_SC_EDITOPTIONS_RES[0].first), pScMod, pScMod, SID_SC_EDITOPTIONS );
1925 for (size_t i = 1; i < std::size(SID_SC_EDITOPTIONS_RES); ++i)
1927 sal_uInt16 nPageId = SID_SC_EDITOPTIONS_RES[i].second;
1928 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1929 continue;
1931 if (!vPageId.empty())
1933 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1934 AddTabPage(nPageId, CuiResId(SID_SC_EDITOPTIONS_RES[i].first), nGroup);
1936 else
1937 AddTabPage(nPageId, CuiResId(SID_SC_EDITOPTIONS_RES[i].first), nGroup);
1944 void OfaTreeOptionsDialog::impressOptions(const std::vector<sal_uInt16>& vPageId)
1946 // Impress options
1947 if (SvtModuleOptions().IsImpressInstalled())
1949 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
1950 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
1951 if ( aFactory == "com.sun.star.presentation.PresentationDocument" )
1953 SvtOptionsDialogOptions aOptionsDlgOpt;
1954 if ( !lcl_isOptionHidden( SID_SD_EDITOPTIONS, aOptionsDlgOpt ) )
1956 SfxModule* pSdMod = SfxApplication::GetModule(SfxToolsModule::Draw);
1957 setGroupName( u"Impress", CuiResId(SID_SD_EDITOPTIONS_RES[0].first) );
1958 sal_uInt16 nGroup = AddGroup( CuiResId(SID_SD_EDITOPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_EDITOPTIONS );
1959 for (size_t i = 1; i < std::size(SID_SD_EDITOPTIONS_RES); ++i)
1961 sal_uInt16 nPageId = SID_SD_EDITOPTIONS_RES[i].second;
1962 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1963 continue;
1965 if (!vPageId.empty())
1967 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
1968 AddTabPage(nPageId, CuiResId(SID_SD_EDITOPTIONS_RES[i].first), nGroup);
1970 else
1971 AddTabPage(nPageId, CuiResId(SID_SD_EDITOPTIONS_RES[i].first), nGroup);
1978 void OfaTreeOptionsDialog::drawOptions(const std::vector<sal_uInt16>& vPageId)
1980 // Draw options
1981 if (SvtModuleOptions().IsDrawInstalled())
1983 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
1984 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
1985 if ( aFactory == "com.sun.star.drawing.DrawingDocument" )
1987 SvtOptionsDialogOptions aOptionsDlgOpt;
1988 if ( !lcl_isOptionHidden( SID_SD_GRAPHIC_OPTIONS, aOptionsDlgOpt ) )
1990 SfxModule* pSdMod = SfxApplication::GetModule(SfxToolsModule::Draw);
1991 setGroupName( u"Draw", CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first) );
1992 sal_uInt16 nGroup = AddGroup( CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[0].first), pSdMod, pSdMod, SID_SD_GRAPHIC_OPTIONS );
1993 for (size_t i = 1; i < std::size(SID_SD_GRAPHIC_OPTIONS_RES); ++i)
1995 sal_uInt16 nPageId = SID_SD_GRAPHIC_OPTIONS_RES[i].second;
1996 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
1997 continue;
1999 if (!vPageId.empty())
2001 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
2002 AddTabPage(nPageId, CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[i].first),
2003 nGroup);
2005 else
2006 AddTabPage(nPageId, CuiResId(SID_SD_GRAPHIC_OPTIONS_RES[i].first), nGroup);
2013 void OfaTreeOptionsDialog::mathOptions(const std::vector<sal_uInt16>& vPageId)
2015 // Math options
2016 if (SvtModuleOptions().IsMathInstalled())
2018 OUString aFactory = getCurrentFactory_Impl(m_xFrame);
2019 DBG_ASSERT(GetModuleIdentifier(m_xFrame) == aFactory, "This should not happen");
2020 if ( aFactory == "com.sun.star.formula.FormulaProperties" )
2022 SvtOptionsDialogOptions aOptionsDlgOpt;
2023 if ( !lcl_isOptionHidden( SID_SM_EDITOPTIONS, aOptionsDlgOpt ) )
2025 SfxModule* pSmMod = SfxApplication::GetModule(SfxToolsModule::Math);
2026 setGroupName( u"Math", CuiResId(SID_SM_EDITOPTIONS_RES[0].first) );
2027 sal_uInt16 nGroup = AddGroup(CuiResId(SID_SM_EDITOPTIONS_RES[0].first), pSmMod, pSmMod, SID_SM_EDITOPTIONS );
2028 for ( size_t i = 1; i < std::size(SID_SM_EDITOPTIONS_RES); ++i )
2030 sal_uInt16 nPageId = SID_SM_EDITOPTIONS_RES[i].second;
2031 if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
2033 if (!vPageId.empty())
2035 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
2036 AddTabPage(nPageId, CuiResId(SID_SM_EDITOPTIONS_RES[i].first),
2037 nGroup);
2039 else
2040 AddTabPage(nPageId, CuiResId(SID_SM_EDITOPTIONS_RES[i].first), nGroup);
2048 void OfaTreeOptionsDialog::databaseOptions(const std::vector<sal_uInt16>& vPageId)
2050 SvtOptionsDialogOptions aOptionsDlgOpt;
2051 SvtModuleOptions aModuleOpt;
2053 // Database - needed only if there is an application which integrates with databases
2054 if ( !lcl_isOptionHidden( SID_SB_STARBASEOPTIONS, aOptionsDlgOpt ) &&
2055 ( aModuleOpt.IsDataBaseInstalled()
2056 || aModuleOpt.IsWriterInstalled()
2057 || aModuleOpt.IsCalcInstalled()
2060 setGroupName( u"Base", CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first) );
2061 sal_uInt16 nGroup = AddGroup( CuiResId(SID_SB_STARBASEOPTIONS_RES[0].first), nullptr, nullptr, SID_SB_STARBASEOPTIONS );
2062 for ( size_t i = 1; i < std::size(SID_SB_STARBASEOPTIONS_RES); ++i )
2064 sal_uInt16 nPageId = SID_SB_STARBASEOPTIONS_RES[i].second;
2065 if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
2067 if (!vPageId.empty())
2069 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
2070 AddTabPage(nPageId, CuiResId(SID_SB_STARBASEOPTIONS_RES[i].first), nGroup);
2072 else
2073 AddTabPage(nPageId, CuiResId(SID_SB_STARBASEOPTIONS_RES[i].first), nGroup);
2079 void OfaTreeOptionsDialog::chartOptions(const std::vector<sal_uInt16>& vPageId)
2081 SvtOptionsDialogOptions aOptionsDlgOpt;
2083 if ( !lcl_isOptionHidden( SID_SCH_EDITOPTIONS, aOptionsDlgOpt ) )
2085 setGroupName( u"Charts", CuiResId(SID_SCH_EDITOPTIONS_RES[0].first) );
2086 sal_uInt16 nGroup = AddGroup( CuiResId(SID_SCH_EDITOPTIONS_RES[0].first), nullptr, nullptr, SID_SCH_EDITOPTIONS );
2087 for ( size_t i = 1; i < std::size(SID_SCH_EDITOPTIONS_RES); ++i )
2089 sal_uInt16 nPageId = SID_SCH_EDITOPTIONS_RES[i].second;
2090 if ( !lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
2092 if (!vPageId.empty())
2094 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
2095 AddTabPage(nPageId, CuiResId(SID_SCH_EDITOPTIONS_RES[i].first), nGroup);
2097 else
2098 AddTabPage(nPageId, CuiResId(SID_SCH_EDITOPTIONS_RES[i].first), nGroup);
2104 void OfaTreeOptionsDialog::internetOptions(const std::vector<sal_uInt16>& vPageId)
2106 SvtOptionsDialogOptions aOptionsDlgOpt;
2108 if ( lcl_isOptionHidden( SID_INET_DLG, aOptionsDlgOpt ) )
2109 return;
2111 setGroupName(u"Internet", CuiResId(SID_INET_DLG_RES[0].first));
2112 sal_uInt16 nGroup = AddGroup(CuiResId(SID_INET_DLG_RES[0].first), nullptr, nullptr, SID_INET_DLG );
2114 for ( size_t i = 1; i < std::size(SID_INET_DLG_RES); ++i )
2116 sal_uInt16 nPageId = SID_INET_DLG_RES[i].second;
2117 if ( lcl_isOptionHidden( nPageId, aOptionsDlgOpt ) )
2118 continue;
2119 #if defined(_WIN32)
2120 // Disable E-mail tab-page on Windows
2121 if ( nPageId == RID_SVXPAGE_INET_MAIL )
2122 continue;
2123 #endif
2124 if (!vPageId.empty())
2126 if (std::find(vPageId.begin(), vPageId.end(), nPageId) != vPageId.end())
2127 AddTabPage(nPageId, CuiResId(SID_INET_DLG_RES[i].first), nGroup);
2129 else
2130 AddTabPage(nPageId, CuiResId(SID_INET_DLG_RES[i].first), nGroup);
2134 void OfaTreeOptionsDialog::Initialize(const Reference<XFrame>& _xFrame)
2136 m_xFrame = _xFrame;
2138 // %PRODUCTNAME options
2139 generalOptions();
2141 // Load and Save options
2142 loadAndSaveOptions();
2144 // Language options
2145 languageOptions();
2147 // Writer and Writer/Web options
2148 writerOptions();
2149 writerWebOptions();
2151 // Calc options
2152 calcOptions();
2154 // Impress options
2155 impressOptions();
2157 // Draw options
2158 drawOptions();
2160 // Math options
2161 mathOptions();
2163 // Database - needed only if there is an application which integrates with databases
2164 databaseOptions();
2166 // Chart options (always installed and active)
2167 chartOptions();
2169 // Internet options
2170 internetOptions();
2172 // store Options Dialogs with their page names and strings
2173 // in order to use them when searching
2174 storeOptionsTree();
2177 static bool isNodeActive( OptionsNode const * pNode, Module* pModule )
2179 if ( !pNode )
2180 return false;
2182 // Node for all modules active?
2183 if ( pNode->m_bAllModules )
2184 return true;
2186 // OOo-Nodes (Writer, Calc, Impress...) are active if node is already inserted
2187 if ( !getGroupName( pNode->m_sId, false ).isEmpty() )
2188 return true;
2190 // no module -> not active
2191 if ( !pModule )
2192 return false;
2194 // search node in active module
2195 if ( pModule->m_bActive )
2197 for (auto const& j : pModule->m_aNodeList)
2198 if ( j->m_sId == pNode->m_sId )
2199 return true;
2201 return false;
2204 void OfaTreeOptionsDialog::LoadExtensionOptions( std::u16string_view rExtensionId )
2206 std::unique_ptr<Module> pModule;
2208 // when called by Tools - Options then load nodes of active module
2209 if ( rExtensionId.empty() )
2211 pModule = LoadModule( GetModuleIdentifier( Reference< XFrame >() ) );
2214 VectorOfNodes aNodeList = LoadNodes( pModule.get(), rExtensionId );
2215 InsertNodes( aNodeList );
2218 OUString OfaTreeOptionsDialog::GetModuleIdentifier( const Reference< XFrame >& rFrame )
2220 OUString sModule;
2221 Reference < XFrame > xCurrentFrame( rFrame );
2222 const Reference< XComponentContext >& xContext = comphelper::getProcessComponentContext();
2223 Reference < XModuleManager2 > xModuleManager = ModuleManager::create(xContext);
2225 if ( !xCurrentFrame.is() )
2227 Reference < XDesktop2 > xDesktop = Desktop::create( xContext );
2228 xCurrentFrame = xDesktop->getCurrentFrame();
2231 if ( xCurrentFrame.is() )
2235 sModule = xModuleManager->identify( xCurrentFrame );
2237 catch ( css::frame::UnknownModuleException& )
2239 SAL_INFO( "cui.options", "unknown module" );
2241 catch ( Exception const & )
2243 TOOLS_WARN_EXCEPTION( "cui.options", "OfaTreeOptionsDialog::GetModuleIdentifier(): exception of XModuleManager::identify()");
2246 return sModule;
2249 std::unique_ptr<Module> OfaTreeOptionsDialog::LoadModule(
2250 std::u16string_view rModuleIdentifier )
2252 std::unique_ptr<Module> pModule;
2253 Reference< XNameAccess > xSet(
2254 officecfg::Office::OptionsDialog::Modules::get());
2256 const Sequence< OUString > seqNames = xSet->getElementNames();
2257 for ( const OUString& rModule : seqNames )
2259 if ( rModuleIdentifier == rModule )
2261 // current active module found
2262 pModule.reset(new Module);
2263 pModule->m_bActive = true;
2265 Reference< XNameAccess > xModAccess;
2266 xSet->getByName( rModule ) >>= xModAccess;
2267 if ( xModAccess.is() )
2269 // load the nodes of this module
2270 Reference< XNameAccess > xNodeAccess;
2271 xModAccess->getByName( u"Nodes"_ustr ) >>= xNodeAccess;
2272 if ( xNodeAccess.is() )
2274 const Sequence< OUString > xTemp = xNodeAccess->getElementNames();
2275 Reference< XNameAccess > xAccess;
2276 sal_Int32 nIndex = -1;
2277 for ( const OUString& rNode : xTemp)
2279 xNodeAccess->getByName( rNode ) >>= xAccess;
2280 if ( xAccess.is() )
2282 xAccess->getByName( u"Index"_ustr ) >>= nIndex;
2283 if ( nIndex < 0 )
2284 // append nodes with index < 0
2285 pModule->m_aNodeList.push_back(
2286 std::unique_ptr<OrderedEntry>(new OrderedEntry(nIndex, rNode)));
2287 else
2289 // search position of the node
2290 std::vector<OrderedEntry *>::size_type y = 0;
2291 for ( ; y < pModule->m_aNodeList.size(); ++y )
2293 sal_Int32 nNodeIdx = pModule->m_aNodeList[y]->m_nIndex;
2294 if ( nNodeIdx < 0 || nNodeIdx > nIndex )
2295 break;
2297 // and insert the node on this position
2298 pModule->m_aNodeList.insert(
2299 pModule->m_aNodeList.begin() + y,
2300 std::unique_ptr<OrderedEntry>(new OrderedEntry( nIndex, rNode )) );
2306 break;
2309 return pModule;
2312 VectorOfNodes OfaTreeOptionsDialog::LoadNodes(
2313 Module* pModule, std::u16string_view rExtensionId)
2315 VectorOfNodes aOutNodeList;
2317 Reference< XNameAccess > xSet(
2318 officecfg::Office::OptionsDialog::Nodes::get());
2319 VectorOfNodes aNodeList;
2320 const Sequence< OUString > seqNames = xSet->getElementNames();
2322 for ( OUString const & sGroupName : seqNames )
2324 Reference< XNameAccess > xNodeAccess;
2325 xSet->getByName( sGroupName ) >>= xNodeAccess;
2327 if ( xNodeAccess.is() )
2329 OUString sNodeId, sLabel, sPageURL;
2330 bool bAllModules = false;
2332 sNodeId = sGroupName;
2333 xNodeAccess->getByName( u"Label"_ustr ) >>= sLabel;
2334 xNodeAccess->getByName( u"OptionsPage"_ustr ) >>= sPageURL;
2335 xNodeAccess->getByName( u"AllModules"_ustr ) >>= bAllModules;
2337 if ( sLabel.isEmpty() )
2338 sLabel = sGroupName;
2339 OUString sTemp = getGroupName( sLabel, !rExtensionId.empty() );
2340 if ( !sTemp.isEmpty() )
2341 sLabel = sTemp;
2342 std::unique_ptr<OptionsNode> pNode(new OptionsNode(sNodeId, sLabel, bAllModules));
2344 if ( rExtensionId.empty() && !isNodeActive( pNode.get(), pModule ) )
2346 continue;
2349 Reference< XNameAccess > xLeavesSet;
2350 xNodeAccess->getByName( u"Leaves"_ustr ) >>= xLeavesSet;
2351 if ( xLeavesSet.is() )
2353 const Sequence< OUString > seqLeaves = xLeavesSet->getElementNames();
2354 for ( OUString const & leafName : seqLeaves )
2356 Reference< XNameAccess > xLeaveAccess;
2357 xLeavesSet->getByName( leafName ) >>= xLeaveAccess;
2359 if ( xLeaveAccess.is() )
2361 OUString sId, sLeafLabel, sEventHdl, sLeafURL, sLeafGrpId;
2362 sal_Int32 nLeafGrpIdx = 0;
2364 xLeaveAccess->getByName( u"Id"_ustr ) >>= sId;
2365 xLeaveAccess->getByName( u"Label"_ustr ) >>= sLeafLabel;
2366 xLeaveAccess->getByName( u"OptionsPage"_ustr ) >>= sLeafURL;
2367 xLeaveAccess->getByName( u"EventHandlerService"_ustr ) >>= sEventHdl;
2368 xLeaveAccess->getByName( u"GroupId"_ustr ) >>= sLeafGrpId;
2369 xLeaveAccess->getByName( u"GroupIndex"_ustr ) >>= nLeafGrpIdx;
2371 if ( rExtensionId.empty() || sId == rExtensionId )
2373 std::unique_ptr<OptionsLeaf> pLeaf(new OptionsLeaf(
2374 sLeafLabel, sLeafURL, sEventHdl, sLeafGrpId, nLeafGrpIdx ));
2376 if ( !sLeafGrpId.isEmpty() )
2378 bool bAlreadyOpened = false;
2379 if ( !pNode->m_aGroupedLeaves.empty() )
2381 for (auto & rGroup : pNode->m_aGroupedLeaves)
2383 if ( !rGroup.empty() &&
2384 rGroup[0]->m_sGroupId == sLeafGrpId )
2386 std::vector<std::unique_ptr<OptionsLeaf>>::size_type l = 0;
2387 for ( ; l < rGroup.size(); ++l )
2389 if ( rGroup[l]->m_nGroupIndex >= nLeafGrpIdx )
2390 break;
2392 rGroup.insert( rGroup.begin() + l, std::move(pLeaf) );
2393 bAlreadyOpened = true;
2394 break;
2398 if ( !bAlreadyOpened )
2400 std::vector< std::unique_ptr<OptionsLeaf> > aGroupedLeaves;
2401 aGroupedLeaves.push_back( std::move(pLeaf) );
2402 pNode->m_aGroupedLeaves.push_back( std::move(aGroupedLeaves) );
2405 else
2406 pNode->m_aLeaves.push_back( std::move(pLeaf) );
2412 // do not insert nodes without leaves
2413 if ( !pNode->m_aLeaves.empty() || !pNode->m_aGroupedLeaves.empty() )
2415 pModule ? aNodeList.push_back( std::move(pNode) ) : aOutNodeList.push_back( std::move(pNode) );
2420 if ( pModule && !aNodeList.empty() )
2422 for ( auto const & i: pModule->m_aNodeList )
2424 OUString sNodeId = i->m_sId;
2425 for ( auto j = aNodeList.begin(); j != aNodeList.end(); ++j )
2427 if ( (*j)->m_sId == sNodeId )
2429 aOutNodeList.push_back( std::move(*j) );
2430 aNodeList.erase( j );
2431 break;
2436 for ( auto & i: aNodeList )
2437 aOutNodeList.push_back( std::move(i) );
2439 return aOutNodeList;
2442 static sal_uInt16 lcl_getGroupId( std::u16string_view rGroupName, const weld::TreeView& rTreeLB )
2444 sal_uInt16 nRet = 0;
2446 std::unique_ptr<weld::TreeIter> xEntry = rTreeLB.make_iterator();
2447 bool bEntry = rTreeLB.get_iter_first(*xEntry);
2448 while (bEntry)
2450 if (!rTreeLB.get_iter_depth(*xEntry))
2452 OUString sTemp(rTreeLB.get_text(*xEntry));
2453 if (sTemp == rGroupName)
2454 return nRet;
2455 nRet++;
2457 bEntry = rTreeLB.iter_next(*xEntry);
2460 return USHRT_MAX;
2463 static void lcl_insertLeaf(
2464 OfaTreeOptionsDialog* pDlg, OptionsNode const * pNode, OptionsLeaf const * pLeaf, const weld::TreeView& rTreeLB )
2466 sal_uInt16 nGrpId = lcl_getGroupId( pNode->m_sLabel, rTreeLB );
2467 if ( USHRT_MAX == nGrpId )
2469 sal_uInt16 nNodeGrpId = getGroupNodeId( pNode->m_sId );
2470 nGrpId = pDlg->AddGroup( pNode->m_sLabel, nullptr, nullptr, nNodeGrpId );
2472 OptionsPageInfo* pInfo = pDlg->AddTabPage( 0, pLeaf->m_sLabel, nGrpId );
2473 pInfo->m_sPageURL = pLeaf->m_sPageURL;
2474 pInfo->m_sEventHdl = pLeaf->m_sEventHdl;
2477 void OfaTreeOptionsDialog::InsertNodes( const VectorOfNodes& rNodeList )
2479 for (auto const& node : rNodeList)
2481 if ( !node->m_aLeaves.empty() || !node->m_aGroupedLeaves.empty() )
2483 for ( auto const & j: node->m_aGroupedLeaves )
2485 for ( size_t k = 0; k < j.size(); ++k )
2487 lcl_insertLeaf( this, node.get(), j[k].get(), *xTreeLB );
2491 for ( auto const & j: node->m_aLeaves )
2493 lcl_insertLeaf( this, node.get(), j.get(), *xTreeLB );
2499 void OfaTreeOptionsDialog::SetNeedsRestart( svtools::RestartReason eReason)
2501 bNeedsRestart = true;
2502 eRestartReason = eReason;
2505 short OfaTreeOptionsDialog::run()
2507 std::unique_ptr< SvxDicListChgClamp > pClamp;
2508 if ( !bIsFromExtensionManager )
2510 // collect all DictionaryList Events while the dialog is executed
2511 pClamp.reset(new SvxDicListChgClamp(LinguMgr::GetDictionaryList()));
2514 return SfxOkDialogController::run();
2517 // class ExtensionsTabPage -----------------------------------------------
2518 ExtensionsTabPage::ExtensionsTabPage(
2519 weld::Container* pParent, OUString aPageURL,
2520 OUString aEvtHdl, const Reference< awt::XContainerWindowProvider >& rProvider )
2521 : m_pContainer(pParent)
2522 , m_sPageURL(std::move(aPageURL))
2523 , m_sEventHdl(std::move(aEvtHdl))
2524 , m_xWinProvider(rProvider)
2528 ExtensionsTabPage::~ExtensionsTabPage()
2530 Hide();
2531 DeactivatePage();
2533 if ( m_xPage.is() )
2537 m_xPage->dispose();
2539 catch (const Exception&)
2542 m_xPage.clear();
2545 if ( m_xPageParent.is() )
2549 m_xPageParent->dispose();
2551 catch (const Exception&)
2554 m_xPageParent.clear();
2558 void ExtensionsTabPage::CreateDialogWithHandler()
2562 bool bWithHandler = !m_sEventHdl.isEmpty();
2563 if ( bWithHandler )
2565 Reference < XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
2566 m_xEventHdl.set( xFactory->createInstance( m_sEventHdl ), UNO_QUERY );
2569 if ( !bWithHandler || m_xEventHdl.is() )
2571 m_xPageParent = m_pContainer->CreateChildFrame();
2572 Reference<awt::XWindowPeer> xParent(m_xPageParent, UNO_QUERY);
2573 m_xPage =
2574 m_xWinProvider->createContainerWindow(
2575 m_sPageURL, OUString(), xParent, m_xEventHdl );
2577 Reference< awt::XControl > xPageControl( m_xPage, UNO_QUERY );
2578 if ( xPageControl.is() )
2580 Reference< awt::XWindowPeer > xWinPeer( xPageControl->getPeer() );
2581 if ( xWinPeer.is() )
2583 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWinPeer );
2584 if ( pWindow )
2585 pWindow->SetStyle( pWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL );
2590 catch (const Exception&)
2592 TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::CreateDialogWithHandler(): exception of XDialogProvider2::createDialogWithHandler()");
2596 bool ExtensionsTabPage::DispatchAction( const OUString& rAction )
2598 bool bRet = false;
2599 if ( m_xEventHdl.is() )
2603 bRet = m_xEventHdl->callHandlerMethod( m_xPage, Any( rAction ), u"external_event"_ustr );
2605 catch ( Exception const & )
2607 TOOLS_WARN_EXCEPTION( "cui.options", "ExtensionsTabPage::DispatchAction(): exception of XDialogEventHandler::callHandlerMethod()" );
2610 return bRet;
2613 void ExtensionsTabPage::Show()
2615 if (!m_xPageParent.is())
2616 return;
2618 VclPtr<vcl::Window> xPageParent = VCLUnoHelper::GetWindow(m_xPageParent);
2619 if (xPageParent)
2621 // NoActivate otherwise setVisible will call Window::Show which will grab
2622 // focus to the page by default
2623 xPageParent->Show(true, ShowFlags::NoActivate);
2626 m_xPageParent->setVisible(true);
2629 void ExtensionsTabPage::Hide()
2631 if (!m_xPageParent.is())
2632 return;
2633 m_xPageParent->setVisible(false);
2636 void ExtensionsTabPage::ActivatePage()
2638 if ( !m_xPage.is() )
2640 CreateDialogWithHandler();
2642 if ( m_xPage.is() )
2644 auto aWindowRect = m_xPageParent->getPosSize();
2645 m_xPage->setPosSize(0, 0, aWindowRect.Width, aWindowRect.Height, awt::PosSize::POSSIZE);
2646 if ( !m_sEventHdl.isEmpty() )
2647 DispatchAction( u"initialize"_ustr );
2651 if ( m_xPage.is() )
2653 m_xPage->setVisible( true );
2657 void ExtensionsTabPage::DeactivatePage()
2659 if ( m_xPage.is() )
2660 m_xPage->setVisible( false );
2663 void ExtensionsTabPage::ResetPage()
2665 DispatchAction( u"back"_ustr );
2666 ActivatePage();
2669 void ExtensionsTabPage::SavePage()
2671 DispatchAction( u"ok"_ustr );
2674 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */