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