Line data Source code
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 <tools/shl.hxx>
22 : #include <vcl/msgbox.hxx>
23 : #include <sfx2/filedlghelper.hxx>
24 : #include <sfx2/app.hxx>
25 : #include <svl/aeitem.hxx>
26 : #include <svtools/svtabbx.hxx>
27 : #include "svtools/treelistentry.hxx"
28 : #include <tools/urlobj.hxx>
29 : #include <vcl/svapp.hxx>
30 : #include <unotools/defaultoptions.hxx>
31 : #include <unotools/localfilehelper.hxx>
32 : #include <unotools/pathoptions.hxx>
33 : #include <unotools/moduleoptions.hxx>
34 : #include <unotools/viewoptions.hxx>
35 :
36 : #define _SVX_OPTPATH_CXX
37 :
38 : #include "optpath.hxx"
39 : #include <dialmgr.hxx>
40 : #include "optpath.hrc"
41 : #include <cuires.hrc>
42 : #include "helpid.hrc"
43 : #include <comphelper/configuration.hxx>
44 : #include <comphelper/processfactory.hxx>
45 : #include <comphelper/string.hxx>
46 : #include <com/sun/star/uno/Exception.hpp>
47 : #include <com/sun/star/beans/XPropertySet.hpp>
48 : #include <com/sun/star/beans/PropertyAttribute.hpp>
49 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
50 : #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
51 : #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
52 : #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
53 : #include <officecfg/Office/Common.hxx>
54 : #include "optHeaderTabListbox.hxx"
55 : #include <readonlyimage.hxx>
56 : #include <vcl/help.hxx>
57 :
58 : using namespace ::com::sun::star::beans;
59 : using namespace ::com::sun::star::lang;
60 : using namespace ::com::sun::star::ui::dialogs;
61 : using namespace ::com::sun::star::uno;
62 : using namespace svx;
63 :
64 : // define ----------------------------------------------------------------
65 :
66 : #define TAB_WIDTH1 80
67 : #define TAB_WIDTH_MIN 10
68 : #define TAB_WIDTH2 1000
69 : #define ITEMID_TYPE 1
70 : #define ITEMID_PATH 2
71 :
72 : #define POSTFIX_INTERNAL rtl::OUString("_internal")
73 : #define POSTFIX_USER rtl::OUString("_user")
74 : #define POSTFIX_WRITABLE rtl::OUString("_writable")
75 : #define VAR_ONE rtl::OUString("%1")
76 : #define IODLG_CONFIGNAME rtl::OUString("FilePicker_Save")
77 :
78 : // struct OptPath_Impl ---------------------------------------------------
79 :
80 0 : struct OptPath_Impl
81 : {
82 : SvtDefaultOptions m_aDefOpt;
83 : Image m_aLockImage;
84 : String m_sMultiPathDlg;
85 : Reference< XPropertySet > m_xPathSettings;
86 :
87 0 : OptPath_Impl(const ResId& rLockRes)
88 0 : : m_aLockImage(rLockRes)
89 : {
90 0 : }
91 : };
92 :
93 : // struct PathUserData_Impl ----------------------------------------------
94 :
95 0 : struct PathUserData_Impl
96 : {
97 : sal_uInt16 nRealId;
98 : SfxItemState eState;
99 : String sUserPath;
100 : String sWritablePath;
101 :
102 0 : PathUserData_Impl( sal_uInt16 nId ) :
103 0 : nRealId( nId ), eState( SFX_ITEM_UNKNOWN ) {}
104 : };
105 :
106 : struct Handle2CfgNameMapping_Impl
107 : {
108 : sal_uInt16 m_nHandle;
109 : const char* m_pCfgName;
110 : };
111 :
112 : static Handle2CfgNameMapping_Impl const Hdl2CfgMap_Impl[] =
113 : {
114 : { SvtPathOptions::PATH_AUTOCORRECT, "AutoCorrect" },
115 : { SvtPathOptions::PATH_AUTOTEXT, "AutoText" },
116 : { SvtPathOptions::PATH_BACKUP, "Backup" },
117 : { SvtPathOptions::PATH_GALLERY, "Gallery" },
118 : { SvtPathOptions::PATH_GRAPHIC, "Graphic" },
119 : { SvtPathOptions::PATH_TEMP, "Temp" },
120 : { SvtPathOptions::PATH_TEMPLATE, "Template" },
121 : { SvtPathOptions::PATH_WORK, "Work" },
122 : #if OSL_DEBUG_LEVEL > 1
123 : { SvtPathOptions::PATH_LINGUISTIC, "Linguistic" },
124 : { SvtPathOptions::PATH_DICTIONARY, "Dictionary" },
125 : #endif
126 : { USHRT_MAX, NULL }
127 : };
128 :
129 0 : static String getCfgName_Impl( sal_uInt16 _nHandle )
130 : {
131 0 : String sCfgName;
132 0 : sal_uInt16 nIndex = 0;
133 0 : while ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle != USHRT_MAX )
134 : {
135 0 : if ( Hdl2CfgMap_Impl[ nIndex ].m_nHandle == _nHandle )
136 : {
137 : // config name found
138 0 : sCfgName = rtl::OUString::createFromAscii( Hdl2CfgMap_Impl[ nIndex ].m_pCfgName );
139 0 : break;
140 : }
141 0 : ++nIndex;
142 : }
143 :
144 0 : return sCfgName;
145 : }
146 :
147 : #define MULTIPATH_DELIMITER ';'
148 :
149 0 : String Convert_Impl( const String& rValue )
150 : {
151 0 : char cDelim = MULTIPATH_DELIMITER;
152 0 : sal_uInt16 nCount = comphelper::string::getTokenCount(rValue, cDelim);
153 0 : String aReturn;
154 0 : for ( sal_uInt16 i=0; i<nCount ; ++i )
155 : {
156 0 : String aValue = rValue.GetToken( i, cDelim );
157 0 : INetURLObject aObj( aValue );
158 0 : if ( aObj.GetProtocol() == INET_PROT_FILE )
159 0 : aReturn += String(aObj.PathToFileName());
160 0 : else if ( ::utl::LocalFileHelper::IsFileContent( aValue ) )
161 0 : aReturn += String(aObj.GetURLPath( INetURLObject::DECODE_WITH_CHARSET ));
162 0 : if ( i+1 < nCount)
163 0 : aReturn += MULTIPATH_DELIMITER;
164 0 : }
165 :
166 0 : return aReturn;
167 : }
168 :
169 : // class SvxControlFocusHelper ---------------------------------------------
170 :
171 0 : long SvxControlFocusHelper::Notify( NotifyEvent& rNEvt )
172 : {
173 0 : long nRet = Control::Notify( rNEvt );
174 :
175 0 : if ( m_pFocusCtrl && rNEvt.GetWindow() != m_pFocusCtrl && rNEvt.GetType() == EVENT_GETFOCUS )
176 0 : m_pFocusCtrl->GrabFocus();
177 0 : return nRet;
178 : }
179 :
180 : // functions -------------------------------------------------------------
181 :
182 0 : sal_Bool IsMultiPath_Impl( const sal_uInt16 nIndex )
183 : {
184 : #if OSL_DEBUG_LEVEL > 1
185 : return ( SvtPathOptions::PATH_AUTOCORRECT == nIndex ||
186 : SvtPathOptions::PATH_AUTOTEXT == nIndex ||
187 : SvtPathOptions::PATH_BASIC == nIndex ||
188 : SvtPathOptions::PATH_GALLERY == nIndex ||
189 : SvtPathOptions::PATH_TEMPLATE == nIndex );
190 : #else
191 : return ( SvtPathOptions::PATH_AUTOCORRECT == nIndex ||
192 : SvtPathOptions::PATH_AUTOTEXT == nIndex ||
193 : SvtPathOptions::PATH_BASIC == nIndex ||
194 : SvtPathOptions::PATH_GALLERY == nIndex ||
195 : SvtPathOptions::PATH_TEMPLATE == nIndex ||
196 : SvtPathOptions::PATH_LINGUISTIC == nIndex ||
197 0 : SvtPathOptions::PATH_DICTIONARY == nIndex );
198 : #endif
199 : }
200 :
201 : // class SvxPathTabPage --------------------------------------------------
202 :
203 0 : SvxPathTabPage::SvxPathTabPage( Window* pParent, const SfxItemSet& rSet ) :
204 :
205 0 : SfxTabPage( pParent, CUI_RES( RID_SFXPAGE_PATH ), rSet ),
206 :
207 0 : aStdBox ( this, CUI_RES( GB_STD ) ),
208 0 : aTypeText ( this, CUI_RES( FT_TYPE ) ),
209 0 : aPathText ( this, CUI_RES( FT_PATH ) ),
210 0 : aPathCtrl ( this, CUI_RES( LB_PATH ) ),
211 0 : aStandardBtn ( this, CUI_RES( BTN_STANDARD ) ),
212 0 : aPathBtn ( this, CUI_RES( BTN_PATH ) ),
213 : pHeaderBar ( NULL ),
214 : pPathBox ( NULL ),
215 0 : pImpl ( new OptPath_Impl( CUI_RES(IMG_LOCK) ) ),
216 0 : xDialogListener ( new ::svt::DialogClosedListener() )
217 :
218 : {
219 0 : pImpl->m_sMultiPathDlg = String( CUI_RES( STR_MULTIPATHDLG ) );
220 0 : aStandardBtn.SetClickHdl( LINK( this, SvxPathTabPage, StandardHdl_Impl ) );
221 0 : Link aLink = LINK( this, SvxPathTabPage, PathHdl_Impl );
222 0 : aPathBtn.SetClickHdl( aLink );
223 0 : Size aBoxSize = aPathCtrl.GetOutputSizePixel();
224 0 : pHeaderBar = new HeaderBar( &aPathCtrl, WB_BUTTONSTYLE | WB_BOTTOMBORDER );
225 0 : pHeaderBar->SetPosSizePixel( Point( 0, 0 ), Size( aBoxSize.Width(), 16 ) );
226 0 : pHeaderBar->SetSelectHdl( LINK( this, SvxPathTabPage, HeaderSelect_Impl ) );
227 0 : pHeaderBar->SetEndDragHdl( LINK( this, SvxPathTabPage, HeaderEndDrag_Impl ) );
228 0 : Size aSz;
229 0 : aSz.Width() = TAB_WIDTH1;
230 : pHeaderBar->InsertItem( ITEMID_TYPE, aTypeText.GetText(),
231 0 : LogicToPixel( aSz, MapMode( MAP_APPFONT ) ).Width(),
232 0 : HIB_LEFT | HIB_VCENTER | HIB_CLICKABLE | HIB_UPARROW );
233 0 : aSz.Width() = TAB_WIDTH2;
234 : pHeaderBar->InsertItem( ITEMID_PATH, aPathText.GetText(),
235 0 : LogicToPixel( aSz, MapMode( MAP_APPFONT ) ).Width(),
236 0 : HIB_LEFT | HIB_VCENTER );
237 :
238 : static long nTabs[] = {3, 0, TAB_WIDTH1, TAB_WIDTH1 + TAB_WIDTH2 };
239 0 : Size aHeadSize = pHeaderBar->GetSizePixel();
240 :
241 0 : WinBits nBits = WB_SORT | WB_HSCROLL | WB_CLIPCHILDREN | WB_TABSTOP;
242 0 : pPathBox = new svx::OptHeaderTabListBox( &aPathCtrl, nBits );
243 0 : aPathCtrl.SetFocusControl( pPathBox );
244 0 : pPathBox->SetDoubleClickHdl( aLink );
245 0 : pPathBox->SetSelectHdl( LINK( this, SvxPathTabPage, PathSelect_Impl ) );
246 0 : pPathBox->SetSelectionMode( MULTIPLE_SELECTION );
247 0 : pPathBox->SetPosSizePixel( Point( 0, aHeadSize.Height() ),
248 0 : Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) );
249 0 : pPathBox->SetTabs( &nTabs[0], MAP_APPFONT );
250 0 : pPathBox->InitHeaderBar( pHeaderBar );
251 0 : pPathBox->SetHighlightRange();
252 0 : pPathBox->SetHelpId( HID_OPTPATH_CTL_PATH );
253 0 : pHeaderBar->SetHelpId( HID_OPTPATH_HEADERBAR );
254 0 : pPathBox->Show();
255 0 : pHeaderBar->Show();
256 :
257 0 : FreeResource();
258 :
259 0 : xDialogListener->SetDialogClosedLink( LINK( this, SvxPathTabPage, DialogClosedHdl ) );
260 0 : }
261 :
262 : // -----------------------------------------------------------------------
263 :
264 0 : SvxPathTabPage::~SvxPathTabPage()
265 : {
266 : // #110603# do not grab focus to a destroyed window !!!
267 0 : aPathCtrl.SetFocusControl( NULL );
268 :
269 0 : pHeaderBar->Hide();
270 0 : for ( sal_uInt16 i = 0; i < pPathBox->GetEntryCount(); ++i )
271 0 : delete (PathUserData_Impl*)pPathBox->GetEntry(i)->GetUserData();
272 0 : delete pPathBox;
273 0 : delete pHeaderBar;
274 0 : delete pImpl;
275 0 : }
276 :
277 : // -----------------------------------------------------------------------
278 :
279 0 : SfxTabPage* SvxPathTabPage::Create( Window* pParent,
280 : const SfxItemSet& rAttrSet )
281 : {
282 0 : return ( new SvxPathTabPage( pParent, rAttrSet ) );
283 : }
284 :
285 : // -----------------------------------------------------------------------
286 :
287 0 : sal_Bool SvxPathTabPage::FillItemSet( SfxItemSet& )
288 : {
289 0 : SvtPathOptions aPathOpt;
290 0 : for ( sal_uInt16 i = 0; i < pPathBox->GetEntryCount(); ++i )
291 : {
292 0 : PathUserData_Impl* pPathImpl = (PathUserData_Impl*)pPathBox->GetEntry(i)->GetUserData();
293 0 : sal_uInt16 nRealId = pPathImpl->nRealId;
294 0 : if ( pPathImpl->eState == SFX_ITEM_SET )
295 0 : SetPathList( nRealId, pPathImpl->sUserPath, pPathImpl->sWritablePath );
296 : }
297 0 : return sal_True;
298 : }
299 :
300 : // -----------------------------------------------------------------------
301 :
302 0 : void SvxPathTabPage::Reset( const SfxItemSet& )
303 : {
304 0 : pPathBox->Clear();
305 0 : SvtPathOptions aPathOpt; //! deprecated
306 :
307 0 : for( sal_uInt16 i = 0; i <= (sal_uInt16)SvtPathOptions::PATH_WORK; ++i )
308 : {
309 : // only writer uses autotext
310 0 : if ( i == SvtPathOptions::PATH_AUTOTEXT
311 0 : && !SvtModuleOptions().IsModuleInstalled( SvtModuleOptions::E_SWRITER ) )
312 0 : continue;
313 :
314 0 : switch (i)
315 : {
316 : case SvtPathOptions::PATH_AUTOCORRECT:
317 : case SvtPathOptions::PATH_AUTOTEXT:
318 : case SvtPathOptions::PATH_BACKUP:
319 : case SvtPathOptions::PATH_GALLERY:
320 : case SvtPathOptions::PATH_GRAPHIC:
321 : case SvtPathOptions::PATH_TEMP:
322 : case SvtPathOptions::PATH_TEMPLATE:
323 : #if OSL_DEBUG_LEVEL > 1
324 : case SvtPathOptions::PATH_LINGUISTIC:
325 : case SvtPathOptions::PATH_DICTIONARY:
326 : #endif
327 : case SvtPathOptions::PATH_WORK:
328 : {
329 0 : String aStr( CUI_RES( RID_SVXSTR_PATH_NAME_START + i ) );
330 0 : String sInternal, sUser, sWritable;
331 0 : sal_Bool bReadOnly = sal_False;
332 0 : GetPathList( i, sInternal, sUser, sWritable, bReadOnly );
333 0 : String sTmpPath = sUser;
334 0 : if ( sTmpPath.Len() > 0 && sWritable.Len() > 0 )
335 0 : sTmpPath += MULTIPATH_DELIMITER;
336 0 : sTmpPath += sWritable;
337 0 : String aValue( sTmpPath );
338 0 : aStr += '\t';
339 0 : aStr += Convert_Impl( aValue );
340 0 : SvTreeListEntry* pEntry = pPathBox->InsertEntry( aStr );
341 0 : if ( bReadOnly )
342 : {
343 0 : pPathBox->SetCollapsedEntryBmp( pEntry, pImpl->m_aLockImage );
344 : }
345 0 : PathUserData_Impl* pPathImpl = new PathUserData_Impl(i);
346 0 : pPathImpl->sUserPath = sUser;
347 0 : pPathImpl->sWritablePath = sWritable;
348 0 : pEntry->SetUserData( pPathImpl );
349 : }
350 : }
351 : }
352 :
353 0 : String aUserData = GetUserData();
354 0 : if ( aUserData.Len() )
355 : {
356 : // restore column width
357 0 : pHeaderBar->SetItemSize( ITEMID_TYPE, aUserData.GetToken(0).ToInt32() );
358 0 : HeaderEndDrag_Impl( NULL );
359 : // restore sort direction
360 0 : sal_Bool bUp = (sal_Bool)(sal_uInt16)aUserData.GetToken(1).ToInt32();
361 0 : HeaderBarItemBits nBits = pHeaderBar->GetItemBits(ITEMID_TYPE);
362 :
363 0 : if ( bUp )
364 : {
365 0 : nBits &= ~HIB_UPARROW;
366 0 : nBits |= HIB_DOWNARROW;
367 : }
368 : else
369 : {
370 0 : nBits &= ~HIB_DOWNARROW;
371 0 : nBits |= HIB_UPARROW;
372 : }
373 0 : pHeaderBar->SetItemBits( ITEMID_TYPE, nBits );
374 0 : HeaderSelect_Impl( NULL );
375 : }
376 0 : PathSelect_Impl( NULL );
377 0 : }
378 :
379 : // -----------------------------------------------------------------------
380 :
381 0 : void SvxPathTabPage::FillUserData()
382 : {
383 0 : String aUserData = String::CreateFromInt32( pHeaderBar->GetItemSize( ITEMID_TYPE ) );
384 0 : aUserData += ';';
385 0 : HeaderBarItemBits nBits = pHeaderBar->GetItemBits( ITEMID_TYPE );
386 0 : sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
387 0 : aUserData += bUp ? '1' : '0';
388 0 : SetUserData( aUserData );
389 0 : }
390 :
391 : // -----------------------------------------------------------------------
392 :
393 0 : IMPL_LINK_NOARG(SvxPathTabPage, PathSelect_Impl)
394 : {
395 0 : sal_uInt16 nSelCount = 0;
396 0 : SvTreeListEntry* pEntry = pPathBox->FirstSelected();
397 :
398 : //the entry image indicates whether the path is write protected
399 0 : Image aEntryImage;
400 0 : if(pEntry)
401 0 : aEntryImage = pPathBox->GetCollapsedEntryBmp( pEntry );
402 0 : sal_Bool bEnable = !aEntryImage;
403 0 : while ( pEntry && ( nSelCount < 2 ) )
404 : {
405 0 : nSelCount++;
406 0 : pEntry = pPathBox->NextSelected( pEntry );
407 : }
408 :
409 0 : aPathBtn.Enable( 1 == nSelCount && bEnable);
410 0 : aStandardBtn.Enable( nSelCount > 0 && bEnable);
411 0 : return 0;
412 : }
413 :
414 : // -----------------------------------------------------------------------
415 :
416 0 : IMPL_LINK_NOARG(SvxPathTabPage, StandardHdl_Impl)
417 : {
418 0 : SvTreeListEntry* pEntry = pPathBox->FirstSelected();
419 0 : while ( pEntry )
420 : {
421 0 : PathUserData_Impl* pPathImpl = (PathUserData_Impl*)pEntry->GetUserData();
422 0 : String aOldPath = pImpl->m_aDefOpt.GetDefaultPath( pPathImpl->nRealId );
423 :
424 0 : if ( aOldPath.Len() )
425 : {
426 0 : String sInternal, sUser, sWritable, sTemp;
427 0 : sal_Bool bReadOnly = sal_False;
428 0 : GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
429 :
430 : sal_uInt16 i;
431 0 : sal_uInt16 nOldCount = comphelper::string::getTokenCount(aOldPath, MULTIPATH_DELIMITER);
432 0 : sal_uInt16 nIntCount = comphelper::string::getTokenCount(sInternal, MULTIPATH_DELIMITER);
433 0 : for ( i = 0; i < nOldCount; ++i )
434 : {
435 0 : bool bFound = false;
436 0 : String sOnePath = aOldPath.GetToken( i, MULTIPATH_DELIMITER );
437 0 : for ( sal_uInt16 j = 0; !bFound && j < nIntCount; ++j )
438 : {
439 0 : if ( sInternal.GetToken( i, MULTIPATH_DELIMITER ) == sOnePath )
440 0 : bFound = true;
441 : }
442 0 : if ( !bFound )
443 : {
444 0 : if ( sTemp.Len() > 0 )
445 0 : sTemp += MULTIPATH_DELIMITER;
446 0 : sTemp += sOnePath;
447 : }
448 0 : }
449 :
450 0 : String sUserPath, sWritablePath;
451 0 : nOldCount = comphelper::string::getTokenCount(sTemp, MULTIPATH_DELIMITER);
452 0 : for ( i = 0; nOldCount > 0 && i < nOldCount - 1; ++i )
453 : {
454 0 : if ( sUserPath.Len() > 0 )
455 0 : sUserPath += MULTIPATH_DELIMITER;
456 0 : sUserPath += sTemp.GetToken( i, MULTIPATH_DELIMITER );
457 : }
458 0 : sWritablePath = sTemp.GetToken( nOldCount - 1, MULTIPATH_DELIMITER );
459 :
460 0 : pPathBox->SetEntryText( Convert_Impl( sTemp ), pEntry, 1 );
461 0 : pPathImpl->eState = SFX_ITEM_SET;
462 0 : pPathImpl->sUserPath = sUserPath;
463 0 : pPathImpl->sWritablePath = sWritablePath;
464 : }
465 0 : pEntry = pPathBox->NextSelected( pEntry );
466 0 : }
467 0 : return 0;
468 : }
469 :
470 : // -----------------------------------------------------------------------
471 :
472 0 : void SvxPathTabPage::ChangeCurrentEntry( const String& _rFolder )
473 : {
474 0 : SvTreeListEntry* pEntry = pPathBox->GetCurEntry();
475 0 : if ( !pEntry )
476 : {
477 : SAL_WARN( "cui.options", "SvxPathTabPage::ChangeCurrentEntry(): no entry" );
478 0 : return;
479 : }
480 :
481 0 : String sInternal, sUser, sWritable;
482 0 : PathUserData_Impl* pPathImpl = (PathUserData_Impl*)pEntry->GetUserData();
483 0 : sal_Bool bReadOnly = sal_False;
484 0 : GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
485 0 : sUser = pPathImpl->sUserPath;
486 0 : sWritable = pPathImpl->sWritablePath;
487 0 : sal_uInt16 nPos = pPathImpl->nRealId;
488 :
489 : // old path is an URL?
490 0 : INetURLObject aObj( sWritable );
491 0 : bool bURL = ( aObj.GetProtocol() != INET_PROT_NOT_VALID );
492 0 : rtl::OUString aPathStr( _rFolder );
493 0 : INetURLObject aNewObj( aPathStr );
494 0 : aNewObj.removeFinalSlash();
495 :
496 : // then the new path also an URL else system path
497 0 : String sNewPathStr = bURL ? aPathStr : aNewObj.getFSysPath( INetURLObject::FSYS_DETECT );
498 :
499 : bool bChanged =
500 : #ifdef UNX
501 : // Unix is case sensitive
502 0 : ( sNewPathStr != sWritable );
503 : #else
504 : ( sNewPathStr.CompareIgnoreCaseToAscii( sWritable ) != COMPARE_EQUAL );
505 : #endif
506 :
507 0 : if ( bChanged )
508 : {
509 0 : pPathBox->SetEntryText( Convert_Impl( sNewPathStr ), pEntry, 1 );
510 0 : nPos = (sal_uInt16)pPathBox->GetModel()->GetAbsPos( pEntry );
511 0 : pPathImpl = (PathUserData_Impl*)pPathBox->GetEntry(nPos)->GetUserData();
512 0 : pPathImpl->eState = SFX_ITEM_SET;
513 0 : pPathImpl->sWritablePath = sNewPathStr;
514 0 : if ( SvtPathOptions::PATH_WORK == pPathImpl->nRealId )
515 : {
516 : // Remove view options entry so the new work path
517 : // will be used for the next open dialog.
518 0 : SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
519 0 : aDlgOpt.Delete();
520 : // Reset also last used dir in the sfx application instance
521 0 : SfxApplication *pSfxApp = SFX_APP();
522 0 : pSfxApp->ResetLastDir();
523 :
524 : // Set configuration flag to notify file picker that it's necessary
525 : // to take over the path provided.
526 : boost::shared_ptr< comphelper::ConfigurationChanges > batch(
527 0 : comphelper::ConfigurationChanges::create());
528 : officecfg::Office::Common::Path::Info::WorkPathChanged::set(
529 0 : true, batch);
530 0 : batch->commit();
531 : }
532 0 : }
533 : }
534 :
535 : // -----------------------------------------------------------------------
536 :
537 0 : IMPL_LINK_NOARG(SvxPathTabPage, PathHdl_Impl)
538 : {
539 0 : SvTreeListEntry* pEntry = pPathBox->GetCurEntry();
540 0 : sal_uInt16 nPos = ( pEntry != NULL ) ? ( (PathUserData_Impl*)pEntry->GetUserData() )->nRealId : 0;
541 0 : String sInternal, sUser, sWritable;
542 0 : if ( pEntry )
543 : {
544 0 : PathUserData_Impl* pPathImpl = (PathUserData_Impl*)pEntry->GetUserData();
545 0 : sal_Bool bReadOnly = sal_False;
546 0 : GetPathList( pPathImpl->nRealId, sInternal, sUser, sWritable, bReadOnly );
547 0 : sUser = pPathImpl->sUserPath;
548 0 : sWritable = pPathImpl->sWritablePath;
549 : }
550 :
551 0 : if(pEntry && !(!((OptHeaderTabListBox*)pPathBox)->GetCollapsedEntryBmp(pEntry)))
552 0 : return 0;
553 :
554 0 : if ( IsMultiPath_Impl( nPos ) )
555 : {
556 0 : SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
557 0 : if ( pFact )
558 : {
559 : AbstractSvxMultiPathDialog* pMultiDlg =
560 0 : pFact->CreateSvxMultiPathDialog( this );
561 : DBG_ASSERT( pMultiDlg, "Dialogdiet fail!" );
562 0 : pMultiDlg->EnableRadioButtonMode();
563 :
564 0 : String sPath( sUser );
565 0 : if ( sPath.Len() > 0 )
566 0 : sPath += MULTIPATH_DELIMITER;
567 0 : sPath += sWritable;
568 0 : pMultiDlg->SetPath( sPath );
569 :
570 0 : String sPathName = pPathBox->GetEntryText( pEntry, 0 );
571 0 : String sNewTitle( pImpl->m_sMultiPathDlg );
572 0 : sNewTitle.SearchAndReplace( VAR_ONE, sPathName );
573 0 : pMultiDlg->SetTitle( sNewTitle );
574 :
575 0 : if ( pMultiDlg->Execute() == RET_OK && pEntry )
576 : {
577 0 : sUser.Erase();
578 0 : sWritable.Erase();
579 0 : String sFullPath;
580 0 : String sNewPath = pMultiDlg->GetPath();
581 0 : char cDelim = MULTIPATH_DELIMITER;
582 0 : sal_uInt16 nCount = comphelper::string::getTokenCount(sNewPath, cDelim);
583 0 : if ( nCount > 0 )
584 : {
585 0 : sal_uInt16 i = 0;
586 0 : for ( ; i < nCount - 1; ++i )
587 : {
588 0 : if ( sUser.Len() > 0 )
589 0 : sUser += cDelim;
590 0 : sUser += sNewPath.GetToken( i, cDelim );
591 : }
592 0 : if ( sFullPath.Len() > 0 )
593 0 : sFullPath += cDelim;
594 0 : sFullPath += sUser;
595 0 : sWritable += sNewPath.GetToken( i, cDelim );
596 0 : if ( sFullPath.Len() > 0 )
597 0 : sFullPath += cDelim;
598 0 : sFullPath += sWritable;
599 : }
600 :
601 0 : pPathBox->SetEntryText( Convert_Impl( sFullPath ), pEntry, 1 );
602 : // save modified flag
603 0 : PathUserData_Impl* pPathImpl = (PathUserData_Impl*)pEntry->GetUserData();
604 0 : pPathImpl->eState = SFX_ITEM_SET;
605 0 : pPathImpl->sUserPath = sUser;
606 0 : pPathImpl->sWritablePath = sWritable;
607 : }
608 0 : delete pMultiDlg;
609 : }
610 : }
611 0 : else if ( pEntry )
612 : {
613 : try
614 : {
615 0 : Reference < XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
616 0 : xFolderPicker = FolderPicker::create(xContext);;
617 :
618 0 : INetURLObject aURL( sWritable, INET_PROT_FILE );
619 0 : xFolderPicker->setDisplayDirectory( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
620 :
621 0 : Reference< XAsynchronousExecutableDialog > xAsyncDlg( xFolderPicker, UNO_QUERY );
622 0 : if ( xAsyncDlg.is() )
623 0 : xAsyncDlg->startExecuteModal( xDialogListener.get() );
624 : else
625 : {
626 0 : short nRet = xFolderPicker->execute();
627 0 : if ( ExecutableDialogResults::OK != nRet )
628 0 : return 0;
629 :
630 0 : String sFolder( xFolderPicker->getDirectory() );
631 0 : ChangeCurrentEntry( sFolder );
632 0 : }
633 : }
634 0 : catch( Exception& )
635 : {
636 : SAL_WARN( "cui.options", "SvxPathTabPage::PathHdl_Impl: exception from folder picker" );
637 : }
638 : }
639 0 : return 0;
640 : }
641 :
642 : // -----------------------------------------------------------------------
643 :
644 0 : IMPL_LINK( SvxPathTabPage, HeaderSelect_Impl, HeaderBar*, pBar )
645 : {
646 0 : if ( pBar && pBar->GetCurItemId() != ITEMID_TYPE )
647 0 : return 0;
648 :
649 0 : HeaderBarItemBits nBits = pHeaderBar->GetItemBits(ITEMID_TYPE);
650 0 : sal_Bool bUp = ( ( nBits & HIB_UPARROW ) == HIB_UPARROW );
651 0 : SvSortMode eMode = SortAscending;
652 :
653 0 : if ( bUp )
654 : {
655 0 : nBits &= ~HIB_UPARROW;
656 0 : nBits |= HIB_DOWNARROW;
657 0 : eMode = SortDescending;
658 : }
659 : else
660 : {
661 0 : nBits &= ~HIB_DOWNARROW;
662 0 : nBits |= HIB_UPARROW;
663 : }
664 0 : pHeaderBar->SetItemBits( ITEMID_TYPE, nBits );
665 0 : SvTreeList* pModel = pPathBox->GetModel();
666 0 : pModel->SetSortMode( eMode );
667 0 : pModel->Resort();
668 0 : return 1;
669 : }
670 :
671 : // -----------------------------------------------------------------------
672 :
673 0 : IMPL_LINK( SvxPathTabPage, HeaderEndDrag_Impl, HeaderBar*, pBar )
674 : {
675 0 : if ( pBar && !pBar->GetCurItemId() )
676 0 : return 0;
677 :
678 0 : if ( !pHeaderBar->IsItemMode() )
679 : {
680 0 : Size aSz;
681 0 : sal_uInt16 nTabs = pHeaderBar->GetItemCount();
682 0 : long nTmpSz = 0;
683 0 : long nWidth = pHeaderBar->GetItemSize(ITEMID_TYPE);
684 0 : long nBarWidth = pHeaderBar->GetSizePixel().Width();
685 :
686 0 : if(nWidth < TAB_WIDTH_MIN)
687 0 : pHeaderBar->SetItemSize( ITEMID_TYPE, TAB_WIDTH_MIN);
688 0 : else if ( ( nBarWidth - nWidth ) < TAB_WIDTH_MIN )
689 0 : pHeaderBar->SetItemSize( ITEMID_TYPE, nBarWidth - TAB_WIDTH_MIN );
690 :
691 0 : for ( sal_uInt16 i = 1; i <= nTabs; ++i )
692 : {
693 0 : long _nWidth = pHeaderBar->GetItemSize(i);
694 0 : aSz.Width() = _nWidth + nTmpSz;
695 0 : nTmpSz += _nWidth;
696 0 : pPathBox->SetTab( i, PixelToLogic( aSz, MapMode(MAP_APPFONT) ).Width(), MAP_APPFONT );
697 : }
698 : }
699 0 : return 1;
700 : }
701 :
702 : // -----------------------------------------------------------------------
703 :
704 0 : IMPL_LINK( SvxPathTabPage, DialogClosedHdl, DialogClosedEvent*, pEvt )
705 : {
706 0 : if ( RET_OK == pEvt->DialogResult )
707 : {
708 : DBG_ASSERT( xFolderPicker.is() == sal_True, "SvxPathTabPage::DialogClosedHdl(): no folder picker" );
709 :
710 0 : String sURL = String( xFolderPicker->getDirectory() );
711 0 : ChangeCurrentEntry( sURL );
712 : }
713 0 : return 0L;
714 : }
715 :
716 : // -----------------------------------------------------------------------
717 :
718 0 : void SvxPathTabPage::GetPathList(
719 : sal_uInt16 _nPathHandle, String& _rInternalPath,
720 : String& _rUserPath, String& _rWritablePath, sal_Bool& _rReadOnly )
721 : {
722 0 : String sCfgName = getCfgName_Impl( _nPathHandle );
723 :
724 : // load PathSettings service if necessary
725 0 : if ( !pImpl->m_xPathSettings.is() )
726 : {
727 0 : Reference< XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory();
728 0 : pImpl->m_xPathSettings = Reference< XPropertySet >( xSMgr->createInstance(
729 : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
730 0 : "com.sun.star.util.PathSettings") ) ), UNO_QUERY );
731 : }
732 :
733 : try
734 : {
735 0 : if ( pImpl->m_xPathSettings.is() )
736 : {
737 : // load internal paths
738 0 : String sProp( sCfgName );
739 0 : sProp = sCfgName;
740 0 : sProp += POSTFIX_INTERNAL;
741 0 : Any aAny = pImpl->m_xPathSettings->getPropertyValue( sProp );
742 0 : Sequence< ::rtl::OUString > aPathSeq;
743 0 : if ( aAny >>= aPathSeq )
744 : {
745 0 : long i, nCount = aPathSeq.getLength();
746 0 : const ::rtl::OUString* pPaths = aPathSeq.getConstArray();
747 :
748 0 : for ( i = 0; i < nCount; ++i )
749 : {
750 0 : if ( _rInternalPath.Len() > 0 )
751 0 : _rInternalPath += ';';
752 0 : _rInternalPath += String( pPaths[i] );
753 : }
754 : }
755 : // load user paths
756 0 : sProp = sCfgName;
757 0 : sProp += POSTFIX_USER;
758 0 : aAny = pImpl->m_xPathSettings->getPropertyValue( sProp );
759 0 : if ( aAny >>= aPathSeq )
760 : {
761 0 : long i, nCount = aPathSeq.getLength();
762 0 : const ::rtl::OUString* pPaths = aPathSeq.getConstArray();
763 :
764 0 : for ( i = 0; i < nCount; ++i )
765 : {
766 0 : if ( _rUserPath.Len() > 0 )
767 0 : _rUserPath += ';';
768 0 : _rUserPath += String( pPaths[i] );
769 : }
770 : }
771 : // then the writable path
772 0 : sProp = sCfgName;
773 0 : sProp += POSTFIX_WRITABLE;
774 0 : aAny = pImpl->m_xPathSettings->getPropertyValue( sProp );
775 0 : ::rtl::OUString sWritablePath;
776 0 : if ( aAny >>= sWritablePath )
777 0 : _rWritablePath = String( sWritablePath );
778 :
779 : // and the readonly flag
780 0 : sProp = sCfgName;
781 0 : Reference< XPropertySetInfo > xInfo = pImpl->m_xPathSettings->getPropertySetInfo();
782 0 : Property aProp = xInfo->getPropertyByName( sProp );
783 0 : _rReadOnly = ( ( aProp.Attributes & PropertyAttribute::READONLY ) == PropertyAttribute::READONLY );
784 : }
785 : }
786 0 : catch( const Exception& )
787 : {
788 : OSL_FAIL( "SvxPathTabPage::GetPathList(): caught an exception!" );
789 0 : }
790 0 : }
791 :
792 : // -----------------------------------------------------------------------
793 :
794 0 : void SvxPathTabPage::SetPathList(
795 : sal_uInt16 _nPathHandle, const String& _rUserPath, const String& _rWritablePath )
796 : {
797 0 : String sCfgName = getCfgName_Impl( _nPathHandle );
798 :
799 : // load PathSettings service if necessary
800 0 : if ( !pImpl->m_xPathSettings.is() )
801 : {
802 0 : Reference< XMultiServiceFactory > xSMgr = comphelper::getProcessServiceFactory();
803 0 : pImpl->m_xPathSettings = Reference< XPropertySet >( xSMgr->createInstance(
804 : rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
805 0 : "com.sun.star.util.PathSettings") ) ), UNO_QUERY );
806 : }
807 :
808 : try
809 : {
810 0 : if ( pImpl->m_xPathSettings.is() )
811 : {
812 : // save user paths
813 0 : char cDelim = MULTIPATH_DELIMITER;
814 0 : sal_uInt16 nCount = comphelper::string::getTokenCount(_rUserPath, cDelim);
815 0 : Sequence< ::rtl::OUString > aPathSeq( nCount );
816 0 : ::rtl::OUString* pArray = aPathSeq.getArray();
817 0 : for ( sal_uInt16 i = 0; i < nCount; ++i )
818 0 : pArray[i] = ::rtl::OUString( _rUserPath.GetToken( i, cDelim ) );
819 0 : String sProp( sCfgName );
820 0 : sProp += POSTFIX_USER;
821 0 : Any aValue = makeAny( aPathSeq );
822 0 : pImpl->m_xPathSettings->setPropertyValue( sProp, aValue );
823 :
824 : // then the writable path
825 0 : aValue = makeAny( ::rtl::OUString( _rWritablePath ) );
826 0 : sProp = sCfgName;
827 0 : sProp += POSTFIX_WRITABLE;
828 0 : pImpl->m_xPathSettings->setPropertyValue( sProp, aValue );
829 : }
830 : }
831 0 : catch( const Exception& e )
832 : {
833 : SAL_WARN("cui", "caught: " << e.Message);
834 0 : }
835 3 : }
836 :
837 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|