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 96 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 110 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 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 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 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 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 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(), 16 ) ); 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 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 287 SfxTabPage* SvxPathTabPage::Create( Window* pParent, 288 const SfxItemSet& rAttrSet ) 289 { 290 return ( new SvxPathTabPage( pParent, rAttrSet ) ); 291 } 292 293 // ----------------------------------------------------------------------- 294 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 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 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 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 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 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 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 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 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 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 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 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