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
SetViewOptUserItem(SvtViewOptions & rOpt,const String & rData)65 static inline void SetViewOptUserItem( SvtViewOptions& rOpt, const String& rData )
66 {
67 rOpt.SetUserItem( VIEWOPT_DATANAME, makeAny( ::rtl::OUString( rData ) ) );
68 }
69
GetViewOptUserItem(const SvtViewOptions & rOpt)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 {
operator ()__anone81cf7da0111::ResMgrHolder104 ResMgr * operator ()()
105 {
106 return ResMgr::CreateResMgr (CREATEVERSIONRESMGR_NAME(svl));
107 }
getOrCreate__anone81cf7da0111::ResMgrHolder108 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 {
SvtSimpleResId__anone81cf7da0111::SvtSimpleResId119 SvtSimpleResId (sal_uInt16 nId) : ResId (nId, *ResMgrHolder::getOrCreate()) {}
120 };
121 }
122
123 //*****************************************************************************
124 // SvtFileDialogFilter_Impl
125 //*****************************************************************************
126
DBG_NAME(SvtFileDialogFilter_Impl)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
~SvtFileDialogFilter_Impl()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 //-----------------------------------------------------------------------------
SvtFileDialogURLSelector(SvtFileDialog * _pParent,const ResId & _rResId,sal_uInt16 _nButtonId)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 //-----------------------------------------------------------------------------
~SvtFileDialogURLSelector()167 SvtFileDialogURLSelector::~SvtFileDialogURLSelector()
168 {
169 delete m_pMenu;
170 }
171
172 //-----------------------------------------------------------------------------
OpenURL(const String & rURL)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 //-----------------------------------------------------------------------------
Activate()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 //-----------------------------------------------------------------------------
SvtUpButton_Impl(SvtFileDialog * pParent,const ResId & rResId)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 //-----------------------------------------------------------------------------
~SvtUpButton_Impl()202 SvtUpButton_Impl::~SvtUpButton_Impl()
203 {
204 delete _pURLs;
205 }
206
207 //-----------------------------------------------------------------------------
FillURLMenu(PopupMenu * _pMenu)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 //-----------------------------------------------------------------------------
Select()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 //-----------------------------------------------------------------------------
Click()273 void SvtUpButton_Impl::Click()
274 {
275 GetDialogParent()->PrevLevel_Impl();
276 }
277
278 //=============================================================================
279 //= SvtTravelButton_Impl
280 //=============================================================================
281
282 //-----------------------------------------------------------------------------
SvtTravelButton_Impl(SvtFileDialog * pParent,const ResId & rResId)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 //-----------------------------------------------------------------------------
SetFavouriteLocations(const::std::vector<String> & _rLocations)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 //-----------------------------------------------------------------------------
~SvtTravelButton_Impl()298 SvtTravelButton_Impl::~SvtTravelButton_Impl()
299 {
300 }
301
302 //-----------------------------------------------------------------------------
FillURLMenu(PopupMenu * _pMenu)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 //-----------------------------------------------------------------------------
Select()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 //-----------------------------------------------------------------------------
Click()346 void SvtTravelButton_Impl::Click()
347 {
348 OpenURL( GetDialogParent()->GetStandardDir() );
349 }
350
351 //*****************************************************************************
352 // SvtExpFileDlg_Impl
353 //*****************************************************************************
354
SvtExpFileDlg_Impl(WinBits)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
~SvtExpFileDlg_Impl()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
SetStandardDir(const String & _rDir)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 {
lcl_DecoratedFilter(const String & _rOriginalFilter)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
ClearFilterList()443 void SvtExpFileDlg_Impl::ClearFilterList( )
444 {
445 _pLbFilter->Clear();
446 }
447
448 //-----------------------------------------------------------------------------
SetCurFilter(SvtFileDialogFilter_Impl * pFilter,const String & rDisplayName)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 //-----------------------------------------------------------------------------
InsertFilterListEntry(const SvtFileDialogFilter_Impl * _pFilterDesc)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
InitFilterList()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
CreateFilterListControl(Window * _pParent,const ResId & _rId)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