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