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 "iodlgimp.hxx" 34 #include "svtools/headbar.hxx" 35 #include <tools/debug.hxx> 36 #include <tools/wldcrd.hxx> 37 #include <tools/urlobj.hxx> 38 #include <vcl/menu.hxx> 39 #include <vcl/msgbox.hxx> 40 #include <vcl/lstbox.hxx> 41 #include <vcl/svapp.hxx> 42 // #97148# --------------- 43 #include "svl/ctypeitm.hxx" 44 #include "svl/eitem.hxx" 45 #include "unotools/viewoptions.hxx" 46 #include "svtools/fileview.hxx" 47 #include "svtools/inettbc.hxx" 48 #include "iodlg.hxx" 49 #include "iodlg.hrc" 50 #include "svtools/imagemgr.hxx" 51 #include <unotools/localfilehelper.hxx> 52 #include "unotools/useroptions.hxx" 53 #include "rtl/instance.hxx" 54 #include <svl/svl.hrc> 55 56 #define _SVSTDARR_STRINGSSORTDTOR 57 #define _SVSTDARR_STRINGSDTOR 58 #define _SVSTDARR_USHORTS 59 #include "svl/svstdarr.hxx" 60 61 using namespace ::com::sun::star::uno; 62 using namespace ::com::sun::star::lang; 63 using namespace ::utl; 64 65 // some stuff for easier changes for SvtViewOptions 66 static const sal_Char* pViewOptDataName = "dialog data"; 67 #define VIEWOPT_DATANAME ::rtl::OUString::createFromAscii( pViewOptDataName ) 68 69 static inline void SetViewOptUserItem( SvtViewOptions& rOpt, const String& rData ) 70 { 71 rOpt.SetUserItem( VIEWOPT_DATANAME, makeAny( ::rtl::OUString( rData ) ) ); 72 } 73 74 static inline String GetViewOptUserItem( const SvtViewOptions& rOpt ) 75 { 76 Any aAny( rOpt.GetUserItem( VIEWOPT_DATANAME ) ); 77 ::rtl::OUString aUserData; 78 aAny >>= aUserData; 79 80 return String( aUserData ); 81 } 82 83 84 // defines f"ur den Style der BrowseBox 85 86 #define STYLE_MULTI_SELECTION \ 87 CNTVIEWSTYLE_NODE_BUTTONS | \ 88 CNTVIEWSTYLE_NODE_BUTTONS_AT_ROOT | \ 89 CNTVIEWSTYLE_SHOW_MESSAGES | \ 90 CNTVIEWSTYLE_SHOW_FOLDERS | \ 91 CNTVIEWSTYLE_NO_SMARTHIGHLIGHT | \ 92 CNTVIEWSTYLE_HIDE_OPENMENU | \ 93 CNTVIEWSTYLE_DEFAULT_APPEARANCE | \ 94 CNTVIEWSTYLE_SORT_BY_FOLDER 95 96 #define STYLE_SINGLE_SELECTION \ 97 STYLE_MULTI_SELECTION | CNTVIEWSTYLE_SINGLE_SELECTION 98 99 #define BOOL_NOT_INITIALIZE ((sal_Bool)2) 100 101 //***************************************************************************** 102 // ResMgrHolder / SvtSimpleResId 103 //***************************************************************************** 104 namespace 105 { 106 struct ResMgrHolder 107 { 108 ResMgr * operator ()() 109 { 110 return ResMgr::CreateResMgr (CREATEVERSIONRESMGR_NAME(svs)); 111 } 112 static ResMgr * getOrCreate() 113 { 114 return rtl_Instance< 115 ResMgr, ResMgrHolder, 116 osl::MutexGuard, osl::GetGlobalMutex >::create ( 117 ResMgrHolder(), osl::GetGlobalMutex()); 118 } 119 }; 120 121 struct SvtSimpleResId : public ResId 122 { 123 SvtSimpleResId (sal_uInt16 nId) : ResId (nId, *ResMgrHolder::getOrCreate()) {} 124 }; 125 } 126 127 //***************************************************************************** 128 // SvtFileDialogFilter_Impl 129 //***************************************************************************** 130 131 DBG_NAME( SvtFileDialogFilter_Impl ) 132 SvtFileDialogFilter_Impl::SvtFileDialogFilter_Impl( const String& rName, const String& rType ) 133 :m_aName( rName ) 134 ,m_aType( rType ) 135 { 136 DBG_CTOR( SvtFileDialogFilter_Impl, NULL ); 137 138 m_aType.ToLowerAscii(); 139 } 140 141 //***************************************************************************** 142 143 SvtFileDialogFilter_Impl::~SvtFileDialogFilter_Impl() 144 { 145 DBG_DTOR( SvtFileDialogFilter_Impl, NULL ); 146 } 147 148 //***************************************************************************** 149 // SvtFileDialogFilterList_Impl 150 //***************************************************************************** 151 152 SV_IMPL_PTRARR( SvtFileDialogFilterList_Impl, SvtFileDialogFilter_Impl* ); 153 154 //============================================================================= 155 //= SvtFileDialogURLSelector 156 //============================================================================= 157 158 //----------------------------------------------------------------------------- 159 SvtFileDialogURLSelector::SvtFileDialogURLSelector( SvtFileDialog* _pParent, const ResId& _rResId, sal_uInt16 _nButtonId ) 160 :MenuButton ( _pParent, _rResId ) 161 ,m_pParent ( _pParent ) 162 ,m_pMenu ( new PopupMenu ) 163 { 164 SetStyle( GetStyle() | WB_NOPOINTERFOCUS | WB_RECTSTYLE | WB_SMALLSTYLE ); 165 SetModeImage( m_pParent->GetButtonImage( _nButtonId ) ); 166 SetMenuMode( MENUBUTTON_MENUMODE_TIMED ); 167 SetDropDown( PUSHBUTTON_DROPDOWN_TOOLBOX ); 168 } 169 170 //----------------------------------------------------------------------------- 171 SvtFileDialogURLSelector::~SvtFileDialogURLSelector() 172 { 173 delete m_pMenu; 174 } 175 176 //----------------------------------------------------------------------------- 177 void SvtFileDialogURLSelector::OpenURL( const String& rURL ) 178 { 179 INetURLObject aObj( rURL ); 180 DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "SvtFileDialogURLSelector::OpenURL: Invalid URL!" ); 181 m_pParent->OpenURL_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) ); 182 } 183 184 //----------------------------------------------------------------------------- 185 void SvtFileDialogURLSelector::Activate() 186 { 187 m_pMenu->Clear(); 188 189 FillURLMenu( m_pMenu ); 190 191 SetPopupMenu( m_pMenu ); 192 } 193 194 //============================================================================= 195 //= SvtUpButton_Impl 196 //============================================================================= 197 198 //----------------------------------------------------------------------------- 199 SvtUpButton_Impl::SvtUpButton_Impl( SvtFileDialog* pParent, const ResId& rResId ) 200 :SvtFileDialogURLSelector( pParent, rResId, IMG_FILEDLG_BTN_UP ) 201 ,_pURLs ( NULL ) 202 { 203 } 204 205 //----------------------------------------------------------------------------- 206 SvtUpButton_Impl::~SvtUpButton_Impl() 207 { 208 delete _pURLs; 209 } 210 211 //----------------------------------------------------------------------------- 212 void SvtUpButton_Impl::FillURLMenu( PopupMenu* _pMenu ) 213 { 214 SvtFileView* pBox = GetDialogParent()->GetView(); 215 216 sal_uInt16 nItemId = 1; 217 218 delete _pURLs; 219 _pURLs = new SvStringsDtor; 220 221 // "Ubergeordnete Ebenen bestimmen. 222 INetURLObject aObject( pBox->GetViewURL() ); 223 sal_Int32 nCount = aObject.getSegmentCount(); 224 225 ::svtools::VolumeInfo aVolInfo( sal_True /* volume */, sal_False /* remote */, 226 sal_False /* removable */, sal_False /* floppy */, 227 sal_False /* compact disk */ ); 228 sal_Bool bIsHighContrast = pBox->GetSettings().GetStyleSettings().GetHighContrastMode(); 229 Image aVolumeImage( SvFileInformationManager::GetFolderImage( aVolInfo, bIsHighContrast ) ); 230 231 while ( nCount >= 1 ) 232 { 233 aObject.removeSegment(); 234 String* pParentURL = new String( aObject.GetMainURL( INetURLObject::NO_DECODE ) ); 235 236 if ( GetDialogParent()->isUrlAllowed( *pParentURL ) ) 237 { 238 String aTitle; 239 // 97148# -------------------------------- 240 if ( !GetDialogParent()->ContentGetTitle( *pParentURL, aTitle ) || aTitle.Len() == 0 ) 241 aTitle = aObject.getName(); 242 243 Image aImage = ( nCount > 1 ) // if nCount == 1 means workplace, which detects the wrong image 244 ? SvFileInformationManager::GetImage( aObject, bIsHighContrast ) 245 : aVolumeImage; 246 247 _pMenu->InsertItem( nItemId++, aTitle, aImage ); 248 _pURLs->Insert( pParentURL, _pURLs->Count() ); 249 250 if ( nCount == 1 ) 251 { 252 // adjust the title of the top level entry (the workspace) 253 _pMenu->SetItemText( --nItemId, SvtSimpleResId( STR_SVT_MIMETYPE_CNT_FSYSBOX ) ); 254 } 255 } 256 257 --nCount; 258 } 259 } 260 261 //----------------------------------------------------------------------------- 262 void SvtUpButton_Impl::Select() 263 { 264 sal_uInt16 nId = GetCurItemId(); 265 266 if ( nId ) 267 { 268 --nId; 269 DBG_ASSERT( nId <= _pURLs->Count(), "SvtUpButton_Impl:falscher Index" ); 270 271 String aURL = *(_pURLs->GetObject( nId )); 272 GetDialogParent()->OpenURL_Impl( aURL ); 273 } 274 } 275 276 //----------------------------------------------------------------------------- 277 void SvtUpButton_Impl::Click() 278 { 279 GetDialogParent()->PrevLevel_Impl(); 280 } 281 282 //============================================================================= 283 //= SvtTravelButton_Impl 284 //============================================================================= 285 286 //----------------------------------------------------------------------------- 287 SvtTravelButton_Impl::SvtTravelButton_Impl( SvtFileDialog* pParent, const ResId& rResId ) 288 :SvtFileDialogURLSelector ( pParent, rResId, IMG_FILEDLG_BTN_STD ) 289 { 290 SetDropDown( 0 ); // by default, don't drop down, as we don't have favourites 291 } 292 293 //----------------------------------------------------------------------------- 294 void SvtTravelButton_Impl::SetFavouriteLocations( const ::std::vector< String >& _rLocations ) 295 { 296 m_aFavourites = _rLocations; 297 // enable the drop down if and only if we have favourites 298 SetDropDown( m_aFavourites.empty() ? 0 : PUSHBUTTON_DROPDOWN_TOOLBOX ); 299 } 300 301 //----------------------------------------------------------------------------- 302 SvtTravelButton_Impl::~SvtTravelButton_Impl() 303 { 304 } 305 306 //----------------------------------------------------------------------------- 307 void SvtTravelButton_Impl::FillURLMenu( PopupMenu* _pMenu ) 308 { 309 if ( m_aFavourites.empty() ) 310 // though we claimed that we do not want to have a drop down button 311 // in this case, VCL nevertheless behaves as if we had one .... :( 312 return; 313 314 _pMenu->Clear(); 315 316 sal_Bool bIsHighContrast = GetDialogParent()->GetView()->GetSettings().GetStyleSettings().GetHighContrastMode(); 317 318 sal_uInt16 nItemId = 1; 319 String sDisplayName; 320 321 ::std::vector< String >::const_iterator aLoop; 322 for ( aLoop = m_aFavourites.begin(); aLoop != m_aFavourites.end(); ++aLoop, ++nItemId ) 323 { 324 if ( GetDialogParent()->isUrlAllowed( *aLoop ) ) 325 { 326 Image aImage = SvFileInformationManager::GetImage( 327 INetURLObject(*aLoop), bIsHighContrast ); 328 if ( LocalFileHelper::ConvertURLToSystemPath(*aLoop, sDisplayName) ) 329 _pMenu->InsertItem( nItemId, sDisplayName, aImage ); 330 else 331 _pMenu->InsertItem( nItemId, *aLoop, aImage ); 332 } 333 } 334 } 335 336 //----------------------------------------------------------------------------- 337 void SvtTravelButton_Impl::Select() 338 { 339 sal_uInt16 nId = GetCurItemId(); 340 if ( nId ) 341 { 342 --nId; 343 DBG_ASSERT( nId < m_aFavourites.size(), "SvtTravelButton_Impl::Select: invalid index!" ); 344 if ( nId < m_aFavourites.size() ) 345 OpenURL( m_aFavourites[ nId ] ); 346 } 347 } 348 349 //----------------------------------------------------------------------------- 350 void SvtTravelButton_Impl::Click() 351 { 352 OpenURL( GetDialogParent()->GetStandardDir() ); 353 } 354 355 //***************************************************************************** 356 // SvtExpFileDlg_Impl 357 //***************************************************************************** 358 359 SvtExpFileDlg_Impl::SvtExpFileDlg_Impl( WinBits ) : 360 361 _pLbFilter ( NULL ), 362 _pCurFilter ( NULL ), 363 _pFilter ( new SvtFileDialogFilterList_Impl() ), 364 _pUserFilter ( NULL ), 365 _pFtFileName ( NULL ), 366 _pEdFileName ( NULL ), 367 _pFtFileVersion ( NULL ), 368 _pLbFileVersion ( NULL ), 369 _pFtTemplates ( NULL ), 370 _pLbTemplates ( NULL ), 371 _pFtImageTemplates ( NULL ), 372 _pLbImageTemplates ( NULL ), 373 _pFtFileType ( NULL ), 374 _pBtnFileOpen ( NULL ), 375 _pBtnCancel ( NULL ), 376 _pBtnHelp ( NULL ), 377 _pBtnUp ( NULL ), 378 _pBtnNewFolder ( NULL ), 379 _pBtnStandard ( NULL ), 380 _pCbPassword ( NULL ), 381 _pFtCurrentPath ( NULL ), 382 _pCbAutoExtension ( NULL ), 383 _pCbOptions ( NULL ), 384 _nState ( FILEDLG_STATE_REMOTE ), 385 _nStyle ( 0 ), 386 _bDoubleClick ( sal_False ), 387 m_bNeedDelayedFilterExecute ( sal_False ), 388 _pDefaultFilter ( NULL ), 389 _bMultiSelection ( sal_False ), 390 _nFixDeltaHeight ( 0 ), 391 _bFolderHasOpened ( sal_False ) 392 { 393 } 394 395 //***************************************************************************** 396 397 SvtExpFileDlg_Impl::~SvtExpFileDlg_Impl() 398 { 399 delete _pFtCurrentPath; 400 delete _pCbPassword; 401 delete _pCbAutoExtension; 402 delete _pCbOptions; 403 delete _pBtnStandard; 404 delete _pBtnNewFolder; 405 delete _pBtnUp; 406 delete _pBtnHelp; 407 delete _pBtnCancel; 408 delete _pBtnFileOpen; 409 delete _pLbFilter; 410 delete _pFtFileType; 411 delete _pLbFileVersion; 412 delete _pFtFileVersion; 413 delete _pFtTemplates; 414 delete _pLbTemplates; 415 delete _pFtImageTemplates; 416 delete _pLbImageTemplates; 417 delete _pEdFileName; 418 delete _pFtFileName; 419 delete _pUserFilter; 420 delete _pFilter; 421 } 422 423 //***************************************************************************** 424 425 void SvtExpFileDlg_Impl::SetStandardDir( const String& _rDir ) 426 { 427 _aStdDir = _rDir; 428 if ( 0 == _aStdDir.Len() ) 429 _aStdDir.AssignAscii( "file:///" ); 430 } 431 432 //***************************************************************************** 433 #if OSL_DEBUG_LEVEL > 0 434 //----------------------------------------------------------------------------- 435 namespace { 436 String lcl_DecoratedFilter( const String& _rOriginalFilter ) 437 { 438 String aDecoratedFilter = '<'; 439 aDecoratedFilter += _rOriginalFilter; 440 aDecoratedFilter += '>'; 441 return aDecoratedFilter; 442 } 443 } 444 #endif 445 //----------------------------------------------------------------------------- 446 447 void SvtExpFileDlg_Impl::ClearFilterList( ) 448 { 449 _pLbFilter->Clear(); 450 } 451 452 //----------------------------------------------------------------------------- 453 void SvtExpFileDlg_Impl::SetCurFilter( SvtFileDialogFilter_Impl* pFilter, const String& rDisplayName ) 454 { 455 DBG_ASSERT( pFilter, "SvtExpFileDlg_Impl::SetCurFilter: invalid filter!" ); 456 DBG_ASSERT( ( rDisplayName == pFilter->GetName() ) 457 || ( rDisplayName == lcl_DecoratedFilter( pFilter->GetName() ) ), 458 "SvtExpFileDlg_Impl::SetCurFilter: arguments are inconsistent!" ); 459 460 _pCurFilter = pFilter; 461 m_sCurrentFilterDisplayName = rDisplayName; 462 } 463 464 //----------------------------------------------------------------------------- 465 void SvtExpFileDlg_Impl::InsertFilterListEntry( const SvtFileDialogFilter_Impl* _pFilterDesc ) 466 { 467 String sName = _pFilterDesc->GetName(); 468 if ( _pFilterDesc->isGroupSeparator() ) 469 sName = String::CreateFromAscii( "------------------------------------------" ); 470 else 471 sName = _pFilterDesc->GetName(); 472 473 // insert an set user data 474 sal_uInt16 nPos = _pLbFilter->InsertEntry( sName ); 475 _pLbFilter->SetEntryData( nPos, const_cast< void* >( static_cast< const void* >( _pFilterDesc ) ) ); 476 } 477 478 //----------------------------------------------------------------------------- 479 480 void SvtExpFileDlg_Impl::InitFilterList( ) 481 { 482 // clear the current list 483 ClearFilterList( ); 484 485 // reinit it 486 sal_uInt16 nPos = _pFilter->Count(); 487 488 // search for the first entry which is no group separator 489 while ( nPos-- && _pFilter->GetObject( nPos ) && _pFilter->GetObject( nPos )->isGroupSeparator() ) 490 ; 491 492 // add all following entries 493 while ( (sal_Int16)nPos >= 0 ) 494 InsertFilterListEntry( _pFilter->GetObject( nPos-- ) ); 495 } 496 497 //----------------------------------------------------------------------------- 498 499 void SvtExpFileDlg_Impl::CreateFilterListControl( Window* _pParent, const ResId& _rId ) 500 { 501 DBG_ASSERT( !_pLbFilter, "SvtExpFileDlg_Impl::CreateFilterListControl: already created the control!" ); 502 if ( !_pLbFilter ) 503 { 504 _pLbFilter = new ListBox( _pParent, _rId ); 505 _pLbFilter->SetDropDownLineCount( 10 ); 506 } 507 } 508