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_fpicker.hxx" 30 31 // includes -------------------------------------------------------------- 32 33 #include "iodlg.hxx" 34 #include <tools/stream.hxx> 35 #include <tools/urlobj.hxx> 36 #include <vcl/fixed.hxx> 37 #include <vcl/lstbox.hxx> 38 #include <vcl/msgbox.hxx> 39 #include <vcl/svapp.hxx> 40 #include <vcl/timer.hxx> 41 #include <unotools/ucbhelper.hxx> 42 #include <ucbhelper/contentbroker.hxx> 43 #include "svtools/ehdl.hxx" 44 #include "svl/urihelper.hxx" 45 #include "unotools/pathoptions.hxx" 46 #include "unotools/viewoptions.hxx" 47 #include "svtools/fileview.hxx" 48 #include "unotools/inetoptions.hxx" 49 #include "svtools/sfxecode.hxx" 50 #include "svl/svarray.hxx" 51 #include "svtools/svtabbx.hxx" 52 53 #define _SVSTDARR_USHORTS 54 #define _SVSTDARR_STRINGSDTOR 55 #include "svl/svstdarr.hxx" 56 #include <toolkit/helper/vclunohelper.hxx> 57 #include <unotools/localfilehelper.hxx> 58 59 #ifndef _SVTOOLS_HRC 60 #include "svtools/svtools.hrc" 61 #endif 62 #ifndef _SVT_HELPID_HRC 63 #include "svtools/helpid.hrc" 64 #endif 65 #ifndef _SVTOOLS_IODLGIMPL_HRC 66 #include "iodlg.hrc" 67 #endif 68 #include "rtl/instance.hxx" 69 #include "asyncfilepicker.hxx" 70 #include "iodlgimp.hxx" 71 #include "svtools/inettbc.hxx" 72 #include "unotools/syslocale.hxx" 73 #include "svtools/QueryFolderName.hxx" 74 #ifndef _RTL_USTRING_HXX 75 #include <rtl/ustring.hxx> 76 #endif 77 #include <com/sun/star/lang/XMultiServiceFactory.hpp> 78 #include <com/sun/star/ucb/XContentProviderManager.hpp> 79 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> 80 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> 81 #include <com/sun/star/ui/dialogs/ControlActions.hpp> 82 #include <com/sun/star/beans/PropertyValue.hpp> 83 #include <com/sun/star/sdbc/XResultSet.hpp> 84 #include <com/sun/star/sdbc/XRow.hpp> 85 #include <com/sun/star/util/URL.hpp> 86 #include <com/sun/star/uno/Exception.hpp> 87 #include <com/sun/star/uno/Reference.hxx> 88 #include <com/sun/star/util/XURLTransformer.hpp> 89 #include <com/sun/star/uno/RuntimeException.hpp> 90 #include <com/sun/star/beans/XPropertySet.hpp> 91 92 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX 93 #include <comphelper/processfactory.hxx> 94 #endif 95 #include <osl/file.h> 96 #include <vcl/waitobj.hxx> 97 98 // #97148# ------------------------------------ 99 #include <com/sun/star/task/XInteractionHandler.hpp> 100 #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp" 101 #include "fpinteraction.hxx" 102 #include <osl/process.h> 103 #include <comphelper/interaction.hxx> 104 105 #include <algorithm> 106 #include <functional> 107 108 //#define AUTOSELECT_USERFILTER 109 // define this for the experimental feature of user-filter auto selection 110 // means if the user enters e.g. *.doc<enter>, and there is a filter which is responsible for *.doc files (only), 111 // then this filter is selected automatically 112 113 using namespace ::com::sun::star::beans; 114 using namespace ::com::sun::star::frame; 115 using namespace ::com::sun::star::ui::dialogs; 116 using namespace ::com::sun::star::uno; 117 using namespace ::com::sun::star::lang; 118 using namespace ::com::sun::star::ucb; 119 using namespace ::com::sun::star::container; 120 using namespace ::com::sun::star::task; 121 using namespace ::com::sun::star::sdbc; 122 using namespace ::utl; 123 using namespace ::svt; 124 125 using namespace ExtendedFilePickerElementIds; 126 using namespace CommonFilePickerElementIds; 127 using namespace InternalFilePickerElementIds; 128 129 #define IODLG_CONFIGNAME String(RTL_CONSTASCII_USTRINGPARAM("FileDialog")) 130 #define IMPGRF_CONFIGNAME String(RTL_CONSTASCII_USTRINGPARAM("ImportGraphicDialog")) 131 132 #define GET_DECODED_NAME(aObj) \ 133 aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ) 134 135 // Zeit die beim Traveln in der Filterbox gewartet wird, 136 // bis in der Browsebox gefiltert wird ( in ms ). 137 #define TRAVELFILTER_TIMEOUT 750 138 139 #define WIDTH_ADDITION 15 140 141 // functions ------------------------------------------------------------- 142 143 namespace 144 { 145 146 //----------------------------------------------------------------------------- 147 String getMostCurrentFilter( SvtExpFileDlg_Impl* pImpl ) 148 { 149 DBG_ASSERT( pImpl, "invalid impl pointer" ); 150 const SvtFileDialogFilter_Impl* pFilter = pImpl->_pUserFilter; 151 152 if ( !pFilter ) 153 pFilter = pImpl->GetCurFilter(); 154 155 // Filtern. 156 if ( !pFilter ) 157 return String(); 158 159 return pFilter->GetType(); 160 } 161 162 //----------------------------------------------------------------------------- 163 sal_Bool restoreCurrentFilter( SvtExpFileDlg_Impl* _pImpl ) 164 { 165 DBG_ASSERT( _pImpl->GetCurFilter(), "restoreCurrentFilter: no current filter!" ); 166 DBG_ASSERT( _pImpl->GetCurFilterDisplayName().Len(), "restoreCurrentFilter: no current filter (no display name)!" ); 167 168 _pImpl->SelectFilterListEntry( _pImpl->GetCurFilterDisplayName() ); 169 170 #ifdef DBG_UTIL 171 String sSelectedDisplayName; 172 DBG_ASSERT( ( _pImpl->GetSelectedFilterEntry( sSelectedDisplayName ) == _pImpl->GetCurFilter() ) 173 && ( sSelectedDisplayName == _pImpl->GetCurFilterDisplayName() ), 174 "restoreCurrentFilter: inconsistence!" ); 175 #endif 176 return _pImpl->m_bNeedDelayedFilterExecute; 177 } 178 179 //----------------------------------------------------------------------------- 180 String GetFsysExtension_Impl( const String& rFile, const String& rLastFilterExt ) 181 { 182 xub_StrLen nDotPos = rFile.SearchBackward( '.' ); 183 if ( nDotPos != STRING_NOTFOUND ) 184 { 185 if ( rLastFilterExt.Len() ) 186 { 187 if ( rFile.Copy( nDotPos + 1 ).EqualsIgnoreCaseAscii( rLastFilterExt ) ) 188 return String( rLastFilterExt ); 189 } 190 else 191 return String( rFile.Copy( nDotPos ) ); 192 } 193 return String(); 194 } 195 196 //----------------------------------------------------------------------------- 197 void SetFsysExtension_Impl( String& rFile, const String& rExtension ) 198 { 199 const sal_Unicode* p0 = rFile.GetBuffer(); 200 const sal_Unicode* p1 = p0 + rFile.Len() - 1; 201 while ( p1 >= p0 && *p1 != sal_Unicode( '.' ) ) 202 p1--; 203 if ( p1 >= p0 ) 204 // remove old extension 205 rFile.Erase( 206 sal::static_int_cast< xub_StrLen >( 207 p1 - p0 + 1 - ( rExtension.Len() > 0 ? 0 : 1 ) ) ); 208 else if ( rExtension.Len() ) 209 // no old extension 210 rFile += sal_Unicode( '.' ); 211 rFile += rExtension; 212 } 213 214 //----------------------------------------------------------------------------- 215 // move the control with the given offset 216 void lcl_MoveControl( Control* _pControl, sal_Int32 _nDeltaX, sal_Int32 _nDeltaY, sal_Int32* _pMaxY = NULL ) 217 { 218 if ( _pControl ) 219 { 220 Point aNewPos = _pControl->GetPosPixel(); 221 222 // adjust the vertical position 223 aNewPos.Y() += _nDeltaY; 224 if ( _pMaxY && ( aNewPos.Y() > *_pMaxY ) ) 225 *_pMaxY = aNewPos.Y(); 226 227 // adjust the horizontal position 228 aNewPos.X() += _nDeltaX; 229 230 _pControl->SetPosPixel( aNewPos ); 231 } 232 } 233 234 //------------------------------------------------------------------------- 235 void lcl_autoUpdateFileExtension( SvtFileDialog* _pDialog, const String& _rLastFilterExt ) 236 { 237 // if auto extension is enabled .... 238 if ( _pDialog->isAutoExtensionEnabled() ) 239 { 240 // automatically switch to the extension of the (maybe just newly selected) extension 241 String aNewFile = _pDialog->getCurrentFileText( ); 242 String aExt = GetFsysExtension_Impl( aNewFile, _rLastFilterExt ); 243 244 // but only if there already is an extension 245 if ( aExt.Len() ) 246 { 247 // check if it is a real file extension, and not only the "post-dot" part in 248 // a directory name 249 // 28.03.2002 - 98337 - fs@openoffice.org 250 sal_Bool bRealExtensions = sal_True; 251 if ( STRING_NOTFOUND != aExt.Search( '/' ) ) 252 bRealExtensions = sal_False; 253 else if ( STRING_NOTFOUND != aExt.Search( '\\' ) ) 254 bRealExtensions = sal_False; 255 else 256 { 257 // no easy way to tell, because the part containing the dot already is the last 258 // segment of the complete file name 259 // So we have to check if the file name denotes a folder or a file. 260 // For performance reasons, we do this for file urls only 261 INetURLObject aURL( aNewFile ); 262 if ( INET_PROT_NOT_VALID == aURL.GetProtocol() ) 263 { 264 String sURL; 265 if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aNewFile, sURL ) ) 266 aURL = INetURLObject( sURL ); 267 } 268 if ( INET_PROT_FILE == aURL.GetProtocol() ) 269 { 270 // #97148# & #102204# ----- 271 try 272 { 273 bRealExtensions = !_pDialog->ContentIsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 274 } 275 catch( ::com::sun::star::uno::Exception& ) 276 { 277 DBG_WARNING( "Exception in lcl_autoUpdateFileExtension" ); 278 } 279 } 280 } 281 282 if ( bRealExtensions ) 283 { 284 SetFsysExtension_Impl( aNewFile, _pDialog->GetDefaultExt() ); 285 _pDialog->setCurrentFileText( aNewFile ); 286 } 287 } 288 } 289 } 290 291 //------------------------------------------------------------------------- 292 sal_Bool lcl_getHomeDirectory( const String& _rForURL, String& /* [out] */ _rHomeDir ) 293 { 294 _rHomeDir.Erase(); 295 296 // now ask the content broker for a provider for this scheme 297 //================================================================= 298 try 299 { 300 // get the content provider manager 301 ::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get(); 302 Reference< XContentProviderManager > xProviderManager; 303 if ( pBroker ) 304 xProviderManager = pBroker->getContentProviderManagerInterface(); 305 306 //================================================================= 307 // get the provider for the current scheme 308 Reference< XContentProvider > xProvider; 309 if ( xProviderManager.is() ) 310 xProvider = xProviderManager->queryContentProvider( _rForURL ); 311 312 DBG_ASSERT( xProvider.is(), "lcl_getHomeDirectory: could not find a (valid) content provider for the current URL!" ); 313 Reference< XPropertySet > xProviderProps( xProvider, UNO_QUERY ); 314 if ( xProviderProps.is() ) 315 { 316 Reference< XPropertySetInfo > xPropInfo = xProviderProps->getPropertySetInfo(); 317 const ::rtl::OUString sHomeDirPropertyName( RTL_CONSTASCII_USTRINGPARAM( "HomeDirectory" ) ); 318 if ( !xPropInfo.is() || xPropInfo->hasPropertyByName( sHomeDirPropertyName ) ) 319 { 320 ::rtl::OUString sHomeDirectory; 321 xProviderProps->getPropertyValue( sHomeDirPropertyName ) >>= sHomeDirectory; 322 _rHomeDir = sHomeDirectory; 323 } 324 } 325 } 326 catch( const Exception& ) 327 { 328 DBG_ERROR( "lcl_getHomeDirectory: caught an exception!" ); 329 } 330 return 0 < _rHomeDir.Len(); 331 } 332 333 //--------------------------------------------------------------------- 334 static String lcl_ensureFinalSlash( const String& _rDir ) 335 { 336 INetURLObject aWorkPathObj( _rDir, INET_PROT_FILE ); 337 aWorkPathObj.setFinalSlash(); 338 return aWorkPathObj.GetMainURL( INetURLObject::NO_DECODE ); 339 } 340 341 //--------------------------------------------------------------------- 342 void convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash ) 343 { 344 const sal_Unicode s_cSeparator = 345 #if defined(WNT) || defined(OS2) 346 ';' 347 #else 348 ':' 349 #endif 350 ; 351 xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator ); 352 _rTokens.resize( 0 ); _rTokens.reserve( nTokens ); 353 for ( xub_StrLen i=0; i<nTokens; ++i ) 354 { 355 // the current token in the list 356 String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator ); 357 if ( !sCurrentToken.Len() ) 358 continue; 359 360 INetURLObject aCurrentURL; 361 362 String sURL; 363 if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) ) 364 aCurrentURL = INetURLObject( sURL ); 365 else 366 { 367 // smart URL parsing, assuming FILE protocol 368 aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE ); 369 } 370 371 if ( _bFinalSlash ) 372 aCurrentURL.setFinalSlash( ); 373 else 374 aCurrentURL.removeFinalSlash( ); 375 _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) ); 376 } 377 } 378 379 //--------------------------------------------------------------------- 380 struct RemoveFinalSlash : public ::std::unary_function< String, void > 381 { 382 void operator()( String& _rURL ) 383 { 384 INetURLObject aURL( _rURL ); 385 #if defined(WNT) || defined(OS2) 386 if ( aURL.getSegmentCount() > 1 ) 387 #endif 388 aURL.removeFinalSlash( ); 389 _rURL = aURL.GetMainURL( INetURLObject::NO_DECODE ); 390 } 391 }; 392 393 // ----------------------------------------------------------------------- 394 /** retrieves the value of an environment variable 395 @return <TRUE/> if and only if the retrieved string value is not empty 396 */ 397 bool getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue ) 398 { 399 _rValue = ::rtl::OUString(); 400 ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName ); 401 osl_getEnvironment( sEnvName.pData, &_rValue.pData ); 402 return _rValue.getLength() != 0; 403 } 404 } 405 406 //*************************************************************************** 407 // ControlChain_Impl 408 //*************************************************************************** 409 410 struct ControlChain_Impl 411 { 412 Window* _pControl; 413 ControlChain_Impl* _pNext; 414 sal_Bool _bHasOwnerShip; 415 416 ControlChain_Impl( Window* pControl, ControlChain_Impl* pNext ); 417 ~ControlChain_Impl(); 418 }; 419 420 //*************************************************************************** 421 422 ControlChain_Impl::ControlChain_Impl 423 ( 424 Window* pControl, 425 ControlChain_Impl* pNext 426 ) 427 : _pControl( pControl ), 428 _pNext( pNext ), 429 _bHasOwnerShip( sal_True ) 430 { 431 } 432 433 //*************************************************************************** 434 435 ControlChain_Impl::~ControlChain_Impl() 436 { 437 if ( _bHasOwnerShip ) 438 { 439 delete _pControl; 440 } 441 delete _pNext; 442 } 443 444 //***************************************************************************** 445 // ResMgrHolder 446 //***************************************************************************** 447 namespace 448 { 449 struct ResMgrHolder 450 { 451 ResMgr * operator ()() 452 { 453 return ResMgr::CreateResMgr (CREATEVERSIONRESMGR_NAME(fps_office)); 454 } 455 456 static ResMgr * getOrCreate() 457 { 458 return rtl_Instance< 459 ResMgr, ResMgrHolder, 460 osl::MutexGuard, osl::GetGlobalMutex >::create ( 461 ResMgrHolder(), osl::GetGlobalMutex()); 462 } 463 }; 464 465 struct SvtResId : public ResId 466 { 467 SvtResId (sal_uInt16 nId) : ResId (nId, *ResMgrHolder::getOrCreate()) {} 468 }; 469 } 470 471 //***************************************************************************** 472 // SvtFileDialog 473 //***************************************************************************** 474 SvtFileDialog::SvtFileDialog 475 ( 476 Window* _pParent, 477 WinBits nBits, 478 WinBits nExtraBits 479 ) : 480 ModalDialog( _pParent, SvtResId( DLG_SVT_EXPLORERFILE ) ) 481 482 ,_pUserControls( NULL ) 483 ,_pCbReadOnly( NULL ) 484 ,_pCbLinkBox( NULL) 485 ,_pCbPreviewBox( NULL ) 486 ,_pCbSelection( NULL ) 487 ,_pPbPlay( NULL ) 488 ,_pPrevWin( NULL ) 489 ,_pPrevBmp( NULL ) 490 ,_pFileView( NULL ) 491 ,_pFileNotifier( NULL ) 492 ,_pImp( new SvtExpFileDlg_Impl( nBits ) ) 493 ,_nExtraBits( nExtraBits ) 494 ,_bIsInExecute( sal_False ) 495 ,m_bInExecuteAsync( false ) 496 ,m_bHasFilename( false ) 497 { 498 Init_Impl( nBits ); 499 } 500 501 //***************************************************************************** 502 503 SvtFileDialog::SvtFileDialog ( Window* _pParent, WinBits nBits ) 504 :ModalDialog( _pParent, SvtResId( DLG_SVT_EXPLORERFILE ) ) 505 ,_pUserControls( NULL ) 506 ,_pCbReadOnly( NULL ) 507 ,_pCbLinkBox( NULL) 508 ,_pCbPreviewBox( NULL ) 509 ,_pCbSelection( NULL ) 510 ,_pPbPlay( NULL ) 511 ,_pPrevWin( NULL ) 512 ,_pPrevBmp( NULL ) 513 ,_pFileView( NULL ) 514 ,_pFileNotifier( NULL ) 515 ,_pImp( new SvtExpFileDlg_Impl( nBits ) ) 516 ,_nExtraBits( 0L ) 517 ,_bIsInExecute( sal_False ) 518 ,m_bHasFilename( false ) 519 { 520 Init_Impl( nBits ); 521 } 522 523 //***************************************************************************** 524 525 SvtFileDialog::~SvtFileDialog() 526 { 527 if ( _pImp->_aIniKey.Len() ) 528 { 529 // save window state 530 SvtViewOptions aDlgOpt( E_DIALOG, _pImp->_aIniKey ); 531 aDlgOpt.SetWindowState( String( GetWindowState(), osl_getThreadTextEncoding() ) ); 532 String sUserData = _pFileView->GetConfigString(); 533 aDlgOpt.SetUserItem( ::rtl::OUString::createFromAscii( "UserData" ), 534 makeAny( ::rtl::OUString( sUserData ) ) ); 535 } 536 537 _pFileView->SetSelectHdl( Link() ); 538 539 delete _pImp; 540 delete _pFileView; 541 542 delete _pCbReadOnly; 543 delete _pCbLinkBox; 544 delete _pCbPreviewBox; 545 delete _pCbSelection; 546 delete _pPbPlay; 547 delete _pPrevWin; 548 delete _pPrevBmp; 549 550 delete _pUserControls; 551 } 552 553 //***************************************************************************** 554 555 void SvtFileDialog::Init_Impl 556 ( 557 WinBits nStyle 558 ) 559 { 560 sal_Bool bIsHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 561 m_aImages = ImageList( SvtResId( bIsHighContrast ? RID_FILEPICKER_IMAGES_HC : RID_FILEPICKER_IMAGES ) ); 562 563 _pImp->_nStyle = nStyle; 564 _pImp->_a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); 565 _pImp->_eMode = ( nStyle & WB_SAVEAS ) ? FILEDLG_MODE_SAVE : FILEDLG_MODE_OPEN; 566 _pImp->_eDlgType = FILEDLG_TYPE_FILEDLG; 567 568 if ( ( nStyle & SFXWB_PATHDIALOG ) == SFXWB_PATHDIALOG ) 569 _pImp->_eDlgType = FILEDLG_TYPE_PATHDLG; 570 571 // Set the directory for the "back to the default dir" button 572 INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() ); 573 SetStandardDir( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) ); 574 575 // Reichweite bestimmen. 576 if ( !( nStyle & SFXWB_NOREMOTE ) ) 577 { 578 _pImp->_nState |= FILEDLG_STATE_REMOTE; 579 } 580 581 // Kontrollelement erzeugen, wobei die Reihenfolge die Tab-Steuerung 582 // bestimmt. 583 _pImp->_pFtFileName = new FixedText( this, SvtResId( FT_EXPLORERFILE_FILENAME ) ); 584 585 SvtURLBox* pURLBox = new SvtURLBox( this ); 586 pURLBox->SetUrlFilter( &m_aURLFilter ); 587 _pImp->_pEdFileName = pURLBox; 588 589 Edit aDummy( this, SvtResId( ED_EXPLORERFILE_FILENAME ) ); 590 _pImp->_pEdFileName->SetPosSizePixel( aDummy.GetPosPixel(), aDummy.GetSizePixel() ); 591 _pImp->_pEdFileName->Show(); 592 pURLBox->SetSelectHdl( LINK( this, SvtFileDialog, EntrySelectHdl_Impl ) ); 593 pURLBox->SetOpenHdl( STATIC_LINK( this, SvtFileDialog, OpenHdl_Impl ) ); 594 595 // in folder picker mode, only auto-complete directories (no files) 596 bool bIsFolderPicker = ( _pImp->_eDlgType == FILEDLG_TYPE_PATHDLG ); 597 pURLBox->SetOnlyDirectories( bIsFolderPicker ); 598 599 // in save mode, don't use the autocompletion as selection in the edit part 600 bool bSaveMode = ( FILEDLG_MODE_SAVE == _pImp->_eMode ); 601 pURLBox->SetNoURLSelection( bSaveMode ); 602 603 _pImp->_pEdFileName->SetHelpId( HID_FILEDLG_AUTOCOMPLETEBOX ); 604 605 _pImp->_pFtFileType = new FixedText( this, SvtResId( FT_EXPLORERFILE_FILETYPE ) ); 606 _pImp->CreateFilterListControl( this, SvtResId( LB_EXPLORERFILE_FILETYPE ) ); 607 608 // move the filter listbox to the space occupied by the version listbox 609 // if that box isn't needed 610 if ( !( _nExtraBits & SFX_EXTRA_SHOWVERSIONS ) && 611 !( _nExtraBits & SFX_EXTRA_TEMPLATES ) && 612 !( _nExtraBits & SFX_EXTRA_IMAGE_TEMPLATE ) ) 613 { 614 { 615 FixedText aSharedListBoxLabel( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) ); 616 _pImp->_pFtFileType->SetPosPixel( aSharedListBoxLabel.GetPosPixel() ); 617 } 618 619 { 620 ListBox aSharedListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) ); 621 _pImp->GetFilterListControl()->SetPosPixel( aSharedListBox.GetPosPixel() ); 622 } 623 } 624 625 _pImp->_pFtCurrentPath = new FixedText( this, SvtResId( FT_EXPLORERFILE_CURRENTPATH ) ); 626 WinBits nTmpStyle = _pImp->_pFtCurrentPath->GetStyle(); 627 nTmpStyle |= WB_PATHELLIPSIS; 628 _pImp->_pFtCurrentPath->SetStyle( nTmpStyle ); 629 630 _pImp->_pBtnFileOpen = new PushButton( this, SvtResId( BTN_EXPLORERFILE_OPEN ) ); 631 _pImp->_pBtnCancel = new CancelButton( this, SvtResId( BTN_EXPLORERFILE_CANCEL ) ); 632 _pImp->_pBtnHelp = new HelpButton( this, SvtResId( BTN_EXPLORERFILE_HELP ) ); 633 634 _pImp->_pBtnUp = new SvtUpButton_Impl( this, SvtResId( BTN_EXPLORERFILE_UP ) ); 635 _pImp->_pBtnNewFolder = new ImageButton( this, SvtResId( BTN_EXPLORERFILE_NEWFOLDER ) ); 636 _pImp->_pBtnNewFolder->SetStyle( _pImp->_pBtnNewFolder->GetStyle() | WB_NOPOINTERFOCUS ); 637 _pImp->_pBtnStandard = new SvtTravelButton_Impl( this, SvtResId( BTN_EXPLORERFILE_STANDARD ) ); 638 639 _pImp->_pBtnUp->SetAccessibleName( _pImp->_pBtnUp->GetQuickHelpText() ); 640 _pImp->_pBtnNewFolder->SetAccessibleName( _pImp->_pBtnNewFolder->GetQuickHelpText() ); 641 _pImp->_pBtnStandard->SetAccessibleName( _pImp->_pBtnStandard->GetQuickHelpText() ); 642 643 if ( ( nStyle & SFXWB_MULTISELECTION ) == SFXWB_MULTISELECTION ) 644 _pImp->_bMultiSelection = sal_True; 645 646 _pFileView = new SvtFileView( this, SvtResId( CTL_EXPLORERFILE_FILELIST ), 647 FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType, 648 _pImp->_bMultiSelection ); 649 _pFileView->SetUrlFilter( &m_aURLFilter ); 650 _pFileView->EnableAutoResize(); 651 652 _pFileView->SetHelpId( HID_FILEDLG_STANDARD ); 653 _pFileView->SetStyle( _pFileView->GetStyle() | WB_TABSTOP ); 654 655 // Positionen und Groessen der Knoepfe bestimmen. 656 Image aNewFolderImg( GetButtonImage( IMG_FILEDLG_CREATEFOLDER ) ); 657 _pImp->_pBtnNewFolder->SetModeImage( aNewFolderImg ); 658 659 Size aSize( aNewFolderImg.GetSizePixel() ); 660 aSize.Width() += FILEDIALOG_DEF_IMAGEBORDER; 661 aSize.Height() += FILEDIALOG_DEF_IMAGEBORDER; 662 _pImp->_pBtnNewFolder->SetSizePixel( aSize ); 663 _pImp->_pBtnUp->SetSizePixel( aSize ); 664 _pImp->_pBtnStandard->SetSizePixel( aSize ); 665 666 Size aDlgSize = GetOutputSizePixel(); 667 long n6AppFontInPixel = 668 LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width(); 669 long n3AppFontInPixel = 670 LogicToPixel( Size( 3, 0 ), MAP_APPFONT ).Width(); 671 672 // calculate the length of all buttons 673 const sal_uInt16 nBtnCount = 3; // "previous level", "new folder" and "standard dir" 674 long nDelta = n6AppFontInPixel; // right border 675 nDelta += ( nBtnCount * aSize.Width() ); // button count * button width 676 nDelta += ( n3AppFontInPixel + n3AppFontInPixel / 2 ); // spacing 1*big 1*small 677 678 Point aPos( 679 aDlgSize.Width() - nDelta, 680 _pImp->_pBtnUp->GetPosPixel().Y() 681 ); 682 Size aCurPathSize( 683 aPos.X() - n6AppFontInPixel, 684 _pImp->_pFtCurrentPath->GetOutputSizePixel().Height() 685 ); 686 _pImp->_pFtCurrentPath->SetOutputSizePixel( aCurPathSize ); 687 _pImp->_pBtnUp->SetPosPixel( aPos ); 688 aPos.X() += aSize.Width(); 689 aPos.X() += n3AppFontInPixel; 690 _pImp->_pBtnNewFolder->SetPosPixel( aPos ); 691 aPos.X() += aSize.Width(); 692 aPos.X() += n3AppFontInPixel / 2; 693 _pImp->_pBtnStandard->SetPosPixel( aPos ); 694 nDelta = aSize.Height(); 695 nDelta -= aCurPathSize.Height(); 696 nDelta /= 2; 697 Point aCurPathPos = _pImp->_pFtCurrentPath->GetPosPixel(); 698 aCurPathPos.Y() += nDelta; 699 _pImp->_pFtCurrentPath->SetPosPixel( aCurPathPos ); 700 701 if ( nStyle & SFXWB_READONLY ) 702 { 703 _pCbReadOnly = new CheckBox( this, SvtResId( CB_EXPLORERFILE_READONLY ) ); 704 _pCbReadOnly->SetHelpId( HID_FILEOPEN_READONLY ); 705 _pCbReadOnly->SetText( SvtResId( STR_SVT_FILEPICKER_READONLY ) ); 706 AddControl( _pCbReadOnly ); 707 ReleaseOwnerShip( _pCbReadOnly ); 708 _pCbReadOnly->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 709 } 710 711 if ( nStyle & SFXWB_PASSWORD ) 712 { 713 _pImp->_pCbPassword = new CheckBox( this, SvtResId( CB_EXPLORERFILE_PASSWORD ) ); 714 _pImp->_pCbPassword->SetText( SvtResId( STR_SVT_FILEPICKER_PASSWORD ) ); 715 AddControl( _pImp->_pCbPassword ); 716 ReleaseOwnerShip( _pImp->_pCbPassword ); 717 _pImp->_pCbPassword->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 718 } 719 720 // set the ini file for extracting the size 721 _pImp->_aIniKey = IODLG_CONFIGNAME; 722 723 AddControls_Impl( ); 724 725 // Zahl der Pixel bestimmen, um die die anderen Elemente in der Position 726 // Angepasst werden muessen. 727 aPos.Y() += aSize.Height(); 728 aPos.Y() += LogicToPixel( Size( 0, 6 ), MAP_APPFONT ).Height(); 729 long nYOffset = aPos.Y(); 730 aPos = _pFileView->GetPosPixel(); 731 nYOffset -= aPos.Y(); 732 733 // Positionen der uebrigen Elemente anpassen. 734 aPos.Y() += nYOffset; 735 _pFileView->SetPosPixel( aPos ); 736 737 lcl_MoveControl( _pImp->_pFtFileName, 0, nYOffset ); 738 lcl_MoveControl( _pImp->_pEdFileName, 0, nYOffset ); 739 740 lcl_MoveControl( _pImp->_pFtFileVersion, 0, nYOffset ); 741 lcl_MoveControl( _pImp->_pLbFileVersion, 0, nYOffset ); 742 743 lcl_MoveControl( _pImp->_pFtTemplates, 0, nYOffset ); 744 lcl_MoveControl( _pImp->_pLbTemplates, 0, nYOffset ); 745 746 lcl_MoveControl( _pImp->_pFtImageTemplates, 0, nYOffset ); 747 lcl_MoveControl( _pImp->_pLbImageTemplates, 0, nYOffset ); 748 749 lcl_MoveControl( _pImp->_pFtFileType, 0, nYOffset ); 750 lcl_MoveControl( _pImp->GetFilterListControl(), 0, nYOffset ); 751 752 lcl_MoveControl( _pImp->_pBtnFileOpen, 0, nYOffset ); 753 lcl_MoveControl( _pImp->_pBtnCancel, 0, nYOffset ); 754 755 lcl_MoveControl( _pImp->_pBtnHelp, 0, nYOffset + 3 ); 756 // a little more spacing between Cancel- and HelpButton 757 758 // Groesse des Dialoges anpassen. 759 aSize = GetSizePixel(); 760 aSize.Height() += nYOffset; 761 SetSizePixel( aSize ); 762 763 // Beschriftungen dem Modus anpassen. 764 sal_uInt16 nResId = STR_EXPLORERFILE_OPEN; 765 sal_uInt16 nButtonResId = 0; 766 767 if ( nStyle & WB_SAVEAS ) 768 { 769 nResId = STR_EXPLORERFILE_SAVE; 770 nButtonResId = STR_EXPLORERFILE_BUTTONSAVE; 771 } 772 773 if ( ( nStyle & SFXWB_PATHDIALOG ) == SFXWB_PATHDIALOG ) 774 { 775 _pImp->_pFtFileName->SetText( SvtResId( STR_PATHNAME ) ); 776 nResId = STR_PATHSELECT; 777 nButtonResId = STR_BUTTONSELECT; 778 } 779 780 SetText( SvtResId( nResId ) ); 781 782 if ( nButtonResId ) 783 _pImp->_pBtnFileOpen->SetText( SvtResId( nButtonResId ) ); 784 785 if ( FILEDLG_TYPE_FILEDLG != _pImp->_eDlgType ) 786 { 787 _pImp->_pFtFileType->Hide(); 788 _pImp->GetFilterListControl()->Hide(); 789 } 790 791 // Einstellungen der Steuerelemente vornehmen. 792 _pImp->_pBtnNewFolder->SetClickHdl( STATIC_LINK( this, SvtFileDialog, NewFolderHdl_Impl ) ); 793 _pImp->_pBtnFileOpen->SetClickHdl( STATIC_LINK( this, SvtFileDialog, OpenHdl_Impl ) ); 794 _pImp->_pBtnCancel->SetClickHdl( LINK( this, SvtFileDialog, CancelHdl_Impl ) ); 795 _pImp->SetFilterListSelectHdl( STATIC_LINK( this, SvtFileDialog, FilterSelectHdl_Impl ) ); 796 _pImp->_pEdFileName->SetGetFocusHdl( STATIC_LINK( this, SvtFileDialog, FileNameGetFocusHdl_Impl ) ); 797 _pImp->_pEdFileName->SetModifyHdl( STATIC_LINK( this, SvtFileDialog, FileNameModifiedHdl_Impl ) ); 798 _pFileView->SetSelectHdl( LINK( this, SvtFileDialog, SelectHdl_Impl ) ); 799 _pFileView->SetDoubleClickHdl( LINK( this, SvtFileDialog, DblClickHdl_Impl ) ); 800 _pFileView->SetOpenDoneHdl( LINK( this, SvtFileDialog, OpenDoneHdl_Impl ) ); 801 802 // Resourcen freigeben. 803 FreeResource(); 804 805 // Timer fuer Filterbox Travel setzen 806 _pImp->_aFilterTimer.SetTimeout( TRAVELFILTER_TIMEOUT ); 807 _pImp->_aFilterTimer.SetTimeoutHdl( STATIC_LINK( this, SvtFileDialog, FilterSelectHdl_Impl ) ); 808 809 if ( WB_SAVEAS & nStyle ) 810 { 811 // different help ids if in save-as mode 812 // 90744 - 09.08.2001 - frank.schoenheit@sun.com 813 SetHelpId( HID_FILESAVE_DIALOG ); 814 815 _pImp->_pEdFileName->SetHelpId( HID_FILESAVE_FILEURL ); 816 _pImp->_pBtnFileOpen->SetHelpId( HID_FILESAVE_DOSAVE ); 817 _pImp->_pBtnNewFolder->SetHelpId( HID_FILESAVE_CREATEDIRECTORY ); 818 _pImp->_pBtnStandard->SetHelpId( HID_FILESAVE_DEFAULTDIRECTORY ); 819 _pImp->_pBtnUp->SetHelpId( HID_FILESAVE_LEVELUP ); 820 _pImp->GetFilterListControl()->SetHelpId( HID_FILESAVE_FILETYPE ); 821 _pFileView->SetHelpId( HID_FILESAVE_FILEVIEW ); 822 823 // formerly, there was only _pLbFileVersion, which was used for 3 different 824 // use cases. For reasons of maintainability, I introduced extra members (_pLbTemplates, _pLbImageTemplates) 825 // for the extra use cases, and separated _pLbFileVersion 826 // I did not find out in which cases the help ID is really needed HID_FILESAVE_TEMPLATE - all 827 // tests I made lead to a dialog where _no_ of the three list boxes was present. 828 // 96930 - 15.08.2002 - fs@openoffice.org 829 if ( _pImp->_pLbFileVersion ) 830 _pImp->_pLbFileVersion->SetHelpId( HID_FILESAVE_TEMPLATE ); 831 if ( _pImp->_pLbTemplates ) 832 _pImp->_pLbTemplates->SetHelpId( HID_FILESAVE_TEMPLATE ); 833 if ( _pImp->_pLbImageTemplates ) 834 _pImp->_pLbImageTemplates->SetHelpId( HID_FILESAVE_TEMPLATE ); 835 836 if ( _pImp->_pCbPassword ) _pImp->_pCbPassword->SetHelpId( HID_FILESAVE_SAVEWITHPASSWORD ); 837 if ( _pImp->_pCbAutoExtension ) _pImp->_pCbAutoExtension->SetHelpId( HID_FILESAVE_AUTOEXTENSION ); 838 if ( _pImp->_pCbOptions ) _pImp->_pCbOptions->SetHelpId( HID_FILESAVE_CUSTOMIZEFILTER ); 839 if ( _pCbSelection ) _pCbSelection->SetHelpId( HID_FILESAVE_SELECTION ); 840 } 841 842 // correct the z-order of the controls 843 implArrangeControls(); 844 845 // special URLs, such as favourites and "restricted" paths 846 implInitializeSpecialURLLists( ); 847 848 /// read our settings from the configuration 849 m_aConfiguration = OConfigurationTreeRoot::createWithServiceFactory( 850 ::comphelper::getProcessServiceFactory(), 851 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI/FilePicker" ) ) 852 ); 853 } 854 855 //***************************************************************************** 856 857 IMPL_STATIC_LINK( SvtFileDialog, NewFolderHdl_Impl, PushButton*, EMPTYARG ) 858 { 859 pThis->_pFileView->EndInplaceEditing( false ); 860 861 INetURLObject aObj( pThis->_pFileView->GetViewURL() ); 862 String sFolderName = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET, RTL_TEXTENCODING_UTF8 ); 863 svtools::QueryFolderNameDialog aDlg( pThis, sFolderName, String( SvtResId( STR_SVT_NEW_FOLDER ) ) ); 864 sal_Bool bHandled = sal_False; 865 866 while ( !bHandled ) 867 { 868 if ( aDlg.Execute() == RET_OK ) 869 bHandled = pThis->_pFileView->CreateNewFolder( aDlg.GetName() ); 870 else 871 bHandled = sal_True; 872 } 873 874 return 0; 875 } 876 877 //***************************************************************************** 878 879 IMPL_STATIC_LINK_NOINSTANCE( SvtFileDialog, ViewHdl_Impl, ImageButton*, EMPTYARG ) 880 { 881 return 0; 882 } 883 884 //***************************************************************************** 885 //----------------------------------------------------------------------------- 886 sal_Bool SvtFileDialog::createNewUserFilter( const String& _rNewFilter, sal_Bool _bAllowUserDefExt ) 887 { 888 // delete the old user filter and create a new one 889 DELETEZ( _pImp->_pUserFilter ); 890 _pImp->_pUserFilter = new SvtFileDialogFilter_Impl( _rNewFilter, _rNewFilter ); 891 892 // remember the extension 893 sal_Bool bIsAllFiles = _rNewFilter.EqualsAscii( FILEDIALOG_FILTER_ALL ); 894 if ( bIsAllFiles ) 895 EraseDefaultExt(); 896 else 897 SetDefaultExt( _rNewFilter.Copy( 2 ) ); 898 // TODO: this is nonsense. In the whole file there are a lotta places where we assume that a user filter 899 // is always "*.<something>". But changing this would take some more time than I have now ... 900 // 05.12.2001 - 95486 - fs@openoffice.org 901 902 // now, the default extension is set to the one of the user filter (or empty) 903 // if the former is not allowed (_bAllowUserDefExt = <FALSE/>), we have to use the ext of the current filter 904 // (if possible) 905 sal_Bool bUseCurFilterExt = sal_True; 906 String sUserFilter = _pImp->_pUserFilter->GetType(); 907 xub_StrLen nSepPos = sUserFilter.SearchBackward( '.' ); 908 if ( STRING_NOTFOUND != nSepPos ) 909 { 910 String sUserExt = sUserFilter.Copy( nSepPos + 1 ); 911 if ( ( STRING_NOTFOUND == sUserExt.Search( '*' ) ) 912 && ( STRING_NOTFOUND == sUserExt.Search( '?' ) ) 913 ) 914 bUseCurFilterExt = sal_False; 915 } 916 917 if ( !_bAllowUserDefExt || bUseCurFilterExt ) 918 { 919 if ( _pImp->GetCurFilter( ) ) 920 SetDefaultExt( _pImp->GetCurFilter( )->GetExtension() ); 921 else 922 EraseDefaultExt(); 923 } 924 925 // outta here 926 return bIsAllFiles; 927 } 928 929 //----------------------------------------------------------------------------- 930 #define FLT_NONEMPTY 0x0001 931 #define FLT_CHANGED 0x0002 932 #define FLT_USERFILTER 0x0004 933 #define FLT_ALLFILESFILTER 0x0008 934 935 //----------------------------------------------------------------------------- 936 sal_uInt16 SvtFileDialog::adjustFilter( const String& _rFilter ) 937 { 938 sal_uInt16 nReturn = 0; 939 940 const sal_Bool bNonEmpty = ( _rFilter.Len() != 0 ); 941 if ( bNonEmpty ) 942 { 943 nReturn |= FLT_NONEMPTY; 944 945 sal_Bool bFilterChanged = sal_True; 946 947 // search for a corresponding filter 948 SvtFileDialogFilter_Impl* pFilter = FindFilter_Impl( _rFilter, sal_False, bFilterChanged ); 949 950 #ifdef AUTOSELECT_USERFILTER 951 // if we found a filter which without allowing multi-extensions -> select it 952 if ( pFilter ) 953 { 954 _pImp->SelectFilterListEntry( pFilter->GetName() ); 955 _pImp->SetCurFilter( pFilter ); 956 } 957 #endif // AUTOSELECT_USERFILTER 958 959 // look for multi-ext filters if necessary 960 if ( !pFilter ) 961 pFilter = FindFilter_Impl( _rFilter, sal_True, bFilterChanged ); 962 963 if ( bFilterChanged ) 964 nReturn |= FLT_CHANGED; 965 966 if ( !pFilter ) 967 { 968 nReturn |= FLT_USERFILTER; 969 // no filter found : use it as user defined filter 970 #ifdef AUTOSELECT_USERFILTER 971 if ( createNewUserFilter( _rFilter, sal_True ) ) 972 #else 973 if ( createNewUserFilter( _rFilter, sal_False ) ) 974 #endif 975 { // it's the "all files" filter 976 nReturn |= FLT_ALLFILESFILTER; 977 978 #ifdef AUTOSELECT_USERFILTER 979 // select the "all files" entry 980 String sAllFilesFilter( SvtResId( STR_FILTERNAME_ALL ) ); 981 if ( _pImp->HasFilterListEntry( sAllFilesFilter ) ) 982 { 983 _pImp->SelectFilterListEntry( sAllFilesFilter ); 984 _pImp->SetCurFilter( _pImp->GetSelectedFilterEntry( sAllFilesFilter ) ); 985 } 986 else 987 _pImp->SetNoFilterListSelection( ); // there is no "all files" entry 988 #endif // AUTOSELECT_USERFILTER 989 } 990 #ifdef AUTOSELECT_USERFILTER 991 else 992 _pImp->SetNoFilterListSelection( ); 993 #endif // AUTOSELECT_USERFILTER 994 } 995 } 996 997 return nReturn; 998 } 999 1000 //----------------------------------------------------------------------------- 1001 IMPL_LINK( SvtFileDialog, CancelHdl_Impl, void*, EMPTYARG ) 1002 { 1003 if ( m_pCurrentAsyncAction.is() ) 1004 { 1005 m_pCurrentAsyncAction->cancel(); 1006 onAsyncOperationFinished(); 1007 } 1008 else 1009 { 1010 EndDialog( sal_False ); 1011 } 1012 return 1L; 1013 } 1014 1015 //----------------------------------------------------------------------------- 1016 IMPL_STATIC_LINK( SvtFileDialog, OpenHdl_Impl, void*, pVoid ) 1017 { 1018 if ( pThis->_pImp->_bMultiSelection && pThis->_pFileView->GetSelectionCount() > 1 ) 1019 { 1020 // bei Multiselektion spezielles Open 1021 pThis->OpenMultiSelection_Impl(); 1022 return 0; 1023 } 1024 1025 String aFileName; 1026 String aOldPath( pThis->_pFileView->GetViewURL() ); 1027 if ( pThis->_pImp->_bDoubleClick || pThis->_pFileView->HasChildPathFocus() ) 1028 // Selection done by doubleclicking in the view, get filename from the view 1029 aFileName = pThis->_pFileView->GetCurrentURL(); 1030 1031 if ( !aFileName.Len() ) 1032 { 1033 // if an entry is selected in the view .... 1034 if ( pThis->_pFileView->GetSelectionCount() ) 1035 { // -> use this one. This will allow us to step down this folder 1036 // #i8928# - 2002-12-20 - fs@openoffice.org 1037 aFileName = pThis->_pFileView->GetCurrentURL(); 1038 } 1039 } 1040 1041 if ( !aFileName.Len() ) 1042 { 1043 if ( pThis->_pImp->_eMode == FILEDLG_MODE_OPEN && pThis->_pImp->_pEdFileName->IsTravelSelect() ) 1044 // OpenHdl called from URLBox; travelling through the list of URLs should not cause an opening 1045 return 0; // MBA->PB: seems to be called never ?! 1046 1047 // get the URL from from the edit field ( if not empty ) 1048 if ( pThis->_pImp->_pEdFileName->GetText().Len() ) 1049 { 1050 String aText = pThis->_pImp->_pEdFileName->GetText(); 1051 1052 // did we reach the root? 1053 if ( !INetURLObject( aOldPath ).getSegmentCount() ) 1054 { 1055 if ( ( aText.Len() == 2 && aText.EqualsAscii( ".." ) ) || 1056 ( aText.Len() == 3 && ( aText.EqualsAscii( "..\\" ) || aText.EqualsAscii( "../" ) ) ) ) 1057 // don't go higher than the root 1058 return 0; 1059 } 1060 1061 #if defined( UNX ) || defined( FS_PRIV_DEBUG ) 1062 if ( ( 1 == aText.Len() ) && ( '~' == aText.GetBuffer()[0] ) ) 1063 { 1064 // go to the home directory 1065 if ( lcl_getHomeDirectory( pThis->_pFileView->GetViewURL(), aFileName ) ) 1066 // in case we got a home dir, reset the text of the edit 1067 pThis->_pImp->_pEdFileName->SetText( String() ); 1068 } 1069 if ( !aFileName.Len() ) 1070 #endif 1071 { 1072 // get url from autocomplete edit 1073 aFileName = pThis->_pImp->_pEdFileName->GetURL(); 1074 } 1075 } 1076 else if ( pVoid == pThis->_pImp->_pBtnFileOpen ) 1077 // OpenHdl was called for the "Open" Button; if edit field is empty, use selected element in the view 1078 aFileName = pThis->_pFileView->GetCurrentURL(); 1079 } 1080 1081 // MBA->PB: ?! 1082 if ( !aFileName.Len() && pVoid == pThis->_pImp->_pEdFileName && pThis->_pImp->_pUserFilter ) 1083 { 1084 DELETEZ( pThis->_pImp->_pUserFilter ); 1085 return 0; 1086 } 1087 1088 sal_uInt16 nLen = aFileName.Len(); 1089 if ( !nLen ) 1090 { 1091 // if the dialog was opened to select a folder, the last selected folder should be selected 1092 if( pThis->_pImp->_eDlgType == FILEDLG_TYPE_PATHDLG ) 1093 { 1094 aFileName = pThis->_pImp->_pFtCurrentPath->GetText(); 1095 nLen = aFileName.Len(); 1096 } 1097 else 1098 // no file selected ! 1099 return 0; 1100 } 1101 1102 // mark input as selected 1103 pThis->_pImp->_pEdFileName->SetSelection( Selection( 0, nLen ) ); 1104 1105 // if a path with wildcards is given, divide the string into path and wildcards 1106 String aFilter; 1107 if ( !pThis->IsolateFilterFromPath_Impl( aFileName, aFilter ) ) 1108 return 0; 1109 1110 // if a filter was retrieved, there were wildcards ! 1111 sal_uInt16 nNewFilterFlags = pThis->adjustFilter( aFilter ); 1112 if ( nNewFilterFlags & FLT_CHANGED ) 1113 { 1114 // cut off all text before wildcard in edit and select wildcard 1115 pThis->_pImp->_pEdFileName->SetText( aFilter ); 1116 pThis->_pImp->_pEdFileName->SetSelection( Selection( 0, aFilter.Len() ) ); 1117 } 1118 1119 { 1120 INetURLObject aFileObject( aFileName ); 1121 if ( ( aFileObject.GetProtocol() == INET_PROT_NOT_VALID ) && aFileName.Len() ) 1122 { 1123 String sCompleted = SvtURLBox::ParseSmart( aFileName, pThis->_pFileView->GetViewURL(), SvtPathOptions().GetWorkPath() ); 1124 if ( sCompleted.Len() ) 1125 aFileName = sCompleted; 1126 } 1127 } 1128 1129 // Pr"ufen, ob es sich um einen Ordner handelt. 1130 sal_Bool bIsFolder = sal_False; 1131 1132 // first thing before doing anyhing with the content: Reset it. When the user presses "open" (or "save" or "export", 1133 // for that matter), s/he wants the complete handling, including all possible error messages, even if s/he 1134 // does the same thing for the same content twice, s/he wants both fails to be displayed. 1135 // Without the reset, it could be that the content cached all relevant information, and will not display any 1136 // error messages for the same content a second time .... 1137 pThis->m_aContent.bindTo( ::rtl::OUString( ) ); 1138 1139 // #97148# & #102204# --------- 1140 if ( aFileName.Len() ) 1141 { 1142 // Make sure we have own Interaction Handler in place. We do not need 1143 // to intercept interactions here, but to record the fact that there 1144 // was an interaction. 1145 SmartContent::InteractionHandlerType eInterActionHandlerType 1146 = pThis->m_aContent.queryCurrentInteractionHandler(); 1147 if ( ( eInterActionHandlerType == SmartContent::IHT_NONE ) || 1148 ( eInterActionHandlerType == SmartContent::IHT_DEFAULT ) ) 1149 pThis->m_aContent.enableOwnInteractionHandler( 1150 OFilePickerInteractionHandler::E_NOINTERCEPTION ); 1151 1152 bIsFolder = pThis->m_aContent.isFolder( aFileName ); 1153 1154 // access denied to the given resource - and interaction was already 1155 // used => break following operations 1156 OFilePickerInteractionHandler* pHandler 1157 = pThis->m_aContent.getOwnInteractionHandler(); 1158 1159 OSL_ENSURE( pHandler, "Got no Interaction Handler!!!" ); 1160 1161 if ( pHandler->wasAccessDenied() ) 1162 return 0; 1163 1164 if ( pThis->m_aContent.isInvalid() && 1165 ( pThis->_pImp->_eMode == FILEDLG_MODE_OPEN ) ) 1166 { 1167 if ( !pHandler->wasUsed() ) 1168 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTS ); 1169 1170 return 0; 1171 } 1172 1173 // restore previous Interaction Handler 1174 if ( eInterActionHandlerType == SmartContent::IHT_NONE ) 1175 pThis->m_aContent.disableInteractionHandler(); 1176 else if ( eInterActionHandlerType == SmartContent::IHT_DEFAULT ) 1177 pThis->m_aContent.enableDefaultInteractionHandler(); 1178 } 1179 1180 if ( !bIsFolder // no existent folder 1181 && pThis->_pImp->_pCbAutoExtension // auto extension is enabled in general 1182 && pThis->_pImp->_pCbAutoExtension->IsChecked() // auto extension is really to be used 1183 && pThis->GetDefaultExt().Len() // there is a default extension 1184 && pThis->GetDefaultExt() != '*' // the default extension is not "all" 1185 && !( FILEDLG_MODE_SAVE == pThis->_pImp->_eMode // we're saving a file 1186 && pThis->_pFileView->GetSelectionCount() // there is a selected file in the file view -> it will later on 1187 ) // (in SvtFileDialog::GetPathList) be taken as file to save to 1188 // (#114818# - 2004-03-17 - fs@openoffice.org) 1189 && FILEDLG_MODE_OPEN != pThis->_pImp->_eMode // pb: #i83408# don't append extension on open 1190 ) 1191 { 1192 // check extension and append the default extension if necessary 1193 appendDefaultExtension(aFileName, 1194 pThis->GetDefaultExt(), 1195 pThis->_pImp->GetCurFilter()->GetType()); 1196 } 1197 1198 sal_Bool bOpenFolder = ( FILEDLG_TYPE_PATHDLG == pThis->_pImp->_eDlgType ) && 1199 !pThis->_pImp->_bDoubleClick && pVoid != pThis->_pImp->_pEdFileName; 1200 if ( bIsFolder ) 1201 { 1202 if ( bOpenFolder ) 1203 { 1204 pThis->_aPath = aFileName; 1205 } 1206 else 1207 { 1208 if ( aFileName != pThis->_pFileView->GetViewURL() ) 1209 { 1210 if ( !pThis->m_aURLFilter.isUrlAllowed( aFileName ) ) 1211 { 1212 pThis->simulateAccessDenied( aFileName ); 1213 return 0; 1214 } 1215 1216 pThis->OpenURL_Impl( aFileName ); 1217 } 1218 else 1219 { 1220 if ( nNewFilterFlags & FLT_CHANGED ) 1221 pThis->ExecuteFilter(); 1222 } 1223 1224 return 0; 1225 } 1226 } 1227 else if ( !( nNewFilterFlags & FLT_NONEMPTY ) ) 1228 { 1229 // Ggf. URL speichern. 1230 pThis->_aPath = aFileName; 1231 } 1232 else 1233 { 1234 // Ggf. neu filtern. 1235 if ( nNewFilterFlags & FLT_CHANGED ) 1236 pThis->ExecuteFilter(); 1237 return 0; 1238 } 1239 1240 INetURLObject aFileObj( aFileName ); 1241 if ( aFileObj.HasError() ) 1242 { 1243 ErrorHandler::HandleError( ERRCODE_IO_GENERAL ); 1244 return 0; 1245 } 1246 1247 // if restrictions for the allowed folders are in place, we need to do a check here 1248 if ( !pThis->m_aURLFilter.isUrlAllowed( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) 1249 { 1250 pThis->simulateAccessDenied( aFileName ); 1251 return 0; 1252 } 1253 1254 switch ( pThis->_pImp->_eMode ) 1255 { 1256 case FILEDLG_MODE_SAVE: 1257 { 1258 if ( ::utl::UCBContentHelper::Exists( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) 1259 { 1260 QueryBox aBox( pThis, WB_YES_NO, SvtResId( STR_SVT_ALREADYEXISTOVERWRITE ) ); 1261 if ( aBox.Execute() != RET_YES ) 1262 return 0; 1263 } 1264 else 1265 { 1266 String aCurPath; 1267 if ( ::utl::LocalFileHelper::ConvertURLToSystemPath( aFileName, aCurPath ) ) 1268 { 1269 // if content does not exist: at least its path must exist 1270 INetURLObject aPathObj = aFileObj; 1271 aPathObj.removeSegment(); 1272 // #97148# & #102204# ------------ 1273 sal_Bool bFolder = pThis->m_aContent.isFolder( aPathObj.GetMainURL( INetURLObject::NO_DECODE ) ); 1274 if ( !bFolder ) 1275 { 1276 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTSPATH ); 1277 return 0; 1278 } 1279 } 1280 } 1281 } 1282 break; 1283 1284 case FILEDLG_MODE_OPEN: 1285 { 1286 // do an existence check herein, again 1287 // 16.11.2001 - 93107 - frank.schoenheit@sun.com 1288 1289 if ( INET_PROT_FILE == aFileObj.GetProtocol( ) ) 1290 { 1291 sal_Bool bExists = sal_False; 1292 // #102204# -------------- 1293 bExists = pThis->m_aContent.is( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) ); 1294 1295 1296 if ( !bExists ) 1297 { 1298 String sError( SvtResId( RID_FILEOPEN_NOTEXISTENTFILE ) ); 1299 1300 String sInvalidFile( aFileObj.GetMainURL( INetURLObject::DECODE_TO_IURI ) ); 1301 if ( INET_PROT_FILE == aFileObj.GetProtocol() ) 1302 { // if it's a file URL, transform the URL into system notation 1303 ::rtl::OUString sURL( sInvalidFile ); 1304 ::rtl::OUString sSystem; 1305 osl_getSystemPathFromFileURL( sURL.pData, &sSystem.pData ); 1306 sInvalidFile = sSystem; 1307 } 1308 sError.SearchAndReplaceAscii( "$name$", sInvalidFile ); 1309 1310 ErrorBox aError( pThis, WB_OK, sError ); 1311 aError.Execute(); 1312 return 0; 1313 } 1314 } 1315 } 1316 break; 1317 1318 default: 1319 DBG_ERROR("SvtFileDialog, OpenHdl_Impl: invalid mode!"); 1320 } 1321 1322 // Interessenten benachrichtigen. 1323 long nRet; 1324 1325 if ( pThis->_aOKHdl.IsSet() ) 1326 nRet = pThis->_aOKHdl.Call( pThis ); 1327 else 1328 nRet = pThis->OK(); 1329 1330 if ( nRet ) 1331 { 1332 pThis->EndDialog( sal_True ); 1333 } 1334 1335 return nRet; 1336 } 1337 1338 //***************************************************************************** 1339 1340 void SvtFileDialog::EnableAutocompletion( sal_Bool _bEnable ) 1341 { 1342 _pImp->_pEdFileName->EnableAutocompletion( _bEnable ); 1343 } 1344 1345 //***************************************************************************** 1346 1347 IMPL_STATIC_LINK( SvtFileDialog, FilterSelectHdl_Impl, ListBox*, pBox ) 1348 { 1349 DBG_ASSERT( pBox, "SvtFileDialog:keine Instanz" ); 1350 1351 // wurde der Handler vom Travel-Timer gefeuert? 1352 if ( pBox == (ListBox*)&pThis->_pImp->_aFilterTimer ) 1353 { 1354 // Anzeige erneut filtern. 1355 pThis->ExecuteFilter(); 1356 return 0; 1357 } 1358 1359 String sSelectedFilterDisplayName; 1360 SvtFileDialogFilter_Impl* pSelectedFilter = pThis->_pImp->GetSelectedFilterEntry( sSelectedFilterDisplayName ); 1361 if ( !pSelectedFilter ) 1362 { // there is no current selection. This happens if for instance the user selects a group separator using 1363 // the keyboard, and then presses enter: When the selection happens, we immediately deselect the entry, 1364 // so in this situation there is no current selection. 1365 if ( restoreCurrentFilter( pThis->_pImp ) ) 1366 pThis->ExecuteFilter(); 1367 } 1368 else 1369 { 1370 if ( pSelectedFilter->isGroupSeparator() ) 1371 { // group separators can't be selected 1372 // return to the previously selected entry 1373 if ( pThis->_pImp->IsFilterListTravelSelect() ) 1374 { 1375 pThis->_pImp->SetNoFilterListSelection( ); 1376 1377 // stop the timer for executing the filter 1378 if ( pThis->_pImp->_aFilterTimer.IsActive() ) 1379 pThis->_pImp->m_bNeedDelayedFilterExecute = sal_True; 1380 pThis->_pImp->_aFilterTimer.Stop(); 1381 } 1382 else 1383 { 1384 if ( restoreCurrentFilter( pThis->_pImp ) ) 1385 pThis->ExecuteFilter(); 1386 } 1387 } 1388 else if ( ( pSelectedFilter != pThis->_pImp->GetCurFilter() ) 1389 || pThis->_pImp->_pUserFilter 1390 ) 1391 { 1392 // Store the old filter for the auto extension handling 1393 String sLastFilterExt = pThis->_pImp->GetCurFilter()->GetExtension(); 1394 DELETEZ( pThis->_pImp->_pUserFilter ); 1395 1396 // Ggf. Filter des Benutzers entfernen. 1397 pThis->_pImp->SetCurFilter( pSelectedFilter, sSelectedFilterDisplayName ); 1398 1399 // Ggf. Endung anzeigen. 1400 pThis->SetDefaultExt( pSelectedFilter->GetExtension() ); 1401 sal_uInt16 nSepPos = pThis->GetDefaultExt().Search( FILEDIALOG_DEF_EXTSEP ); 1402 1403 if ( nSepPos != STRING_NOTFOUND ) 1404 pThis->EraseDefaultExt( nSepPos ); 1405 1406 // update the extension of the current file if necessary 1407 lcl_autoUpdateFileExtension( pThis, sLastFilterExt ); 1408 1409 // wenn der Benutzer schnell durch die Filterbox 1410 // travelt, nicht sofort Filtern 1411 if ( pThis->_pImp->IsFilterListTravelSelect() ) 1412 { 1413 // FilterSelectHdl_Impl soll in 1414 // TRAVELFILTER_TIMEOUT ms neu gefeuert werden 1415 pThis->_pImp->_aFilterTimer.Start(); 1416 } 1417 else 1418 { 1419 // evtl. vorher gestarteten Timer stoppen 1420 pThis->_pImp->_aFilterTimer.Stop(); 1421 1422 // Anzeige erneut filtern. 1423 pThis->ExecuteFilter(); 1424 } 1425 } 1426 } 1427 1428 return 0; 1429 } 1430 1431 //***************************************************************************** 1432 1433 IMPL_STATIC_LINK( SvtFileDialog, FileNameGetFocusHdl_Impl, void*, EMPTYARG ) 1434 { 1435 pThis->_pFileView->SetNoSelection(); 1436 pThis->_pFileView->Update(); 1437 return 0; 1438 } 1439 1440 //***************************************************************************** 1441 1442 IMPL_STATIC_LINK( SvtFileDialog, FileNameModifiedHdl_Impl, void*, EMPTYARG ) 1443 { 1444 FileNameGetFocusHdl_Impl( pThis, NULL ); 1445 return 0; 1446 } 1447 1448 //***************************************************************************** 1449 1450 SvtFileDialogFilter_Impl* SvtFileDialog::FindFilter_Impl 1451 ( 1452 const String& _rFilter, 1453 sal_Bool _bMultiExt,/* sal_True - auch Filter mit mehreren Endungen 1454 beruecksichtigen 1455 sal_False - keine ... 1456 */ 1457 sal_Bool& _rFilterChanged 1458 ) 1459 1460 /* [Beschreibung] 1461 1462 Die Methode sucht in den eingef"ugten Filtern nach der 1463 spezifizierten Endung. 1464 */ 1465 1466 { 1467 SvtFileDialogFilter_Impl* pFoundFilter = NULL; 1468 SvtFileDialogFilterList_Impl* pList = _pImp->_pFilter; 1469 sal_uInt16 nFilter = pList->Count(); 1470 1471 while ( nFilter-- ) 1472 { 1473 SvtFileDialogFilter_Impl* pFilter = pList->GetObject( nFilter ); 1474 const String& rType = pFilter->GetType(); 1475 String aSingleType = rType; 1476 1477 if ( _bMultiExt ) 1478 { 1479 sal_uInt16 nIdx = 0; 1480 while ( !pFoundFilter && nIdx != STRING_NOTFOUND ) 1481 { 1482 aSingleType = rType.GetToken( 0, FILEDIALOG_DEF_EXTSEP, nIdx ); 1483 #ifdef UNX 1484 if ( aSingleType.CompareTo( _rFilter ) == COMPARE_EQUAL ) 1485 #else 1486 if ( aSingleType.CompareIgnoreCaseToAscii( _rFilter ) == COMPARE_EQUAL ) 1487 #endif 1488 pFoundFilter = pFilter; 1489 } 1490 } 1491 #ifdef UNX 1492 else if ( rType.CompareTo( _rFilter ) == COMPARE_EQUAL ) 1493 #else 1494 else if ( rType.CompareIgnoreCaseToAscii( _rFilter ) == COMPARE_EQUAL ) 1495 #endif 1496 pFoundFilter = pFilter; 1497 1498 if ( pFoundFilter ) 1499 { 1500 // Filter aktivieren. 1501 _rFilterChanged = _pImp->_pUserFilter || ( _pImp->GetCurFilter() != pFilter ); 1502 1503 createNewUserFilter( _rFilter, sal_False ); 1504 1505 break; 1506 } 1507 } 1508 return pFoundFilter; 1509 } 1510 1511 //***************************************************************************** 1512 1513 void SvtFileDialog::ExecuteFilter() 1514 { 1515 _pImp->m_bNeedDelayedFilterExecute = sal_False; 1516 executeAsync( AsyncPickerAction::eExecuteFilter, String(), getMostCurrentFilter( _pImp ) ); 1517 } 1518 1519 //***************************************************************************** 1520 1521 void SvtFileDialog::OpenMultiSelection_Impl() 1522 1523 /* [Beschreibung] 1524 1525 OpenHandler f"ur MultiSelektion 1526 */ 1527 1528 { 1529 String aPath; 1530 sal_uLong nCount = _pFileView->GetSelectionCount(); 1531 SvLBoxEntry* pEntry = nCount ? _pFileView->FirstSelected() : NULL; 1532 1533 if ( nCount && pEntry ) 1534 _aPath = _pFileView->GetURL( pEntry ); 1535 1536 // Interessenten benachrichtigen. 1537 long nRet; 1538 1539 if ( _aOKHdl.IsSet() ) 1540 nRet = _aOKHdl.Call( this ); 1541 else 1542 nRet = OK(); 1543 1544 if ( nRet ) 1545 EndDialog( sal_True ); 1546 } 1547 1548 //***************************************************************************** 1549 1550 void SvtFileDialog::UpdateControls( const String& rURL ) 1551 { 1552 _pImp->_pEdFileName->SetBaseURL( rURL ); 1553 1554 INetURLObject aObj( rURL ); 1555 1556 //========================================================================= 1557 { 1558 String sText; 1559 DBG_ASSERT( INET_PROT_NOT_VALID != aObj.GetProtocol(), "SvtFileDialog::UpdateControls: Invalid URL!" ); 1560 1561 if ( aObj.getSegmentCount() ) 1562 { 1563 ::utl::LocalFileHelper::ConvertURLToSystemPath( rURL, sText ); 1564 if ( sText.Len() ) 1565 { 1566 // no Fsys path for server file system ( only UCB has mountpoints! ) 1567 if ( INET_PROT_FILE != aObj.GetProtocol() ) 1568 sText = rURL.Copy( static_cast< sal_uInt16 >( 1569 INetURLObject::GetScheme( aObj.GetProtocol() ).getLength() ) ); 1570 } 1571 1572 if ( !sText.Len() && aObj.getSegmentCount() ) 1573 sText = rURL; 1574 } 1575 1576 // path mode ? 1577 if ( FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType ) 1578 // -> set new path in the edit field 1579 _pImp->_pEdFileName->SetText( sText ); 1580 1581 // in the "current path" field, truncate the trailing slash 1582 if ( aObj.hasFinalSlash() ) 1583 { 1584 aObj.removeFinalSlash(); 1585 String sURL( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 1586 if ( !::utl::LocalFileHelper::ConvertURLToSystemPath( sURL, sText ) ) 1587 sText = sURL; 1588 } 1589 1590 if ( !sText.Len() && rURL.Len() ) 1591 // happens, for instance, for URLs which the INetURLObject does not know to belong to a hierarchical scheme 1592 sText = rURL; 1593 _pImp->_pFtCurrentPath->SetText( sText ); 1594 } 1595 1596 //========================================================================= 1597 _aPath = rURL; 1598 if ( _pFileNotifier ) 1599 _pFileNotifier->notify( DIRECTORY_CHANGED, 0 ); 1600 } 1601 1602 //***************************************************************************** 1603 1604 IMPL_LINK( SvtFileDialog, SelectHdl_Impl, SvTabListBox*, pBox ) 1605 { 1606 SvLBoxEntry* pEntry = pBox->FirstSelected(); 1607 DBG_ASSERT( pEntry, "SelectHandler without selected entry" ); 1608 SvtContentEntry* pUserData = (SvtContentEntry*)pEntry->GetUserData(); 1609 1610 if ( pUserData ) 1611 { 1612 INetURLObject aObj( pUserData->maURL ); 1613 if ( FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType ) 1614 { 1615 if ( aObj.GetProtocol() == INET_PROT_FILE ) 1616 { 1617 if ( !pUserData->mbIsFolder ) 1618 aObj.removeSegment(); 1619 String aName = aObj.getFSysPath( (INetURLObject::FSysStyle)(INetURLObject::FSYS_DETECT & ~INetURLObject::FSYS_VOS) ); 1620 _pImp->_pEdFileName->SetText( aName ); 1621 _pImp->_pEdFileName->SetSelection( Selection( 0, aName.Len() ) ); 1622 _aPath = pUserData->maURL; 1623 } 1624 else if ( !pUserData->mbIsFolder ) 1625 { 1626 _pImp->_pEdFileName->SetText( pUserData->maURL ); 1627 _pImp->_pEdFileName->SetSelection( Selection( 0, pUserData->maURL.Len() ) ); 1628 _aPath = pUserData->maURL; 1629 } 1630 else 1631 _pImp->_pEdFileName->SetText( UniString() ); 1632 } 1633 else 1634 { 1635 if ( !pUserData->mbIsFolder ) 1636 { 1637 String aName = pBox->GetEntryText( pEntry, 0 ); 1638 _pImp->_pEdFileName->SetText( aName ); 1639 _pImp->_pEdFileName->SetSelection( Selection( 0, aName.Len() ) ); 1640 _aPath = pUserData->maURL; 1641 } 1642 } 1643 } 1644 1645 if ( _pImp->_bMultiSelection && _pFileView->GetSelectionCount() > 1 ) 1646 { 1647 // bei Multiselektion den Datei-Edit leeren 1648 _pImp->_pEdFileName->SetText( String() ); 1649 } 1650 1651 FileSelect(); 1652 1653 return 0; 1654 } 1655 1656 //***************************************************************************** 1657 1658 IMPL_LINK( SvtFileDialog, DblClickHdl_Impl, SvTabListBox*, EMPTYARG ) 1659 { 1660 _pImp->_bDoubleClick = sal_True; 1661 OpenHdl_Impl( this, NULL ); 1662 _pImp->_bDoubleClick = sal_False; 1663 1664 return 0; 1665 } 1666 1667 //***************************************************************************** 1668 1669 IMPL_LINK( SvtFileDialog, EntrySelectHdl_Impl, ComboBox*, EMPTYARG ) 1670 { 1671 FileSelect(); 1672 1673 return 0; 1674 } 1675 1676 //***************************************************************************** 1677 1678 IMPL_LINK( SvtFileDialog, OpenDoneHdl_Impl, SvtFileView*, pView ) 1679 { 1680 String sCurrentFolder( pView->GetViewURL() ); 1681 // check if we can create new folders 1682 EnableControl( _pImp->_pBtnNewFolder, ContentCanMakeFolder( sCurrentFolder ) && m_aURLFilter.isUrlAllowed( sCurrentFolder, false ) ); 1683 1684 // check if we can travel one level up 1685 bool bCanTravelUp = ContentHasParentFolder( pView->GetViewURL() ); 1686 if ( bCanTravelUp ) 1687 { 1688 // additional check: the parent folder should not be prohibited 1689 INetURLObject aCurrentFolder( sCurrentFolder ); 1690 DBG_ASSERT( INET_PROT_NOT_VALID != aCurrentFolder.GetProtocol(), 1691 "SvtFileDialog::OpenDoneHdl_Impl: invalid current URL!" ); 1692 1693 aCurrentFolder.removeSegment(); 1694 bCanTravelUp &= m_aURLFilter.isUrlAllowed( aCurrentFolder.GetMainURL( INetURLObject::NO_DECODE ) ); 1695 } 1696 EnableControl( _pImp->_pBtnUp, bCanTravelUp ); 1697 1698 return 0; 1699 } 1700 1701 //***************************************************************************** 1702 1703 IMPL_LINK( SvtFileDialog, AutoExtensionHdl_Impl, CheckBox*, EMPTYARG ) 1704 { 1705 if ( _pFileNotifier ) 1706 _pFileNotifier->notify( CTRL_STATE_CHANGED, 1707 CHECKBOX_AUTOEXTENSION ); 1708 1709 // update the extension of the current file if necessary 1710 lcl_autoUpdateFileExtension( this, _pImp->GetCurFilter()->GetExtension() ); 1711 1712 return 0; 1713 } 1714 1715 //***************************************************************************** 1716 1717 IMPL_LINK( SvtFileDialog, ClickHdl_Impl, CheckBox*, pCheckBox ) 1718 { 1719 if ( ! _pFileNotifier ) 1720 return 0; 1721 1722 sal_Int16 nId = -1; 1723 1724 if ( pCheckBox == _pImp->_pCbOptions ) 1725 nId = CHECKBOX_FILTEROPTIONS; 1726 else if ( pCheckBox == _pCbSelection ) 1727 nId = CHECKBOX_SELECTION; 1728 else if ( pCheckBox == _pCbReadOnly ) 1729 nId = CHECKBOX_READONLY; 1730 else if ( pCheckBox == _pImp->_pCbPassword ) 1731 nId = CHECKBOX_PASSWORD; 1732 else if ( pCheckBox == _pCbLinkBox ) 1733 nId = CHECKBOX_LINK; 1734 else if ( pCheckBox == _pCbPreviewBox ) 1735 nId = CHECKBOX_PREVIEW; 1736 1737 if ( nId != -1 ) 1738 _pFileNotifier->notify( CTRL_STATE_CHANGED, nId ); 1739 1740 return 0; 1741 } 1742 1743 //***************************************************************************** 1744 1745 IMPL_LINK( SvtFileDialog, PlayButtonHdl_Impl, PushButton*, EMPTYARG ) 1746 { 1747 if ( _pFileNotifier ) 1748 _pFileNotifier->notify( CTRL_STATE_CHANGED, 1749 PUSHBUTTON_PLAY ); 1750 1751 return 0; 1752 } 1753 1754 //***************************************************************************** 1755 1756 long SvtFileDialog::Notify( NotifyEvent& rNEvt ) 1757 1758 /* [Beschreibung] 1759 1760 Die Methode wird gerufen, <BACKSPACE> abzufangen. 1761 */ 1762 1763 { 1764 sal_uInt16 nType = rNEvt.GetType(); 1765 long nRet = 0; 1766 1767 if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() ) 1768 { 1769 const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode(); 1770 sal_uInt16 nCode = rKeyCode.GetCode(); 1771 1772 if ( !rKeyCode.GetModifier() && 1773 KEY_BACKSPACE == nCode && !_pImp->_pEdFileName->HasChildPathFocus() ) 1774 { 1775 nRet = 0; //! (long)_pFileView->DoBeamerKeyInput( *rNEvt.GetKeyEvent() ); 1776 1777 if ( !nRet && _pImp->_pBtnUp->IsEnabled() ) 1778 { 1779 PrevLevel_Impl(); 1780 nRet = 1; 1781 } 1782 } 1783 // else if ( rKeyCode.IsMod1() && ( KEY_C == nCode || KEY_V == nCode || KEY_X == nCode ) ) 1784 // { 1785 /* (mhu) 1786 String aVerb = KEY_C == nCode ? UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_COPY)) : 1787 ( KEY_V == nCode ? UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_PASTE)) : UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_CUT)) ); 1788 //(dv) if ( !CntPopupMenu::DoVerbCommand( aVerb, _pFileView->GetView() ) ) 1789 //(dv) Sound::Beep(); 1790 */ 1791 // } 1792 } 1793 return nRet ? nRet : ModalDialog::Notify( rNEvt ); 1794 } 1795 1796 //***************************************************************************** 1797 1798 long SvtFileDialog::OK() 1799 { 1800 return sal_True; 1801 } 1802 1803 //***************************************************************************** 1804 1805 class SvtDefModalDialogParent_Impl 1806 { 1807 private: 1808 Window* _pOld; 1809 1810 public: 1811 SvtDefModalDialogParent_Impl( Window *pNew ) : 1812 _pOld( Application::GetDefDialogParent() ) 1813 { Application::SetDefDialogParent( pNew ); } 1814 1815 ~SvtDefModalDialogParent_Impl() { Application::SetDefDialogParent( _pOld ); } 1816 }; 1817 1818 //***************************************************************************** 1819 1820 //--------------------------------------------------------------------- 1821 void SvtFileDialog::updateListboxLabelSizes() 1822 { 1823 sal_Int16 nLineControlId[5] = { 1824 LISTBOX_VERSION, LISTBOX_TEMPLATE, LISTBOX_IMAGE_TEMPLATE, LISTBOX_FILTER, EDIT_FILEURL 1825 }; 1826 1827 // determine the maximum width needed for the listbox labels 1828 long nMaxWidth = 0; 1829 for ( sal_Int32 i=0; i<5; ++i ) 1830 { 1831 FixedText* pLabel = static_cast< FixedText* >( getControl( nLineControlId[i], sal_True ) ); 1832 if ( !pLabel ) 1833 continue; 1834 nMaxWidth = ::std::max( pLabel->GetTextWidth( pLabel->GetText() ), nMaxWidth ); 1835 } 1836 1837 // ensure that all labels are wide enough 1838 for ( sal_Int32 i=0; i<5; ++i ) 1839 { 1840 FixedText* pLabel = static_cast< FixedText* >( getControl( nLineControlId[i], sal_True ) ); 1841 ListBox* pListbox = static_cast< ListBox* >( getControl( nLineControlId[i], sal_False ) ); 1842 if ( !pLabel || !pListbox ) 1843 continue; 1844 Size aCurrentSize( pLabel->GetSizePixel() ); 1845 if ( aCurrentSize.Width() >= nMaxWidth ) 1846 continue; 1847 1848 long nChange = nMaxWidth - aCurrentSize.Width(); 1849 pLabel->SetSizePixel( Size( nMaxWidth, aCurrentSize.Height() ) ); 1850 1851 aCurrentSize = pListbox->GetSizePixel(); 1852 pListbox->SetSizePixel( Size( aCurrentSize.Width() - nChange, aCurrentSize.Height() ) ); 1853 lcl_MoveControl( pListbox, nChange, 0 ); 1854 } 1855 } 1856 1857 namespace 1858 { 1859 1860 bool implIsInvalid( const String & rURL ) 1861 { 1862 SmartContent aContent( rURL ); 1863 aContent.enableOwnInteractionHandler( ::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST ); 1864 aContent.isFolder(); // do this _before_ asking isInvalid! Otherwise result might be wrong. 1865 return aContent.isInvalid(); 1866 } 1867 1868 } 1869 1870 //--------------------------------------------------------------------- 1871 String SvtFileDialog::implGetInitialURL( const String& _rPath, const String& _rFallback ) 1872 { 1873 // an URL parser for the fallback 1874 INetURLObject aURLParser; 1875 1876 // set the path 1877 bool bWasAbsolute = sal_False; 1878 aURLParser = aURLParser.smartRel2Abs( _rPath, bWasAbsolute ); 1879 1880 // is it a valid folder? 1881 m_aContent.bindTo( aURLParser.GetMainURL( INetURLObject::NO_DECODE ) ); 1882 sal_Bool bIsFolder = m_aContent.isFolder( ); // do this _before_ asking isInvalid! 1883 sal_Bool bIsInvalid = m_aContent.isInvalid(); 1884 1885 if ( bIsInvalid && m_bHasFilename && !aURLParser.hasFinalSlash() ) 1886 { // check if the parent folder exists 1887 // #108429# - 2003-03-26 - fs@openoffice.org 1888 INetURLObject aParent( aURLParser ); 1889 aParent.removeSegment( ); 1890 aParent.setFinalSlash( ); 1891 bIsInvalid = implIsInvalid( aParent.GetMainURL( INetURLObject::NO_DECODE ) ); 1892 } 1893 1894 if ( bIsInvalid ) 1895 { 1896 INetURLObject aFallback( _rFallback ); 1897 bIsInvalid = implIsInvalid( aFallback.GetMainURL( INetURLObject::NO_DECODE ) ); 1898 1899 if ( !bIsInvalid ) 1900 aURLParser = aFallback; 1901 } 1902 1903 if ( bIsInvalid ) 1904 { 1905 INetURLObject aParent( aURLParser ); 1906 while ( bIsInvalid && aParent.removeSegment() ) 1907 { 1908 aParent.setFinalSlash( ); 1909 bIsInvalid = implIsInvalid( aParent.GetMainURL( INetURLObject::NO_DECODE ) ); 1910 } 1911 1912 if ( !bIsInvalid ) 1913 aURLParser = aParent; 1914 } 1915 1916 if ( !bIsInvalid && bIsFolder ) 1917 { 1918 aURLParser.setFinalSlash(); 1919 } 1920 return aURLParser.GetMainURL( INetURLObject::NO_DECODE ); 1921 } 1922 1923 //--------------------------------------------------------------------- 1924 short SvtFileDialog::Execute() 1925 { 1926 if ( !PrepareExecute() ) 1927 return 0; 1928 1929 // Start des Dialogs. 1930 _bIsInExecute = sal_True; 1931 short nResult = ModalDialog::Execute(); 1932 _bIsInExecute = sal_False; 1933 1934 DBG_ASSERT( !m_pCurrentAsyncAction.is(), "SvtFilePicker::Execute: still running an async action!" ); 1935 // the dialog should not be cancellable while an async action is running - firs, the action 1936 // needs to be cancelled 1937 1938 // letztes Verzeichnis merken 1939 if ( RET_OK == nResult ) 1940 { 1941 INetURLObject aURL( _aPath ); 1942 if ( aURL.GetProtocol() == INET_PROT_FILE ) 1943 { 1944 // nur bei File-URL's und nicht bei virtuelle Folder 1945 // das ausgew"ahlte Verzeichnis merken 1946 sal_Int32 nLevel = aURL.getSegmentCount(); 1947 // #97148# & #102204# ------ 1948 sal_Bool bDir = m_aContent.isFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) ); 1949 // sal_Bool bClassPath = ( ( _pImp->_nStyle & SFXWB_CLASSPATH ) == SFXWB_CLASSPATH ); 1950 if ( nLevel > 1 && ( FILEDLG_TYPE_FILEDLG == _pImp->_eDlgType || !bDir ) ) 1951 aURL.removeSegment(); 1952 } 1953 } 1954 1955 return nResult; 1956 } 1957 1958 //--------------------------------------------------------------------- 1959 void SvtFileDialog::StartExecuteModal( const Link& rEndDialogHdl ) 1960 { 1961 PrepareExecute(); 1962 1963 // Start des Dialogs. 1964 // _bIsInExecute = sal_True; 1965 ModalDialog::StartExecuteModal( rEndDialogHdl ); 1966 } 1967 1968 //----------------------------------------------------------------------------- 1969 void SvtFileDialog::onAsyncOperationStarted() 1970 { 1971 EnableUI( sal_False ); 1972 // the cancel button must be always enabled 1973 _pImp->_pBtnCancel->Enable( sal_True ); 1974 _pImp->_pBtnCancel->GrabFocus(); 1975 } 1976 1977 //----------------------------------------------------------------------------- 1978 void SvtFileDialog::onAsyncOperationFinished() 1979 { 1980 EnableUI( sal_True ); 1981 m_pCurrentAsyncAction = NULL; 1982 if ( !m_bInExecuteAsync ) 1983 _pImp->_pEdFileName->GrabFocus(); 1984 // (if m_bInExecuteAsync is true, then the operation was finished within the minium wait time, 1985 // and to the user, the operation appears to be synchronous) 1986 } 1987 1988 //------------------------------------------------------------------------- 1989 void SvtFileDialog::displayIOException( const String& _rURL, IOErrorCode _eCode ) 1990 { 1991 try 1992 { 1993 // create make a human-readable string from the URL 1994 String sDisplayPath( _rURL ); 1995 ::utl::LocalFileHelper::ConvertURLToSystemPath( _rURL, sDisplayPath ); 1996 1997 // build an own exception which tells "access denied" 1998 InteractiveAugmentedIOException aException; 1999 aException.Arguments.realloc( 2 ); 2000 aException.Arguments[ 0 ] <<= ::rtl::OUString( sDisplayPath ); 2001 aException.Arguments[ 1 ] <<= PropertyValue( 2002 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ), 2003 -1, aException.Arguments[ 0 ], PropertyState_DIRECT_VALUE 2004 ); 2005 // (formerly, it was sufficient to put the URL first parameter. Nowadays, 2006 // the services expects the URL in a PropertyValue named "Uri" ...) 2007 aException.Code = _eCode; 2008 aException.Classification = InteractionClassification_ERROR; 2009 2010 // let and interaction handler handle this exception 2011 ::comphelper::OInteractionRequest* pRequest = NULL; 2012 Reference< ::com::sun::star::task::XInteractionRequest > xRequest = pRequest = 2013 new ::comphelper::OInteractionRequest( makeAny( aException ) ); 2014 pRequest->addContinuation( new ::comphelper::OInteractionAbort( ) ); 2015 2016 Reference< XInteractionHandler > xHandler( 2017 ::comphelper::getProcessServiceFactory()->createInstance( 2018 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") ) 2019 ), 2020 UNO_QUERY 2021 ); 2022 if ( xHandler.is() ) 2023 xHandler->handle( xRequest ); 2024 } 2025 catch( const Exception& ) 2026 { 2027 DBG_ERROR( "iodlg::displayIOException: caught an exception!" ); 2028 } 2029 } 2030 2031 //----------------------------------------------------------------------------- 2032 void SvtFileDialog::EnableUI( sal_Bool _bEnable ) 2033 { 2034 Enable( _bEnable ); 2035 2036 if ( _bEnable ) 2037 { 2038 for ( ::std::set< Control* >::iterator aLoop = m_aDisabledControls.begin(); 2039 aLoop != m_aDisabledControls.end(); 2040 ++aLoop 2041 ) 2042 { 2043 (*aLoop)->Enable( sal_False ); 2044 } 2045 } 2046 } 2047 2048 //----------------------------------------------------------------------------- 2049 void SvtFileDialog::EnableControl( Control* _pControl, sal_Bool _bEnable ) 2050 { 2051 if ( !_pControl ) 2052 { 2053 DBG_ERRORFILE( "SvtFileDialog::EnableControl: invalid control!" ); 2054 return; 2055 } 2056 2057 _pControl->Enable( _bEnable ); 2058 2059 if ( _bEnable ) 2060 { 2061 ::std::set< Control* >::iterator aPos = m_aDisabledControls.find( _pControl ); 2062 if ( m_aDisabledControls.end() != aPos ) 2063 m_aDisabledControls.erase( aPos ); 2064 } 2065 else 2066 m_aDisabledControls.insert( _pControl ); 2067 } 2068 2069 //---------------------------------------------------------------------------- 2070 2071 short SvtFileDialog::PrepareExecute() 2072 { 2073 rtl::OUString aEnvValue; 2074 if ( getEnvironmentValue( "WorkDirMustContainRemovableMedia", aEnvValue ) && 2075 aEnvValue.equalsAscii( "1" ) ) 2076 { 2077 try 2078 { 2079 INetURLObject aStdDir( GetStandardDir() ); 2080 ::ucbhelper::Content aCnt( rtl::OUString( aStdDir.GetMainURL( 2081 INetURLObject::NO_DECODE ) ), 2082 Reference< XCommandEnvironment >() ); 2083 Sequence< rtl::OUString > aProps(2); 2084 aProps[0] = rtl::OUString::createFromAscii( "IsVolume" ); 2085 aProps[1] = rtl::OUString::createFromAscii( "IsRemoveable" ); 2086 2087 Reference< XResultSet > xResultSet 2088 = aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_FOLDERS_ONLY ); 2089 if ( xResultSet.is() ) 2090 { 2091 Reference< XRow > xRow( xResultSet, UNO_QUERY ); 2092 2093 bool bEmpty = true; 2094 if ( !xResultSet->next() ) 2095 { 2096 // folder is empty 2097 bEmpty = true; 2098 } 2099 else 2100 { 2101 // @@@ KSO 05/18/2006: support for removable media currently hardcoded/incomplete in OSL 2102 // 2103 // do 2104 // { 2105 // // check, whether child is a removable volume 2106 // if ( xRow->getBoolean( 1 ) && !xRow->wasNull() ) 2107 // { 2108 // if ( xRow->getBoolean( 2 ) && !xRow->wasNull() ) 2109 // { 2110 bEmpty = false; 2111 // break; 2112 // } 2113 // } 2114 // } 2115 // while ( xResultSet->next() ); 2116 } 2117 2118 if ( bEmpty ) 2119 { 2120 ErrorBox aBox( this, WB_OK, SvtResId( STR_SVT_NOREMOVABLEDEVICE ) ); 2121 aBox.Execute(); 2122 return 0; 2123 } 2124 } 2125 } 2126 catch ( ContentCreationException const & ) 2127 { 2128 } 2129 catch ( CommandAbortedException const & ) 2130 { 2131 } 2132 } 2133 2134 // #102204# --------------- 2135 if ( ( _pImp->_nStyle & WB_SAVEAS ) && m_bHasFilename ) 2136 // when doing a save-as, we do not want the handler to handle "this file does not exist" messages 2137 // - finally we're going to save that file, aren't we? 2138 // #105812# - 2002-12-02 - fs@openoffice.org 2139 m_aContent.enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST); 2140 else 2141 m_aContent.enableDefaultInteractionHandler(); 2142 2143 // #53016# evtl. nur ein Filename ohne Pfad? 2144 String aFileNameOnly; 2145 if( _aPath.Len() && (_pImp->_eMode == FILEDLG_MODE_SAVE) 2146 && (_aPath.Search(':') == STRING_NOTFOUND) 2147 && (_aPath.Search('\\') == STRING_NOTFOUND) 2148 && (_aPath.Search('/') == STRING_NOTFOUND)) 2149 { 2150 aFileNameOnly = _aPath; 2151 _aPath.Erase(); 2152 } 2153 2154 // kein Startpfad angegeben? 2155 if ( !_aPath.Len() ) 2156 { 2157 // dann das Standard-Dir verwenden 2158 _aPath = lcl_ensureFinalSlash( _pImp->GetStandardDir() ); 2159 2160 // #53016# vorgegebener Dateiname an Pfad anh"angen 2161 if ( aFileNameOnly.Len() ) 2162 _aPath += aFileNameOnly; 2163 } 2164 2165 //..................................................................... 2166 _aPath = implGetInitialURL( _aPath, GetStandardDir() ); 2167 2168 if ( _pImp->_nStyle & WB_SAVEAS && !m_bHasFilename ) 2169 // when doing a save-as, we do not want the handler to handle "this file does not exist" messages 2170 // - finally we're going to save that file, aren't we? 2171 m_aContent.enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST); 2172 2173 //..................................................................... 2174 // care for possible restrictions on the paths we're allowed to show 2175 if ( !m_aURLFilter.isUrlAllowed( _aPath ) ) 2176 _aPath = m_aURLFilter.getFilter()[0]; 2177 2178 // Ggf. Filter anzeigen. 2179 _pImp->InitFilterList(); 2180 2181 // Initialen Filter einstellen. 2182 sal_uInt16 nFilterCount = GetFilterCount(); 2183 String aAll( SvtResId( STR_FILTERNAME_ALL ) ); 2184 sal_Bool bHasAll = _pImp->HasFilterListEntry( aAll ); 2185 if ( _pImp->GetCurFilter() || nFilterCount == 1 || ( nFilterCount == 2 && bHasAll ) ) 2186 { 2187 // Ggf. einzigen Filter als aktuellen Filter setzen oder den einzigen 2188 // Filter, der nicht auf alle Dateien verweist. 2189 if ( !_pImp->GetCurFilter() ) 2190 { 2191 sal_uInt16 nPos = 0; 2192 if ( 2 == nFilterCount && bHasAll ) 2193 { 2194 nPos = nFilterCount; 2195 while ( nPos-- ) 2196 { 2197 if ( GetFilterName( nPos ) != aAll ) 2198 break; 2199 } 2200 } 2201 SvtFileDialogFilter_Impl* pNewCurFilter = _pImp->_pFilter->GetObject( nPos ); 2202 DBG_ASSERT( pNewCurFilter, "SvtFileDialog::Execute: invalid filter pos!" ); 2203 _pImp->SetCurFilter( pNewCurFilter, pNewCurFilter->GetName() ); 2204 } 2205 2206 // Anzeige anpassen. 2207 _pImp->SelectFilterListEntry( _pImp->GetCurFilter()->GetName() ); 2208 SetDefaultExt( _pImp->GetCurFilter()->GetExtension() ); 2209 sal_uInt16 nSepPos = GetDefaultExt().Search( FILEDIALOG_DEF_EXTSEP ); 2210 if ( nSepPos != STRING_NOTFOUND ) 2211 EraseDefaultExt( nSepPos ); 2212 } 2213 else 2214 { 2215 // Ggf. Filter fuer alle Dateien setzen bzw. erzeugen. 2216 if ( !bHasAll ) 2217 { 2218 SvtFileDialogFilter_Impl* pAllFilter = implAddFilter( aAll, UniString(RTL_CONSTASCII_USTRINGPARAM(FILEDIALOG_FILTER_ALL)) ); 2219 _pImp->InsertFilterListEntry( pAllFilter ); 2220 _pImp->SetCurFilter( pAllFilter, aAll ); 2221 } 2222 _pImp->SelectFilterListEntry( aAll ); 2223 } 2224 2225 _pImp->_pDefaultFilter = _pImp->GetCurFilter(); 2226 2227 // HACK #50065# 2228 // ggf. Filter isolieren. 2229 String aFilter; 2230 2231 if ( !IsolateFilterFromPath_Impl( _aPath, aFilter ) ) 2232 return 0; 2233 2234 sal_uInt16 nNewFilterFlags = adjustFilter( aFilter ); 2235 if ( nNewFilterFlags & ( FLT_NONEMPTY | FLT_USERFILTER ) ) 2236 { 2237 _pImp->_pEdFileName->SetText( aFilter ); 2238 } 2239 // HACK #50065# 2240 2241 // Instanz fuer den gesetzten Pfad erzeugen und anzeigen. 2242 INetURLObject aFolderURL( _aPath ); 2243 String aFileName( aFolderURL.getName( INetURLObject::LAST_SEGMENT, false ) ); 2244 xub_StrLen nFileNameLen = aFileName.Len(); 2245 bool bFileToSelect = nFileNameLen != 0; 2246 if ( bFileToSelect && aFileName.GetChar( nFileNameLen - 1 ) != INET_PATH_TOKEN ) 2247 { 2248 _pImp->_pEdFileName->SetText( GET_DECODED_NAME( aFolderURL ) ); 2249 aFolderURL.removeSegment(); 2250 } 2251 2252 INetURLObject aObj = aFolderURL; 2253 if ( aObj.GetProtocol() == INET_PROT_FILE ) 2254 { 2255 // Ordner als aktuelles Verzeichnis setzen. 2256 aObj.setFinalSlash(); 2257 } 2258 2259 UpdateControls( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 2260 2261 // Somebody might want to enable some controls acording to the current filter 2262 FilterSelect(); 2263 2264 // Zustand der Steuerelemente anpassen. 2265 // EndListeningAll(); 2266 2267 ViewHdl_Impl( this, NULL ); 2268 OpenURL_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 2269 2270 _pFileView->Show(); 2271 SvtDefModalDialogParent_Impl aDefParent( this ); 2272 2273 // ggf. Gr"osse aus Ini lesen und setzen 2274 InitSize(); 2275 2276 return 1; 2277 } 2278 2279 //----------------------------------------------------------------------------- 2280 void SvtFileDialog::implInitializeSpecialURLLists( ) 2281 { 2282 m_aURLFilter = ::svt::RestrictedPaths(); 2283 2284 ::std::vector< String > aFavourites; 2285 if ( m_aURLFilter.hasFilter() ) 2286 { 2287 // if we have restrictions, then the "favourites" are the restricted folders only 2288 aFavourites = m_aURLFilter.getFilter(); 2289 // for approved URLs, we needed the final slashes, for 2290 // favourites, we do not want to have them 2291 ::std::for_each( aFavourites.begin(), aFavourites.end(), RemoveFinalSlash() ); 2292 } 2293 else 2294 { 2295 ::rtl::OUString sFavouritesList; 2296 if ( getEnvironmentValue( "PathFavourites", sFavouritesList ) ) 2297 convertStringListToUrls( sFavouritesList, aFavourites, false ); 2298 } 2299 2300 DBG_ASSERT( _pImp->_pBtnStandard, "SvtFileDialog::implInitializeSpecialURLLists: how this?" ); 2301 if ( _pImp->_pBtnStandard ) 2302 _pImp->_pBtnStandard->SetFavouriteLocations( aFavourites ); 2303 } 2304 2305 //----------------------------------------------------------------------------- 2306 void SvtFileDialog::executeAsync( ::svt::AsyncPickerAction::Action _eAction, 2307 const String& _rURL, const String& _rFilter ) 2308 { 2309 DBG_ASSERT( !m_pCurrentAsyncAction.is(), "SvtFileDialog::executeAsync: previous async action not yet finished!" ); 2310 2311 m_pCurrentAsyncAction = new AsyncPickerAction( this, _pFileView, _eAction ); 2312 2313 bool bReallyAsync = true; 2314 m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FillAsynchronously" ) ) ) >>= bReallyAsync; 2315 2316 sal_Int32 nMinTimeout = 0; 2317 m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Timeout/Min" ) ) ) >>= nMinTimeout; 2318 sal_Int32 nMaxTimeout = 0; 2319 m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Timeout/Max" ) ) ) >>= nMaxTimeout; 2320 2321 m_bInExecuteAsync = true; 2322 m_pCurrentAsyncAction->execute( _rURL, _rFilter, bReallyAsync ? nMinTimeout : -1, nMaxTimeout, GetBlackList() ); 2323 m_bInExecuteAsync = false; 2324 } 2325 2326 //***************************************************************************** 2327 2328 void SvtFileDialog::FileSelect() 2329 { 2330 if ( _pFileNotifier ) 2331 _pFileNotifier->notify( FILE_SELECTION_CHANGED, 0 ); 2332 } 2333 2334 //***************************************************************************** 2335 2336 void SvtFileDialog::FilterSelect() 2337 { 2338 if ( _pFileNotifier ) 2339 _pFileNotifier->notify( CTRL_STATE_CHANGED, 2340 LISTBOX_FILTER ); 2341 } 2342 2343 //***************************************************************************** 2344 2345 void SvtFileDialog::SetStandardDir( const String& rStdDir ) 2346 2347 /* [Beschreibung] 2348 2349 Die Methode setzt den Pfad f"ur den Standardknopf. 2350 */ 2351 2352 { 2353 INetURLObject aObj( rStdDir ); 2354 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid protocol!" ); 2355 aObj.setFinalSlash(); 2356 _pImp->SetStandardDir( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 2357 } 2358 2359 void SvtFileDialog::SetBlackList( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList ) 2360 { 2361 _pImp->SetBlackList( rBlackList ); 2362 } 2363 2364 //***************************************************************************** 2365 2366 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& SvtFileDialog::GetBlackList() const 2367 { 2368 return _pImp->GetBlackList(); 2369 } 2370 //***************************************************************************** 2371 2372 const String& SvtFileDialog::GetStandardDir() const 2373 2374 /* [Beschreibung] 2375 2376 Diese Methode gibt den eingestellten Standardpfad zur"uck. 2377 */ 2378 2379 { 2380 return _pImp->GetStandardDir(); 2381 } 2382 2383 //***************************************************************************** 2384 2385 void SvtFileDialog::PrevLevel_Impl() 2386 { 2387 _pFileView->EndInplaceEditing( false ); 2388 2389 String sDummy; 2390 executeAsync( AsyncPickerAction::ePrevLevel, sDummy, sDummy ); 2391 } 2392 2393 //***************************************************************************** 2394 2395 void SvtFileDialog::OpenURL_Impl( const String& _rURL ) 2396 { 2397 _pFileView->EndInplaceEditing( false ); 2398 2399 DBG_ASSERT( m_aURLFilter.isUrlAllowed( _rURL ), "SvtFileDialog::OpenURL_Impl: forbidden URL! Should have been handled by the caller!" ); 2400 executeAsync( AsyncPickerAction::eOpenURL, _rURL, getMostCurrentFilter( _pImp ) ); 2401 } 2402 2403 //***************************************************************************** 2404 SvtFileDialogFilter_Impl* SvtFileDialog::implAddFilter( const String& _rFilter, const String& _rType ) 2405 { 2406 SvtFileDialogFilter_Impl* pNewFilter = new SvtFileDialogFilter_Impl( _rFilter, _rType ); 2407 _pImp->_pFilter->C40_INSERT( SvtFileDialogFilter_Impl, pNewFilter, (sal_uInt16)0 ); 2408 2409 if ( !_pImp->GetCurFilter() ) 2410 _pImp->SetCurFilter( pNewFilter, _rFilter ); 2411 2412 return pNewFilter; 2413 } 2414 2415 //***************************************************************************** 2416 2417 void SvtFileDialog::AddFilter( const String& _rFilter, const String& _rType ) 2418 { 2419 DBG_ASSERT( !IsInExecute(), "SvtFileDialog::AddFilter: currently executing!" ); 2420 implAddFilter ( _rFilter, _rType ); 2421 } 2422 2423 //***************************************************************************** 2424 void SvtFileDialog::AddFilterGroup( const String& _rFilter, const Sequence< StringPair >& _rFilters ) 2425 { 2426 DBG_ASSERT( !IsInExecute(), "SvtFileDialog::AddFilter: currently executing!" ); 2427 2428 implAddFilter( _rFilter, String() ); 2429 const StringPair* pSubFilters = _rFilters.getConstArray(); 2430 const StringPair* pSubFiltersEnd = pSubFilters + _rFilters.getLength(); 2431 for ( ; pSubFilters != pSubFiltersEnd; ++pSubFilters ) 2432 implAddFilter( pSubFilters->First, pSubFilters->Second ); 2433 } 2434 2435 //***************************************************************************** 2436 2437 //----------------------------------------------------------------------------- 2438 void SvtFileDialog::SetCurFilter( const String& rFilter ) 2439 { 2440 DBG_ASSERT( !IsInExecute(), "SvtFileDialog::SetCurFilter: currently executing!" ); 2441 2442 // Entsprechenden Filter suchen. 2443 sal_uInt16 nPos = _pImp->_pFilter->Count(); 2444 2445 while ( nPos-- ) 2446 { 2447 SvtFileDialogFilter_Impl* pFilter = _pImp->_pFilter->GetObject( nPos ); 2448 if ( pFilter->GetName() == rFilter ) 2449 { 2450 _pImp->SetCurFilter( pFilter, rFilter ); 2451 break; 2452 } 2453 } 2454 } 2455 2456 //***************************************************************************** 2457 2458 String SvtFileDialog::GetCurFilter() const 2459 { 2460 String aFilter; 2461 2462 const SvtFileDialogFilter_Impl* pCurrentFilter = _pImp->GetCurFilter(); 2463 if ( pCurrentFilter ) 2464 aFilter = pCurrentFilter->GetName(); 2465 2466 return aFilter; 2467 } 2468 2469 String SvtFileDialog::getCurFilter( ) const 2470 { 2471 return GetCurFilter(); 2472 } 2473 2474 //***************************************************************************** 2475 2476 sal_uInt16 SvtFileDialog::GetFilterCount() const 2477 { 2478 return _pImp->_pFilter->Count(); 2479 } 2480 2481 //***************************************************************************** 2482 2483 const String& SvtFileDialog::GetFilterName( sal_uInt16 nPos ) const 2484 { 2485 DBG_ASSERT( nPos < GetFilterCount(), "invalid index" ); 2486 return _pImp->_pFilter->GetObject( nPos )->GetName(); 2487 } 2488 2489 //***************************************************************************** 2490 2491 void SvtFileDialog::InitSize() 2492 { 2493 if ( ! _pImp->_aIniKey.Len() ) 2494 return; 2495 2496 Size aDlgSize = GetResizeOutputSizePixel(); 2497 SetMinOutputSizePixel( aDlgSize ); 2498 2499 if ( !_pImp->_nFixDeltaHeight ) 2500 { 2501 // Fixgr"ossen errechnen und merken 2502 Point aPnt = _pFileView->GetPosPixel(); 2503 long nBoxH = _pFileView->GetSizePixel().Height(); 2504 long nH = GetSizePixel().Height(); 2505 _pImp->_nFixDeltaHeight = nH - nBoxH; 2506 } 2507 2508 // initialize from config 2509 SvtViewOptions aDlgOpt( E_DIALOG, _pImp->_aIniKey ); 2510 2511 if ( aDlgOpt.Exists() ) 2512 { 2513 SetWindowState( ByteString( String( aDlgOpt.GetWindowState() ), osl_getThreadTextEncoding() ) ); 2514 2515 Any aUserData = aDlgOpt.GetUserItem( ::rtl::OUString::createFromAscii( "UserData" ) ); 2516 ::rtl::OUString sCfgStr; 2517 if ( aUserData >>= sCfgStr ) 2518 _pFileView->SetConfigString( String( sCfgStr ) ); 2519 } 2520 } 2521 2522 //***************************************************************************** 2523 2524 SvStringsDtor* SvtFileDialog::GetPathList() const 2525 { 2526 SvStringsDtor* pList = new SvStringsDtor; 2527 sal_uLong nCount = _pFileView->GetSelectionCount(); 2528 SvLBoxEntry* pEntry = nCount ? _pFileView->FirstSelected() : NULL; 2529 2530 if ( ! pEntry ) 2531 { 2532 String* pURL; 2533 2534 if ( _pImp->_pEdFileName->GetText().Len() && _bIsInExecute ) 2535 pURL = new String( _pImp->_pEdFileName->GetURL() ); 2536 else 2537 pURL = new String( _aPath ); 2538 2539 pList->Insert( pURL, pList->Count() ); 2540 } 2541 else 2542 { 2543 while ( pEntry ) 2544 { 2545 String* pURL = new String( _pFileView->GetURL( pEntry ) ); 2546 pList->Insert( pURL, pList->Count() ); 2547 pEntry = _pFileView->NextSelected( pEntry ); 2548 } 2549 } 2550 2551 return pList; 2552 } 2553 2554 //***************************************************************************** 2555 2556 void SvtFileDialog::implArrangeControls() 2557 { 2558 // this is the list of controls in the order they should be tabbed 2559 // from topleft to bottomright 2560 // pb: #136070# new order so all LabeledBy relations are correct now 2561 Control* pControls[] = 2562 { 2563 _pImp->_pFtCurrentPath, 2564 _pImp->_pBtnUp, _pImp->_pBtnNewFolder, _pImp->_pBtnStandard, // image buttons 2565 _pFileView, // the file view 2566 _pImp->_pFtFileName, _pImp->_pEdFileName, 2567 _pImp->_pFtFileVersion, _pImp->_pLbFileVersion, 2568 _pImp->_pFtTemplates, _pImp->_pLbTemplates, 2569 _pImp->_pFtImageTemplates, _pImp->_pLbImageTemplates, 2570 _pImp->_pFtFileType, _pImp->GetFilterListControl(), // edit fields/list boxes 2571 _pImp->_pCbPassword, _pImp->_pCbAutoExtension, _pImp->_pCbOptions, // checkboxes 2572 _pCbReadOnly, _pCbLinkBox, _pCbPreviewBox, _pCbSelection, _pPbPlay, // check boxes (continued) 2573 _pImp->_pBtnFileOpen, _pImp->_pBtnCancel, _pImp->_pBtnHelp // buttons 2574 2575 // (including the FixedTexts is important - not for tabbing order (they're irrelevant there), 2576 // but for working keyboard shortcuts) 2577 // 96861 - 23.01.2002 - fs@openoffice.org 2578 }; 2579 2580 // loop through all these controls and adjust the z-order 2581 Window* pPreviousWin = NULL; 2582 Control** pCurrent = pControls; 2583 for ( sal_Int32 i = 0; i < sal_Int32(sizeof( pControls ) / sizeof( pControls[ 0 ] )); ++i, ++pCurrent ) 2584 { 2585 if ( !*pCurrent ) 2586 // this control is not available in the current operation mode -> skip 2587 continue; 2588 2589 if ( pPreviousWin ) 2590 (*pCurrent)->SetZOrder( pPreviousWin, WINDOW_ZORDER_BEHIND ); 2591 else 2592 (*pCurrent)->SetZOrder( NULL, WINDOW_ZORDER_FIRST ); 2593 2594 pPreviousWin = *pCurrent; 2595 } 2596 2597 // FileName edit not the first control but it should have the focus initially 2598 _pImp->_pEdFileName->GrabFocus(); 2599 } 2600 2601 //***************************************************************************** 2602 2603 sal_Bool SvtFileDialog::IsolateFilterFromPath_Impl( String& rPath, String& rFilter ) 2604 { 2605 String aEmpty; 2606 String aReversePath( rPath ); 2607 aReversePath.Reverse(); 2608 sal_uInt16 nQuestionMarkPos = rPath.Search( '?' ); 2609 2610 if ( nQuestionMarkPos != STRING_NOTFOUND ) 2611 { 2612 // Fragezeichen als Wildcard nur bei Files 2613 INetProtocol eProt = INetURLObject::CompareProtocolScheme( rPath ); 2614 2615 if ( INET_PROT_NOT_VALID != eProt && INET_PROT_FILE != eProt ) 2616 nQuestionMarkPos = STRING_NOTFOUND; 2617 } 2618 sal_uInt16 nWildCardPos = Min( rPath.Search( FILEDIALOG_DEF_WILDCARD ), nQuestionMarkPos ); 2619 rFilter = aEmpty; 2620 2621 if ( nWildCardPos != STRING_NOTFOUND ) 2622 { 2623 sal_uInt16 nPathTokenPos = aReversePath.Search( INET_PATH_TOKEN ); 2624 2625 if ( nPathTokenPos == STRING_NOTFOUND ) 2626 { 2627 String aDelim( 2628 #if defined(WNT) || defined(OS2) 2629 '\\' 2630 #else 2631 '/' 2632 #endif 2633 ); 2634 2635 nPathTokenPos = aReversePath.Search( aDelim ); 2636 #if defined(OS2) 2637 if ( nPathTokenPos == STRING_NOTFOUND ) 2638 { 2639 nPathTokenPos = aReversePath.Search( '/' ); 2640 } 2641 #endif 2642 #if !defined( UNX ) 2643 if ( nPathTokenPos == STRING_NOTFOUND ) 2644 { 2645 nPathTokenPos = aReversePath.Search( ':' ); 2646 } 2647 #endif 2648 } 2649 2650 // Syntax pr"ufen. 2651 if ( nPathTokenPos != STRING_NOTFOUND ) 2652 { 2653 if ( nPathTokenPos < (rPath.Len() - nWildCardPos - 1) ) 2654 { 2655 ErrorHandler::HandleError( ERRCODE_SFX_INVALIDSYNTAX ); 2656 return sal_False; 2657 } 2658 2659 // Filter abschneiden. 2660 rFilter = aReversePath; 2661 rFilter.Erase( nPathTokenPos ); 2662 rFilter.Reverse(); 2663 2664 // Ordner bestimmen. 2665 rPath = aReversePath; 2666 rPath.Erase( 0, nPathTokenPos ); 2667 rPath.Reverse(); 2668 } 2669 else 2670 { 2671 rFilter = rPath; 2672 rPath = aEmpty; 2673 } 2674 } 2675 2676 return sal_True; 2677 } 2678 2679 //***************************************************************************** 2680 2681 //----------------------------------------------------------------------------- 2682 void SvtFileDialog::implUpdateImages( ) 2683 { 2684 // determine high contrast mode 2685 { 2686 sal_Bool bIsHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode(); 2687 m_aImages = ImageList( SvtResId( bIsHighContrast ? RID_FILEPICKER_IMAGES_HC : RID_FILEPICKER_IMAGES ) ); 2688 } 2689 2690 // set the appropriate images on the buttons 2691 if ( _pImp->_pBtnUp ) 2692 _pImp->_pBtnUp->SetModeImage( GetButtonImage( IMG_FILEDLG_BTN_UP ) ); 2693 2694 if ( _pImp->_pBtnStandard ) 2695 _pImp->_pBtnStandard->SetModeImage( GetButtonImage( IMG_FILEDLG_BTN_STD ) ); 2696 2697 if ( _pImp->_pBtnNewFolder ) 2698 _pImp->_pBtnNewFolder->SetModeImage( GetButtonImage( IMG_FILEDLG_CREATEFOLDER ) ); 2699 } 2700 2701 //----------------------------------------------------------------------------- 2702 void SvtFileDialog::DataChanged( const DataChangedEvent& _rDCEvt ) 2703 { 2704 if ( DATACHANGED_SETTINGS == _rDCEvt.GetType() ) 2705 implUpdateImages( ); 2706 2707 ModalDialog::DataChanged( _rDCEvt ); 2708 } 2709 2710 //----------------------------------------------------------------------------- 2711 void SvtFileDialog::Resize() 2712 { 2713 if ( IsRollUp() ) 2714 return; 2715 2716 Size aDlgSize = GetResizeOutputSizePixel(); 2717 Size aOldSize = _pImp->_aDlgSize; 2718 _pImp->_aDlgSize = aDlgSize; 2719 long nWinDeltaW = 0; 2720 2721 if ( _pPrevWin && 2722 _pPrevWin->GetPosPixel().X() > _pFileView->GetPosPixel().X() ) 2723 { 2724 nWinDeltaW = _pPrevWin->GetOutputSizePixel().Width() + _pImp->_a6Size.Width(); 2725 } 2726 2727 Size aNewSize = _pFileView->GetSizePixel(); 2728 Point aBoxPos( _pFileView->GetPosPixel() ); 2729 long nDeltaY = aNewSize.Height(); 2730 long nDeltaX = aNewSize.Width(); 2731 aNewSize.Height() = aDlgSize.Height() - _pImp->_nFixDeltaHeight; 2732 aNewSize.Width() = aDlgSize.Width() - aBoxPos.X() - _pImp->_a6Size.Width() - nWinDeltaW; 2733 if ( aOldSize.Height() ) 2734 nDeltaY = _pImp->_aDlgSize.Height() - aOldSize.Height(); 2735 else 2736 nDeltaY = aNewSize.Height() - nDeltaY; 2737 nDeltaX = aNewSize.Width() - nDeltaX; 2738 2739 if ( nWinDeltaW ) 2740 nWinDeltaW = nDeltaX * 2 / 3; 2741 aNewSize.Width() -= nWinDeltaW; 2742 nDeltaX -= nWinDeltaW; 2743 2744 _pFileView->SetSizePixel( aNewSize ); 2745 2746 if ( !nDeltaY && !nDeltaX ) 2747 // Dieses Resize wurde nur zum Ein - oder Ausblenden des Indicators aufgerufen 2748 return; 2749 2750 // ------------- 2751 // move controls 2752 2753 // controls to move vertically 2754 { 2755 Control* aMoveControlsVert[] = 2756 { 2757 _pImp->_pFtFileName, _pImp->_pEdFileName, _pImp->_pFtFileVersion, _pImp->_pLbFileVersion, 2758 _pImp->_pFtTemplates, _pImp->_pLbTemplates, _pImp->_pFtImageTemplates, _pImp->_pLbImageTemplates, 2759 _pImp->_pFtFileType, _pImp->GetFilterListControl(), _pCbReadOnly, _pCbLinkBox, _pCbPreviewBox, 2760 _pPbPlay, _pImp->_pCbPassword, _pImp->_pCbAutoExtension, _pImp->_pCbOptions, _pCbSelection 2761 }; 2762 Control** ppMoveControls = aMoveControlsVert; 2763 Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsVert ) / sizeof( aMoveControlsVert[0] ); 2764 for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls ) 2765 lcl_MoveControl( *ppMoveControls, 0, nDeltaY ); 2766 } 2767 2768 // controls to move vertically and horizontally 2769 { 2770 Control* aMoveControlsBoth[] = 2771 { 2772 _pImp->_pBtnFileOpen, _pImp->_pBtnCancel, _pImp->_pBtnHelp 2773 }; 2774 Control** ppMoveControls = aMoveControlsBoth; 2775 Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsBoth ) / sizeof( aMoveControlsBoth[0] ); 2776 for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls ) 2777 lcl_MoveControl( *ppMoveControls, nDeltaX, nDeltaY ); 2778 } 2779 2780 // controls to move horizontally 2781 { 2782 Control* aMoveControlsHor[] = 2783 { 2784 _pImp->_pBtnUp, _pImp->_pBtnNewFolder, _pImp->_pBtnStandard 2785 }; 2786 Control** ppMoveControls = aMoveControlsHor; 2787 Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsHor ) / sizeof( aMoveControlsHor[0] ); 2788 for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls ) 2789 lcl_MoveControl( *ppMoveControls, nDeltaX, 0 ); 2790 } 2791 2792 // --------------- 2793 // resize controls 2794 { 2795 Control* aSizeControls[] = 2796 { 2797 _pImp->_pEdFileName, _pImp->_pLbFileVersion, _pImp->_pLbTemplates, _pImp->_pLbImageTemplates, 2798 _pImp->GetFilterListControl(), _pImp->_pFtCurrentPath, 2799 }; 2800 sal_Int32 nSizeControls = sizeof( aSizeControls ) / sizeof( aSizeControls[0] ); 2801 Control** ppSizeControls = aSizeControls; 2802 for ( sal_Int32 j=0; j<nSizeControls; ++j, ++ppSizeControls ) 2803 { 2804 if ( *ppSizeControls ) 2805 { 2806 aNewSize = (*ppSizeControls)->GetSizePixel(); 2807 aNewSize.Width() += nDeltaX; 2808 (*ppSizeControls)->SetSizePixel( aNewSize ); 2809 } 2810 } 2811 } 2812 2813 // zus"atzliche Controls ausrichten 2814 if ( _pPrevWin && 2815 _pPrevWin->GetPosPixel().X() > _pFileView->GetPosPixel().X() ) 2816 { 2817 // Controls vom Typ Window speziell ausrichten 2818 // auch die Gr"osse anpassen 2819 Point aNewPos = _pPrevWin->GetPosPixel(); 2820 aNewPos.X() += nDeltaX; 2821 _pPrevWin->SetPosPixel( aNewPos ); 2822 _pPrevBmp->SetPosPixel( aNewPos ); 2823 aNewSize = _pPrevWin->GetOutputSizePixel(); 2824 aNewSize.Width() += nWinDeltaW; 2825 aNewSize.Height() += nDeltaY; 2826 if ( !aOldSize.Height() ) 2827 aNewSize.Height() -= ( _pImp->_a6Size.Height() / 2 ); 2828 _pPrevWin->SetOutputSizePixel( aNewSize ); 2829 _pPrevBmp->SetOutputSizePixel( aNewSize ); 2830 _pPrevBmp->Invalidate(); 2831 } 2832 2833 if ( _pFileNotifier ) 2834 _pFileNotifier->notify( DIALOG_SIZE_CHANGED, 0 ); 2835 } 2836 2837 //***************************************************************************** 2838 2839 //----------------------------------------------------------------------------- 2840 Control* SvtFileDialog::getControl( sal_Int16 _nControlId, sal_Bool _bLabelControl ) const 2841 { 2842 Control* pReturn = NULL; 2843 2844 switch ( _nControlId ) 2845 { 2846 case CONTROL_FILEVIEW: 2847 pReturn = _bLabelControl ? NULL : static_cast< Control* >( _pFileView ); 2848 break; 2849 2850 case EDIT_FILEURL: 2851 pReturn = _bLabelControl 2852 ? static_cast< Control* >( _pImp->_pFtFileName ) 2853 : static_cast< Control* >( _pImp->_pEdFileName ); 2854 break; 2855 2856 case EDIT_FILEURL_LABEL: 2857 pReturn = static_cast< Control* >( _pImp->_pFtFileName ); 2858 break; 2859 2860 case CHECKBOX_AUTOEXTENSION: 2861 pReturn = _pImp->_pCbAutoExtension; 2862 break; 2863 2864 case CHECKBOX_PASSWORD: 2865 pReturn = _pImp->_pCbPassword; 2866 break; 2867 2868 case CHECKBOX_FILTEROPTIONS: 2869 pReturn = _pImp->_pCbOptions; 2870 break; 2871 2872 case CHECKBOX_READONLY: 2873 pReturn = _pCbReadOnly; 2874 break; 2875 2876 case CHECKBOX_LINK: 2877 pReturn = _pCbLinkBox; 2878 break; 2879 2880 case CHECKBOX_PREVIEW: 2881 pReturn = _pCbPreviewBox; 2882 break; 2883 2884 case CHECKBOX_SELECTION: 2885 pReturn = _pCbSelection; 2886 break; 2887 2888 case LISTBOX_FILTER: 2889 pReturn = _bLabelControl ? _pImp->_pFtFileType : _pImp->GetFilterListControl(); 2890 break; 2891 2892 case LISTBOX_FILTER_LABEL: 2893 pReturn = _pImp->_pFtFileType; 2894 break; 2895 2896 case FIXEDTEXT_CURRENTFOLDER: 2897 pReturn = _pImp->_pFtCurrentPath; 2898 break; 2899 2900 case LISTBOX_VERSION: 2901 pReturn = _bLabelControl 2902 ? static_cast< Control* >( _pImp->_pFtFileVersion ) 2903 : static_cast< Control* >( _pImp->_pLbFileVersion ); 2904 break; 2905 2906 case LISTBOX_TEMPLATE: 2907 pReturn = _bLabelControl 2908 ? static_cast< Control* >( _pImp->_pFtTemplates ) 2909 : static_cast< Control* >( _pImp->_pLbTemplates ); 2910 break; 2911 2912 case LISTBOX_IMAGE_TEMPLATE: 2913 pReturn = _bLabelControl 2914 ? static_cast< Control* >( _pImp->_pFtImageTemplates ) 2915 : static_cast< Control* >( _pImp->_pLbImageTemplates ); 2916 break; 2917 2918 case LISTBOX_VERSION_LABEL: 2919 pReturn = _pImp->_pFtFileVersion; 2920 break; 2921 2922 case LISTBOX_TEMPLATE_LABEL: 2923 pReturn = _pImp->_pFtTemplates; 2924 break; 2925 2926 case LISTBOX_IMAGE_TEMPLATE_LABEL: 2927 pReturn = _pImp->_pFtImageTemplates; 2928 break; 2929 2930 case PUSHBUTTON_OK: 2931 pReturn = _pImp->_pBtnFileOpen; 2932 break; 2933 2934 case PUSHBUTTON_CANCEL: 2935 pReturn = _pImp->_pBtnCancel; 2936 break; 2937 2938 case PUSHBUTTON_PLAY: 2939 pReturn = _pPbPlay; 2940 break; 2941 2942 case PUSHBUTTON_HELP: 2943 pReturn = _pImp->_pBtnHelp; 2944 break; 2945 2946 case TOOLBOXBUTOON_DEFAULT_LOCATION: 2947 pReturn = _pImp->_pBtnStandard; 2948 break; 2949 2950 case TOOLBOXBUTOON_LEVEL_UP: 2951 pReturn = _pImp->_pBtnUp; 2952 break; 2953 2954 case TOOLBOXBUTOON_NEW_FOLDER: 2955 pReturn = _pImp->_pBtnNewFolder; 2956 break; 2957 2958 case LISTBOX_FILTER_SELECTOR: 2959 // only exists on SalGtkFilePicker 2960 break; 2961 2962 default: 2963 DBG_ERRORFILE( "SvtFileDialog::getControl: invalid id!" ); 2964 } 2965 return pReturn; 2966 } 2967 2968 // ----------------------------------------------------------------------- 2969 void SvtFileDialog::enableControl( sal_Int16 _nControlId, sal_Bool _bEnable ) 2970 { 2971 Control* pControl = getControl( _nControlId, sal_False ); 2972 if ( pControl ) 2973 EnableControl( pControl, _bEnable ); 2974 Control* pLabel = getControl( _nControlId, sal_True ); 2975 if ( pLabel ) 2976 EnableControl( pLabel, _bEnable ); 2977 } 2978 2979 // ----------------------------------------------------------------------- 2980 void SvtFileDialog::AddControls_Impl( ) 2981 { 2982 // create the "insert as link" checkbox, if needed 2983 if ( _nExtraBits & SFX_EXTRA_INSERTASLINK ) 2984 { 2985 _pCbLinkBox = new CheckBox( this ); 2986 _pCbLinkBox ->SetText( SvtResId( STR_SVT_FILEPICKER_INSERT_AS_LINK ) ); 2987 _pCbLinkBox ->SetHelpId( HID_FILEDLG_LINK_CB ); 2988 AddControl( _pCbLinkBox ); 2989 ReleaseOwnerShip( _pCbLinkBox ); 2990 _pCbLinkBox->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 2991 } 2992 2993 // create the "show preview" checkbox ( and the preview window, too ), if needed 2994 if ( _nExtraBits & SFX_EXTRA_SHOWPREVIEW ) 2995 { 2996 _pImp->_aIniKey = IMPGRF_CONFIGNAME; 2997 // because the "<All Formats> (*.bmp,*...)" entry is to wide, 2998 // we need to disable the auto width feature of the filter box 2999 _pImp->DisableFilterBoxAutoWidth(); 3000 3001 // "Vorschau" 3002 _pCbPreviewBox = new CheckBox( this ); 3003 _pCbPreviewBox->SetText( SvtResId( STR_SVT_FILEPICKER_SHOW_PREVIEW ) ); 3004 _pCbPreviewBox->SetHelpId( HID_FILEDLG_PREVIEW_CB ); 3005 AddControl( _pCbPreviewBox ); 3006 ReleaseOwnerShip( _pCbPreviewBox ); 3007 _pCbPreviewBox->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 3008 3009 // Preview-Fenster erst hier erzeugen 3010 _pPrevWin = new Window( this, WinBits( WB_BORDER ) ); 3011 AddControl( _pPrevWin ); 3012 ReleaseOwnerShip( _pPrevWin ); 3013 _pPrevWin->Hide(); 3014 3015 _pPrevBmp = new FixedBitmap( this, WinBits( WB_BORDER ) ); 3016 _pPrevBmp->SetBackground( Wallpaper( Color( COL_WHITE ) ) ); 3017 _pPrevBmp->Show(); 3018 _pPrevBmp->SetAccessibleName(SvtResId(STR_PREVIEW)); 3019 } 3020 3021 if ( _nExtraBits & SFX_EXTRA_AUTOEXTENSION ) 3022 { 3023 _pImp->_pCbAutoExtension = new CheckBox( this, SvtResId( CB_AUTO_EXTENSION ) ); 3024 _pImp->_pCbAutoExtension->SetText( SvtResId( STR_SVT_FILEPICKER_AUTO_EXTENSION ) ); 3025 _pImp->_pCbAutoExtension->Check( sal_True ); 3026 AddControl( _pImp->_pCbAutoExtension ); 3027 ReleaseOwnerShip( _pImp->_pCbAutoExtension ); 3028 _pImp->_pCbAutoExtension->SetClickHdl( LINK( this, SvtFileDialog, AutoExtensionHdl_Impl ) ); 3029 } 3030 3031 if ( _nExtraBits & SFX_EXTRA_FILTEROPTIONS ) 3032 { 3033 _pImp->_pCbOptions = new CheckBox( this, SvtResId( CB_OPTIONS ) ); 3034 _pImp->_pCbOptions->SetText( SvtResId( STR_SVT_FILEPICKER_FILTER_OPTIONS ) ); 3035 AddControl( _pImp->_pCbOptions ); 3036 ReleaseOwnerShip( _pImp->_pCbOptions ); 3037 _pImp->_pCbOptions->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 3038 } 3039 3040 if ( _nExtraBits & SFX_EXTRA_SELECTION ) 3041 { 3042 _pCbSelection = new CheckBox( this, SvtResId( CB_OPTIONS ) ); 3043 _pCbSelection->SetText( SvtResId( STR_SVT_FILEPICKER_SELECTION ) ); 3044 AddControl( _pCbSelection ); 3045 ReleaseOwnerShip( _pCbSelection ); 3046 _pCbSelection->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) ); 3047 } 3048 3049 if ( _nExtraBits & SFX_EXTRA_PLAYBUTTON ) 3050 { 3051 _pPbPlay = new PushButton( this ); 3052 _pPbPlay->SetText( SvtResId( STR_SVT_FILEPICKER_PLAY ) ); 3053 _pPbPlay->SetHelpId( HID_FILESAVE_DOPLAY ); 3054 AddControl( _pPbPlay ); 3055 ReleaseOwnerShip( _pPbPlay ); 3056 _pPbPlay->SetClickHdl( LINK( this, SvtFileDialog, PlayButtonHdl_Impl ) ); 3057 } 3058 3059 if ( _nExtraBits & SFX_EXTRA_SHOWVERSIONS ) 3060 { 3061 _pImp->_pFtFileVersion = new FixedText( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) ); 3062 _pImp->_pFtFileVersion->SetText( SvtResId( STR_SVT_FILEPICKER_VERSION ) ); 3063 3064 _pImp->_pLbFileVersion = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) ); 3065 _pImp->_pLbFileVersion->SetHelpId( HID_FILEOPEN_VERSION ); 3066 } 3067 else if ( _nExtraBits & SFX_EXTRA_TEMPLATES ) 3068 { 3069 _pImp->_pFtTemplates = new FixedText( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) ); 3070 _pImp->_pFtTemplates->SetText( SvtResId( STR_SVT_FILEPICKER_TEMPLATES ) ); 3071 3072 _pImp->_pLbTemplates = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) ); 3073 _pImp->_pLbTemplates->SetHelpId( HID_FILEOPEN_VERSION ); 3074 // This is strange. During the re-factoring during 96930, I discovered that this help id 3075 // is set in the "Templates mode". This was hidden in the previous implementation. 3076 // Shouldn't this be a more meaningfull help id. 3077 // 96930 - 15.08.2002 - fs@openoffice.org 3078 } 3079 else if ( _nExtraBits & SFX_EXTRA_IMAGE_TEMPLATE ) 3080 { 3081 _pImp->_pFtImageTemplates = new FixedText( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) ); 3082 _pImp->_pFtImageTemplates->SetText( SvtResId( STR_SVT_FILEPICKER_IMAGE_TEMPLATE ) ); 3083 3084 _pImp->_pLbImageTemplates = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) ); 3085 _pImp->_pLbImageTemplates->SetHelpId( HID_FILEOPEN_IMAGE_TEMPLATE ); 3086 } 3087 } 3088 3089 // ----------------------------------------------------------------------- 3090 sal_Int32 SvtFileDialog::getTargetColorDepth() 3091 { 3092 if ( _pPrevBmp ) 3093 return _pPrevBmp->GetBitCount(); 3094 else 3095 return 0; 3096 } 3097 3098 // ----------------------------------------------------------------------- 3099 sal_Int32 SvtFileDialog::getAvailableWidth() 3100 { 3101 if ( _pPrevBmp ) 3102 return _pPrevBmp->GetOutputSizePixel().Width(); 3103 else 3104 return 0; 3105 } 3106 3107 // ----------------------------------------------------------------------- 3108 sal_Int32 SvtFileDialog::getAvailableHeight() 3109 { 3110 if ( _pPrevBmp ) 3111 return _pPrevBmp->GetOutputSizePixel().Height(); 3112 else 3113 return 0; 3114 } 3115 3116 // ----------------------------------------------------------------------- 3117 void SvtFileDialog::setImage( sal_Int16 /*aImageFormat*/, const Any& rImage ) 3118 { 3119 if ( ! _pPrevBmp || ! _pPrevBmp->IsVisible() ) 3120 return; 3121 3122 Sequence < sal_Int8 > aBmpSequence; 3123 3124 if ( rImage >>= aBmpSequence ) 3125 { 3126 Bitmap aBmp; 3127 SvMemoryStream aData( aBmpSequence.getArray(), 3128 aBmpSequence.getLength(), 3129 STREAM_READ ); 3130 aData >> aBmp; 3131 3132 _pPrevBmp->SetBitmap( aBmp ); 3133 } 3134 else 3135 { 3136 Bitmap aEmpty; 3137 _pPrevBmp->SetBitmap( aEmpty ); 3138 } 3139 } 3140 3141 // ----------------------------------------------------------------------- 3142 sal_Bool SvtFileDialog::setShowState( sal_Bool /*bShowState*/ ) 3143 { 3144 // #97633 for the system filedialog it's 3145 // usefull to make the preview switchable 3146 // because the preview occupies 3147 // half of the size of the file listbox 3148 // which is not the case here, 3149 // so we (TRA/FS) decided not to make 3150 // the preview window switchable because 3151 // else we would have to change the layout 3152 // of the file dialog dynamically 3153 // support for set/getShowState is opionally 3154 // see com::sun::star::ui::dialogs::XFilePreview 3155 /* 3156 if ( _pPrevBmp ) 3157 { 3158 _pPrevBmp->Show( bShowState ); 3159 return sal_True; 3160 } 3161 else 3162 return sal_False; 3163 */ 3164 3165 return sal_False; 3166 } 3167 3168 // ----------------------------------------------------------------------- 3169 String SvtFileDialog::getCurrentFileText( ) const 3170 { 3171 String sReturn; 3172 if ( _pImp && _pImp->_pEdFileName ) 3173 sReturn = _pImp->_pEdFileName->GetText(); 3174 return sReturn; 3175 } 3176 3177 // ----------------------------------------------------------------------- 3178 void SvtFileDialog::setCurrentFileText( const String& _rText, bool _bSelectAll ) 3179 { 3180 if ( _pImp && _pImp->_pEdFileName ) 3181 { 3182 _pImp->_pEdFileName->SetText( _rText ); 3183 if ( _bSelectAll ) 3184 _pImp->_pEdFileName->SetSelection( Selection( 0, _rText.Len() ) ); 3185 } 3186 } 3187 3188 // ----------------------------------------------------------------------- 3189 sal_Bool SvtFileDialog::isAutoExtensionEnabled() 3190 { 3191 return _pImp->_pCbAutoExtension && _pImp->_pCbAutoExtension->IsChecked(); 3192 } 3193 3194 // ----------------------------------------------------------------------- 3195 sal_Bool SvtFileDialog::getShowState() 3196 { 3197 if ( _pPrevBmp ) 3198 return _pPrevBmp->IsVisible(); 3199 else 3200 return sal_False; 3201 } 3202 3203 // ----------------------------------------------------------------------- 3204 void SvtFileDialog::ReleaseOwnerShip( Window* pUserControl ) 3205 3206 /* 3207 [Beschreibung] 3208 Die Methode sorgt dafuer das das spezifizierte Element nicht mehr im Besitz 3209 der Instanz ist. 3210 */ 3211 3212 { 3213 ControlChain_Impl* pElement = _pUserControls; 3214 while ( pElement ) 3215 { 3216 if ( pElement->_pControl == pUserControl ) 3217 { 3218 pElement->_bHasOwnerShip = sal_False; 3219 break; 3220 } 3221 pElement = pElement->_pNext; 3222 } 3223 } 3224 3225 //*************************************************************************** 3226 3227 sal_Bool SvtFileDialog::AddControl( Window* pControl, sal_Bool bNewLine ) 3228 { 3229 // control already exists 3230 ControlChain_Impl* pElement = _pUserControls; 3231 while ( pElement ) 3232 { 3233 if ( pElement->_pControl == pControl ) 3234 return sal_False; 3235 pElement = pElement->_pNext; 3236 } 3237 3238 // Check if controls have already been added. 3239 Size aNewControlSize( pControl->GetOutputSizePixel() ); 3240 Size aDlgSize( GetOutputSizePixel() ); 3241 WindowType nType = pControl->GetType(); 3242 if ( !aNewControlSize.Height() ) 3243 { 3244 // Detect a size. 3245 Size aSize( 0, 10 ); 3246 if ( nType == WINDOW_PUSHBUTTON ) 3247 { 3248 Size aDefSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT ); 3249 long nTextWidth = pControl->GetTextWidth( pControl->GetText() ); 3250 aSize.Width() = nTextWidth + WIDTH_ADDITION; 3251 3252 // PushButton: Mindestbreite 50 logische Einheiten, 3253 // H"ohe immer 14 logische Einheiten 3254 if ( aDefSiz.Width() > aSize.Width() ) 3255 aSize.Width() = aDefSiz.Width(); 3256 aSize.Height() = aDefSiz.Height(); 3257 aNewControlSize = aSize; 3258 } 3259 else 3260 aNewControlSize = LogicToPixel( aSize, MAP_APPFONT ); 3261 if ( nType != WINDOW_PUSHBUTTON ) 3262 aNewControlSize.Width() = pControl->GetTextWidth( pControl->GetText() ) + WIDTH_ADDITION; 3263 if ( nType == WINDOW_CHECKBOX ) 3264 aNewControlSize.Width() += WIDTH_ADDITION; 3265 if ( nType == WINDOW_WINDOW ) 3266 { 3267 aNewControlSize.Height() = GetOutputSizePixel().Height() - 18; 3268 aNewControlSize.Width() = 200; 3269 aDlgSize.Width() += 210; 3270 SetOutputSizePixel( aDlgSize ); 3271 } 3272 pControl->SetOutputSizePixel( aNewControlSize ); 3273 } 3274 Point aNewControlPos; 3275 Size* pNewDlgSize = NULL; 3276 sal_Bool bNewRow = bNewLine; 3277 sal_Bool bFirstNewRow = sal_False; 3278 3279 if ( nType == WINDOW_WINDOW ) 3280 { 3281 aNewControlPos.X() = aDlgSize.Width() - 210; 3282 aNewControlPos.Y() = 8; 3283 } 3284 else if ( _pUserControls ) 3285 { 3286 Point aNewControlRange( _pUserControls->_pControl->GetPosPixel() ); 3287 long nPrevControlHeight = _pUserControls->_pControl->GetSizePixel().Height(); 3288 aNewControlRange += 3289 Point( _pUserControls->_pControl->GetOutputSizePixel().Width(), 0 ); 3290 aNewControlPos = aNewControlRange; 3291 if ( nPrevControlHeight > aNewControlSize.Height() ) 3292 { 3293 long nY = nPrevControlHeight; 3294 nY -= aNewControlSize.Height(); 3295 nY /= 2; 3296 aNewControlPos.Y() += nY; 3297 } 3298 aNewControlPos += LogicToPixel( Point( 3, 0 ), MAP_APPFONT ); 3299 aNewControlRange += LogicToPixel( Point( 9, 0 ), MAP_APPFONT ); 3300 aNewControlRange += Point( aNewControlSize.Width(), 0 ); 3301 3302 // Check if a new row has to be created. 3303 if ( aNewControlRange.X() > aDlgSize.Width() ) 3304 bNewRow = sal_True; 3305 } 3306 else 3307 { 3308 // Create a new row if there was no usercontrol before. 3309 bNewRow = sal_True; 3310 bFirstNewRow = sal_True; 3311 } 3312 3313 // Check if a new row has to be created. 3314 Size aBorderSize = LogicToPixel( Size( 6, 6 ), MAP_APPFONT ); 3315 long nLeftBorder = aBorderSize.Width(); 3316 long nLowerBorder = aBorderSize.Height(); 3317 if ( bNewRow ) 3318 { 3319 // Set control at the beginning of a new line. 3320 long nSmallBorderHeight = nLowerBorder / 2; 3321 aNewControlPos = Point( nLeftBorder, 0 ); 3322 aNewControlPos += Point( 0, aDlgSize.Height() ); 3323 aNewControlPos.Y() -= nSmallBorderHeight; 3324 // Set new size. 3325 pNewDlgSize = new Size( aDlgSize ); 3326 pNewDlgSize->Height() -= nSmallBorderHeight; 3327 pNewDlgSize->Height() += aNewControlSize.Height(); 3328 pNewDlgSize->Height() += nLowerBorder; 3329 } 3330 else 3331 { 3332 // Check if the window has to be resized. 3333 Size aNewControlRange( 0, aNewControlPos.Y() ); 3334 aNewControlRange.Height() += aNewControlSize.Height(); 3335 aNewControlRange.Height() += nLowerBorder; 3336 if ( aNewControlRange.Height() > aDlgSize.Height() ) 3337 pNewDlgSize = new Size( aDlgSize.Width(), aNewControlRange.Height() ); 3338 } 3339 3340 // Update view. 3341 if ( pNewDlgSize ) 3342 { 3343 SetOutputSizePixel( *pNewDlgSize ); 3344 delete pNewDlgSize; 3345 } 3346 pControl->SetPosPixel( aNewControlPos ); 3347 pControl->Show(); 3348 _pUserControls = new ControlChain_Impl( pControl, _pUserControls ); 3349 3350 return sal_True; 3351 } 3352 3353 sal_Bool SvtFileDialog::ContentHasParentFolder( const rtl::OUString& rURL ) 3354 { 3355 m_aContent.bindTo( rURL ); 3356 3357 if ( m_aContent.isInvalid() ) 3358 return sal_False; 3359 3360 return m_aContent.hasParentFolder( ) && m_aContent.isValid(); 3361 } 3362 3363 sal_Bool SvtFileDialog::ContentCanMakeFolder( const rtl::OUString& rURL ) 3364 { 3365 m_aContent.bindTo( rURL ); 3366 3367 if ( m_aContent.isInvalid() ) 3368 return sal_False; 3369 3370 return m_aContent.canCreateFolder( ) && m_aContent.isValid(); 3371 } 3372 3373 sal_Bool SvtFileDialog::ContentGetTitle( const rtl::OUString& rURL, String& rTitle ) 3374 { 3375 m_aContent.bindTo( rURL ); 3376 3377 if ( m_aContent.isInvalid() ) 3378 return sal_False; 3379 3380 ::rtl::OUString sTitle; 3381 m_aContent.getTitle( sTitle ); 3382 rTitle = sTitle; 3383 3384 return m_aContent.isValid(); 3385 } 3386 3387 void SvtFileDialog::appendDefaultExtension(String& _rFileName, 3388 const String& _rFilterDefaultExtension, 3389 const String& _rFilterExtensions) 3390 { 3391 String aTemp(_rFileName); 3392 aTemp.ToLowerAscii(); 3393 String aType(_rFilterExtensions); 3394 aType.ToLowerAscii(); 3395 3396 if ( ! aType.EqualsAscii(FILEDIALOG_FILTER_ALL) ) 3397 { 3398 sal_uInt16 nWildCard = aType.GetTokenCount( FILEDIALOG_DEF_EXTSEP ); 3399 sal_uInt16 nIndex, nPos = 0; 3400 3401 for ( nIndex = 0; nIndex < nWildCard; nIndex++ ) 3402 { 3403 String aExt(aType.GetToken( 0, FILEDIALOG_DEF_EXTSEP, nPos )); 3404 // take care of a leading * 3405 sal_uInt16 nExtOffset = (aExt.GetBuffer()[0] == '*' ? 1 : 0); 3406 sal_Unicode* pExt = aExt.GetBufferAccess() + nExtOffset; 3407 xub_StrLen nExtLen = aExt.Len() - nExtOffset; 3408 xub_StrLen nOffset = aTemp.Len() - nExtLen; 3409 // minimize search by starting at last possible index 3410 if ( aTemp.Search(pExt, nOffset) == nOffset ) 3411 break; 3412 } 3413 3414 if ( nIndex >= nWildCard ) 3415 { 3416 _rFileName += '.'; 3417 _rFileName += _rFilterDefaultExtension; 3418 } 3419 } 3420 } 3421 3422 // ----------------------------------------------------------------------- 3423 3424 // QueryFolderNameDialog ------------------------------------------------------- 3425 3426 namespace svtools { 3427 3428 QueryFolderNameDialog::QueryFolderNameDialog 3429 ( 3430 Window* _pParent, 3431 const String& rTitle, 3432 const String& rDefaultText, 3433 String* pGroupName 3434 ) : 3435 ModalDialog( _pParent, SvtResId( DLG_SVT_QUERYFOLDERNAME ) ), 3436 3437 aNameText ( this, SvtResId( FT_SVT_QUERYFOLDERNAME_DLG_NAME ) ), 3438 aNameEdit ( this, SvtResId( ED_SVT_QUERYFOLDERNAME_DLG_NAME ) ), 3439 aNameLine ( this, SvtResId( FL_SVT_QUERYFOLDERNAME_DLG_NAME ) ), 3440 aOKBtn ( this, SvtResId( BT_SVT_QUERYFOLDERNAME_DLG_OK ) ), 3441 aCancelBtn ( this, SvtResId( BT_SVT_QUERYFOLDERNAME_DLG_CANCEL ) ) 3442 { 3443 FreeResource(); 3444 SetText( rTitle ); 3445 aNameEdit.SetText( rDefaultText ); 3446 aNameEdit.SetSelection( Selection( 0, rDefaultText.Len() ) ); 3447 aOKBtn.SetClickHdl( LINK( this, QueryFolderNameDialog, OKHdl ) ); 3448 aNameEdit.SetModifyHdl( LINK( this, QueryFolderNameDialog, NameHdl ) ); 3449 3450 if ( pGroupName ) 3451 aNameLine.SetText( *pGroupName ); 3452 }; 3453 3454 // ----------------------------------------------------------------------- 3455 IMPL_LINK( QueryFolderNameDialog, OKHdl, Button *, EMPTYARG ) 3456 { 3457 // trim the strings 3458 aNameEdit.SetText( aNameEdit.GetText().EraseLeadingChars().EraseTrailingChars() ); 3459 EndDialog( RET_OK ); 3460 return 1; 3461 } 3462 3463 // ----------------------------------------------------------------------- 3464 IMPL_LINK( QueryFolderNameDialog, NameHdl, Edit *, EMPTYARG ) 3465 { 3466 // trim the strings 3467 String aName = aNameEdit.GetText(); 3468 aName.EraseLeadingChars().EraseTrailingChars(); 3469 if ( aName.Len() ) 3470 { 3471 if ( !aOKBtn.IsEnabled() ) 3472 aOKBtn.Enable( sal_True ); 3473 } 3474 else 3475 { 3476 if ( aOKBtn.IsEnabled() ) 3477 aOKBtn.Enable( sal_False ); 3478 } 3479 3480 return 0; 3481 } 3482 3483 } 3484