LibreOffice Module cui (master)  1
optpath.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <svx/svxdlg.hxx>
21 #include <sfx2/filedlghelper.hxx>
22 #include <sfx2/app.hxx>
23 #include <tools/urlobj.hxx>
25 #include <unotools/pathoptions.hxx>
27 #include <unotools/viewoptions.hxx>
28 
29 #include <bitmaps.hlst>
30 #include <dialmgr.hxx>
31 #include <optpath.hxx>
32 #include <strings.hrc>
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/FolderPicker.hpp>
40 #include <com/sun/star/ui/dialogs/FilePicker.hpp>
41 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
42 #include <com/sun/star/util/thePathSettings.hpp>
43 #include <tools/diagnose_ex.h>
44 #include <sal/log.hxx>
45 
46 using namespace css;
47 using namespace css::beans;
48 using namespace css::lang;
49 using namespace css::ui::dialogs;
50 using namespace css::uno;
51 using namespace svx;
52 
53 // define ----------------------------------------------------------------
54 
55 constexpr OUStringLiteral POSTFIX_INTERNAL = u"_internal";
56 constexpr OUStringLiteral POSTFIX_USER = u"_user";
57 constexpr OUStringLiteral POSTFIX_WRITABLE = u"_writable";
58 constexpr OUStringLiteral VAR_ONE = u"%1";
59 constexpr OUStringLiteral IODLG_CONFIGNAME = u"FilePicker_Save";
60 
61 // struct OptPath_Impl ---------------------------------------------------
62 
64 {
65  OUString m_sMultiPathDlg;
66  Reference< css::util::XPathSettings > m_xPathSettings;
67 
69  : m_sMultiPathDlg(CuiResId(RID_SVXSTR_EDIT_PATHS))
70  {
71  }
72 };
73 
74 namespace {
75 
76 struct PathUserData_Impl
77 {
78  SvtPathOptions::Paths nRealId;
79  bool bItemStateSet;
80  OUString sUserPath;
81  OUString sWritablePath;
82  bool bReadOnly;
83 
84  explicit PathUserData_Impl(SvtPathOptions::Paths nId)
85  : nRealId(nId)
86  , bItemStateSet(false)
87  , bReadOnly(false)
88  {
89  }
90 };
91 
92 struct Handle2CfgNameMapping_Impl
93 {
95  const char* m_pCfgName;
96 };
97 
98 }
99 
100 Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
101 {
102  { SvtPathOptions::Paths::AutoCorrect, "AutoCorrect" },
103  { SvtPathOptions::Paths::AutoText, "AutoText" },
104  { SvtPathOptions::Paths::Backup, "Backup" },
105  { SvtPathOptions::Paths::Gallery, "Gallery" },
106  { SvtPathOptions::Paths::Graphic, "Graphic" },
107  { SvtPathOptions::Paths::Temp, "Temp" },
108  { SvtPathOptions::Paths::Template, "Template" },
109  { SvtPathOptions::Paths::Work, "Work" },
110  { SvtPathOptions::Paths::Dictionary, "Dictionary" },
111  { SvtPathOptions::Paths::Classification, "Classification" },
112 #if OSL_DEBUG_LEVEL > 1
113  { SvtPathOptions::Paths::Linguistic, "Linguistic" },
114 #endif
115  { SvtPathOptions::Paths::LAST, nullptr }
116 };
117 
118 static OUString getCfgName_Impl( SvtPathOptions::Paths _nHandle )
119 {
120  OUString sCfgName;
121  sal_uInt16 nIndex = 0;
122  while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != SvtPathOptions::Paths::LAST )
123  {
124  if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
125  {
126  // config name found
127  sCfgName = OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
128  break;
129  }
130  ++nIndex;
131  }
132 
133  return sCfgName;
134 }
135 
136 #define MULTIPATH_DELIMITER ';'
137 
138 static OUString Convert_Impl( const OUString& rValue )
139 {
140  if (rValue.isEmpty())
141  return OUString();
142 
143  sal_Int32 nPos = 0;
144  OUStringBuffer aReturn;
145  for (;;)
146  {
147  OUString aValue = rValue.getToken( 0, MULTIPATH_DELIMITER, nPos );
148  INetURLObject aObj( aValue );
149  if ( aObj.GetProtocol() == INetProtocol::File )
150  aReturn.append(aObj.PathToFileName());
151  if ( nPos < 0 )
152  break;
153  aReturn.append(MULTIPATH_DELIMITER);
154  }
155 
156  return aReturn.makeStringAndClear();
157 }
158 
159 // functions -------------------------------------------------------------
160 
161 static bool IsMultiPath_Impl( const SvtPathOptions::Paths nIndex )
162 {
163 #if OSL_DEBUG_LEVEL > 1
164  return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
166  SvtPathOptions::Paths::Basic == nIndex ||
167  SvtPathOptions::Paths::Gallery == nIndex ||
169 #else
170  return ( SvtPathOptions::Paths::AutoCorrect == nIndex ||
172  SvtPathOptions::Paths::Basic == nIndex ||
173  SvtPathOptions::Paths::Gallery == nIndex ||
177 #endif
178 }
179 
180 // class SvxPathTabPage --------------------------------------------------
181 
183  : SfxTabPage( pPage, pController, "cui/ui/optpathspage.ui", "OptPathsPage", &rSet)
184  , pImpl(new OptPath_Impl)
185  , xDialogListener ( new ::svt::DialogClosedListener() )
186  , m_xStandardBtn(m_xBuilder->weld_button("default"))
187  , m_xPathBtn(m_xBuilder->weld_button("edit"))
188  , m_xPathBox(m_xBuilder->weld_tree_view("paths"))
189 {
190  m_xStandardBtn->connect_clicked(LINK(this, SvxPathTabPage, StandardHdl_Impl));
191  m_xPathBtn->connect_clicked( LINK( this, SvxPathTabPage, PathHdl_Impl ) );
192 
193  m_xPathBox->set_size_request(m_xPathBox->get_approximate_digit_width() * 60,
194  m_xPathBox->get_height_rows(20));
195 
196  m_xPathBox->connect_row_activated( LINK( this, SvxPathTabPage, DoubleClickPathHdl_Impl ) );
197  m_xPathBox->connect_column_clicked(LINK(this, SvxPathTabPage, HeaderBarClick));
198  m_xPathBox->connect_changed( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
199  m_xPathBox->set_selection_mode(SelectionMode::Multiple);
200 
201  xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
202 }
203 
204 IMPL_LINK(SvxPathTabPage, HeaderBarClick, int, nColumn, void)
205 {
206  bool bSortAtoZ = !m_xPathBox->get_sort_order();
207  m_xPathBox->set_sort_order(bSortAtoZ);
208  m_xPathBox->set_sort_indicator(bSortAtoZ ? TRISTATE_TRUE : TRISTATE_FALSE, nColumn);
209 }
210 
212 {
213  for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
214  delete reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(i).toInt64());
215 }
216 
217 std::unique_ptr<SfxTabPage> SvxPathTabPage::Create( weld::Container* pPage, weld::DialogController* pController,
218  const SfxItemSet* rAttrSet )
219 {
220  return std::make_unique<SvxPathTabPage>( pPage, pController, *rAttrSet );
221 }
222 
224 {
225  for (int i = 0, nEntryCount = m_xPathBox->n_children(); i < nEntryCount; ++i)
226  {
227  PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(i).toInt64());
228  SvtPathOptions::Paths nRealId = pPathImpl->nRealId;
229  if (pPathImpl->bItemStateSet )
230  SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
231  }
232  return true;
233 }
234 
236 {
237  m_xPathBox->clear();
238  m_xPathBox->make_unsorted();
239 
240  std::unique_ptr<weld::TreeIter> xIter = m_xPathBox->make_iterator();
241  for( sal_uInt16 i = 0; i <= sal_uInt16(SvtPathOptions::Paths::Classification); ++i )
242  {
243  // only writer uses autotext
244  if ( static_cast<SvtPathOptions::Paths>(i) == SvtPathOptions::Paths::AutoText
246  continue;
247 
248  TranslateId pId;
249 
250  switch (static_cast<SvtPathOptions::Paths>(i))
251  {
253  pId = RID_SVXSTR_KEY_AUTOCORRECT_DIR;
254  break;
256  pId = RID_SVXSTR_KEY_GLOSSARY_PATH;
257  break;
259  pId = RID_SVXSTR_KEY_BACKUP_PATH;
260  break;
262  pId = RID_SVXSTR_KEY_GALLERY_DIR;
263  break;
265  pId = RID_SVXSTR_KEY_GRAPHICS_PATH;
266  break;
268  pId = RID_SVXSTR_KEY_TEMP_PATH;
269  break;
271  pId = RID_SVXSTR_KEY_TEMPLATE_PATH;
272  break;
274  pId = RID_SVXSTR_KEY_DICTIONARY_PATH;
275  break;
277  pId = RID_SVXSTR_KEY_CLASSIFICATION_PATH;
278  break;
279 #if OSL_DEBUG_LEVEL > 1
281  pId = RID_SVXSTR_KEY_LINGUISTIC_DIR;
282  break;
283 #endif
285  pId = RID_SVXSTR_KEY_WORK_PATH;
286  break;
287  default: break;
288  }
289 
290  if (pId)
291  {
292  m_xPathBox->append(xIter.get());
293 
294  OUString aStr(CuiResId(pId));
295  m_xPathBox->set_text(*xIter, aStr, 0);
296 
297  OUString sInternal, sUser, sWritable;
298  bool bReadOnly = false;
299  GetPathList( static_cast<SvtPathOptions::Paths>(i), sInternal, sUser, sWritable, bReadOnly );
300 
301  if (bReadOnly)
302  m_xPathBox->set_image(*xIter, RID_SVXBMP_LOCK);
303 
304  OUString sTmpPath = sUser;
305  if ( !sTmpPath.isEmpty() && !sWritable.isEmpty() )
306  sTmpPath += OUStringChar(MULTIPATH_DELIMITER);
307  sTmpPath += sWritable;
308  const OUString aValue = Convert_Impl( sTmpPath );
309 
310  m_xPathBox->set_text(*xIter, aValue, 1);
311 
312  const OUString aValueInternal = Convert_Impl( sInternal );
313 
314  m_xPathBox->set_text(*xIter, aValueInternal, 2);
315 
316  m_xPathBox->set_sensitive(*xIter, !bReadOnly, 0);
317  m_xPathBox->set_sensitive(*xIter, !bReadOnly, 1);
318  m_xPathBox->set_sensitive(*xIter, !bReadOnly, 2);
319 
320  PathUserData_Impl* pPathImpl = new PathUserData_Impl(static_cast<SvtPathOptions::Paths>(i));
321  pPathImpl->sUserPath = sUser;
322  pPathImpl->sWritablePath = sWritable;
323  pPathImpl->bReadOnly = bReadOnly;
324 
325  OUString sId = OUString::number(reinterpret_cast<sal_Int64>(pPathImpl));
326  m_xPathBox->set_id(*xIter, sId);
327  }
328  }
329 
330  m_xPathBox->columns_autosize();
331  m_xPathBox->make_sorted();
332  PathSelect_Impl(*m_xPathBox);
333 }
334 
336 {
337  bool bEnable = false;
338  int nEntry = m_xPathBox->get_selected_index();
339  if (nEntry != -1)
340  {
341  PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64());
342  bEnable = !pPathImpl->bReadOnly;
343  }
344  sal_uInt16 nSelCount = m_xPathBox->count_selected_rows();
345  m_xPathBtn->set_sensitive(1 == nSelCount && bEnable);
346  m_xStandardBtn->set_sensitive(nSelCount > 0 && bEnable);
347 }
348 
349 IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl, weld::Button&, void)
350 {
351  m_xPathBox->selected_foreach([this](weld::TreeIter& rEntry){
352  PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(rEntry).toInt64());
353  OUString aOldPath = SvtDefaultOptions::GetDefaultPath( pPathImpl->nRealId );
354 
355  if ( !aOldPath.isEmpty() )
356  {
357  OUString sInternal, sUser, sWritable, sTemp;
358  bool bReadOnly = false;
359  GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
360 
361  sal_Int32 nOldPos = 0;
362  do
363  {
364  bool bFound = false;
365  const OUString sOnePath = aOldPath.getToken( 0, MULTIPATH_DELIMITER, nOldPos );
366  if ( !sInternal.isEmpty() )
367  {
368  sal_Int32 nInternalPos = 0;
369  do
370  {
371  if ( sInternal.getToken( 0, MULTIPATH_DELIMITER, nInternalPos ) == sOnePath )
372  bFound = true;
373  }
374  while ( !bFound && nInternalPos >= 0 );
375  }
376  if ( !bFound )
377  {
378  if ( !sTemp.isEmpty() )
379  sTemp += OUStringChar(MULTIPATH_DELIMITER);
380  sTemp += sOnePath;
381  }
382  }
383  while ( nOldPos >= 0 );
384 
385  OUString sWritablePath;
386  OUStringBuffer sUserPath;
387  if ( !sTemp.isEmpty() )
388  {
389  sal_Int32 nNextPos = 0;
390  for (;;)
391  {
392  const OUString sToken = sTemp.getToken( 0, MULTIPATH_DELIMITER, nNextPos );
393  if ( nNextPos<0 )
394  {
395  // Last token need a different handling
396  sWritablePath = sToken;
397  break;
398  }
399  if ( !sUserPath.isEmpty() )
400  sUserPath.append(MULTIPATH_DELIMITER);
401  sUserPath.append(sToken);
402  }
403  }
404  m_xPathBox->set_text(rEntry, Convert_Impl(sTemp), 1);
405  pPathImpl->bItemStateSet = true;
406  pPathImpl->sUserPath = sUserPath.makeStringAndClear();
407  pPathImpl->sWritablePath = sWritablePath;
408  }
409  return false;
410  });
411 }
412 
413 void SvxPathTabPage::ChangeCurrentEntry( const OUString& _rFolder )
414 {
415  int nEntry = m_xPathBox->get_cursor_index();
416  if (nEntry == -1)
417  {
418  SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
419  return;
420  }
421 
422  OUString sInternal, sUser, sWritable;
423  PathUserData_Impl* pPathImpl = reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64());
424  bool bReadOnly = false;
425  GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
426  sUser = pPathImpl->sUserPath;
427  sWritable = pPathImpl->sWritablePath;
428 
429  // old path is a URL?
430  INetURLObject aObj( sWritable );
431  bool bURL = ( aObj.GetProtocol() != INetProtocol::NotValid );
432  INetURLObject aNewObj( _rFolder );
433  aNewObj.removeFinalSlash();
434 
435  // then the new path also a URL else system path
436  OUString sNewPathStr = bURL ? _rFolder : aNewObj.getFSysPath( FSysStyle::Detect );
437 
438  bool bChanged =
439 #ifdef UNX
440 // Unix is case sensitive
441  ( sNewPathStr != sWritable );
442 #else
443  !sNewPathStr.equalsIgnoreAsciiCase( sWritable );
444 #endif
445 
446  if ( !bChanged )
447  return;
448 
449  m_xPathBox->set_text(nEntry, Convert_Impl(sNewPathStr), 1);
450  pPathImpl->bItemStateSet = true;
451  pPathImpl->sWritablePath = sNewPathStr;
452  if ( SvtPathOptions::Paths::Work == pPathImpl->nRealId )
453  {
454  // Remove view options entry so the new work path
455  // will be used for the next open dialog.
456  SvtViewOptions aDlgOpt( EViewType::Dialog, IODLG_CONFIGNAME );
457  aDlgOpt.Delete();
458  // Reset also last used dir in the sfx application instance
459  SfxApplication *pSfxApp = SfxGetpApp();
460  pSfxApp->ResetLastDir();
461  }
462 }
463 
464 IMPL_LINK_NOARG(SvxPathTabPage, DoubleClickPathHdl_Impl, weld::TreeView&, bool)
465 {
466  PathHdl_Impl(*m_xPathBtn);
467  return true;
468 }
469 
471 {
472  int nEntry = m_xPathBox->get_cursor_index();
473  PathUserData_Impl* pPathImpl = nEntry != -1 ? reinterpret_cast<PathUserData_Impl*>(m_xPathBox->get_id(nEntry).toInt64()) : nullptr;
474  if (!pPathImpl || pPathImpl->bReadOnly)
475  return;
476 
477  SvtPathOptions::Paths nPos = pPathImpl->nRealId;
478  OUString sInternal, sUser, sWritable;
479  bool bPickFile = false;
480  bool bReadOnly = false;
481  GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
482  sUser = pPathImpl->sUserPath;
483  sWritable = pPathImpl->sWritablePath;
484  bPickFile = pPathImpl->nRealId == SvtPathOptions::Paths::Classification;
485 
486  if (IsMultiPath_Impl(nPos))
487  {
491 
492  OUString sPath( sUser );
493  if ( !sPath.isEmpty() )
494  sPath += OUStringChar(MULTIPATH_DELIMITER);
495  sPath += sWritable;
496  pMultiDlg->SetPath( sPath );
497 
498  const OUString sPathName = m_xPathBox->get_text(nEntry, 0);
499  const OUString sNewTitle = pImpl->m_sMultiPathDlg.replaceFirst( VAR_ONE, sPathName );
500  pMultiDlg->SetTitle( sNewTitle );
501 
502  if (pMultiDlg->Execute() == RET_OK)
503  {
504  sUser.clear();
505  sWritable.clear();
506  OUString sFullPath;
507  OUString sNewPath = pMultiDlg->GetPath();
508  if ( !sNewPath.isEmpty() )
509  {
510  sal_Int32 nNextPos = 0;
511  for (;;)
512  {
513  const OUString sToken(sNewPath.getToken( 0, MULTIPATH_DELIMITER, nNextPos ));
514  if ( nNextPos<0 )
515  {
516  // Last token need a different handling
517  sWritable = sToken;
518  break;
519  }
520  if ( !sUser.isEmpty() )
521  sUser += OUStringChar(MULTIPATH_DELIMITER);
522  sUser += sToken;
523  }
524  sFullPath = sUser;
525  if ( !sFullPath.isEmpty() )
526  sFullPath += OUStringChar(MULTIPATH_DELIMITER);
527  sFullPath += sWritable;
528  }
529 
530  m_xPathBox->set_text(nEntry, Convert_Impl(sFullPath), 1);
531  // save modified flag
532  pPathImpl->bItemStateSet = true;
533  pPathImpl->sUserPath = sUser;
534  pPathImpl->sWritablePath = sWritable;
535  }
536  }
537  else if (!bPickFile)
538  {
539  try
540  {
542  xFolderPicker = sfx2::createFolderPicker(xContext, GetFrameWeld());
543 
544  INetURLObject aURL( sWritable, INetProtocol::File );
545  xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
546 
547  Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
548  if ( xAsyncDlg.is() )
549  xAsyncDlg->startExecuteModal( xDialogListener );
550  else
551  {
552  short nRet = xFolderPicker->execute();
553  if (ExecutableDialogResults::OK != nRet)
554  return;
555 
556  OUString sFolder(xFolderPicker->getDirectory());
557  ChangeCurrentEntry(sFolder);
558  }
559  }
560  catch( Exception const & )
561  {
562  TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
563  }
564  }
565  else
566  {
567  try
568  {
569  sfx2::FileDialogHelper aHelper(ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE, FileDialogFlags::NONE, GetFrameWeld());
570  uno::Reference<ui::dialogs::XFilePicker3> xFilePicker = aHelper.GetFilePicker();
571  xFilePicker->appendFilter(OUString(), "*.xml");
572  if (xFilePicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
573  {
574  uno::Sequence<OUString> aPathSeq(xFilePicker->getSelectedFiles());
575  ChangeCurrentEntry(aPathSeq[0]);
576  }
577  }
578  catch (const uno::Exception&)
579  {
580  DBG_UNHANDLED_EXCEPTION("cui.options", "exception from file picker");
581  }
582  }
583 }
584 
585 IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt, void )
586 {
587  if (RET_OK == pEvt->DialogResult)
588  {
589  assert(xFolderPicker.is() && "SvxPathTabPage::DialogClosedHdl(): no folder picker");
590  OUString sURL = xFolderPicker->getDirectory();
591  ChangeCurrentEntry( sURL );
592  }
593 }
594 
596  SvtPathOptions::Paths _nPathHandle, OUString& _rInternalPath,
597  OUString& _rUserPath, OUString& _rWritablePath, bool& _rReadOnly )
598 {
599  OUString sCfgName = getCfgName_Impl( _nPathHandle );
600 
601  try
602  {
603  // load PathSettings service if necessary
604  if ( !pImpl->m_xPathSettings.is() )
605  {
607  pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
608  }
609 
610  // load internal paths
611  Any aAny = pImpl->m_xPathSettings->getPropertyValue(
612  sCfgName + POSTFIX_INTERNAL);
613  Sequence< OUString > aPathSeq;
614  if ( aAny >>= aPathSeq )
615  {
616  tools::Long i, nCount = aPathSeq.getLength();
617  const OUString* pPaths = aPathSeq.getConstArray();
618 
619  for ( i = 0; i < nCount; ++i )
620  {
621  if ( !_rInternalPath.isEmpty() )
622  _rInternalPath += ";";
623  _rInternalPath += pPaths[i];
624  }
625  }
626  // load user paths
627  aAny = pImpl->m_xPathSettings->getPropertyValue(
628  sCfgName + POSTFIX_USER);
629  if ( aAny >>= aPathSeq )
630  {
631  tools::Long i, nCount = aPathSeq.getLength();
632  const OUString* pPaths = aPathSeq.getConstArray();
633 
634  for ( i = 0; i < nCount; ++i )
635  {
636  if ( !_rUserPath.isEmpty() )
637  _rUserPath += ";";
638  _rUserPath += pPaths[i];
639  }
640  }
641  // then the writable path
642  aAny = pImpl->m_xPathSettings->getPropertyValue(
643  sCfgName + POSTFIX_WRITABLE);
644  OUString sWritablePath;
645  if ( aAny >>= sWritablePath )
646  _rWritablePath = sWritablePath;
647 
648  // and the readonly flag
649  Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
650  Property aProp = xInfo->getPropertyByName(sCfgName);
651  _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
652  }
653  catch( const Exception& )
654  {
655  TOOLS_WARN_EXCEPTION( "cui.options", "SvxPathTabPage::GetPathList()" );
656  }
657 }
658 
659 
661  SvtPathOptions::Paths _nPathHandle, const OUString& _rUserPath, const OUString& _rWritablePath )
662 {
663  OUString sCfgName = getCfgName_Impl( _nPathHandle );
664 
665  try
666  {
667  // load PathSettings service if necessary
668  if ( !pImpl->m_xPathSettings.is() )
669  {
671  pImpl->m_xPathSettings = css::util::thePathSettings::get( xContext );
672  }
673 
674  // save user paths
675  const sal_Int32 nCount = comphelper::string::getTokenCount(_rUserPath, MULTIPATH_DELIMITER);
676  Sequence< OUString > aPathSeq( nCount );
677  OUString* pArray = aPathSeq.getArray();
678  sal_Int32 nPos = 0;
679  for ( sal_Int32 i = 0; i < nCount; ++i )
680  pArray[i] = _rUserPath.getToken( 0, MULTIPATH_DELIMITER, nPos );
681  Any aValue( aPathSeq );
682  pImpl->m_xPathSettings->setPropertyValue(
683  sCfgName + POSTFIX_USER, aValue);
684 
685  // then the writable path
686  aValue <<= _rWritablePath;
687  pImpl->m_xPathSettings->setPropertyValue(
688  sCfgName + POSTFIX_WRITABLE, aValue);
689  }
690  catch( const Exception& )
691  {
692  TOOLS_WARN_EXCEPTION("cui.options", "");
693  }
694 }
695 
696 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral POSTFIX_WRITABLE
Definition: optpath.cxx:57
URL aURL
sal_Int32 nIndex
IMPL_LINK(SvxPathTabPage, HeaderBarClick, int, nColumn, void)
Definition: optpath.cxx:204
static SvxAbstractDialogFactory * Create()
bool IsModuleInstalled(EModule eModule) const
long Long
static OUString Convert_Impl(const OUString &rValue)
Definition: optpath.cxx:138
virtual bool FillItemSet(SfxItemSet *rSet) override
Definition: optpath.cxx:223
virtual VclPtr< AbstractSvxMultiPathDialog > CreateSvxMultiPathDialog(weld::Window *pParent)=0
bool bReadOnly
void GetPathList(SvtPathOptions::Paths _nPathHandle, OUString &_rInternalPath, OUString &_rUserPath, OUString &_rWritablePath, bool &_rReadOnly)
Definition: optpath.cxx:595
TRISTATE_TRUE
SvxPathTabPage(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet &rSet)
Definition: optpath.cxx:182
SfxApplication * SfxGetpApp()
OUString PathToFileName() const
Reference< css::util::XPathSettings > m_xPathSettings
Definition: optpath.cxx:66
std::unique_ptr< weld::TreeView > m_xPathBox
Definition: optpath.hxx:43
constexpr OUStringLiteral POSTFIX_USER
Definition: optpath.cxx:56
std::unique_ptr< weld::Button > m_xStandardBtn
Definition: optpath.hxx:41
IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl, weld::TreeView &, void)
Definition: optpath.cxx:335
int nCount
#define MULTIPATH_DELIMITER
Definition: optpath.cxx:136
constexpr OUStringLiteral VAR_ONE
Definition: optpath.cxx:58
sal_Int32 getTokenCount(std::string_view rIn, char cTok)
OUString CuiResId(TranslateId aKey)
Definition: cuiresmgr.cxx:23
#define DBG_UNHANDLED_EXCEPTION(...)
OUString getFSysPath(FSysStyle eStyle, sal_Unicode *pDelimiter=nullptr) const
#define TOOLS_WARN_EXCEPTION(area, stream)
void SetPathList(SvtPathOptions::Paths _nPathHandle, const OUString &_rUserPath, const OUString &_rWritablePath)
Definition: optpath.cxx:660
int i
void ResetLastDir()
virtual ~SvxPathTabPage() override
Definition: optpath.cxx:211
OUString GetDefaultPath(SvtPathOptions::Paths nId)
static OUString getCfgName_Impl(SvtPathOptions::Paths _nHandle)
Definition: optpath.cxx:118
Any aHelper
TRISTATE_FALSE
float u
OUString m_sMultiPathDlg
Definition: optpath.cxx:65
bool removeFinalSlash()
static bool IsMultiPath_Impl(const SvtPathOptions::Paths nIndex)
Definition: optpath.cxx:161
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
virtual void Reset(const SfxItemSet *rSet) override
Definition: optpath.cxx:235
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
rtl::Reference< ::svt::DialogClosedListener > xDialogListener
Definition: optpath.hxx:38
virtual void SetPath(const OUString &rPath)=0
INetProtocol GetProtocol() const
RET_OK
void ChangeCurrentEntry(const OUString &_rFolder)
Definition: optpath.cxx:413
const sal_Int32 m_nHandle
Reference< XComponentContext > getProcessComponentContext()
Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[]
Definition: optpath.cxx:100
constexpr OUStringLiteral IODLG_CONFIGNAME
Definition: optpath.cxx:59
#define SAL_WARN(area, stream)
const css::uno::Reference< css::ui::dialogs::XFilePicker3 > & GetFilePicker() const
static std::unique_ptr< SfxTabPage > Create(weld::Container *pPage, weld::DialogController *pController, const SfxItemSet *rSet)
Definition: optpath.cxx:217
weld::Window * GetFrameWeld(const SfxFrame *pFrame)
aStr
std::unique_ptr< OptPath_Impl > pImpl
Definition: optpath.hxx:36
constexpr OUStringLiteral POSTFIX_INTERNAL
Definition: optpath.cxx:55
std::unique_ptr< weld::Button > m_xPathBtn
Definition: optpath.hxx:42
sal_uInt16 nPos
OUString sId