xref: /aoo41x/main/fpicker/source/office/iodlgimp.cxx (revision cdf0e10c)
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