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 #include "OfficeFilePicker.hxx"
28 #include "iodlg.hxx"
29 
30 #ifndef _LIST_
31 #include <list>
32 #endif
33 #ifndef _FUNCTIONAL_
34 #include <functional>
35 #endif
36 #ifndef _ALGORITHM_
37 #include <algorithm>
38 #endif
39 #include <tools/urlobj.hxx>
40 #include <tools/debug.hxx>
41 #define _SVSTDARR_STRINGSDTOR
42 #include "svl/svstdarr.hxx"
43 #include <com/sun/star/uno/Any.hxx>
44 #include <com/sun/star/ui/dialogs/FilePickerEvent.hpp>
45 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
46 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/awt/XWindow.hpp>
50 #include <com/sun/star/beans/StringPair.hpp>
51 #include <com/sun/star/uno/Sequence.hxx>
52 #include <com/sun/star/beans/NamedValue.hpp>
53 #include <unotools/ucbhelper.hxx>
54 #include <unotools/pathoptions.hxx>
55 #include <comphelper/sequence.hxx>
56 #include <cppuhelper/typeprovider.hxx>
57 #include "vos/mutex.hxx"
58 #ifndef _SV_APP_HXX
59 #include "vcl/svapp.hxx"
60 #endif
61 
62 // define ----------------------------------------------------------------
63 
64 #define MAKE_ANY	::com::sun::star::uno::makeAny
65 
66 // using ----------------------------------------------------------------
67 
68 using namespace		::com::sun::star::container;
69 using namespace		::com::sun::star::lang;
70 using namespace		::com::sun::star::ui::dialogs;
71 using namespace		::com::sun::star::uno;
72 using namespace		::com::sun::star::beans;
73 using namespace		::com::sun::star::awt;
74 using namespace		::utl;
75 
76 //=====================================================================
77 
78 //=====================================================================
79 
80 struct FilterEntry
81 {
82 protected:
83 	::rtl::OUString		m_sTitle;
84 	::rtl::OUString		m_sFilter;
85 
86 	UnoFilterList		m_aSubFilters;
87 
88 public:
FilterEntryFilterEntry89 	FilterEntry( const ::rtl::OUString& _rTitle, const ::rtl::OUString& _rFilter )
90 		:m_sTitle( _rTitle )
91 		,m_sFilter( _rFilter )
92 	{
93 	}
94 
95 	FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters );
96 
getTitleFilterEntry97 	::rtl::OUString		getTitle() const { return m_sTitle; }
getFilterFilterEntry98 	::rtl::OUString		getFilter() const { return m_sFilter; }
99 
100 	/// determines if the filter has sub filter (i.e., the filter is a filter group in real)
101 	sal_Bool			hasSubFilters( ) const;
102 
103 	/** retrieves the filters belonging to the entry
104 	@return
105 		the number of sub filters
106 	*/
107 	sal_Int32			getSubFilters( UnoFilterList& _rSubFilterList );
108 
109 	// helpers for iterating the sub filters
beginSubFiltersFilterEntry110 	const UnoFilterEntry*	beginSubFilters() const { return m_aSubFilters.getConstArray(); }
endSubFiltersFilterEntry111 	const UnoFilterEntry*	endSubFilters() const { return m_aSubFilters.getConstArray() + m_aSubFilters.getLength(); }
112 };
113 
114 //=====================================================================
115 
116 //---------------------------------------------------------------------
FilterEntry(const::rtl::OUString & _rTitle,const UnoFilterList & _rSubFilters)117 FilterEntry::FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters )
118 	:m_sTitle( _rTitle )
119 	,m_aSubFilters( _rSubFilters )
120 {
121 }
122 
123 //---------------------------------------------------------------------
hasSubFilters() const124 sal_Bool FilterEntry::hasSubFilters( ) const
125 {
126 	return ( 0 < m_aSubFilters.getLength() );
127 }
128 
129 //---------------------------------------------------------------------
getSubFilters(UnoFilterList & _rSubFilterList)130 sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList )
131 {
132 	_rSubFilterList = m_aSubFilters;
133 	return m_aSubFilters.getLength();
134 }
135 
136 // struct ElementEntry_Impl ----------------------------------------------
137 
138 struct ElementEntry_Impl
139 {
140 	sal_Int16		m_nElementID;
141 	sal_Int16		m_nControlAction;
142 	Any				m_aValue;
143 	rtl::OUString	m_aLabel;
144 	sal_Bool		m_bEnabled		: 1;
145 
146 	sal_Bool		m_bHasValue		: 1;
147 	sal_Bool		m_bHasLabel		: 1;
148 	sal_Bool		m_bHasEnabled	: 1;
149 
150 					ElementEntry_Impl( sal_Int16 nId );
151 
setValueElementEntry_Impl152 	void			setValue( const Any& rVal ) { m_aValue = rVal; m_bHasValue = sal_True; }
setActionElementEntry_Impl153 	void			setAction( sal_Int16 nAction ) { m_nControlAction = nAction; }
setLabelElementEntry_Impl154 	void			setLabel( const rtl::OUString& rVal ) { m_aLabel = rVal; m_bHasLabel = sal_True; }
setEnabledElementEntry_Impl155 	void			setEnabled( sal_Bool bEnabled ) { m_bEnabled = bEnabled; m_bHasEnabled = sal_True; }
156 };
157 
ElementEntry_Impl(sal_Int16 nId)158 ElementEntry_Impl::ElementEntry_Impl( sal_Int16 nId )
159 	: m_nElementID( nId )
160 	, m_nControlAction( 0 )
161 	, m_bEnabled( sal_False )
162 	, m_bHasValue( sal_False )
163 	, m_bHasLabel( sal_False )
164 	, m_bHasEnabled( sal_False )
165 {}
166 
167 //------------------------------------------------------------------------------------
prepareExecute()168 void SvtFilePicker::prepareExecute()
169 {
170 	// set the default directory
171 	// --**-- doesn't match the spec yet
172 	if ( m_aDisplayDirectory.getLength() > 0 || m_aDefaultName.getLength() > 0 )
173 	{
174 		sal_Bool isFileSet = sal_False;
175 		if ( m_aDisplayDirectory.getLength() > 0 )
176 		{
177 
178 			INetURLObject aPath;
179 			INetURLObject givenPath( m_aDisplayDirectory );
180 			if (!givenPath.HasError())
181 				aPath = givenPath;
182 			else
183 			{
184 				INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() );
185 				aPath = aStdDirObj;
186 			}
187 			if ( m_aDefaultName.getLength() > 0 )
188 			{
189 				aPath.insertName( m_aDefaultName );
190 				getDialog()->SetHasFilename( true );
191 			}
192 			String sPath = aPath.GetMainURL( INetURLObject::NO_DECODE );
193 			getDialog()->SetPath( sPath );
194 			isFileSet = sal_True;
195 		}
196 		if ( !isFileSet && m_aDefaultName.getLength() > 0 )
197 		{
198 			getDialog()->SetPath( m_aDefaultName );
199 			getDialog()->SetHasFilename( true );
200 		}
201 	}
202 	else
203 	{
204 		// set default-standard-dir
205 		INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() );
206 		getDialog()->SetPath( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) );
207 	}
208 
209 	// set the control values and set the control labels, too
210 	if ( m_pElemList && !m_pElemList->empty() )
211 	{
212 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
213 
214 		ElementList::iterator aListIter;
215 		for ( aListIter = m_pElemList->begin();
216 			  aListIter != m_pElemList->end(); ++aListIter )
217 		{
218 			ElementEntry_Impl& rEntry = *aListIter;
219 			if ( rEntry.m_bHasValue )
220 				aAccess.setValue( rEntry.m_nElementID, rEntry.m_nControlAction, rEntry.m_aValue );
221 			if ( rEntry.m_bHasLabel )
222 				aAccess.setLabel( rEntry.m_nElementID, rEntry.m_aLabel );
223 			if ( rEntry.m_bHasEnabled )
224 				aAccess.enableControl( rEntry.m_nElementID, rEntry.m_bEnabled );
225 		}
226 
227 		getDialog()->updateListboxLabelSizes();
228 	}
229 
230 	if ( m_pFilterList && !m_pFilterList->empty() )
231 	{
232 		for (   FilterList::iterator aListIter = m_pFilterList->begin();
233 				aListIter != m_pFilterList->end();
234 				++aListIter
235 			)
236 		{
237 			if ( aListIter->hasSubFilters() )
238 			{   // it's a filter group
239 				UnoFilterList aSubFilters;
240 				aListIter->getSubFilters( aSubFilters );
241 
242 				getDialog()->AddFilterGroup( aListIter->getTitle(), aSubFilters );
243 			}
244 			else
245 				// it's a single filter
246 				getDialog()->AddFilter( aListIter->getTitle(), aListIter->getFilter() );
247 		}
248 	}
249 
250 	// set the default filter
251 	if ( m_aCurrentFilter.getLength() > 0 )
252 		getDialog()->SetCurFilter( m_aCurrentFilter );
253 
254 }
255 
256 //-----------------------------------------------------------------------------
IMPL_LINK(SvtFilePicker,DialogClosedHdl,Dialog *,pDlg)257 IMPL_LINK( SvtFilePicker, DialogClosedHdl, Dialog*, pDlg )
258 {
259 	if ( m_xDlgClosedListener.is() )
260 	{
261 		sal_Int16 nRet = static_cast< sal_Int16 >( pDlg->GetResult() );
262 		::com::sun::star::ui::dialogs::DialogClosedEvent aEvent( *this, nRet );
263 		m_xDlgClosedListener->dialogClosed( aEvent );
264 		m_xDlgClosedListener.clear();
265 	}
266 	return 0;
267 }
268 
269 //------------------------------------------------------------------------------------
270 // SvtFilePicker
271 //------------------------------------------------------------------------------------
272 
273 //------------------------------------------------------------------------------------
getWinBits(WinBits & rExtraBits)274 WinBits SvtFilePicker::getWinBits( WinBits& rExtraBits )
275 {
276 	// set the winbits for creating the filedialog
277 	WinBits nBits = 0L;
278 	rExtraBits = 0L;
279 
280 	// set the standard bits according to the service name
281 	if ( m_nServiceType == TemplateDescription::FILEOPEN_SIMPLE )
282 	{
283 		nBits = WB_OPEN;
284 	}
285 	else if ( m_nServiceType == TemplateDescription::FILESAVE_SIMPLE )
286 	{
287 		nBits = WB_SAVEAS;
288 	}
289 	else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION )
290 	{
291 		nBits = WB_SAVEAS;
292 		rExtraBits = SFX_EXTRA_AUTOEXTENSION;
293 	}
294 	else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD )
295 	{
296 		nBits = WB_SAVEAS | SFXWB_PASSWORD;
297 		rExtraBits = SFX_EXTRA_AUTOEXTENSION;
298 	}
299 	else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS )
300 	{
301 		nBits = WB_SAVEAS | SFXWB_PASSWORD;
302 		rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_FILTEROPTIONS;
303 	}
304 	else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE )
305 	{
306 		nBits = WB_SAVEAS;
307 		rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_TEMPLATES;
308 	}
309 	else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION )
310 	{
311 		nBits = WB_SAVEAS;
312 		rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_SELECTION;
313 	}
314 
315 	else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE )
316 	{
317 		nBits = WB_OPEN;
318 		rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW | SFX_EXTRA_IMAGE_TEMPLATE;
319 	}
320 	else if ( m_nServiceType == TemplateDescription::FILEOPEN_PLAY )
321 	{
322 		nBits = WB_OPEN;
323 		rExtraBits = SFX_EXTRA_PLAYBUTTON;
324 	}
325 	else if ( m_nServiceType == TemplateDescription::FILEOPEN_READONLY_VERSION )
326 	{
327 		nBits = WB_OPEN | SFXWB_READONLY;
328 		rExtraBits = SFX_EXTRA_SHOWVERSIONS;
329 	}
330 	else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW )
331 	{
332 		nBits = WB_OPEN;
333 		rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW;
334 	}
335 	if ( m_bMultiSelection && ( ( nBits & WB_OPEN ) == WB_OPEN ) )
336 		nBits |= SFXWB_MULTISELECTION;
337 
338 	return nBits;
339 }
340 
341 //------------------------------------------------------------------------------------
notify(sal_Int16 _nEventId,sal_Int16 _nControlId)342 void SvtFilePicker::notify( sal_Int16 _nEventId, sal_Int16 _nControlId )
343 {
344 	if ( !m_xListener.is() )
345 		return;
346 
347 	FilePickerEvent aEvent( *this, _nControlId );
348 
349 	switch ( _nEventId )
350 	{
351 		case FILE_SELECTION_CHANGED:
352 			m_xListener->fileSelectionChanged( aEvent );
353 			break;
354 		case DIRECTORY_CHANGED:
355 			m_xListener->directoryChanged( aEvent );
356 			break;
357 		case HELP_REQUESTED:
358 			m_xListener->helpRequested( aEvent );
359 			break;
360 		case CTRL_STATE_CHANGED:
361 			m_xListener->controlStateChanged( aEvent );
362 			break;
363 		case DIALOG_SIZE_CHANGED:
364 			m_xListener->dialogSizeChanged();
365 			break;
366 		default:
367 			DBG_ERRORFILE( "SvtFilePicker::notify(): Unknown event id!" );
368 			break;
369 	}
370 }
371 
372 //------------------------------------------------------------------------------------
373 namespace {
374 	//................................................................................
375 	struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool >
376 	{
377 	protected:
378 		const ::rtl::OUString& rTitle;
379 
380 	public:
FilterTitleMatch__anonf86628670111::FilterTitleMatch381 		FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { }
382 
383 		//............................................................................
operator ()__anonf86628670111::FilterTitleMatch384 		bool operator () ( const FilterEntry& _rEntry )
385 		{
386 			sal_Bool bMatch;
387 			if ( !_rEntry.hasSubFilters() )
388 				// a real filter
389 				bMatch = ( _rEntry.getTitle() == rTitle );
390 			else
391 				// a filter group -> search the sub filters
392 				bMatch =
393 					_rEntry.endSubFilters() != ::std::find_if(
394 						_rEntry.beginSubFilters(),
395 						_rEntry.endSubFilters(),
396 						*this
397 					);
398 
399 			return bMatch ? true : false;
400 		}
operator ()__anonf86628670111::FilterTitleMatch401 		bool operator () ( const UnoFilterEntry& _rEntry )
402 		{
403 			return _rEntry.First == rTitle ? true : false;
404 		}
405 	};
406 }
407 
408 //------------------------------------------------------------------------------------
FilterNameExists(const::rtl::OUString & rTitle)409 sal_Bool SvtFilePicker::FilterNameExists( const ::rtl::OUString& rTitle )
410 {
411 	sal_Bool bRet = sal_False;
412 
413 	if ( m_pFilterList )
414 		bRet =
415 			m_pFilterList->end() != ::std::find_if(
416 				m_pFilterList->begin(),
417 				m_pFilterList->end(),
418 				FilterTitleMatch( rTitle )
419 			);
420 
421 	return bRet;
422 }
423 
424 //------------------------------------------------------------------------------------
FilterNameExists(const UnoFilterList & _rGroupedFilters)425 sal_Bool SvtFilePicker::FilterNameExists( const UnoFilterList& _rGroupedFilters )
426 {
427 	sal_Bool bRet = sal_False;
428 
429 	if ( m_pFilterList )
430 	{
431 		const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray();
432 		const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength();
433 		for ( ; pStart != pEnd; ++pStart )
434 			if ( m_pFilterList->end() != ::std::find_if( m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch( pStart->First ) ) )
435 				break;
436 
437 		bRet = pStart != pEnd;
438 	}
439 
440 	return bRet;
441 }
442 
443 //------------------------------------------------------------------------------------
ensureFilterList(const::rtl::OUString & _rInitialCurrentFilter)444 void SvtFilePicker::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter )
445 {
446 	if ( !m_pFilterList )
447 	{
448 		m_pFilterList = new FilterList;
449 
450 		// set the first filter to the current filter
451 		if ( ! m_aCurrentFilter.getLength() )
452 			m_aCurrentFilter = _rInitialCurrentFilter;
453 	}
454 }
455 
456 //------------------------------------------------------------------------------------
457 // class SvtFilePicker
458 //------------------------------------------------------------------------------------
SvtFilePicker(const Reference<XMultiServiceFactory> & xFactory)459 SvtFilePicker::SvtFilePicker( const Reference < XMultiServiceFactory >& xFactory )
460 	:OCommonPicker( xFactory )
461 	,m_pFilterList		( NULL )
462 	,m_pElemList		( NULL )
463 	,m_bMultiSelection	( sal_False )
464 	,m_nServiceType		( TemplateDescription::FILEOPEN_SIMPLE )
465 {
466 }
467 
~SvtFilePicker()468 SvtFilePicker::~SvtFilePicker()
469 {
470 	if ( m_pFilterList && !m_pFilterList->empty() )
471 		m_pFilterList->erase( m_pFilterList->begin(), m_pFilterList->end() );
472 	delete m_pFilterList;
473 
474 	if ( m_pElemList && !m_pElemList->empty() )
475 		m_pElemList->erase( m_pElemList->begin(), m_pElemList->end() );
476 	delete m_pElemList;
477 }
478 
479 //------------------------------------------------------------------------------------
implExecutePicker()480 sal_Int16 SvtFilePicker::implExecutePicker( )
481 {
482 	getDialog()->SetFileCallback( this );
483 
484 	prepareExecute();
485 
486 	getDialog()->EnableAutocompletion( sal_True );
487 	// now we are ready to execute the dialog
488 	sal_Int16 nRet = getDialog()->Execute();
489 
490 	// the execution of the dialog yields, so it is possible the at this point the window or the dialog is closed
491 	if ( getDialog() )
492 		getDialog()->SetFileCallback( NULL );
493 
494 	return nRet;
495 }
496 
497 //------------------------------------------------------------------------------------
implCreateDialog(Window * _pParent)498 SvtFileDialog* SvtFilePicker::implCreateDialog( Window* _pParent )
499 {
500 	WinBits	nExtraBits;
501 	WinBits	nBits = getWinBits( nExtraBits );
502 
503 	SvtFileDialog* dialog = new SvtFileDialog( _pParent, nBits, nExtraBits );
504 
505 	// Set StandardDir if present
506 	if ( m_aStandardDir.getLength() > 0)
507 	{
508 		String sStandardDir = String( m_aStandardDir );
509 		dialog->SetStandardDir( sStandardDir );
510 		dialog->SetBlackList( m_aBlackList );
511 	}
512 
513 	return dialog;
514 }
515 
516 //------------------------------------------------------------------------------------
517 // disambiguate XInterface
518 //------------------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(SvtFilePicker,OCommonPicker,SvtFilePicker_Base)519 IMPLEMENT_FORWARD_XINTERFACE2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base )
520 
521 //------------------------------------------------------------------------------------
522 // disambiguate XTypeProvider
523 //------------------------------------------------------------------------------------
524 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base )
525 
526 //------------------------------------------------------------------------------------
527 // XExecutableDialog functions
528 //------------------------------------------------------------------------------------
529 
530 //------------------------------------------------------------------------------------
531 void SAL_CALL SvtFilePicker::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
532 {
533 	OCommonPicker::setTitle( _rTitle );
534 }
535 
536 //------------------------------------------------------------------------------------
execute()537 sal_Int16 SAL_CALL SvtFilePicker::execute(  ) throw (RuntimeException)
538 {
539 	return OCommonPicker::execute();
540 }
541 
542 //------------------------------------------------------------------------------------
543 // XAsynchronousExecutableDialog functions
544 //------------------------------------------------------------------------------------
545 
546 //------------------------------------------------------------------------------------
setDialogTitle(const::rtl::OUString & _rTitle)547 void SAL_CALL SvtFilePicker::setDialogTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
548 {
549 	setTitle( _rTitle );
550 }
551 
552 //------------------------------------------------------------------------------------
startExecuteModal(const Reference<::com::sun::star::ui::dialogs::XDialogClosedListener> & xListener)553 void SAL_CALL SvtFilePicker::startExecuteModal( const Reference< ::com::sun::star::ui::dialogs::XDialogClosedListener >& xListener ) throw (RuntimeException)
554 {
555 	m_xDlgClosedListener = xListener;
556 	prepareDialog();
557 	prepareExecute();
558 	getDialog()->EnableAutocompletion( sal_True );
559 	getDialog()->StartExecuteModal( LINK( this, SvtFilePicker, DialogClosedHdl ) );
560 }
561 
562 //------------------------------------------------------------------------------------
563 // XFilePicker functions
564 //------------------------------------------------------------------------------------
565 
setMultiSelectionMode(sal_Bool bMode)566 void SAL_CALL SvtFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( RuntimeException )
567 {
568 	checkAlive();
569 
570 	::vos::OGuard aGuard( Application::GetSolarMutex() );
571 	m_bMultiSelection = bMode;
572 }
573 
setDefaultName(const rtl::OUString & aName)574 void SAL_CALL SvtFilePicker::setDefaultName( const rtl::OUString& aName ) throw( RuntimeException )
575 {
576 	checkAlive();
577 
578 	::vos::OGuard aGuard( Application::GetSolarMutex() );
579 	m_aDefaultName = aName;
580 }
581 
setDisplayDirectory(const rtl::OUString & aDirectory)582 void SAL_CALL SvtFilePicker::setDisplayDirectory( const rtl::OUString& aDirectory )
583 	throw( IllegalArgumentException, RuntimeException )
584 {
585 	checkAlive();
586 
587 	::vos::OGuard aGuard( Application::GetSolarMutex() );
588 	m_aDisplayDirectory = aDirectory;
589 }
590 
getDisplayDirectory()591 rtl::OUString SAL_CALL SvtFilePicker::getDisplayDirectory() throw( RuntimeException )
592 {
593 	checkAlive();
594 
595 	::vos::OGuard aGuard( Application::GetSolarMutex() );
596 	if ( getDialog() )
597 	{
598 		rtl::OUString aPath = getDialog()->GetPath();
599 
600 		// #97148# ----
601 		if( m_aOldHideDirectory == aPath )
602 			return m_aOldDisplayDirectory;
603 		m_aOldHideDirectory = aPath;
604 
605 		// #102204# -----
606 		if( !getDialog()->ContentIsFolder( aPath ) )
607 		{
608 			INetURLObject aFolder( aPath );
609 			aFolder.CutLastName();
610 			aPath = aFolder.GetMainURL( INetURLObject::NO_DECODE );
611 		}
612 		m_aOldDisplayDirectory = aPath;
613 		return aPath;
614 	}
615 	else
616 		return m_aDisplayDirectory;
617 }
618 
getFiles()619 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getFiles() throw( RuntimeException )
620 {
621 	checkAlive();
622 
623 	::vos::OGuard aGuard( Application::GetSolarMutex() );
624 	if ( ! getDialog() )
625 	{
626 		Sequence< rtl::OUString > aEmpty;
627 		return aEmpty;
628 	}
629 
630 	// if there is more than one path we have to return the path to the
631 	// files first and then the list of the selected entries
632 
633 	SvStringsDtor* pPathList = getDialog()->GetPathList();
634 	sal_uInt16 i, nCount = pPathList->Count();
635 	sal_uInt16 nTotal = nCount > 1 ? nCount+1: nCount;
636 
637 	Sequence< rtl::OUString > aPath( nTotal );
638 
639 	if ( nCount == 1 )
640 		aPath[0] = rtl::OUString( *pPathList->GetObject( 0 ) );
641 	else if ( nCount > 1 )
642 	{
643 		INetURLObject aObj( *pPathList->GetObject( 0 ) );
644 		aObj.removeSegment();
645 		aPath[0] = aObj.GetMainURL( INetURLObject::NO_DECODE );
646 
647 		for ( i = 0; i < nCount; /* i++ is done below */ )
648 		{
649 			aObj.SetURL( *pPathList->GetObject(i++) );
650 			aPath[i] = aObj.getName();
651 		}
652 	}
653 
654 	delete pPathList;
655 	return aPath;
656 }
657 
658 //------------------------------------------------------------------------------------
659 // XFilePickerControlAccess functions
660 //------------------------------------------------------------------------------------
661 
setValue(sal_Int16 nElementID,sal_Int16 nControlAction,const Any & rValue)662 void SAL_CALL SvtFilePicker::setValue( sal_Int16 nElementID,
663 									   sal_Int16 nControlAction,
664 									   const Any& rValue )
665 	throw( RuntimeException )
666 {
667 	checkAlive();
668 
669 	::vos::OGuard aGuard( Application::GetSolarMutex() );
670 	if ( getDialog() )
671 	{
672 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
673 		aAccess.setValue( nElementID, nControlAction, rValue );
674 	}
675 	else
676 	{
677 		if ( !m_pElemList )
678 			m_pElemList = new ElementList;
679 
680 		sal_Bool bFound = sal_False;
681 		ElementList::iterator aListIter;
682 
683 		for ( aListIter = m_pElemList->begin();
684 			  aListIter != m_pElemList->end(); ++aListIter )
685 		{
686 			ElementEntry_Impl& rEntry = *aListIter;
687 			if ( ( rEntry.m_nElementID == nElementID ) &&
688 				( !rEntry.m_bHasValue || ( rEntry.m_nControlAction == nControlAction ) ) )
689 			{
690 				rEntry.setAction( nControlAction );
691 				rEntry.setValue( rValue );
692 				bFound = sal_True;
693 			}
694 		}
695 
696 		if ( !bFound )
697 		{
698 			ElementEntry_Impl aNew( nElementID );
699 			aNew.setAction( nControlAction );
700 			aNew.setValue( rValue );
701 			m_pElemList->insert( m_pElemList->end(), aNew );
702 		}
703 	}
704 }
705 
706 //------------------------------------------------------------------------------------
707 
getValue(sal_Int16 nElementID,sal_Int16 nControlAction)708 Any SAL_CALL SvtFilePicker::getValue( sal_Int16 nElementID, sal_Int16 nControlAction )
709 	throw( RuntimeException )
710 {
711 	checkAlive();
712 
713 	::vos::OGuard aGuard( Application::GetSolarMutex() );
714 	Any aAny;
715 
716 	// execute() called?
717 	if ( getDialog() )
718 	{
719 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
720 		aAny = aAccess.getValue( nElementID, nControlAction );
721 	}
722 	else if ( m_pElemList && !m_pElemList->empty() )
723 	{
724 		ElementList::iterator aListIter;
725 		for ( aListIter = m_pElemList->begin();
726 			  aListIter != m_pElemList->end(); ++aListIter )
727 		{
728 			ElementEntry_Impl& rEntry = *aListIter;
729 			if ( ( rEntry.m_nElementID == nElementID ) &&
730 				 ( rEntry.m_bHasValue ) &&
731 				 ( rEntry.m_nControlAction == nControlAction ) )
732 			{
733 				aAny = rEntry.m_aValue;
734 				break;
735 			}
736 		}
737 	}
738 
739 	return aAny;
740 }
741 
742 
743 //------------------------------------------------------------------------------------
setLabel(sal_Int16 nLabelID,const rtl::OUString & rValue)744 void SAL_CALL SvtFilePicker::setLabel( sal_Int16 nLabelID, const rtl::OUString& rValue )
745 	throw ( RuntimeException )
746 {
747 	checkAlive();
748 
749 	::vos::OGuard aGuard( Application::GetSolarMutex() );
750 	if ( getDialog() )
751 	{
752 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
753 		aAccess.setLabel( nLabelID, rValue );
754 	}
755 	else
756 	{
757 		if ( !m_pElemList )
758 			m_pElemList = new ElementList;
759 
760 		sal_Bool bFound = sal_False;
761 		ElementList::iterator aListIter;
762 
763 		for ( aListIter = m_pElemList->begin();
764 			  aListIter != m_pElemList->end(); ++aListIter )
765 		{
766 			ElementEntry_Impl& rEntry = *aListIter;
767 			if ( rEntry.m_nElementID == nLabelID )
768 			{
769 				rEntry.setLabel( rValue );
770 				bFound = sal_True;
771 			}
772 		}
773 
774 		if ( !bFound )
775 		{
776 			ElementEntry_Impl aNew( nLabelID );
777 			aNew.setLabel( rValue );
778 			m_pElemList->insert( m_pElemList->end(), aNew );
779 		}
780 	}
781 }
782 
783 //------------------------------------------------------------------------------------
getLabel(sal_Int16 nLabelID)784 rtl::OUString SAL_CALL SvtFilePicker::getLabel( sal_Int16 nLabelID )
785 	throw ( RuntimeException )
786 {
787 	checkAlive();
788 
789 	::vos::OGuard aGuard( Application::GetSolarMutex() );
790 	rtl::OUString aLabel;
791 
792 	if ( getDialog() )
793 	{
794 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
795 		aLabel = aAccess.getLabel( nLabelID );
796 	}
797 	else if ( m_pElemList && !m_pElemList->empty() )
798 	{
799 		ElementList::iterator aListIter;
800 		for ( aListIter = m_pElemList->begin();
801 			  aListIter != m_pElemList->end(); ++aListIter )
802 		{
803 			ElementEntry_Impl& rEntry = *aListIter;
804 			if ( rEntry.m_nElementID == nLabelID )
805 			{
806 				if ( rEntry.m_bHasLabel )
807 					aLabel = rEntry.m_aLabel;
808 				break;
809 			}
810 		}
811 	}
812 
813 	return aLabel;
814 }
815 
816 //------------------------------------------------------------------------------------
enableControl(sal_Int16 nElementID,sal_Bool bEnable)817 void SAL_CALL SvtFilePicker::enableControl( sal_Int16 nElementID, sal_Bool bEnable )
818 	throw( RuntimeException )
819 {
820 	checkAlive();
821 
822 	::vos::OGuard aGuard( Application::GetSolarMutex() );
823 	if ( getDialog() )
824 	{
825 		::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
826 		aAccess.enableControl( nElementID, bEnable );
827 	}
828 	else
829 	{
830 		if ( !m_pElemList )
831 			m_pElemList = new ElementList;
832 
833 		sal_Bool bFound = sal_False;
834 		ElementList::iterator aListIter;
835 
836 		for ( aListIter = m_pElemList->begin();
837 			  aListIter != m_pElemList->end(); ++aListIter )
838 		{
839 			ElementEntry_Impl& rEntry = *aListIter;
840 			if ( rEntry.m_nElementID == nElementID )
841 			{
842 				rEntry.setEnabled( bEnable );
843 				bFound = sal_True;
844 			}
845 		}
846 
847 		if ( !bFound )
848 		{
849 			ElementEntry_Impl aNew( nElementID );
850 			aNew.setEnabled( bEnable );
851 			m_pElemList->insert( m_pElemList->end(), aNew );
852 		}
853 	}
854 }
855 
856 //------------------------------------------------------------------------------------
857 // XFilePickerNotifier functions
858 //------------------------------------------------------------------------------------
859 
addFilePickerListener(const Reference<XFilePickerListener> & xListener)860 void SAL_CALL SvtFilePicker::addFilePickerListener( const Reference< XFilePickerListener >& xListener ) throw ( RuntimeException )
861 {
862 	checkAlive();
863 
864 	::vos::OGuard aGuard( Application::GetSolarMutex() );
865 	m_xListener = xListener;
866 }
867 
868 //------------------------------------------------------------------------------------
removeFilePickerListener(const Reference<XFilePickerListener> &)869 void SAL_CALL SvtFilePicker::removeFilePickerListener( const Reference< XFilePickerListener >& ) throw ( RuntimeException )
870 {
871 	checkAlive();
872 
873 	::vos::OGuard aGuard( Application::GetSolarMutex() );
874 	m_xListener.clear();
875 }
876 
877 //------------------------------------------------------------------------------------
878 // XFilePreview functions
879 //------------------------------------------------------------------------------------
880 
getSupportedImageFormats()881 Sequence< sal_Int16 > SAL_CALL SvtFilePicker::getSupportedImageFormats()
882 	throw ( RuntimeException )
883 {
884 	checkAlive();
885 
886 	::vos::OGuard aGuard( Application::GetSolarMutex() );
887 	Sequence< sal_Int16 > aFormats( 1 );
888 
889 	aFormats[0] = FilePreviewImageFormats::BITMAP;
890 
891 	return aFormats;
892 }
893 
894 //------------------------------------------------------------------------------------
getTargetColorDepth()895 sal_Int32 SAL_CALL SvtFilePicker::getTargetColorDepth() throw ( RuntimeException )
896 {
897 	checkAlive();
898 
899 	::vos::OGuard aGuard( Application::GetSolarMutex() );
900 	sal_Int32 nDepth = 0;
901 
902 	if ( getDialog() )
903 		nDepth = getDialog()->getTargetColorDepth();
904 
905 	return nDepth;
906 }
907 
908 //------------------------------------------------------------------------------------
getAvailableWidth()909 sal_Int32 SAL_CALL SvtFilePicker::getAvailableWidth() throw ( RuntimeException )
910 {
911 	checkAlive();
912 
913 	::vos::OGuard aGuard( Application::GetSolarMutex() );
914 	sal_Int32 nWidth = 0;
915 
916 	if ( getDialog() )
917 		nWidth = getDialog()->getAvailableWidth();
918 
919 	return nWidth;
920 }
921 
922 //------------------------------------------------------------------------------------
getAvailableHeight()923 sal_Int32 SAL_CALL SvtFilePicker::getAvailableHeight() throw ( RuntimeException )
924 {
925 	checkAlive();
926 
927 	::vos::OGuard aGuard( Application::GetSolarMutex() );
928 	sal_Int32 nHeigth = 0;
929 
930 	if ( getDialog() )
931 		nHeigth = getDialog()->getAvailableHeight();
932 
933 	return nHeigth;
934 }
935 
936 //------------------------------------------------------------------------------------
setImage(sal_Int16 aImageFormat,const Any & rImage)937 void SAL_CALL SvtFilePicker::setImage( sal_Int16 aImageFormat, const Any& rImage )
938 	throw ( IllegalArgumentException, RuntimeException )
939 {
940 	checkAlive();
941 
942 	::vos::OGuard aGuard( Application::GetSolarMutex() );
943 	if ( getDialog() )
944 		getDialog()->setImage( aImageFormat, rImage );
945 }
946 
947 //------------------------------------------------------------------------------------
setShowState(sal_Bool bShowState)948 sal_Bool SAL_CALL SvtFilePicker::setShowState( sal_Bool bShowState )
949 	throw ( RuntimeException )
950 {
951 	checkAlive();
952 
953 	::vos::OGuard aGuard( Application::GetSolarMutex() );
954 	sal_Bool bRet = sal_False;
955 
956 	if ( getDialog() )
957 		bRet = getDialog()->setShowState( bShowState );
958 
959 	return bRet;
960 }
961 
962 //------------------------------------------------------------------------------------
getShowState()963 sal_Bool SAL_CALL SvtFilePicker::getShowState() throw ( RuntimeException )
964 {
965 	checkAlive();
966 
967 	::vos::OGuard aGuard( Application::GetSolarMutex() );
968 	sal_Bool bRet = sal_False;
969 
970 	if ( getDialog() )
971 		bRet = getDialog()->getShowState();
972 
973 	return bRet;
974 }
975 
976 //------------------------------------------------------------------------------------
977 // XFilterGroupManager functions
978 //------------------------------------------------------------------------------------
979 
appendFilterGroup(const::rtl::OUString & sGroupTitle,const Sequence<StringPair> & aFilters)980 void SAL_CALL SvtFilePicker::appendFilterGroup(	const ::rtl::OUString& sGroupTitle,
981 												const Sequence< StringPair >& aFilters )
982 	throw ( IllegalArgumentException, RuntimeException )
983 {
984 	checkAlive();
985 
986 	::vos::OGuard aGuard( Application::GetSolarMutex() );
987 
988 	// check the names
989 	if ( FilterNameExists( aFilters ) )
990 		throw IllegalArgumentException(
991 			rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("filter name exists")),
992 			static_cast< OWeakObject * >(this), 1);
993 
994 	// ensure that we have a filter list
995 	::rtl::OUString sInitialCurrentFilter;
996 	if ( aFilters.getLength() )
997 		sInitialCurrentFilter = aFilters[0].First;
998 	ensureFilterList( sInitialCurrentFilter );
999 
1000 	// append the filter
1001 	m_pFilterList->insert( m_pFilterList->end(), FilterEntry( sGroupTitle, aFilters ) );
1002 }
1003 
1004 //------------------------------------------------------------------------------------
1005 // XFilterManager functions
1006 //------------------------------------------------------------------------------------
1007 
appendFilter(const rtl::OUString & aTitle,const rtl::OUString & aFilter)1008 void SAL_CALL SvtFilePicker::appendFilter( const rtl::OUString& aTitle,
1009 										   const rtl::OUString& aFilter )
1010 	throw( IllegalArgumentException, RuntimeException )
1011 {
1012 	checkAlive();
1013 
1014 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1015 	// check the name
1016 	if ( FilterNameExists( aTitle ) )
1017 		// TODO: a more precise exception message
1018 		throw IllegalArgumentException();
1019 
1020 	// ensure that we have a filter list
1021 	ensureFilterList( aTitle );
1022 
1023 	// append the filter
1024 	m_pFilterList->insert( m_pFilterList->end(), FilterEntry( aTitle, aFilter ) );
1025 }
1026 
1027 //------------------------------------------------------------------------------------
setCurrentFilter(const rtl::OUString & aTitle)1028 void SAL_CALL SvtFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
1029 	throw( IllegalArgumentException, RuntimeException )
1030 {
1031 	checkAlive();
1032 
1033 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1034 	if ( ! FilterNameExists( aTitle ) )
1035 		throw IllegalArgumentException();
1036 
1037 	m_aCurrentFilter = aTitle;
1038 
1039 	if ( getDialog() )
1040 		getDialog()->SetCurFilter( aTitle );
1041 }
1042 
1043 //------------------------------------------------------------------------------------
getCurrentFilter()1044 rtl::OUString SAL_CALL SvtFilePicker::getCurrentFilter()
1045 	throw( RuntimeException )
1046 {
1047 	checkAlive();
1048 
1049 	::vos::OGuard aGuard( Application::GetSolarMutex() );
1050 	rtl::OUString aFilter = getDialog() ? rtl::OUString( getDialog()->GetCurFilter() ) :
1051 										  rtl::OUString( m_aCurrentFilter );
1052 	return aFilter;
1053 }
1054 
1055 
1056 //------------------------------------------------------------------------------------
1057 // XInitialization functions
1058 //------------------------------------------------------------------------------------
1059 
initialize(const Sequence<Any> & _rArguments)1060 void SAL_CALL SvtFilePicker::initialize( const Sequence< Any >& _rArguments )
1061 	throw ( Exception, RuntimeException )
1062 {
1063 	checkAlive();
1064 
1065 	Sequence< Any > aArguments( _rArguments.getLength());
1066 
1067 	m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE;
1068 
1069 	if ( _rArguments.getLength() >= 1 )
1070 	{
1071 		// compatibility: one argument, type sal_Int16 , specifies the service type
1072 		int index = 0;
1073 
1074 		if (_rArguments[0] >>= m_nServiceType)
1075 		{
1076 			// skip the first entry if it was the ServiceType, because it's not needed in OCommonPicker::initialize and it's not a NamedValue
1077 			NamedValue emptyNamedValue;
1078 			aArguments[0] <<= emptyNamedValue;
1079 			index = 1;
1080 
1081 		}
1082 		for ( int i = index; i < _rArguments.getLength(); i++)
1083 		{
1084 			NamedValue namedValue;
1085 			aArguments[i] <<= _rArguments[i];
1086 
1087 			if (aArguments[i] >>= namedValue )
1088 			{
1089 
1090 				if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StandardDir" ) ) ) )
1091 				{
1092 					::rtl::OUString sStandardDir;
1093 
1094 					namedValue.Value >>= sStandardDir;
1095 
1096 					// Set the directory for the "back to the default dir" button
1097 						if ( sStandardDir.getLength() > 0 )
1098 					{
1099 						m_aStandardDir = sStandardDir;
1100 					}
1101 				}
1102 				else if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BlackList" ) ) ) )
1103 				{
1104 					namedValue.Value >>= m_aBlackList;
1105 				}
1106 			}
1107 		}
1108 	}
1109 
1110 	// let the base class analyze the sequence (will call into implHandleInitializationArgument)
1111 	OCommonPicker::initialize( aArguments );
1112 }
1113 
1114 //-------------------------------------------------------------------------
implHandleInitializationArgument(const::rtl::OUString & _rName,const Any & _rValue)1115 sal_Bool SvtFilePicker::implHandleInitializationArgument( const ::rtl::OUString& _rName, const Any& _rValue ) SAL_THROW( ( Exception, RuntimeException ) )
1116 {
1117 	if ( _rName.equalsAscii( "TemplateDescription" ) )
1118 	{
1119 		m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE;
1120 		OSL_VERIFY( _rValue >>= m_nServiceType );
1121 		return sal_True;
1122 	}
1123 	if ( _rName.equalsAscii( "StandardDir" ) )
1124 	{
1125 		OSL_VERIFY( _rValue >>= m_aStandardDir );
1126 		return sal_True;
1127 	}
1128 
1129 	if ( _rName.equalsAscii( "BlackList" ) )
1130 	{
1131 		OSL_VERIFY( _rValue >>= m_aBlackList );
1132 		return sal_True;
1133 	}
1134 
1135 
1136 
1137 	return OCommonPicker::implHandleInitializationArgument( _rName, _rValue );
1138 }
1139 
1140 //------------------------------------------------------------------------------------
1141 // XServiceInfo
1142 //------------------------------------------------------------------------------------
1143 
1144 /* XServiceInfo */
getImplementationName()1145 rtl::OUString SAL_CALL SvtFilePicker::getImplementationName() throw( RuntimeException )
1146 {
1147 	return impl_getStaticImplementationName();
1148 }
1149 
1150 /* XServiceInfo */
supportsService(const rtl::OUString & sServiceName)1151 sal_Bool SAL_CALL SvtFilePicker::supportsService( const rtl::OUString& sServiceName ) throw( RuntimeException )
1152 {
1153 	Sequence< rtl::OUString > seqServiceNames = getSupportedServiceNames();
1154 	const rtl::OUString* pArray = seqServiceNames.getConstArray();
1155 	for ( sal_Int32 i = 0; i < seqServiceNames.getLength(); i++ )
1156 	{
1157 		if ( sServiceName == pArray[i] )
1158 		{
1159 			return sal_True ;
1160 		}
1161 	}
1162 	return sal_False ;
1163 }
1164 
1165 /* XServiceInfo */
getSupportedServiceNames()1166 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getSupportedServiceNames() throw( RuntimeException )
1167 {
1168 	return impl_getStaticSupportedServiceNames();
1169 }
1170 
1171 /* Helper for XServiceInfo */
impl_getStaticSupportedServiceNames()1172 Sequence< rtl::OUString > SvtFilePicker::impl_getStaticSupportedServiceNames()
1173 {
1174 	Sequence< rtl::OUString > seqServiceNames( 1 );
1175 	rtl::OUString* pArray = seqServiceNames.getArray();
1176 	pArray[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.OfficeFilePicker" );
1177 	return seqServiceNames ;
1178 }
1179 
1180 /* Helper for XServiceInfo */
impl_getStaticImplementationName()1181 rtl::OUString SvtFilePicker::impl_getStaticImplementationName()
1182 {
1183 	return rtl::OUString::createFromAscii( "com.sun.star.svtools.OfficeFilePicker" );
1184 }
1185 
1186 /* Helper for registry */
impl_createInstance(const Reference<XComponentContext> & rxContext)1187 Reference< XInterface > SAL_CALL SvtFilePicker::impl_createInstance(
1188 	const Reference< XComponentContext >& rxContext) throw( Exception )
1189 {
1190 	Reference< XMultiServiceFactory > xServiceManager (rxContext->getServiceManager(), UNO_QUERY_THROW);
1191 	return Reference< XInterface >( *new SvtFilePicker( xServiceManager ) );
1192 }
1193