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