Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / cui / source / options / optpath.cxx
blobdfca56dfae59d3a9ef4c74eef215983d1e8e5c2c
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 <svx/svxdlg.hxx>
21 #include <sfx2/filedlghelper.hxx>
22 #include <sfx2/app.hxx>
23 #include <tools/urlobj.hxx>
24 #include <unotools/defaultoptions.hxx>
25 #include <unotools/pathoptions.hxx>
26 #include <unotools/moduleoptions.hxx>
27 #include <unotools/viewoptions.hxx>
29 #include <bitmaps.hlst>
30 #include <dialmgr.hxx>
31 #include <optpath.hxx>
32 #include <strings.hrc>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/string.hxx>
35 #include <com/sun/star/uno/Exception.hpp>
36 #include <com/sun/star/beans/PropertyAttribute.hpp>
37 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
38 #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
39 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
40 #include <com/sun/star/ui/dialogs/XFilePicker3.hpp>
41 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
42 #include <com/sun/star/util/thePathSettings.hpp>
43 #include <comphelper/diagnose_ex.hxx>
44 #include <sal/log.hxx>
45 #include <o3tl/string_view.hxx>
47 using namespace css;
48 using namespace css::beans;
49 using namespace css::lang;
50 using namespace css::ui::dialogs;
51 using namespace css::uno;
52 using namespace svx;
54 // define ----------------------------------------------------------------
56 constexpr OUStringLiteral POSTFIX_INTERNAL = u"_internal";
57 constexpr OUStringLiteral POSTFIX_USER = u"_user";
58 constexpr OUStringLiteral POSTFIX_WRITABLE = u"_writable";
59 constexpr OUStringLiteral VAR_ONE = u"%1";
60 constexpr OUStringLiteral IODLG_CONFIGNAME = u"FilePicker_Save";
62 // struct OptPath_Impl ---------------------------------------------------
64 struct OptPath_Impl
66 OUString m_sMultiPathDlg;
67 Reference< css::util::XPathSettings > m_xPathSettings;
69 OptPath_Impl()
70 : m_sMultiPathDlg(CuiResId(RID_CUISTR_EDIT_PATHS))
75 namespace {
77 struct PathUserData_Impl
79 SvtPathOptions::Paths nRealId;
80 bool bItemStateSet;
81 OUString sUserPath;
82 OUString sWritablePath;
83 bool bReadOnly;
85 explicit PathUserData_Impl(SvtPathOptions::Paths nId)
86 : nRealId(nId)
87 , bItemStateSet(false)
88 , bReadOnly(false)
93 struct Handle2CfgNameMapping_Impl
95 SvtPathOptions::Paths m_nHandle;
96 const char* m_pCfgName;
101 Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
103 { SvtPathOptions::Paths::AutoCorrect, "AutoCorrect" },
104 { SvtPathOptions::Paths::AutoText, "AutoText" },
105 { SvtPathOptions::Paths::Backup, "Backup" },
106 { SvtPathOptions::Paths::Gallery, "Gallery" },
107 { SvtPathOptions::Paths::Graphic, "Graphic" },
108 { SvtPathOptions::Paths::Temp, "Temp" },
109 { SvtPathOptions::Paths::Template, "Template" },
110 { SvtPathOptions::Paths::Work, "Work" },
111 { SvtPathOptions::Paths::Dictionary, "Dictionary" },
112 { SvtPathOptions::Paths::Classification, "Classification" },
113 #if OSL_DEBUG_LEVEL > 1
114 { SvtPathOptions::Paths::Linguistic, "Linguistic" },
115 #endif
116 { SvtPathOptions::Paths::LAST, nullptr }
119 static OUString getCfgName_Impl( SvtPathOptions::Paths _nHandle )
121 OUString sCfgName;
122 sal_uInt16 nIndex = 0;
123 while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != SvtPathOptions::Paths::LAST )
125 if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
127 // config name found
128 sCfgName = OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
129 break;
131 ++nIndex;
134 return sCfgName;
137 #define MULTIPATH_DELIMITER ';'
139 static OUString Convert_Impl( std::u16string_view rValue )
141 if (rValue.empty())
142 return OUString();
144 sal_Int32 nPos = 0;
145 OUStringBuffer aReturn;
146 for (;;)
148 OUString aValue( o3tl::getToken(rValue, 0, MULTIPATH_DELIMITER, nPos ) );
149 INetURLObject aObj( aValue );
150 if ( aObj.GetProtocol() == INetProtocol::File )
151 aReturn.append(aObj.PathToFileName());
152 if ( nPos < 0 )
153 break;
154 aReturn.append(MULTIPATH_DELIMITER);
157 return aReturn.makeStringAndClear();
160 // functions -------------------------------------------------------------
162 static bool IsMultiPath_Impl( const SvtPathOptions::Paths nIndex )
164 #if OSL_DEBUG_LEVEL > 1
165 return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
166 SvtPathOptions::Paths::AutoText == nIndex ||
167 SvtPathOptions::Paths::Basic == nIndex ||
168 SvtPathOptions::Paths::Gallery == nIndex ||
169 SvtPathOptions::Paths::Template == nIndex );
170 #else
171 return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
172 SvtPathOptions::Paths::AutoText == nIndex ||
173 SvtPathOptions::Paths::Basic == nIndex ||
174 SvtPathOptions::Paths::Gallery == nIndex ||
175 SvtPathOptions::Paths::Template == nIndex ||
176 SvtPathOptions::Paths::Linguistic == nIndex ||
177 SvtPathOptions::Paths::Dictionary == nIndex );
178 #endif
181 // class SvxPathTabPage --------------------------------------------------
183 SvxPathTabPage::SvxPathTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet)
184 : SfxTabPage( pPage, pController, "cui/ui/optpathspage.ui", "OptPathsPage", &rSet)
185 , pImpl(new OptPath_Impl)
186 , xDialogListener ( new ::svt::DialogClosedListener() )
187 , m_xStandardBtn(m_xBuilder->weld_button("default"))
188 , m_xPathBtn(m_xBuilder->weld_button("edit"))
189 , m_xPathBox(m_xBuilder->weld_tree_view("paths"))
191 m_xStandardBtn->connect_clicked(LINK(this, SvxPathTabPage, StandardHdl_Impl));
192 m_xPathBtn->connect_clicked( LINK( this, SvxPathTabPage, PathHdl_Impl ) );
194 m_xPathBox->set_size_request(m_xPathBox->get_approximate_digit_width() * 60,
195 m_xPathBox->get_height_rows(20));
197 m_xPathBox->connect_row_activated( LINK( this, SvxPathTabPage, DoubleClickPathHdl_Impl ) );
198 m_xPathBox->connect_column_clicked(LINK(this, SvxPathTabPage, HeaderBarClick));
199 m_xPathBox->connect_changed( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
200 m_xPathBox->set_selection_mode(SelectionMode::Multiple);
202 xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
205 IMPL_LINK(SvxPathTabPage, HeaderBarClick, int, nColumn, void)
207 bool bSortAtoZ = !m_xPathBox->get_sort_order();
208 m_xPathBox->set_sort_order(bSortAtoZ);
209 m_xPathBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
212 SvxPathTabPage::~SvxPathTabPage()
214 for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
215 delete weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
218 std::unique_ptr<SfxTabPage> SvxPathTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
219 const SfxItemSet* rAttrSet )
221 return std::make_unique<SvxPathTabPage>( pPage, pController, *rAttrSet );
224 bool SvxPathTabPage::FillItemSet( SfxItemSet* )
226 for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
228 PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(i));
229 SvtPathOptions::Paths nRealId = pPathImpl->nRealId;
230 if (pPathImpl->bItemStateSet )
231 SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
233 return true;
236 void SvxPathTabPage::Reset( const SfxItemSet* )
238 m_xPathBox->clear();
239 m_xPathBox->make_unsorted();
241 std::unique_ptr<weld::TreeIter> xIter = m_xPathBox->make_iterator();
242 for( sal_uInt16 i = 0; i <= sal_uInt16(SvtPathOptions::Paths::Classification); ++i )
244 // only writer uses autotext
245 if ( static_cast<SvtPathOptions::Paths>(i) == SvtPathOptions::Paths::AutoText
246 && !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::EModule::WRITER ) )
247 continue;
249 TranslateId pId;
251 switch (static_cast<SvtPathOptions::Paths>(i))
253 case SvtPathOptions::Paths::AutoCorrect:
254 pId = RID_CUISTR_KEY_AUTOCORRECT_DIR;
255 break;
256 case SvtPathOptions::Paths::AutoText:
257 pId = RID_CUISTR_KEY_GLOSSARY_PATH;
258 break;
259 case SvtPathOptions::Paths::Backup:
260 pId = RID_CUISTR_KEY_BACKUP_PATH;
261 break;
262 case SvtPathOptions::Paths::Gallery:
263 pId = RID_CUISTR_KEY_GALLERY_DIR;
264 break;
265 case SvtPathOptions::Paths::Graphic:
266 pId = RID_CUISTR_KEY_GRAPHICS_PATH;
267 break;
268 case SvtPathOptions::Paths::Temp:
269 pId = RID_CUISTR_KEY_TEMP_PATH;
270 break;
271 case SvtPathOptions::Paths::Template:
272 pId = RID_CUISTR_KEY_TEMPLATE_PATH;
273 break;
274 case SvtPathOptions::Paths::Dictionary:
275 pId = RID_CUISTR_KEY_DICTIONARY_PATH;
276 break;
277 case SvtPathOptions::Paths::Classification:
278 pId = RID_CUISTR_KEY_CLASSIFICATION_PATH;
279 break;
280 #if OSL_DEBUG_LEVEL > 1
281 case SvtPathOptions::Paths::Linguistic:
282 pId = RID_CUISTR_KEY_LINGUISTIC_DIR;
283 break;
284 #endif
285 case SvtPathOptions::Paths::Work:
286 pId = RID_CUISTR_KEY_WORK_PATH;
287 break;
288 default: break;
291 if (pId)
293 m_xPathBox->append(xIter.get());
295 OUString aStr(CuiResId(pId));
296 m_xPathBox->set_text(*xIter, aStr, 0);
298 OUString sInternal, sUser, sWritable;
299 bool bReadOnly = false;
300 GetPathList( static_cast<SvtPathOptions::Paths>(i), sInternal, sUser, sWritable, bReadOnly );
302 if (bReadOnly)
303 m_xPathBox->set_image(*xIter, RID_SVXBMP_LOCK);
305 OUString sTmpPath = sUser;
306 if ( !sTmpPath.isEmpty() && !sWritable.isEmpty() )
307 sTmpPath += OUStringChar(MULTIPATH_DELIMITER);
308 sTmpPath += sWritable;
309 const OUString aValue = Convert_Impl( sTmpPath );
311 m_xPathBox->set_text(*xIter, aValue, 1);
313 const OUString aValueInternal = Convert_Impl( sInternal );
315 m_xPathBox->set_text(*xIter, aValueInternal, 2);
317 m_xPathBox->set_sensitive(*xIter, !bReadOnly, 0);
318 m_xPathBox->set_sensitive(*xIter, !bReadOnly, 1);
319 m_xPathBox->set_sensitive(*xIter, !bReadOnly, 2);
321 PathUserData_Impl* pPathImpl = new PathUserData_Impl(static_cast<SvtPathOptions::Paths>(i));
322 pPathImpl->sUserPath = sUser;
323 pPathImpl->sWritablePath = sWritable;
324 pPathImpl->bReadOnly = bReadOnly;
326 OUString sId = weld::toId(pPathImpl);
327 m_xPathBox->set_id(*xIter, sId);
331 m_xPathBox->columns_autosize();
332 m_xPathBox->make_sorted();
333 PathSelect_Impl(*m_xPathBox);
336 IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl, weld::TreeView&, void)
338 bool bEnable = false;
339 int nEntry = m_xPathBox->get_selected_index();
340 if (nEntry != -1)
342 PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
343 bEnable = !pPathImpl->bReadOnly;
345 sal_uInt16 nSelCount = m_xPathBox->count_selected_rows();
346 m_xPathBtn->set_sensitive(1 == nSelCount && bEnable);
347 m_xStandardBtn->set_sensitive(nSelCount > 0 && bEnable);
350 IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl, weld::Button&, void)
352 m_xPathBox->selected_foreach([this](weld::TreeIter& rEntry){
353 PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(rEntry));
354 OUString aOldPath = SvtDefaultOptions::GetDefaultPath( pPathImpl->nRealId );
356 if ( !aOldPath.isEmpty() )
358 OUString sInternal, sUser, sWritable, sTemp;
359 bool bReadOnly = false;
360 GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
362 sal_Int32 nOldPos = 0;
365 bool bFound = false;
366 const std::u16string_view sOnePath = o3tl::getToken(aOldPath, 0, MULTIPATH_DELIMITER, nOldPos );
367 if ( !sInternal.isEmpty() )
369 sal_Int32 nInternalPos = 0;
372 if ( o3tl::getToken(sInternal, 0, MULTIPATH_DELIMITER, nInternalPos ) == sOnePath )
373 bFound = true;
375 while ( !bFound && nInternalPos >= 0 );
377 if ( !bFound )
379 if ( !sTemp.isEmpty() )
380 sTemp += OUStringChar(MULTIPATH_DELIMITER);
381 sTemp += sOnePath;
384 while ( nOldPos >= 0 );
386 OUString sWritablePath;
387 OUStringBuffer sUserPath;
388 if ( !sTemp.isEmpty() )
390 sal_Int32 nNextPos = 0;
391 for (;;)
393 const OUString sToken = sTemp.getToken( 0, MULTIPATH_DELIMITER, nNextPos );
394 if ( nNextPos<0 )
396 // Last token need a different handling
397 sWritablePath = sToken;
398 break;
400 if ( !sUserPath.isEmpty() )
401 sUserPath.append(MULTIPATH_DELIMITER);
402 sUserPath.append(sToken);
405 m_xPathBox->set_text(rEntry, Convert_Impl(sTemp), 1);
406 pPathImpl->bItemStateSet = true;
407 pPathImpl->sUserPath = sUserPath.makeStringAndClear();
408 pPathImpl->sWritablePath = sWritablePath;
410 return false;
414 void SvxPathTabPage::ChangeCurrentEntry( const OUString& _rFolder )
416 int nEntry = m_xPathBox->get_cursor_index();
417 if (nEntry == -1)
419 SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
420 return;
423 OUString sInternal, sUser, sWritable;
424 PathUserData_Impl* pPathImpl = weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry));
425 bool bReadOnly = false;
426 GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
427 sUser = pPathImpl->sUserPath;
428 sWritable = pPathImpl->sWritablePath;
430 // old path is a URL?
431 INetURLObject aObj( sWritable );
432 bool bURL = ( aObj.GetProtocol() != INetProtocol::NotValid );
433 INetURLObject aNewObj( _rFolder );
434 aNewObj.removeFinalSlash();
436 // then the new path also a URL else system path
437 OUString sNewPathStr = bURL ? _rFolder : aNewObj.getFSysPath( FSysStyle::Detect );
439 bool bChanged =
440 #ifdef UNX
441 // Unix is case sensitive
442 ( sNewPathStr != sWritable );
443 #else
444 !sNewPathStr.equalsIgnoreAsciiCase( sWritable );
445 #endif
447 if ( !bChanged )
448 return;
450 m_xPathBox->set_text(nEntry, Convert_Impl(sNewPathStr), 1);
451 pPathImpl->bItemStateSet = true;
452 pPathImpl->sWritablePath = sNewPathStr;
453 if ( SvtPathOptions::Paths::Work == pPathImpl->nRealId )
455 // Remove view options entry so the new work path
456 // will be used for the next open dialog.
457 SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
458 aDlgOpt.Delete();
459 // Reset also last used dir in the sfx application instance
460 SfxApplication *pSfxApp = SfxGetpApp();
461 pSfxApp->ResetLastDir();
465 IMPL_LINK_NOARG(SvxPathTabPage, DoubleClickPathHdl_Impl, weld::TreeView&, bool)
467 PathHdl_Impl(*m_xPathBtn);
468 return true;
471 IMPL_LINK_NOARG(SvxPathTabPage, PathHdl_Impl, weld::Button&, void)
473 int nEntry = m_xPathBox->get_cursor_index();
474 PathUserData_Impl* pPathImpl = nEntry != -1 ? weld::fromId<PathUserData_Impl*>(m_xPathBox->get_id(nEntry)) : nullptr;
475 if (!pPathImpl || pPathImpl->bReadOnly)
476 return;
478 SvtPathOptions::Paths nPos = pPathImpl->nRealId;
479 OUString sInternal, sUser, sWritable;
480 bool bPickFile = false;
481 bool bReadOnly = false;
482 GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
483 sUser = pPathImpl->sUserPath;
484 sWritable = pPathImpl->sWritablePath;
485 bPickFile = pPathImpl->nRealId == SvtPathOptions::Paths::Classification;
487 if (IsMultiPath_Impl(nPos))
489 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
490 ScopedVclPtr<AbstractSvxMultiPathDialog> pMultiDlg(
491 pFact->CreateSvxMultiPathDialog(GetFrameWeld()));
493 OUString sPath( sUser );
494 if ( !sPath.isEmpty() )
495 sPath += OUStringChar(MULTIPATH_DELIMITER);
496 sPath += sWritable;
497 pMultiDlg->SetPath( sPath );
499 const OUString sPathName = m_xPathBox->get_text(nEntry, 0);
500 const OUString sNewTitle = pImpl->m_sMultiPathDlg.replaceFirst( VAR_ONE, sPathName );
501 pMultiDlg->SetTitle( sNewTitle );
503 if (pMultiDlg->Execute() == RET_OK)
505 sUser.clear();
506 sWritable.clear();
507 OUString sFullPath;
508 OUString sNewPath = pMultiDlg->GetPath();
509 if ( !sNewPath.isEmpty() )
511 sal_Int32 nNextPos = 0;
512 for (;;)
514 const OUString sToken(sNewPath.getToken( 0, MULTIPATH_DELIMITER, nNextPos ));
515 if ( nNextPos<0 )
517 // Last token need a different handling
518 sWritable = sToken;
519 break;
521 if ( !sUser.isEmpty() )
522 sUser += OUStringChar(MULTIPATH_DELIMITER);
523 sUser += sToken;
525 sFullPath = sUser;
526 if ( !sFullPath.isEmpty() )
527 sFullPath += OUStringChar(MULTIPATH_DELIMITER);
528 sFullPath += sWritable;
531 m_xPathBox->set_text(nEntry, Convert_Impl(sFullPath), 1);
532 // save modified flag
533 pPathImpl->bItemStateSet = true;
534 pPathImpl->sUserPath = sUser;
535 pPathImpl->sWritablePath = sWritable;
538 else if (!bPickFile)
542 Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
543 xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
545 INetURLObject aURL( sWritable, INetProtocol::File );
546 xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
548 Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
549 if ( xAsyncDlg.is() )
550 xAsyncDlg->startExecuteModal( xDialogListener );
551 else
553 short nRet = xFolderPicker->execute();
554 if (ExecutableDialogResults::OK != nRet)
555 return;
557 OUString sFolder(xFolderPicker->getDirectory());
558 ChangeCurrentEntry(sFolder);
561 catch( Exception const & )
563 TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
566 else
570 sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
571 uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = aHelper.GetFilePicker();
572 xFilePicker->appendFilter(OUString(), "*.xml");
573 if (xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
575 uno::Sequence<OUString> aPathSeq(xFilePicker->getSelectedFiles());
576 ChangeCurrentEntry(aPathSeq[0]);
579 catch (const uno::Exception&)
581 DBG_UNHANDLED_EXCEPTION("cui.options", "exception from file picker");
586 IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
588 if (RET_OK == pEvt->DialogResult)
590 assert(xFolderPicker.is() && "SvxPathTabPage::DialogClosedHdl(): no folder picker");
591 OUString sURL = xFolderPicker->getDirectory();
592 ChangeCurrentEntry( sURL );
596 void SvxPathTabPage::GetPathList(
597 SvtPathOptions::Paths _nPathHandle, OUString& _rInternalPath,
598 OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly )
600 OUString sCfgName = getCfgName_Impl( _nPathHandle );
604 // load PathSettings service if necessary
605 if ( !pImpl->m_xPathSettings.is() )
607 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
608 pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
611 // load internal paths
612 Any aAny = pImpl->m_xPathSettings->getPropertyValue(
613 sCfgName + POSTFIX_INTERNAL);
614 Sequence< OUString > aPathSeq;
615 if ( aAny >>= aPathSeq )
617 tools::Long i, nCount = aPathSeq.getLength();
618 const OUString* pPaths = aPathSeq.getConstArray();
620 for ( i = 0; i < nCount; ++i )
622 if ( !_rInternalPath.isEmpty() )
623 _rInternalPath += ";";
624 _rInternalPath += pPaths[i];
627 // load user paths
628 aAny = pImpl->m_xPathSettings->getPropertyValue(
629 sCfgName + POSTFIX_USER);
630 if ( aAny >>= aPathSeq )
632 tools::Long i, nCount = aPathSeq.getLength();
633 const OUString* pPaths = aPathSeq.getConstArray();
635 for ( i = 0; i < nCount; ++i )
637 if ( !_rUserPath.isEmpty() )
638 _rUserPath += ";";
639 _rUserPath += pPaths[i];
642 // then the writable path
643 aAny = pImpl->m_xPathSettings->getPropertyValue(
644 sCfgName + POSTFIX_WRITABLE);
645 OUString sWritablePath;
646 if ( aAny >>= sWritablePath )
647 _rWritablePath = sWritablePath;
649 // and the readonly flag
650 Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
651 Property aProp = xInfo->getPropertyByName(sCfgName);
652 _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
654 catch( const Exception& )
656 TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::GetPathList()" );
661 void SvxPathTabPage::SetPathList(
662 SvtPathOptions::Paths _nPathHandle, std::u16string_view _rUserPath, const OUString& _rWritablePath )
664 OUString sCfgName = getCfgName_Impl( _nPathHandle );
668 // load PathSettings service if necessary
669 if ( !pImpl->m_xPathSettings.is() )
671 Reference< XComponentContext > xContext = comphelper::getProcessComponentContext();
672 pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
675 // save user paths
676 const sal_Int32 nCount = comphelper::string::getTokenCount(_rUserPath, MULTIPATH_DELIMITER);
677 Sequence< OUString > aPathSeq( nCount );
678 OUString* pArray = aPathSeq.getArray();
679 sal_Int32 nPos = 0;
680 for ( sal_Int32 i = 0; i < nCount; ++i )
681 pArray[i] = o3tl::getToken(_rUserPath, 0, MULTIPATH_DELIMITER, nPos );
682 Any aValue( aPathSeq );
683 pImpl->m_xPathSettings->setPropertyValue(
684 sCfgName + POSTFIX_USER, aValue);
686 // then the writable path
687 aValue <<= _rWritablePath;
688 pImpl->m_xPathSettings->setPropertyValue(
689 sCfgName + POSTFIX_WRITABLE, aValue);
691 catch( const Exception& )
693 TOOLS_WARN_EXCEPTION("cui.options", "");
697 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */