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