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_sfx2.hxx"
30 #include <sfx2/filedlghelper.hxx>
31 #include <sal/types.h>
32 #include <com/sun/star/lang/XInitialization.hpp>
33 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
34 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
35 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
36 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
37 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
38 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
39 #include <com/sun/star/ui/dialogs/XControlInformation.hpp>
40 #include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
41 #include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
42 #include <com/sun/star/ui/dialogs/XFilePreview.hpp>
43 #include <com/sun/star/ui/dialogs/XFilterManager.hpp>
44 #include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
45 #include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
46 #include <com/sun/star/ui/dialogs/XFilePicker2.hpp>
47 #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp>
48 #include <com/sun/star/lang/XServiceInfo.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50 #include <com/sun/star/beans/NamedValue.hpp>
51 #include <com/sun/star/embed/ElementModes.hpp>
52 #include <com/sun/star/container/XEnumeration.hpp>
53 #include <com/sun/star/container/XContainerQuery.hpp>
54 #include <com/sun/star/task/XInteractionRequest.hpp>
55 #include <com/sun/star/ucb/InteractiveAugmentedIOException.hpp>
56 
57 #include <comphelper/processfactory.hxx>
58 #include <comphelper/types.hxx>
59 #include <comphelper/sequenceashashmap.hxx>
60 #include <comphelper/stillreadwriteinteraction.hxx>
61 #include <tools/urlobj.hxx>
62 #include <vcl/help.hxx>
63 #include <unotools/ucbstreamhelper.hxx>
64 #include <unotools/ucbhelper.hxx>
65 #include <unotools/localfilehelper.hxx>
66 #include <vos/thread.hxx>
67 #include <vos/mutex.hxx>
68 #include <vos/security.hxx>
69 #include <vcl/cvtgrf.hxx>
70 #include <vcl/msgbox.hxx>
71 #include <vcl/mnemonic.hxx>
72 #include <unotools/pathoptions.hxx>
73 #include <unotools/securityoptions.hxx>
74 #include <svl/itemset.hxx>
75 #include <svl/eitem.hxx>
76 #include <svl/intitem.hxx>
77 #include <svl/stritem.hxx>
78 #include <svtools/filter.hxx>
79 #include <unotools/viewoptions.hxx>
80 #include <unotools/moduleoptions.hxx>
81 #include <svtools/helpid.hrc>
82 #include <comphelper/docpasswordrequest.hxx>
83 #include <comphelper/docpasswordhelper.hxx>
84 #include <ucbhelper/content.hxx>
85 #include <ucbhelper/commandenvironment.hxx>
86 #include <comphelper/storagehelper.hxx>
87 #include <toolkit/helper/vclunohelper.hxx>
88 #include <sfx2/app.hxx>
89 #include <sfx2/frame.hxx>
90 #include <sfx2/docfile.hxx>
91 #include <sfx2/docfac.hxx>
92 #include "openflag.hxx"
93 #include <sfx2/passwd.hxx>
94 #include "sfx2/sfxresid.hxx"
95 #include <sfx2/sfxsids.hrc>
96 #include "filedlghelper.hrc"
97 #include "filtergrouping.hxx"
98 #include <sfx2/request.hxx>
99 #include "filedlgimpl.hxx"
100 #include <helpid.hrc>
101 #include <sfxlocal.hrc>
102 
103 //-----------------------------------------------------------------------------
104 
105 using namespace ::com::sun::star;
106 using namespace ::com::sun::star::container;
107 using namespace ::com::sun::star::lang;
108 using namespace ::com::sun::star::ui::dialogs;
109 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
110 using namespace ::com::sun::star::uno;
111 using namespace ::com::sun::star::beans;
112 using namespace ::rtl;
113 using namespace ::cppu;
114 
115 //-----------------------------------------------------------------------------
116 
117 #define IODLG_CONFIGNAME		String(DEFINE_CONST_UNICODE("FilePicker_Save"))
118 #define IMPGRF_CONFIGNAME		String(DEFINE_CONST_UNICODE("FilePicker_Graph"))
119 #define USERITEM_NAME			::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "UserItem" ))
120 
121 //-----------------------------------------------------------------------------
122 
123 namespace sfx2
124 {
125 
126 const OUString* GetLastFilterConfigId( FileDialogHelper::Context _eContext )
127 {
128     static const OUString aSD_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SdExportLastFilter" ) );
129     static const OUString aSI_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SiExportLastFilter" ) );
130     static const OUString aSW_EXPORT_IDENTIFIER( RTL_CONSTASCII_USTRINGPARAM( "SwExportLastFilter" ) );
131 
132     const OUString* pRet = NULL;
133 
134     switch( _eContext )
135     {
136         case FileDialogHelper::SD_EXPORT: pRet = &aSD_EXPORT_IDENTIFIER; break;
137         case FileDialogHelper::SI_EXPORT: pRet = &aSI_EXPORT_IDENTIFIER; break;
138         case FileDialogHelper::SW_EXPORT: pRet = &aSW_EXPORT_IDENTIFIER; break;
139         default: break;
140     }
141 
142     return pRet;
143 }
144 
145 String EncodeSpaces_Impl( const String& rSource );
146 String DecodeSpaces_Impl( const String& rSource );
147 
148 // ------------------------------------------------------------------------
149 // -----------		FileDialogHelper_Impl		---------------------------
150 // ------------------------------------------------------------------------
151 
152 // ------------------------------------------------------------------------
153 // XFilePickerListener Methods
154 // ------------------------------------------------------------------------
155 void SAL_CALL FileDialogHelper_Impl::fileSelectionChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
156 {
157 	::vos::OGuard aGuard( Application::GetSolarMutex() );
158 	mpAntiImpl->FileSelectionChanged( aEvent );
159 }
160 
161 // ------------------------------------------------------------------------
162 void SAL_CALL FileDialogHelper_Impl::directoryChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
163 {
164 	::vos::OGuard aGuard( Application::GetSolarMutex() );
165 	mpAntiImpl->DirectoryChanged( aEvent );
166 }
167 
168 // ------------------------------------------------------------------------
169 OUString SAL_CALL FileDialogHelper_Impl::helpRequested( const FilePickerEvent& aEvent ) throw ( RuntimeException )
170 {
171 	::vos::OGuard aGuard( Application::GetSolarMutex() );
172 	return mpAntiImpl->HelpRequested( aEvent );
173 }
174 
175 // ------------------------------------------------------------------------
176 void SAL_CALL FileDialogHelper_Impl::controlStateChanged( const FilePickerEvent& aEvent ) throw ( RuntimeException )
177 {
178 	::vos::OGuard aGuard( Application::GetSolarMutex() );
179 	mpAntiImpl->ControlStateChanged( aEvent );
180 }
181 
182 // ------------------------------------------------------------------------
183 void SAL_CALL FileDialogHelper_Impl::dialogSizeChanged() throw ( RuntimeException )
184 {
185 	::vos::OGuard aGuard( Application::GetSolarMutex() );
186 	mpAntiImpl->DialogSizeChanged();
187 }
188 
189 // ------------------------------------------------------------------------
190 // XDialogClosedListener Methods
191 // ------------------------------------------------------------------------
192 void SAL_CALL FileDialogHelper_Impl::dialogClosed( const DialogClosedEvent& _rEvent ) throw ( RuntimeException )
193 {
194     ::vos::OGuard aGuard( Application::GetSolarMutex() );
195     mpAntiImpl->DialogClosed( _rEvent );
196     postExecute( _rEvent.DialogResult );
197 }
198 
199 // ------------------------------------------------------------------------
200 // handle XFilePickerListener events
201 // ------------------------------------------------------------------------
202 void FileDialogHelper_Impl::handleFileSelectionChanged( const FilePickerEvent& )
203 {
204 	if ( mbHasVersions )
205 		updateVersions();
206 
207 	if ( mbShowPreview )
208 		maPreViewTimer.Start();
209 }
210 
211 // ------------------------------------------------------------------------
212 void FileDialogHelper_Impl::handleDirectoryChanged( const FilePickerEvent& )
213 {
214 	if ( mbShowPreview )
215 		TimeOutHdl_Impl( NULL );
216 }
217 
218 // ------------------------------------------------------------------------
219 OUString FileDialogHelper_Impl::handleHelpRequested( const FilePickerEvent& aEvent )
220 {
221 	//!!! todo: cache the help strings (here or TRA)
222 
223 	rtl::OString sHelpId;
224 	// mapping from element id -> help id
225 	switch ( aEvent.ElementId )
226 	{
227 		case ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION :
228 			sHelpId = HID_FILESAVE_AUTOEXTENSION;
229 			break;
230 
231 		case ExtendedFilePickerElementIds::CHECKBOX_PASSWORD :
232 			sHelpId = HID_FILESAVE_SAVEWITHPASSWORD;
233 			break;
234 
235 		case ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS :
236 			sHelpId = HID_FILESAVE_CUSTOMIZEFILTER;
237 			break;
238 
239 		case ExtendedFilePickerElementIds::CHECKBOX_READONLY :
240 			sHelpId = HID_FILEOPEN_READONLY;
241 			break;
242 
243 		case ExtendedFilePickerElementIds::CHECKBOX_LINK :
244 			sHelpId = HID_FILEDLG_LINK_CB;
245 			break;
246 
247 		case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW :
248 			sHelpId = HID_FILEDLG_PREVIEW_CB;
249 			break;
250 
251 		case ExtendedFilePickerElementIds::PUSHBUTTON_PLAY :
252 			sHelpId = HID_FILESAVE_DOPLAY;
253 			break;
254 
255         case ExtendedFilePickerElementIds::LISTBOX_VERSION_LABEL :
256 		case ExtendedFilePickerElementIds::LISTBOX_VERSION :
257 			sHelpId = HID_FILEOPEN_VERSION;
258 			break;
259 
260         case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE_LABEL :
261 		case ExtendedFilePickerElementIds::LISTBOX_TEMPLATE :
262 			sHelpId = HID_FILESAVE_TEMPLATE;
263 			break;
264 
265         case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE_LABEL :
266 		case ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE :
267 			sHelpId = HID_FILEOPEN_IMAGE_TEMPLATE;
268 			break;
269 
270 		case ExtendedFilePickerElementIds::CHECKBOX_SELECTION :
271 			sHelpId = HID_FILESAVE_SELECTION;
272 			break;
273 
274 		default:
275 			DBG_ERRORFILE( "invalid element id" );
276 	}
277 
278 	OUString aHelpText;
279 	Help* pHelp = Application::GetHelp();
280 	if ( pHelp )
281 		aHelpText = String( pHelp->GetHelpText( String( ByteString(sHelpId), RTL_TEXTENCODING_UTF8), NULL ) );
282 	return aHelpText;
283 }
284 
285 // ------------------------------------------------------------------------
286 void FileDialogHelper_Impl::handleControlStateChanged( const FilePickerEvent& aEvent )
287 {
288 	switch ( aEvent.ElementId )
289 	{
290 		case CommonFilePickerElementIds::LISTBOX_FILTER:
291 			updateFilterOptionsBox();
292 			enablePasswordBox( sal_False );
293 			updateSelectionBox();
294 			// only use it for export and with our own dialog
295 			if ( mbExport && !mbSystemPicker )
296 				updateExportButton();
297 			break;
298 
299 		case ExtendedFilePickerElementIds::CHECKBOX_PREVIEW:
300 			updatePreviewState();
301 			break;
302 	}
303 }
304 
305 // ------------------------------------------------------------------------
306 void FileDialogHelper_Impl::handleDialogSizeChanged()
307 {
308     if ( mbShowPreview )
309         TimeOutHdl_Impl( NULL );
310 }
311 
312 // ------------------------------------------------------------------------
313 // XEventListener Methods
314 // ------------------------------------------------------------------------
315 void SAL_CALL FileDialogHelper_Impl::disposing( const EventObject& ) throw ( RuntimeException )
316 {
317 	::vos::OGuard aGuard( Application::GetSolarMutex() );
318 	dispose();
319 }
320 
321 // ------------------------------------------------------------------------
322 // ------------------------------------------------------------------------
323 // ------------------------------------------------------------------------
324 void FileDialogHelper_Impl::dispose()
325 {
326 	if ( mxFileDlg.is() )
327 	{
328 		// remove the event listener
329 		uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
330 		if ( xNotifier.is() )
331 			xNotifier->removeFilePickerListener( this );
332 
333 		::comphelper::disposeComponent( mxFileDlg );
334 		mxFileDlg.clear();
335 	}
336 }
337 
338 // ------------------------------------------------------------------------
339 String FileDialogHelper_Impl::getCurrentFilterUIName() const
340 {
341 	String aFilterName;
342 	uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
343 
344 	if( xFltMgr.is() )
345 	{
346 		aFilterName = xFltMgr->getCurrentFilter();
347 
348 		if ( aFilterName.Len() && isShowFilterExtensionEnabled() )
349 			aFilterName = getFilterName( aFilterName );
350 	}
351 
352 	return aFilterName;
353 }
354 
355 // ------------------------------------------------------------------------
356 void FileDialogHelper_Impl::LoadLastUsedFilter( const OUString& _rContextIdentifier )
357 {
358 	SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
359 
360 	if( aDlgOpt.Exists() )
361 	{
362 		OUString	aLastFilter;
363 		if( aDlgOpt.GetUserItem( _rContextIdentifier ) >>= aLastFilter )
364 			setFilter( aLastFilter );
365 	}
366 }
367 
368 // ------------------------------------------------------------------------
369 void FileDialogHelper_Impl::SaveLastUsedFilter( const OUString& _rContextIdentifier )
370 {
371 	SvtViewOptions( E_DIALOG, IODLG_CONFIGNAME ).SetUserItem( _rContextIdentifier,
372 						makeAny( getFilterWithExtension( getFilter() ) ) );
373 }
374 
375 // ------------------------------------------------------------------------
376 void FileDialogHelper_Impl::SaveLastUsedFilter( void )
377 {
378 	const OUString*	pConfigId = GetLastFilterConfigId( meContext );
379 	if( pConfigId )
380 		SaveLastUsedFilter( *pConfigId );
381 }
382 
383 // ------------------------------------------------------------------------
384 const SfxFilter* FileDialogHelper_Impl::getCurentSfxFilter()
385 {
386 	String aFilterName = getCurrentFilterUIName();
387 
388 	const SfxFilter* pFilter = NULL;
389 	if ( mpMatcher && aFilterName.Len() )
390 		pFilter = mpMatcher->GetFilter4UIName( aFilterName, m_nMustFlags, m_nDontFlags );
391 
392 	return pFilter;
393 }
394 
395 // ------------------------------------------------------------------------
396 sal_Bool FileDialogHelper_Impl::updateExtendedControl( sal_Int16 _nExtendedControlId, sal_Bool _bEnable )
397 {
398 	sal_Bool bIsEnabled = sal_False;
399 
400 	uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
401 	if ( xCtrlAccess.is() )
402 	{
403 		try
404 		{
405 			xCtrlAccess->enableControl( _nExtendedControlId, _bEnable );
406 			bIsEnabled = _bEnable;
407 		}
408 		catch( const IllegalArgumentException& )
409 		{
410 			DBG_ERROR( "FileDialogHelper_Impl::updateExtendedControl: caught an exception!" );
411 		}
412 	}
413 	return bIsEnabled;
414 }
415 
416 // ------------------------------------------------------------------------
417 sal_Bool FileDialogHelper_Impl::CheckFilterOptionsCapability( const SfxFilter* _pFilter )
418 {
419 	sal_Bool bResult = sal_False;
420 
421 	if( mxFilterCFG.is() && _pFilter )
422 	{
423 		try {
424    			Sequence < PropertyValue > aProps;
425    			Any aAny = mxFilterCFG->getByName( _pFilter->GetName() );
426    			if ( aAny >>= aProps )
427    			{
428        			::rtl::OUString aServiceName;
429        			sal_Int32 nPropertyCount = aProps.getLength();
430        			for( sal_Int32 nProperty=0; nProperty < nPropertyCount; ++nProperty )
431 				{
432            			if( aProps[nProperty].Name.equals( DEFINE_CONST_OUSTRING( "UIComponent") ) )
433            			{
434                			aProps[nProperty].Value >>= aServiceName;
435 						if( aServiceName.getLength() )
436 							bResult = sal_True;
437 					}
438 				}
439 			}
440 		}
441 		catch( Exception& )
442 		{
443 		}
444 	}
445 
446 	return bResult;
447 }
448 
449 // ------------------------------------------------------------------------
450 sal_Bool FileDialogHelper_Impl::isInOpenMode() const
451 {
452 	sal_Bool bRet = sal_False;
453 
454 	switch ( m_nDialogType )
455 	{
456 		case FILEOPEN_SIMPLE:
457 		case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
458 		case FILEOPEN_PLAY:
459 		case FILEOPEN_READONLY_VERSION:
460 		case FILEOPEN_LINK_PREVIEW:
461 			bRet = sal_True;
462 	}
463 
464 	return bRet;
465 }
466 
467 // ------------------------------------------------------------------------
468 
469 void FileDialogHelper_Impl::updateFilterOptionsBox()
470 {
471 	if ( !m_bHaveFilterOptions )
472 		return;
473 
474 	updateExtendedControl(
475 		ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS,
476 		CheckFilterOptionsCapability( getCurentSfxFilter() )
477 	);
478 }
479 
480 // ------------------------------------------------------------------------
481 
482 void FileDialogHelper_Impl::updateExportButton()
483 {
484 	uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
485 	if ( xCtrlAccess.is() )
486 	{
487 		OUString sEllipses( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
488 		OUString sOldLabel( xCtrlAccess->getLabel( CommonFilePickerElementIds::PUSHBUTTON_OK ) );
489 
490 		// initialize button label; we need the label with the mnemonic char
491 		if ( !maButtonLabel.getLength() || maButtonLabel.indexOf( MNEMONIC_CHAR ) == -1 )
492 		{
493 			// cut the ellipses, if necessary
494 			sal_Int32 nIndex = sOldLabel.indexOf( sEllipses );
495 			if ( -1 == nIndex )
496 				nIndex = sOldLabel.getLength();
497 			maButtonLabel = sOldLabel.copy( 0, nIndex );
498 		}
499 
500 		OUString sLabel = maButtonLabel;
501 		// filter with options -> append ellipses on export button label
502 		if ( CheckFilterOptionsCapability( getCurentSfxFilter() ) )
503 			sLabel += OUString( RTL_CONSTASCII_USTRINGPARAM( "..." ) );
504 
505 		if ( sOldLabel != sLabel )
506 		{
507 			try
508 			{
509 				xCtrlAccess->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK, sLabel );
510 			}
511 			catch( const IllegalArgumentException& )
512 			{
513 				DBG_ERRORFILE( "FileDialogHelper_Impl::updateExportButton: caught an exception!" );
514 			}
515 		}
516 	}
517 }
518 
519 // ------------------------------------------------------------------------
520 void FileDialogHelper_Impl::updateSelectionBox()
521 {
522 	if ( !mbHasSelectionBox )
523 		return;
524 
525     // Does the selection box exist?
526     sal_Bool bSelectionBoxFound = sal_False;
527     uno::Reference< XControlInformation > xCtrlInfo( mxFileDlg, UNO_QUERY );
528     if ( xCtrlInfo.is() )
529     {
530         Sequence< ::rtl::OUString > aCtrlList = xCtrlInfo->getSupportedControls();
531         sal_uInt32 nCount = aCtrlList.getLength();
532         for ( sal_uInt32 nCtrl = 0; nCtrl < nCount; ++nCtrl )
533             if ( aCtrlList[ nCtrl ].equalsAscii("SelectionBox") )
534             {
535                 bSelectionBoxFound = sal_False;
536                 break;
537             }
538     }
539 
540     if ( bSelectionBoxFound )
541     {
542         const SfxFilter* pFilter = getCurentSfxFilter();
543         mbSelectionFltrEnabled = updateExtendedControl(
544             ExtendedFilePickerElementIds::CHECKBOX_SELECTION,
545             ( mbSelectionEnabled && pFilter && ( pFilter->GetFilterFlags() & SFX_FILTER_SUPPORTSSELECTION ) != 0 ) );
546         uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
547         xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, makeAny( (sal_Bool)mbSelection ) );
548     }
549 }
550 
551 // ------------------------------------------------------------------------
552 void FileDialogHelper_Impl::enablePasswordBox( sal_Bool bInit )
553 {
554 	if ( ! mbHasPassword )
555 		return;
556 
557 	sal_Bool bWasEnabled = mbIsPwdEnabled;
558 
559     const SfxFilter* pCurrentFilter = getCurentSfxFilter();
560 	mbIsPwdEnabled = updateExtendedControl(
561 		ExtendedFilePickerElementIds::CHECKBOX_PASSWORD,
562         pCurrentFilter && ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_ENCRYPTION )
563 	);
564 
565 	if( bInit )
566 	{
567 		// in case of inintialization previous state is not interesting
568 		if( mbIsPwdEnabled )
569 		{
570 			uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
571 			if( mbPwdCheckBoxState )
572 				xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
573 		}
574 	}
575 	else if( !bWasEnabled && mbIsPwdEnabled )
576 	{
577 		uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
578 		if( mbPwdCheckBoxState )
579 			xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_True ) );
580 	}
581 	else if( bWasEnabled && !mbIsPwdEnabled )
582 	{
583 		// remember user settings until checkbox is enabled
584 		uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
585 		Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
586 		sal_Bool bPassWord = sal_False;
587 		mbPwdCheckBoxState = ( aValue >>= bPassWord ) && bPassWord;
588 		xCtrlAccess->setValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0, makeAny( sal_False ) );
589 	}
590 }
591 
592 // ------------------------------------------------------------------------
593 void FileDialogHelper_Impl::updatePreviewState( sal_Bool _bUpdatePreviewWindow )
594 {
595 	if ( mbHasPreview )
596 	{
597 		uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
598 
599 		// check, wether or not we have to display a preview
600 		if ( xCtrlAccess.is() )
601 		{
602 			try
603 			{
604 				Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
605 				sal_Bool bShowPreview = sal_False;
606 
607 				if ( aValue >>= bShowPreview )
608 				{
609 					mbShowPreview = bShowPreview;
610 
611 					// #97633
612 					// setShowState has currently no effect for the
613 					// OpenOffice FilePicker (see svtools/source/filepicker/iodlg.cxx)
614 					uno::Reference< XFilePreview > xFilePreview( mxFileDlg, UNO_QUERY );
615 					if ( xFilePreview.is() )
616 						xFilePreview->setShowState( mbShowPreview );
617 
618 					if ( _bUpdatePreviewWindow )
619 						TimeOutHdl_Impl( NULL );
620 				}
621 			}
622 			catch( Exception )
623 			{
624 				DBG_ERRORFILE( "FileDialogHelper_Impl::updatePreviewState: caught an exception!" );
625 			}
626 		}
627 	}
628 }
629 
630 // ------------------------------------------------------------------------
631 void FileDialogHelper_Impl::updateVersions()
632 {
633 	Sequence < OUString > aEntries;
634 	Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
635 
636 	if ( aPathSeq.getLength() == 1 )
637 	{
638 		INetURLObject aObj( aPathSeq[0] );
639 
640 		if ( ( aObj.GetProtocol() == INET_PROT_FILE ) &&
641 			( utl::UCBContentHelper::IsDocument( aObj.GetMainURL( INetURLObject::NO_DECODE ) ) ) )
642 		{
643 			try
644 			{
645 				uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
646 																aObj.GetMainURL( INetURLObject::NO_DECODE ),
647 																embed::ElementModes::READ );
648 
649 				DBG_ASSERT( xStorage.is(), "The method must return the storage or throw an exception!" );
650 				if ( !xStorage.is() )
651 					throw uno::RuntimeException();
652 
653 				uno::Sequence < util::RevisionTag > xVersions = SfxMedium::GetVersionList( xStorage );
654 
655                 aEntries.realloc( xVersions.getLength() + 1 );
656                 aEntries[0] = OUString( String ( SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ) ) );
657 
658                 for ( sal_Int32 i=0; i<xVersions.getLength(); i++ )
659                     aEntries[ i + 1 ] = xVersions[i].Identifier;
660 
661                 // TODO/LATER: not sure that this information must be shown in future ( binfilter? )
662 //REMOVE					else
663 //REMOVE					{
664 //REMOVE						SfxFilterFlags nMust = SFX_FILTER_IMPORT | SFX_FILTER_OWN;
665 //REMOVE						SfxFilterFlags nDont = SFX_FILTER_NOTINSTALLED | SFX_FILTER_STARONEFILTER;
666 //REMOVE						if ( SFX_APP()->GetFilterMatcher().GetFilter4ClipBoardId( pStor->GetFormat(), nMust, nDont ) )
667 //REMOVE						{
668 //REMOVE							aEntries.realloc( 1 );
669 //REMOVE							aEntries[0] = OUString( String ( SfxResId( STR_SFX_FILEDLG_ACTUALVERSION ) ) );
670 //REMOVE						}
671 //REMOVE					}
672 			}
673 			catch( uno::Exception& )
674 			{
675 			}
676 		}
677 	}
678 
679 	uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
680 	Any aValue;
681 
682 	try
683 	{
684 		xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
685 						ControlActions::DELETE_ITEMS, aValue );
686 	}
687 	catch( IllegalArgumentException ){}
688 
689 	sal_Int32 nCount = aEntries.getLength();
690 
691 	if ( nCount )
692 	{
693 		try
694 		{
695 			aValue <<= aEntries;
696 			xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
697 							ControlActions::ADD_ITEMS, aValue );
698 
699 			Any aPos;
700 			aPos <<= (sal_Int32) 0;
701 			xDlg->setValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
702 							ControlActions::SET_SELECT_ITEM, aPos );
703 		}
704 		catch( IllegalArgumentException ){}
705 	}
706 }
707 
708 // -----------------------------------------------------------------------
709 class OReleaseSolarMutex
710 {
711 private:
712 	const sal_Int32	m_nAquireCount;
713 public:
714 	OReleaseSolarMutex( )
715 		:m_nAquireCount( Application::ReleaseSolarMutex() )
716 	{
717 	}
718 	~OReleaseSolarMutex( )
719 	{
720 		Application::AcquireSolarMutex( m_nAquireCount );
721 	}
722 };
723 
724 // -----------------------------------------------------------------------
725 IMPL_LINK( FileDialogHelper_Impl, TimeOutHdl_Impl, Timer*, EMPTYARG )
726 {
727 	if ( !mbHasPreview )
728 		return 0;
729 
730 	maGraphic.Clear();
731 
732 	Any aAny;
733 	uno::Reference < XFilePreview > xFilePicker( mxFileDlg, UNO_QUERY );
734 
735 	if ( ! xFilePicker.is() )
736 		return 0;
737 
738 	Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
739 
740 	if ( mbShowPreview && ( aPathSeq.getLength() == 1 ) )
741 	{
742 		OUString	aURL = aPathSeq[0];
743 
744 		if ( ERRCODE_NONE == getGraphic( aURL, maGraphic ) )
745 		{
746 			// #89491
747 			// changed the code slightly;
748 			// before: the bitmap was scaled and
749 			// surrounded a white frame
750 			// now: the bitmap will only be scaled
751 			// and the filepicker implementation
752 			// is responsible for placing it at its
753 			// proper position and painting a frame
754 
755 			Bitmap aBmp = maGraphic.GetBitmap();
756 
757 			// scale the bitmap to the correct size
758 			sal_Int32 nOutWidth  = xFilePicker->getAvailableWidth();
759 			sal_Int32 nOutHeight = xFilePicker->getAvailableHeight();
760 			sal_Int32 nBmpWidth  = aBmp.GetSizePixel().Width();
761 			sal_Int32 nBmpHeight = aBmp.GetSizePixel().Height();
762 
763 			double nXRatio = (double) nOutWidth / nBmpWidth;
764 			double nYRatio = (double) nOutHeight / nBmpHeight;
765 
766 			if ( nXRatio < nYRatio )
767 				aBmp.Scale( nXRatio, nXRatio );
768 			else
769 				aBmp.Scale( nYRatio, nYRatio );
770 
771             // #94505# Convert to true color, to allow CopyPixel
772             aBmp.Convert( BMP_CONVERSION_24BIT );
773 
774 			// and copy it into the Any
775 			SvMemoryStream aData;
776 
777 			aData << aBmp;
778 
779             const Sequence < sal_Int8 > aBuffer(
780                 static_cast< const sal_Int8* >(aData.GetData()),
781                 aData.GetEndOfData() );
782 
783 			aAny <<= aBuffer;
784 		}
785 	}
786 
787 	try
788 	{
789 		OReleaseSolarMutex aReleaseForCallback;
790 		// clear the preview window
791 		xFilePicker->setImage( FilePreviewImageFormats::BITMAP, aAny );
792 	}
793 	catch( IllegalArgumentException )
794 	{
795 	}
796 
797 	return 0;
798 }
799 
800 // ------------------------------------------------------------------------
801 ErrCode FileDialogHelper_Impl::getGraphic( const OUString& rURL,
802 										   Graphic& rGraphic ) const
803 {
804 	if ( utl::UCBContentHelper::IsFolder( rURL ) )
805 		return ERRCODE_IO_NOTAFILE;
806 
807 	if ( !mpGraphicFilter )
808 		return ERRCODE_IO_NOTSUPPORTED;
809 
810 	// select graphic filter from dialog filter selection
811 	OUString aCurFilter( getFilter() );
812 
813 	sal_uInt16 nFilter = aCurFilter.getLength() && mpGraphicFilter->GetImportFormatCount()
814 					? mpGraphicFilter->GetImportFormatNumber( aCurFilter )
815 					: GRFILTER_FORMAT_DONTKNOW;
816 
817 	INetURLObject aURLObj( rURL );
818 
819 	if ( aURLObj.HasError() || INET_PROT_NOT_VALID == aURLObj.GetProtocol() )
820 	{
821 		aURLObj.SetSmartProtocol( INET_PROT_FILE );
822 		aURLObj.SetSmartURL( rURL );
823 	}
824 
825 	ErrCode nRet = ERRCODE_NONE;
826 
827 	sal_uInt32 nFilterImportFlags = GRFILTER_I_FLAGS_SET_LOGSIZE_FOR_JPEG;
828 	// non-local?
829 	if ( INET_PROT_FILE != aURLObj.GetProtocol() )
830 	{
831 		SvStream* pStream = ::utl::UcbStreamHelper::CreateStream( rURL, STREAM_READ );
832 
833 		if( pStream )
834 			nRet = mpGraphicFilter->ImportGraphic( rGraphic, rURL, *pStream, nFilter, NULL, nFilterImportFlags );
835 		else
836 			nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
837 		delete pStream;
838 	}
839 	else
840 	{
841 		nRet = mpGraphicFilter->ImportGraphic( rGraphic, aURLObj, nFilter, NULL, nFilterImportFlags );
842 	}
843 
844 	return nRet;
845 }
846 
847 // ------------------------------------------------------------------------
848 ErrCode FileDialogHelper_Impl::getGraphic( Graphic& rGraphic ) const
849 {
850 	ErrCode nRet = ERRCODE_NONE;
851 
852 	if ( ! maGraphic )
853 	{
854 		OUString aPath;;
855 		Sequence < OUString > aPathSeq = mxFileDlg->getFiles();
856 
857 		if ( aPathSeq.getLength() == 1 )
858 		{
859 			aPath = aPathSeq[0];
860 		}
861 
862 		if ( aPath.getLength() )
863 			nRet = getGraphic( aPath, rGraphic );
864 		else
865 			nRet = ERRCODE_IO_GENERAL;
866 	}
867 	else
868 		rGraphic = maGraphic;
869 
870 	return nRet;
871 }
872 
873 // ------------------------------------------------------------------------
874 sal_Bool lcl_isSystemFilePicker( const uno::Reference< XFilePicker >& _rxFP )
875 {
876 	try
877 	{
878 		uno::Reference< XServiceInfo > xSI( _rxFP, UNO_QUERY );
879 		if ( xSI.is() && xSI->supportsService( DEFINE_CONST_OUSTRING( "com.sun.star.ui.dialogs.SystemFilePicker" ) ) )
880 			return sal_True;
881 	}
882 	catch( const Exception& )
883 	{
884 	}
885 	return sal_False;
886 }
887 
888 
889 // ------------------------------------------------------------------------
890 // -----------		FileDialogHelper_Impl		---------------------------
891 // ------------------------------------------------------------------------
892 
893 FileDialogHelper_Impl::FileDialogHelper_Impl(
894 	FileDialogHelper* _pAntiImpl,
895 	sal_Int16 nDialogType,
896 	sal_Int64 nFlags,
897 	sal_Int16 nDialog,
898 	Window* _pPreferredParentWindow,
899 	const String& sStandardDir,
900 	const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList
901 	)
902 	:m_nDialogType			( nDialogType )
903 	,meContext				( FileDialogHelper::UNKNOWN_CONTEXT )
904 {
905 	const char* pServiceName=0;
906 	if ( nDialog == SFX2_IMPL_DIALOG_SYSTEM )
907 		pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
908 	else if ( nDialog == SFX2_IMPL_DIALOG_OOO )
909 		pServiceName = FILE_OPEN_SERVICE_NAME_OOO;
910 	else
911 		pServiceName = FILE_OPEN_SERVICE_NAME;
912 	OUString aService = ::rtl::OUString::createFromAscii( pServiceName );
913 
914 	uno::Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
915 
916 	// create the file open dialog
917 	// the flags can be SFXWB_INSERT or SFXWB_MULTISELECTION
918 
919 	mpPreferredParentWindow = _pPreferredParentWindow;
920 	mpAntiImpl				= _pAntiImpl;
921 	mnError 				= ERRCODE_NONE;
922 	mbHasAutoExt			= sal_False;
923 	mbHasPassword			= sal_False;
924 	m_bHaveFilterOptions	= sal_False;
925 	mbIsPwdEnabled			= sal_True;
926 	mbHasVersions			= sal_False;
927 	mbHasPreview			= sal_False;
928 	mbShowPreview			= sal_False;
929 	mbHasLink				= sal_False;
930 	mbDeleteMatcher 		= sal_False;
931 	mbInsert				= SFXWB_INSERT == ( nFlags & SFXWB_INSERT );
932 	mbExport				= SFXWB_EXPORT == ( nFlags & SFXWB_EXPORT );
933 	mbIsSaveDlg 			= sal_False;
934 	mbPwdCheckBoxState		= sal_False;
935 	mbSelection				= sal_False;
936 	mbSelectionEnabled		= sal_True;
937 	mbHasSelectionBox       = sal_False;
938 	mbSelectionFltrEnabled  = sal_False;
939 
940 	// default settings
941     m_nDontFlags = SFX_FILTER_INTERNAL | SFX_FILTER_NOTINFILEDLG | SFX_FILTER_NOTINSTALLED;
942 	if( WB_OPEN == ( nFlags & WB_OPEN ) )
943 		m_nMustFlags = SFX_FILTER_IMPORT;
944 	else
945 		m_nMustFlags = SFX_FILTER_EXPORT;
946 
947 
948 	mpMatcher = NULL;
949 	mpGraphicFilter = NULL;
950 	mnPostUserEventId = 0;
951 
952 	// create the picker component
953 	mxFileDlg = mxFileDlg.query( xFactory->createInstance( aService ) );
954 	mbSystemPicker = lcl_isSystemFilePicker( mxFileDlg );
955 
956 	uno::Reference< XFilePickerNotifier > xNotifier( mxFileDlg, UNO_QUERY );
957 	uno::Reference< XInitialization > xInit( mxFileDlg, UNO_QUERY );
958 
959 	if ( ! mxFileDlg.is() || ! xNotifier.is() )
960 	{
961 		mnError = ERRCODE_ABORT;
962 		return;
963 	}
964 
965 
966 	if ( xInit.is() )
967 	{
968 		sal_Int16 nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
969 
970 		switch ( m_nDialogType )
971 		{
972 			case FILEOPEN_SIMPLE:
973 				nTemplateDescription = TemplateDescription::FILEOPEN_SIMPLE;
974 				break;
975 
976 			case FILESAVE_SIMPLE:
977 				nTemplateDescription = TemplateDescription::FILESAVE_SIMPLE;
978 				mbIsSaveDlg = sal_True;
979 				break;
980 
981 			case FILESAVE_AUTOEXTENSION_PASSWORD:
982 				nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD;
983 				mbHasPassword = sal_True;
984 				mbHasAutoExt = sal_True;
985 				mbIsSaveDlg = sal_True;
986 				break;
987 
988 			case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
989 				nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS;
990 				mbHasPassword = sal_True;
991 
992 				m_bHaveFilterOptions = sal_True;
993 				if( xFactory.is() )
994 				{
995 					mxFilterCFG = uno::Reference< XNameAccess >(
996 						xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ),
997 						UNO_QUERY );
998 				}
999 
1000 				mbHasAutoExt = sal_True;
1001 				mbIsSaveDlg = sal_True;
1002 				break;
1003 
1004 			case FILESAVE_AUTOEXTENSION_SELECTION:
1005 				nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION;
1006 				mbHasAutoExt = sal_True;
1007 				mbIsSaveDlg = sal_True;
1008 				mbHasSelectionBox = sal_True;
1009 				if ( mbExport && !mxFilterCFG.is() && xFactory.is() )
1010 				{
1011 					mxFilterCFG = uno::Reference< XNameAccess >(
1012 						xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.document.FilterFactory" ) ),
1013 						UNO_QUERY );
1014 				}
1015 				break;
1016 
1017 			case FILESAVE_AUTOEXTENSION_TEMPLATE:
1018 				nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE;
1019 				mbHasAutoExt = sal_True;
1020 				mbIsSaveDlg = sal_True;
1021 				break;
1022 
1023 			case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
1024 				nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
1025 				mbHasPreview = sal_True;
1026 				mbHasLink = sal_True;
1027 
1028 				// aPreviewTimer
1029 				maPreViewTimer.SetTimeout( 500 );
1030 				maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1031 				break;
1032 
1033 			case FILEOPEN_PLAY:
1034 				nTemplateDescription = TemplateDescription::FILEOPEN_PLAY;
1035 				break;
1036 
1037 			case FILEOPEN_READONLY_VERSION:
1038 				nTemplateDescription = TemplateDescription::FILEOPEN_READONLY_VERSION;
1039 				mbHasVersions = sal_True;
1040 				break;
1041 
1042 			case FILEOPEN_LINK_PREVIEW:
1043 				nTemplateDescription = TemplateDescription::FILEOPEN_LINK_PREVIEW;
1044 				mbHasPreview = sal_True;
1045 				mbHasLink = sal_True;
1046 				// aPreviewTimer
1047 				maPreViewTimer.SetTimeout( 500 );
1048 				maPreViewTimer.SetTimeoutHdl( LINK( this, FileDialogHelper_Impl, TimeOutHdl_Impl ) );
1049 				break;
1050 
1051 			case FILESAVE_AUTOEXTENSION:
1052 				nTemplateDescription = TemplateDescription::FILESAVE_AUTOEXTENSION;
1053 				mbHasAutoExt = sal_True;
1054 				mbIsSaveDlg = sal_True;
1055 				break;
1056 
1057 			default:
1058 				DBG_ERRORFILE( "FileDialogHelper::ctor with unknown type" );
1059 				break;
1060 		}
1061 
1062 
1063 
1064 		//Sequence < Any > aInitArguments( mbSystemPicker || !mpPreferredParentWindow ? 1 : 3 );
1065 		Sequence < Any > aInitArguments( !mpPreferredParentWindow ? 3 : 4 );
1066 
1067 		// This is a hack. We currently know that the internal file picker implementation
1068 		// supports the extended arguments as specified below.
1069         // TODO:
1070 		// a) adjust the service description so that it includes the TemplateDescription and ParentWindow args
1071 		// b) adjust the implementation of the system file picker to that it recognizes it
1072 		if ( mbSystemPicker )
1073 		{
1074 			aInitArguments[0] <<= nTemplateDescription;
1075 		}
1076 		else
1077 		{
1078 			aInitArguments[0] <<= NamedValue(
1079 									::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "TemplateDescription" ) ),
1080 									makeAny( nTemplateDescription )
1081 								);
1082 
1083 			::rtl::OUString sStandardDirTemp = ::rtl::OUString( sStandardDir );
1084 
1085 			aInitArguments[1] <<= NamedValue(
1086 									::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StandardDir" ) ),
1087 									makeAny( sStandardDirTemp )
1088 								);
1089 
1090 			aInitArguments[2] <<= NamedValue(
1091 									::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BlackList" ) ),
1092 									makeAny( rBlackList )
1093 								);
1094 
1095 
1096 			if ( mpPreferredParentWindow )
1097 				aInitArguments[3] <<= NamedValue(
1098 										::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParentWindow" ) ),
1099 										makeAny( VCLUnoHelper::GetInterface( mpPreferredParentWindow ) )
1100 									);
1101 
1102 
1103 		}
1104 
1105 		try
1106 		{
1107 			xInit->initialize( aInitArguments );
1108 		}
1109 		catch( const Exception& )
1110 		{
1111 			DBG_ERROR( "FileDialogHelper_Impl::FileDialogHelper_Impl: could not initialize the picker!" );
1112 		}
1113 	}
1114 
1115 
1116 	// set multiselection mode
1117 	if ( nFlags & SFXWB_MULTISELECTION )
1118 		mxFileDlg->setMultiSelectionMode( sal_True );
1119 
1120 	if ( mbHasLink )		// generate graphic filter only on demand
1121 		addGraphicFilter();
1122 
1123 	// Export dialog
1124 	if ( mbExport )
1125 	{
1126 		mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_EXPORT ) ) ) );
1127 		try {
1128                 com::sun::star::uno::Reference < XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY_THROW );
1129 				xCtrlAccess->enableControl( ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR, sal_True );
1130 		}
1131 		catch( const Exception & ) { }
1132 	}
1133 
1134 	// the "insert file" dialog needs another title
1135 	if ( mbInsert )
1136 	{
1137 		mxFileDlg->setTitle( OUString( String( SfxResId( STR_SFX_EXPLORERFILE_INSERT ) ) ) );
1138 		uno::Reference < XFilePickerControlAccess > xExtDlg( mxFileDlg, UNO_QUERY );
1139 		if ( xExtDlg.is() )
1140 		{
1141 			try
1142 			{
1143 				xExtDlg->setLabel( CommonFilePickerElementIds::PUSHBUTTON_OK,
1144 								   OUString( String( SfxResId( STR_SFX_EXPLORERFILE_BUTTONINSERT ) ) ) );
1145 			}
1146 			catch( IllegalArgumentException ){}
1147 		}
1148 	}
1149 
1150 	// add the event listener
1151 	xNotifier->addFilePickerListener( this );
1152 }
1153 
1154 // ------------------------------------------------------------------------
1155 FileDialogHelper_Impl::~FileDialogHelper_Impl()
1156 {
1157 	// Remove user event if we haven't received it yet
1158 	if ( mnPostUserEventId )
1159 		Application::RemoveUserEvent( mnPostUserEventId );
1160 	mnPostUserEventId = 0;
1161 
1162 	delete mpGraphicFilter;
1163 
1164 	if ( mbDeleteMatcher )
1165 		delete mpMatcher;
1166 
1167 	maPreViewTimer.SetTimeoutHdl( Link() );
1168 
1169 	::comphelper::disposeComponent( mxFileDlg );
1170 }
1171 
1172 #define nMagic -1
1173 
1174 class PickerThread_Impl : public ::vos::OThread
1175 {
1176 	uno::Reference < XFilePicker > mxPicker;
1177 	::vos::OMutex			maMutex;
1178 	virtual void SAL_CALL	run();
1179 	sal_Int16				mnRet;
1180 public:
1181 							PickerThread_Impl( const uno::Reference < XFilePicker >& rPicker )
1182 							: mxPicker( rPicker ), mnRet(nMagic) {}
1183 
1184 	sal_Int16				GetReturnValue()
1185 							{ ::vos::OGuard aGuard( maMutex ); return mnRet; }
1186 
1187 	void					SetReturnValue( sal_Int16 aRetValue )
1188 							{ ::vos::OGuard aGuard( maMutex ); mnRet = aRetValue; }
1189 };
1190 
1191 void SAL_CALL PickerThread_Impl::run()
1192 {
1193 	try
1194 	{
1195 		sal_Int16 n = mxPicker->execute();
1196 		SetReturnValue( n );
1197 	}
1198 	catch( RuntimeException& )
1199 	{
1200 		SetReturnValue( ExecutableDialogResults::CANCEL );
1201 		DBG_ERRORFILE( "RuntimeException caught" );
1202 	}
1203 }
1204 
1205 // ------------------------------------------------------------------------
1206 void FileDialogHelper_Impl::setControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
1207 {
1208 	DBG_ASSERT( _pControlId && _pHelpId, "FileDialogHelper_Impl::setControlHelpIds: invalid array pointers!" );
1209 	if ( !_pControlId || !_pHelpId )
1210 		return;
1211 
1212 	// forward these ids to the file picker
1213 	try
1214 	{
1215 		const ::rtl::OUString sHelpIdPrefix( RTL_CONSTASCII_USTRINGPARAM( INET_HID_SCHEME ) );
1216 		// the ids for the single controls
1217 		uno::Reference< XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1218 		if ( xControlAccess.is() )
1219 		{
1220 			while ( *_pControlId )
1221 			{
1222                 DBG_ASSERT( INetURLObject( rtl::OStringToOUString( *_pHelpId, RTL_TEXTENCODING_UTF8 ) ).GetProtocol() == INET_PROT_NOT_VALID, "Wrong HelpId!" );
1223 				::rtl::OUString sId( sHelpIdPrefix );
1224 				sId += ::rtl::OUString( *_pHelpId, strlen( *_pHelpId ), RTL_TEXTENCODING_UTF8 );
1225 				xControlAccess->setValue( *_pControlId, ControlActions::SET_HELP_URL, makeAny( sId ) );
1226 
1227 				++_pControlId; ++_pHelpId;
1228 			}
1229 		}
1230 	}
1231 	catch( const Exception& )
1232 	{
1233 		DBG_ERROR( "FileDialogHelper_Impl::setControlHelpIds: caught an exception while setting the help ids!" );
1234 	}
1235 }
1236 
1237 // ------------------------------------------------------------------------
1238 IMPL_LINK( FileDialogHelper_Impl, InitControls, void*, NOTINTERESTEDIN )
1239 {
1240     (void)NOTINTERESTEDIN;
1241     mnPostUserEventId = 0;
1242 	enablePasswordBox( sal_True );
1243 	updateFilterOptionsBox( );
1244 	updateSelectionBox( );
1245 
1246     return 0L;
1247 }
1248 
1249 // ------------------------------------------------------------------------
1250 void FileDialogHelper_Impl::preExecute()
1251 {
1252 	loadConfig( );
1253 	setDefaultValues( );
1254 	updatePreviewState( sal_False );
1255 
1256 	implInitializeFileName( );
1257 	// #106079# / 2002-12-09 / fs@openoffice.org
1258 
1259 #if !(defined(MACOSX) && defined(QUARTZ)) && !defined(WNT)
1260 	// allow for dialog implementations which need to be executed before they return valid values for
1261 	// current filter and such
1262 
1263 	// On Vista (at least SP1) it's the same as on MacOSX, the modal dialog won't let message pass
1264 	// through before it returns from execution
1265     mnPostUserEventId = Application::PostUserEvent( LINK( this, FileDialogHelper_Impl, InitControls ) );
1266 #else
1267 	// However, the Mac OS X implementation's pickers run modally in execute and so the event doesn't
1268 	// get through in time... so we call the methods directly
1269     enablePasswordBox( sal_True );
1270 	updateFilterOptionsBox( );
1271 	updateSelectionBox( );
1272 #endif
1273 }
1274 
1275 // ------------------------------------------------------------------------
1276 void FileDialogHelper_Impl::postExecute( sal_Int16 _nResult )
1277 {
1278 	if ( ExecutableDialogResults::CANCEL != _nResult )
1279 		saveConfig();
1280 }
1281 
1282 // ------------------------------------------------------------------------
1283 void FileDialogHelper_Impl::implInitializeFileName( )
1284 {
1285 	if ( maFileName.getLength() )
1286 	{
1287 		INetURLObject aObj( maPath );
1288 		aObj.Append( maFileName );
1289 
1290 		// in case we're operating as save dialog, and "auto extension" is checked,
1291 		// cut the extension from the name
1292 		// #106079# / 2002-12-09 / fs@openoffice.org
1293 		if ( mbIsSaveDlg && mbHasAutoExt )
1294 		{
1295 			try
1296 			{
1297 				sal_Bool bAutoExtChecked = sal_False;
1298 
1299 				uno::Reference < XFilePickerControlAccess > xControlAccess( mxFileDlg, UNO_QUERY );
1300 				if	(	xControlAccess.is()
1301 					&&	(	xControlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 )
1302 						>>=	bAutoExtChecked
1303 						)
1304 					)
1305 				{
1306 					if ( bAutoExtChecked )
1307 					{	// cut the extension
1308 						aObj.removeExtension( );
1309 						mxFileDlg->setDefaultName( aObj.GetName( INetURLObject::DECODE_WITH_CHARSET ) );
1310 					}
1311 				}
1312 			}
1313 			catch( const Exception& )
1314 			{
1315 				DBG_ERROR( "FileDialogHelper_Impl::implInitializeFileName: could not ask for the auto-extension current-value!" );
1316 			}
1317 		}
1318 	}
1319 }
1320 
1321 // ------------------------------------------------------------------------
1322 sal_Int16 FileDialogHelper_Impl::implDoExecute()
1323 {
1324 	preExecute();
1325 
1326 	sal_Int16 nRet = ExecutableDialogResults::CANCEL;
1327 
1328 //On MacOSX the native file picker has to run in the primordial thread because of drawing issues
1329 //On Linux the native gtk file picker, when backed by gnome-vfs2, needs to be run in the same
1330 //primordial thread as the ucb gnome-vfs2 provider was initialized in.
1331 /*
1332 #ifdef WNT
1333 	if ( mbSystemPicker )
1334 	{
1335 		PickerThread_Impl* pThread = new PickerThread_Impl( mxFileDlg );
1336 		pThread->create();
1337 		while ( pThread->GetReturnValue() == nMagic )
1338 			Application::Yield();
1339 		pThread->join();
1340 		nRet = pThread->GetReturnValue();
1341 		delete pThread;
1342 	}
1343 	else
1344 #endif
1345 */
1346 	{
1347 		try
1348 		{
1349 #ifdef WNT
1350             if ( mbSystemPicker )
1351             {
1352                 OReleaseSolarMutex aSolarMutex;
1353                 nRet = mxFileDlg->execute();
1354             }
1355             else
1356 #endif
1357             nRet = mxFileDlg->execute();
1358 		}
1359 		catch( const Exception& )
1360 		{
1361 			DBG_ERRORFILE( "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1362 		}
1363 	}
1364 
1365 	postExecute( nRet );
1366 
1367 	return nRet;
1368 }
1369 
1370 // ------------------------------------------------------------------------
1371 void FileDialogHelper_Impl::implStartExecute()
1372 {
1373     DBG_ASSERT( mxFileDlg.is(), "invalid file dialog" );
1374 
1375     preExecute();
1376 
1377     if ( mbSystemPicker )
1378     {
1379     }
1380     else
1381     {
1382         try
1383         {
1384             uno::Reference< XAsynchronousExecutableDialog > xAsyncDlg( mxFileDlg, UNO_QUERY );
1385             if ( xAsyncDlg.is() )
1386                 xAsyncDlg->startExecuteModal( this );
1387         }
1388         catch( const Exception& )
1389         {
1390             DBG_ERRORFILE( "FileDialogHelper_Impl::implDoExecute: caught an exception!" );
1391         }
1392     }
1393 }
1394 
1395 // ------------------------------------------------------------------------
1396 String FileDialogHelper_Impl::implEnsureURLExtension(const String& sURL,
1397 													 const String& /*sExtension*/)
1398 {
1399     return sURL;
1400     /*
1401 	// This feature must be active for file save/export only !
1402 	if (
1403 		(! mbIsSaveDlg) &&
1404 		(! mbExport   )
1405 		)
1406 		return sURL;
1407 
1408 	// no extension available (because "ALL *.*" was selected) ?
1409 	// Nod idea what else should happen here .-)
1410 	if (sExtension.Len() < 1)
1411 		return sURL;
1412 
1413 	// Some FilePicker implementations already add the right extension ...
1414 	// or might be the user used the right one already ...
1415 	// Dont create duplicate extension.
1416 	INetURLObject aURL(sURL);
1417 	if (aURL.getExtension().equals(sExtension))
1418 		return sURL;
1419 
1420 	// Ignore any other extension set by the user.
1421 	// Make sure suitable extension is used always.
1422 	// e.g. "test.bla.odt" for "ODT"
1423 	::rtl::OUStringBuffer sNewURL(256);
1424 	sNewURL.append     (sURL      );
1425 	sNewURL.appendAscii("."       );
1426 	sNewURL.append     (sExtension);
1427 	return sNewURL.makeStringAndClear();
1428     */
1429 }
1430 
1431 // ------------------------------------------------------------------------
1432 void lcl_saveLastURLs(SvStringsDtor*&                                    rpURLList ,
1433                       ::comphelper::SequenceAsVector< ::rtl::OUString >& lLastURLs )
1434 {
1435     lLastURLs.clear();
1436     sal_uInt16 c = rpURLList->Count();
1437     sal_uInt16 i = 0;
1438     for (i=0; i<c; ++i)
1439         lLastURLs.push_back(*(rpURLList->GetObject(i)));
1440 }
1441 
1442 // ------------------------------------------------------------------------
1443 void FileDialogHelper_Impl::implGetAndCacheFiles(const uno::Reference< XInterface >& xPicker  ,
1444 													   SvStringsDtor*&               rpURLList,
1445 												 const SfxFilter*                    pFilter  )
1446 {
1447     rpURLList = NULL;
1448 
1449 	String sExtension;
1450 	if (pFilter)
1451 	{
1452 		sExtension = pFilter->GetDefaultExtension ();
1453 		sExtension.EraseAllChars( '*' );
1454 		sExtension.EraseAllChars( '.' );
1455 	}
1456 
1457     // a) the new way (optional!)
1458     uno::Reference< XFilePicker2 > xPickNew(xPicker, UNO_QUERY);
1459     if (xPickNew.is())
1460     {
1461                              rpURLList = new SvStringsDtor;
1462         Sequence< OUString > lFiles    = xPickNew->getSelectedFiles();
1463         ::sal_Int32          nFiles    = lFiles.getLength();
1464         for (::sal_Int32 i = 0; i < nFiles; i++)
1465         {
1466 			String* pURL = new String(implEnsureURLExtension(lFiles[i], sExtension));
1467             rpURLList->Insert( pURL, rpURLList->Count() );
1468         }
1469     }
1470 
1471     // b) the olde way ... non optional.
1472     else
1473     {
1474         uno::Reference< XFilePicker > xPickOld(xPicker, UNO_QUERY_THROW);
1475         Sequence< OUString > lFiles = xPickOld->getFiles();
1476         ::sal_Int32          nFiles = lFiles.getLength();
1477         if ( nFiles == 1 )
1478         {
1479                     rpURLList = new SvStringsDtor;
1480 			String* pURL      = new String(implEnsureURLExtension(lFiles[0], sExtension));
1481             rpURLList->Insert( pURL, 0 );
1482         }
1483         else
1484         if ( nFiles > 1 )
1485         {
1486             rpURLList = new SvStringsDtor;
1487 
1488             INetURLObject aPath( lFiles[0] );
1489             aPath.setFinalSlash();
1490 
1491             for (::sal_Int32 i = 1; i < nFiles; i++)
1492             {
1493                 if (i == 1)
1494                     aPath.Append( lFiles[i] );
1495                 else
1496                     aPath.setName( lFiles[i] );
1497 
1498                 String* pURL = new String(implEnsureURLExtension(aPath.GetMainURL( INetURLObject::NO_DECODE ), sExtension) );
1499                 rpURLList->Insert( pURL, rpURLList->Count() );
1500             }
1501         }
1502     }
1503 
1504 	lcl_saveLastURLs(rpURLList, mlLastURLs);
1505 }
1506 
1507 // ------------------------------------------------------------------------
1508 ErrCode FileDialogHelper_Impl::execute( SvStringsDtor*& rpURLList,
1509 										SfxItemSet *&	rpSet,
1510 										String& 		rFilter )
1511 {
1512     // rFilter is a pure output parameter, it shouldn't be used for anything else
1513     // changing this would surely break code
1514     // rpSet is in/out parameter, usually just a media-descriptor that can be changed by dialog
1515 
1516 	uno::Reference< XFilePickerControlAccess > xCtrlAccess( mxFileDlg, UNO_QUERY );
1517 
1518 	// retrieves parameters from rpSet
1519 	// for now only Password is used
1520 	if ( rpSet )
1521 	{
1522 		// check password checkbox if the document had password before
1523 		if( mbHasPassword )
1524 		{
1525 			SFX_ITEMSET_ARG( rpSet, pPassItem, SfxBoolItem, SID_PASSWORDINTERACTION, sal_False );
1526 			mbPwdCheckBoxState = ( pPassItem != NULL && pPassItem->GetValue() );
1527 
1528             // in case the document has password to modify, the dialog should be shown
1529 			SFX_ITEMSET_ARG( rpSet, pPassToModifyItem, SfxUnoAnyItem, SID_MODIFYPASSWORDINFO, sal_False );
1530             mbPwdCheckBoxState |= ( pPassToModifyItem && pPassToModifyItem->GetValue().hasValue() );
1531 		}
1532 
1533 		SFX_ITEMSET_ARG( rpSet, pSelectItem, SfxBoolItem, SID_SELECTION, sal_False );
1534 		if ( pSelectItem )
1535 			mbSelection = pSelectItem->GetValue();
1536 		else
1537 			mbSelectionEnabled = sal_False;
1538 
1539 		// the password will be set in case user decide so
1540 		rpSet->ClearItem( SID_PASSWORDINTERACTION );
1541 		rpSet->ClearItem( SID_PASSWORD );
1542 		rpSet->ClearItem( SID_ENCRYPTIONDATA );
1543         rpSet->ClearItem( SID_RECOMMENDREADONLY );
1544         rpSet->ClearItem( SID_MODIFYPASSWORDINFO );
1545 
1546 	}
1547 
1548 	if ( mbHasPassword && !mbPwdCheckBoxState )
1549 	{
1550 		SvtSecurityOptions aSecOpt;
1551 		mbPwdCheckBoxState = (
1552 			aSecOpt.IsOptionSet( SvtSecurityOptions::E_DOCWARN_RECOMMENDPASSWORD ) );
1553 	}
1554 
1555 	rpURLList = NULL;
1556 
1557 	if ( ! mxFileDlg.is() )
1558 		return ERRCODE_ABORT;
1559 
1560 	if ( ExecutableDialogResults::CANCEL != implDoExecute() )
1561 	{
1562 		// create an itemset if there is no
1563 		if( !rpSet )
1564 			rpSet = new SfxAllItemSet( SFX_APP()->GetPool() );
1565 
1566         // the item should remain only if it was set by the dialog
1567         rpSet->ClearItem( SID_SELECTION );
1568 
1569 		if( mbExport && mbHasSelectionBox )
1570 		{
1571 			try
1572 			{
1573 				Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
1574 				sal_Bool bSelection = sal_False;
1575 				if ( aValue >>= bSelection )
1576 					rpSet->Put( SfxBoolItem( SID_SELECTION, bSelection ) );
1577 			}
1578 			catch( IllegalArgumentException )
1579 			{
1580 				DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1581 			}
1582 		}
1583 
1584 
1585 		// set the read-only flag. When inserting a file, this flag is always set
1586 		if ( mbInsert )
1587 			rpSet->Put( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
1588 		else
1589 		{
1590 			if ( ( FILEOPEN_READONLY_VERSION == m_nDialogType ) && xCtrlAccess.is() )
1591 			{
1592 				try
1593 				{
1594 					Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_READONLY, 0 );
1595 					sal_Bool bReadOnly = sal_False;
1596 					if ( ( aValue >>= bReadOnly ) && bReadOnly )
1597 						rpSet->Put( SfxBoolItem( SID_DOC_READONLY, bReadOnly ) );
1598 				}
1599 				catch( IllegalArgumentException )
1600 				{
1601 					DBG_ERROR( "FileDialogHelper_Impl::execute: caught an IllegalArgumentException!" );
1602 				}
1603 			}
1604 		}
1605 		if ( mbHasVersions && xCtrlAccess.is() )
1606 		{
1607 			try
1608 			{
1609 				Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::LISTBOX_VERSION,
1610 													ControlActions::GET_SELECTED_ITEM_INDEX );
1611 				sal_Int32 nVersion = 0;
1612 				if ( ( aValue >>= nVersion ) && nVersion > 0 )
1613 					// open a special version; 0 == current version
1614 					rpSet->Put( SfxInt16Item( SID_VERSION, (short)nVersion ) );
1615 			}
1616 			catch( IllegalArgumentException ){}
1617 		}
1618 
1619 		// set the filter
1620 		getRealFilter( rFilter );
1621 
1622         const SfxFilter* pCurrentFilter = getCurentSfxFilter();
1623 
1624 		// fill the rpURLList
1625 		implGetAndCacheFiles( mxFileDlg, rpURLList, pCurrentFilter );
1626 		if ( rpURLList == NULL || rpURLList->GetObject(0) == NULL )
1627 			return ERRCODE_ABORT;
1628 
1629 		// check, wether or not we have to display a password box
1630 		if ( pCurrentFilter && mbHasPassword && mbIsPwdEnabled && xCtrlAccess.is() )
1631 		{
1632 			try
1633 			{
1634 				Any aValue = xCtrlAccess->getValue( ExtendedFilePickerElementIds::CHECKBOX_PASSWORD, 0 );
1635 				sal_Bool bPassWord = sal_False;
1636 				if ( ( aValue >>= bPassWord ) && bPassWord )
1637 				{
1638 					// ask for a password
1639                     uno::Reference < ::com::sun::star::task::XInteractionHandler > xInteractionHandler( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
1640 
1641                     if( xInteractionHandler.is() )
1642                     {
1643                         // TODO: need a save way to distinguish MS filters from other filters
1644                         // for now MS-filters are the only alien filters that support encryption
1645                         sal_Bool bMSType = !pCurrentFilter->IsOwnFormat();
1646                         ::comphelper::DocPasswordRequestType eType = bMSType ?
1647                             ::comphelper::DocPasswordRequestType_MS :
1648                             ::comphelper::DocPasswordRequestType_STANDARD;
1649 
1650                         ::rtl::Reference< ::comphelper::DocPasswordRequest > pPasswordRequest( new ::comphelper::DocPasswordRequest( eType, ::com::sun::star::task::PasswordRequestMode_PASSWORD_CREATE, *(rpURLList->GetObject(0)), ( pCurrentFilter->GetFilterFlags() & SFX_FILTER_PASSWORDTOMODIFY ) != 0 ) );
1651 
1652                         uno::Reference< com::sun::star::task::XInteractionRequest > rRequest( pPasswordRequest.get() );
1653                         xInteractionHandler->handle( rRequest );
1654                         if ( pPasswordRequest->isPassword() )
1655                         {
1656                             if ( pPasswordRequest->getPassword().getLength() )
1657                             {
1658                                 // TODO/LATER: The filters should show the password dialog themself in future
1659                                 if ( bMSType )
1660                                 {
1661                                     // all the current MS-filters use MSCodec_Std97 implementation
1662                                     uno::Sequence< sal_Int8 > aUniqueID = ::comphelper::DocPasswordHelper::GenerateRandomByteSequence( 16 );
1663                                     uno::Sequence< sal_Int8 > aEncryptionKey = ::comphelper::DocPasswordHelper::GenerateStd97Key( pPasswordRequest->getPassword(), aUniqueID );
1664 
1665                                     if ( aEncryptionKey.getLength() )
1666                                     {
1667                                         ::comphelper::SequenceAsHashMap aHashData;
1668                                         aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97EncryptionKey" ) ) ] <<= aEncryptionKey;
1669                                         aHashData[ ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "STD97UniqueID" ) ) ] <<= aUniqueID;
1670 
1671                                         rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aHashData.getAsConstNamedValueList() ) ) );
1672                                     }
1673                                     else
1674                                         return ERRCODE_IO_NOTSUPPORTED;
1675                                 }
1676                                 else
1677                                 {
1678                                     rpSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( ::comphelper::OStorageHelper::CreatePackageEncryptionData( pPasswordRequest->getPassword() ) ) ) );
1679                                 }
1680                             }
1681 
1682                             if ( pPasswordRequest->getRecommendReadOnly() )
1683                                 rpSet->Put( SfxBoolItem( SID_RECOMMENDREADONLY, sal_True ) );
1684 
1685                             if ( bMSType )
1686                             {
1687                                 // the empty password has 0 as Hash
1688                                 sal_Int32 nHash = SfxMedium::CreatePasswordToModifyHash( pPasswordRequest->getPasswordToModify(), ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ).equals( pCurrentFilter->GetServiceName() ) );
1689                                 if ( nHash )
1690                                     rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( nHash ) ) );
1691                             }
1692                             else
1693                             {
1694                                 uno::Sequence< beans::PropertyValue > aModifyPasswordInfo = ::comphelper::DocPasswordHelper::GenerateNewModifyPasswordInfo( pPasswordRequest->getPasswordToModify() );
1695                                 if ( aModifyPasswordInfo.getLength() )
1696                                     rpSet->Put( SfxUnoAnyItem( SID_MODIFYPASSWORDINFO, uno::makeAny( aModifyPasswordInfo ) ) );
1697                             }
1698                         }
1699                         else
1700                             return ERRCODE_ABORT;
1701                     }
1702 				}
1703 			}
1704 			catch( IllegalArgumentException ){}
1705 		}
1706 
1707         SaveLastUsedFilter();
1708         return ERRCODE_NONE;
1709 	}
1710 	else
1711 		return ERRCODE_ABORT;
1712 }
1713 
1714 // ------------------------------------------------------------------------
1715 ErrCode FileDialogHelper_Impl::execute()
1716 {
1717 	if ( ! mxFileDlg.is() )
1718 		return ERRCODE_ABORT;
1719 
1720 	sal_Int16 nRet = implDoExecute();
1721 
1722 	maPath = mxFileDlg->getDisplayDirectory();
1723 
1724 	if ( ExecutableDialogResults::CANCEL == nRet )
1725 		return ERRCODE_ABORT;
1726 	else
1727 	{
1728 		return ERRCODE_NONE;
1729 	}
1730 }
1731 
1732 // ------------------------------------------------------------------------
1733 OUString FileDialogHelper_Impl::getPath() const
1734 {
1735 	OUString aPath;
1736 
1737 	if ( mxFileDlg.is() )
1738 		aPath = mxFileDlg->getDisplayDirectory();
1739 
1740 	if ( !aPath.getLength() )
1741 		aPath = maPath;
1742 
1743 	return aPath;
1744 }
1745 
1746 // ------------------------------------------------------------------------
1747 OUString FileDialogHelper_Impl::getFilter() const
1748 {
1749 	String aFilter = getCurrentFilterUIName();
1750 
1751 	if( !aFilter.Len() )
1752 		aFilter = maCurFilter;
1753 
1754 	return aFilter;
1755 }
1756 
1757 // ------------------------------------------------------------------------
1758 void FileDialogHelper_Impl::getRealFilter( String& _rFilter ) const
1759 {
1760 	_rFilter = getCurrentFilterUIName();
1761 
1762 	if ( !_rFilter.Len() )
1763 		_rFilter = maCurFilter;
1764 
1765 	if ( _rFilter.Len() && mpMatcher )
1766 	{
1767 		const SfxFilter* pFilter =
1768 			mpMatcher->GetFilter4UIName( _rFilter, m_nMustFlags, m_nDontFlags );
1769 		_rFilter = pFilter ? pFilter->GetFilterName() : _rFilter.Erase();
1770 	}
1771 }
1772 
1773 // ------------------------------------------------------------------------
1774 void FileDialogHelper_Impl::displayFolder( const ::rtl::OUString& _rPath )
1775 {
1776 	if ( ! _rPath.getLength() )
1777 		// nothing to do
1778 		return;
1779 
1780 	/*
1781 	if ( !::utl::UCBContentHelper::IsFolder( _rPath ) )
1782 		// only valid folders accepted here
1783 		return;
1784 	*/
1785 
1786 	maPath = _rPath;
1787 	if ( mxFileDlg.is() )
1788 	{
1789 		try
1790 		{
1791 			mxFileDlg->setDisplayDirectory( maPath );
1792 		}
1793 		catch( const IllegalArgumentException& )
1794 		{
1795 			DBG_ERROR( "FileDialogHelper_Impl::displayFolder: caught an exception!" );
1796 		}
1797 	}
1798 }
1799 
1800 // ------------------------------------------------------------------------
1801 void FileDialogHelper_Impl::setFileName( const ::rtl::OUString& _rFile )
1802 {
1803 	maFileName = _rFile;
1804 	if ( mxFileDlg.is() )
1805 	{
1806 		try
1807 		{
1808 			mxFileDlg->setDefaultName( maFileName );
1809 		}
1810 		catch( const IllegalArgumentException& )
1811 		{
1812 			DBG_ERROR( "FileDialogHelper_Impl::setFileName: caught an exception!" );
1813 		}
1814 	}
1815 }
1816 
1817 // ------------------------------------------------------------------------
1818 void FileDialogHelper_Impl::setFilter( const OUString& rFilter )
1819 {
1820 	DBG_ASSERT( rFilter.indexOf(':') == -1, "Old filter name used!");
1821 
1822 	maCurFilter = rFilter;
1823 
1824 	if ( rFilter.getLength() && mpMatcher )
1825 	{
1826 		const SfxFilter* pFilter = mpMatcher->GetFilter4FilterName(
1827 										rFilter, m_nMustFlags, m_nDontFlags );
1828 		if ( pFilter )
1829 			maCurFilter = pFilter->GetUIName();
1830 	}
1831 
1832 	uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1833 
1834 	if ( maCurFilter.getLength() && xFltMgr.is() )
1835 	{
1836 		try
1837 		{
1838 			xFltMgr->setCurrentFilter( maCurFilter );
1839 		}
1840 		catch( IllegalArgumentException ){}
1841 	}
1842 }
1843 
1844 // ------------------------------------------------------------------------
1845 void FileDialogHelper_Impl::createMatcher( const String& rFactory )
1846 {
1847 	mpMatcher = new SfxFilterMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
1848 	mbDeleteMatcher = sal_True;
1849 }
1850 
1851 // ------------------------------------------------------------------------
1852 void FileDialogHelper_Impl::addFilters( sal_Int64 nFlags,
1853 										const String& rFactory,
1854 										SfxFilterFlags nMust,
1855 										SfxFilterFlags nDont )
1856 {
1857 	uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1858 
1859 	if ( ! xFltMgr.is() )
1860 		return;
1861 
1862     // we still need a matcher to convert UI names to filter names
1863     if ( !rFactory.Len() )
1864     {
1865         SfxApplication *pSfxApp = SFX_APP();
1866         mpMatcher = &pSfxApp->GetFilterMatcher();
1867         mbDeleteMatcher = sal_False;
1868     }
1869     else
1870     {
1871         mpMatcher = new SfxFilterMatcher( rFactory );
1872         mbDeleteMatcher = sal_True;
1873     }
1874 
1875     uno::Reference< XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
1876     uno::Reference< XContainerQuery > xFilterCont(
1877         xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory")),
1878         UNO_QUERY);
1879     if ( ! xFilterCont.is() )
1880         return;
1881 
1882 	m_nMustFlags |= nMust;
1883 	m_nDontFlags |= nDont;
1884 
1885 	// create the list of filters
1886     ::rtl::OUStringBuffer sQuery(256);
1887     sQuery.appendAscii("getSortedFilterList()");
1888     sQuery.appendAscii(":module="										);
1889     sQuery.append     (rFactory											); // use long name here !
1890     sQuery.appendAscii(":iflags="                                       );
1891     sQuery.append     (::rtl::OUString::valueOf((sal_Int32)m_nMustFlags));
1892     sQuery.appendAscii(":eflags="                                       );
1893     sQuery.append     (::rtl::OUString::valueOf((sal_Int32)m_nDontFlags));
1894 
1895     uno::Reference< XEnumeration > xResult;
1896     try
1897     {
1898         xResult = xFilterCont->createSubSetEnumerationByQuery(sQuery.makeStringAndClear());
1899     }
1900     catch( uno::Exception& )
1901     {
1902         DBG_ERRORFILE( "Could not get filters from the configuration!" );
1903     }
1904 
1905     TSortedFilterList         aIter   (xResult);
1906 
1907     // no matcher any longer used ...
1908 	mbDeleteMatcher = sal_False;
1909 
1910 	// append the filters
1911 	::rtl::OUString sFirstFilter;
1912 	if ( WB_OPEN == ( nFlags & WB_OPEN ) )
1913 		::sfx2::appendFiltersForOpen( aIter, xFltMgr, sFirstFilter, *this );
1914 	else if ( mbExport )
1915 		::sfx2::appendExportFilters( aIter, xFltMgr, sFirstFilter, *this );
1916 	else
1917 		::sfx2::appendFiltersForSave( aIter, xFltMgr, sFirstFilter, *this, rFactory );
1918 
1919 	// set our initial selected filter (if we do not already have one)
1920 	if ( !maSelectFilter.getLength() )
1921 		maSelectFilter = sFirstFilter;
1922 }
1923 
1924 // ------------------------------------------------------------------------
1925 void FileDialogHelper_Impl::addFilter( const OUString& rFilterName,
1926 									   const OUString& rExtension )
1927 {
1928 	uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1929 
1930 	if ( ! xFltMgr.is() )
1931 		return;
1932 
1933 	try
1934 	{
1935 		xFltMgr->appendFilter( rFilterName, rExtension );
1936 
1937 		if ( !maSelectFilter.getLength() )
1938 			maSelectFilter = rFilterName;
1939 	}
1940 	catch( IllegalArgumentException )
1941 	{
1942 #ifdef DBG_UTIL
1943 		ByteString aMsg( "Could not append Filter" );
1944 		aMsg += ByteString( String( rFilterName ), RTL_TEXTENCODING_UTF8 );
1945 		DBG_ERRORFILE( aMsg.GetBuffer() );
1946 #endif
1947 	}
1948 }
1949 
1950 // ------------------------------------------------------------------------
1951 void FileDialogHelper_Impl::addGraphicFilter()
1952 {
1953 	uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
1954 
1955 	if ( ! xFltMgr.is() )
1956 		return;
1957 
1958 	// create the list of filters
1959 	mpGraphicFilter = new GraphicFilter;
1960 	sal_uInt16 i, j, nCount = mpGraphicFilter->GetImportFormatCount();
1961 
1962 	// compute the extension string for all known import filters
1963 	String aExtensions;
1964 
1965 	for ( i = 0; i < nCount; i++ )
1966 	{
1967 		j = 0;
1968 		String sWildcard;
1969 		while( sal_True )
1970 		{
1971 			sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
1972 			if ( !sWildcard.Len() )
1973 				break;
1974 			if ( aExtensions.Search( sWildcard ) == STRING_NOTFOUND )
1975 			{
1976 				if ( aExtensions.Len() )
1977 					aExtensions += sal_Unicode(';');
1978 				aExtensions += sWildcard;
1979 			}
1980 		}
1981 	}
1982 
1983 #if defined(WNT)
1984 	if ( aExtensions.Len() > 240 )
1985 		aExtensions = DEFINE_CONST_UNICODE( FILEDIALOG_FILTER_ALL );
1986 #endif
1987 	sal_Bool bIsInOpenMode = isInOpenMode();
1988 
1989 	try
1990 	{
1991 		OUString aAllFilterName = String( SfxResId( STR_SFX_IMPORT_ALL ) );
1992 		aAllFilterName = ::sfx2::addExtension( aAllFilterName, aExtensions, bIsInOpenMode, *this );
1993 
1994 		xFltMgr->appendFilter( aAllFilterName, aExtensions );
1995 		maSelectFilter = aAllFilterName;
1996 	}
1997 	catch( IllegalArgumentException )
1998 	{
1999 		DBG_ERRORFILE( "Could not append Filter" );
2000 	}
2001 
2002 	// Now add the filter
2003 	for ( i = 0; i < nCount; i++ )
2004 	{
2005 		String aName = mpGraphicFilter->GetImportFormatName( i );
2006 		String aExt;
2007 		j = 0;
2008 		String sWildcard;
2009 		while( sal_True )
2010 		{
2011 			sWildcard = mpGraphicFilter->GetImportWildcard( i, j++ );
2012 			if ( !sWildcard.Len() )
2013 				break;
2014 			if ( aExt.Search( sWildcard ) == STRING_NOTFOUND )
2015 			{
2016 				if ( aExt.Len() )
2017 					aExt += sal_Unicode(';');
2018 				aExt += sWildcard;
2019 			}
2020 		}
2021 		aName = ::sfx2::addExtension( aName, aExt, bIsInOpenMode, *this );
2022 		try
2023 		{
2024 			xFltMgr->appendFilter( aName, aExt );
2025 		}
2026 		catch( IllegalArgumentException )
2027 		{
2028 			DBG_ERRORFILE( "Could not append Filter" );
2029 		}
2030 	}
2031 }
2032 
2033 // ------------------------------------------------------------------------
2034 #define GRF_CONFIG_STR		"   "
2035 #define STD_CONFIG_STR		"1 "
2036 
2037 void FileDialogHelper_Impl::saveConfig()
2038 {
2039 	uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2040 	Any aValue;
2041 
2042 	if ( ! xDlg.is() )
2043 		return;
2044 
2045 	if ( mbHasPreview )
2046 	{
2047 		SvtViewOptions aDlgOpt( E_DIALOG, IMPGRF_CONFIGNAME );
2048 		String aUserData = DEFINE_CONST_UNICODE( GRF_CONFIG_STR );
2049 
2050 		try
2051 		{
2052 			aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0 );
2053 			sal_Bool bValue = sal_False;
2054 			aValue >>= bValue;
2055 			aUserData.SetToken( 0, ' ', String::CreateFromInt32( (sal_Int32) bValue ) );
2056 
2057 			aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0 );
2058 			bValue = sal_False;
2059 			aValue >>= bValue;
2060 			aUserData.SetToken( 1, ' ', String::CreateFromInt32( (sal_Int32) bValue ) );
2061 
2062 			INetURLObject aObj( getPath() );
2063 
2064 			if ( aObj.GetProtocol() == INET_PROT_FILE )
2065 				aUserData.SetToken( 2, ' ', aObj.GetMainURL( INetURLObject::NO_DECODE ) );
2066 
2067 			String aFilter = getFilter();
2068 			aFilter = EncodeSpaces_Impl( aFilter );
2069 			aUserData.SetToken( 3, ' ', aFilter );
2070 
2071 			aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2072 		}
2073 		catch( IllegalArgumentException ){}
2074 	}
2075 	else
2076 	{
2077 		sal_Bool bWriteConfig = sal_False;
2078 		SvtViewOptions aDlgOpt( E_DIALOG, IODLG_CONFIGNAME );
2079 		String aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR );
2080 
2081 		if ( aDlgOpt.Exists() )
2082 		{
2083 			Any aUserItem = aDlgOpt.GetUserItem( USERITEM_NAME );
2084 			OUString aTemp;
2085 			if ( aUserItem >>= aTemp )
2086 				aUserData = String( aTemp );
2087 		}
2088 
2089 		if ( mbHasAutoExt )
2090 		{
2091 			try
2092 			{
2093 				aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0 );
2094 				sal_Bool bAutoExt = sal_True;
2095 				aValue >>= bAutoExt;
2096 				aUserData.SetToken( 0, ' ', String::CreateFromInt32( (sal_Int32) bAutoExt ) );
2097 				bWriteConfig = sal_True;
2098 			}
2099 			catch( IllegalArgumentException ){}
2100 		}
2101 
2102 		if ( ! mbIsSaveDlg )
2103 		{
2104 			OUString aPath = getPath();
2105 			if ( aPath.getLength() &&
2106 				 utl::LocalFileHelper::IsLocalFile( aPath ) )
2107 			{
2108 				aUserData.SetToken( 1, ' ', aPath );
2109 				bWriteConfig = sal_True;
2110 			}
2111 		}
2112 
2113 		if( mbHasSelectionBox && mbSelectionFltrEnabled )
2114 		{
2115 			try
2116 			{
2117 				aValue = xDlg->getValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0 );
2118 				sal_Bool bSelection = sal_True;
2119 				aValue >>= bSelection;
2120 				if ( aUserData.GetTokenCount(' ') < 3 )
2121 					aUserData.Append(' ');
2122 				aUserData.SetToken( 2, ' ', String::CreateFromInt32( (sal_Int32) bSelection ) );
2123 				bWriteConfig = sal_True;
2124 			}
2125 			catch( IllegalArgumentException ){}
2126 		}
2127 
2128 		if ( bWriteConfig )
2129 			aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( OUString( aUserData ) ) );
2130 	}
2131 
2132 	SfxApplication *pSfxApp = SFX_APP();
2133 	pSfxApp->SetLastDir_Impl( getPath() );
2134 }
2135 
2136 // ------------------------------------------------------------------------
2137 namespace
2138 {
2139 	static ::rtl::OUString getInitPath( const String& _rFallback, const xub_StrLen _nFallbackToken )
2140 	{
2141 		SfxApplication *pSfxApp = SFX_APP();
2142 		String sPath = pSfxApp->GetLastDir_Impl();
2143 
2144 		if ( !sPath.Len() )
2145 			sPath = _rFallback.GetToken( _nFallbackToken, ' ' );
2146 
2147 		// check if the path points to a valid (accessible) directory
2148 		sal_Bool bValid = sal_False;
2149 		if ( sPath.Len() )
2150 		{
2151 			String sPathCheck( sPath );
2152 			if ( sPathCheck.GetBuffer()[ sPathCheck.Len() - 1 ] != '/' )
2153 				sPathCheck += '/';
2154 			sPathCheck += '.';
2155 			try
2156 			{
2157 				::ucbhelper::Content aContent( sPathCheck, uno::Reference< ucb::XCommandEnvironment >() );
2158 				bValid = aContent.isFolder();
2159 			}
2160 			catch( Exception& ) {}
2161 		}
2162 
2163 		if ( !bValid )
2164 			sPath.Erase();
2165 
2166 		return sPath;
2167 	}
2168 }
2169 
2170 // ------------------------------------------------------------------------
2171 void FileDialogHelper_Impl::loadConfig()
2172 {
2173 	uno::Reference < XFilePickerControlAccess > xDlg( mxFileDlg, UNO_QUERY );
2174 	Any aValue;
2175 
2176 	if ( ! xDlg.is() )
2177 		return;
2178 
2179 	if ( mbHasPreview )
2180 	{
2181 		SvtViewOptions aViewOpt( E_DIALOG, IMPGRF_CONFIGNAME );
2182 		String aUserData;
2183 
2184 		if ( aViewOpt.Exists() )
2185 		{
2186 			Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2187 			OUString aTemp;
2188 			if ( aUserItem >>= aTemp )
2189 				aUserData = String( aTemp );
2190 		}
2191 
2192 		if ( aUserData.Len() > 0 )
2193 		{
2194 			try
2195 			{
2196 				// respect the last "insert as link" state
2197 				sal_Bool bLink = (sal_Bool) aUserData.GetToken( 0, ' ' ).ToInt32();
2198 				aValue <<= bLink;
2199 				xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_LINK, 0, aValue );
2200 
2201 				// respect the last "show preview" state
2202 				sal_Bool bShowPreview = (sal_Bool) aUserData.GetToken( 1, ' ' ).ToInt32();
2203 				aValue <<= bShowPreview;
2204 				xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, 0, aValue );
2205 
2206 				if ( !maPath.getLength() )
2207 					displayFolder( getInitPath( aUserData, 2 ) );
2208 
2209 				if ( ! maCurFilter.getLength() )
2210 				{
2211 					String aFilter = aUserData.GetToken( 3, ' ' );
2212 					aFilter = DecodeSpaces_Impl( aFilter );
2213 					setFilter( aFilter );
2214 				}
2215 
2216 				// set the member so we know that we have to show the preview
2217 				mbShowPreview = bShowPreview;
2218 			}
2219 			catch( IllegalArgumentException ){}
2220 		}
2221 
2222 		if ( !maPath.getLength() )
2223 			displayFolder( SvtPathOptions().GetGraphicPath() );
2224 	}
2225 	else
2226 	{
2227 		SvtViewOptions aViewOpt( E_DIALOG, IODLG_CONFIGNAME );
2228 		String aUserData;
2229 
2230 		if ( aViewOpt.Exists() )
2231 		{
2232 			Any aUserItem = aViewOpt.GetUserItem( USERITEM_NAME );
2233 			OUString aTemp;
2234 			if ( aUserItem >>= aTemp )
2235 				aUserData = String( aTemp );
2236 		}
2237 
2238 		if ( ! aUserData.Len() )
2239 			aUserData = DEFINE_CONST_UNICODE( STD_CONFIG_STR );
2240 
2241 		if ( ! maPath.getLength() )
2242 			displayFolder( getInitPath( aUserData, 1 ) );
2243 
2244 		if ( mbHasAutoExt )
2245 		{
2246 			sal_Int32 nFlag = aUserData.GetToken( 0, ' ' ).ToInt32();
2247 			aValue <<= (sal_Bool) nFlag;
2248 			try
2249 			{
2250 				xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue );
2251 			}
2252 			catch( IllegalArgumentException ){}
2253 		}
2254 
2255 		if( mbHasSelectionBox )
2256 		{
2257 			sal_Int32 nFlag = aUserData.GetToken( 2, ' ' ).ToInt32();
2258 			aValue <<= (sal_Bool) nFlag;
2259 			try
2260 			{
2261 				xDlg->setValue( ExtendedFilePickerElementIds::CHECKBOX_SELECTION, 0, aValue );
2262 			}
2263 			catch( IllegalArgumentException ){}
2264 		}
2265 
2266 		if ( !maPath.getLength() )
2267 			displayFolder( SvtPathOptions().GetWorkPath() );
2268 	}
2269 }
2270 
2271 // ------------------------------------------------------------------------
2272 void FileDialogHelper_Impl::setDefaultValues()
2273 {
2274 	// when no filter is set, we set the curentFilter to <all>
2275 	if ( !maCurFilter.getLength() && maSelectFilter.getLength() )
2276 	{
2277 		uno::Reference< XFilterManager > xFltMgr( mxFileDlg, UNO_QUERY );
2278 		try
2279 		{
2280 			xFltMgr->setCurrentFilter( maSelectFilter );
2281 		}
2282 		catch( IllegalArgumentException )
2283 		{}
2284 	}
2285 
2286 	// when no path is set, we use the standard 'work' folder
2287 	if ( ! maPath.getLength() )
2288 	{
2289 		OUString aWorkFolder = SvtPathOptions().GetWorkPath();
2290         try
2291         {
2292 		    mxFileDlg->setDisplayDirectory( aWorkFolder );
2293         }
2294         catch( const Exception& )
2295         {
2296             DBG_ERROR( "FileDialogHelper_Impl::setDefaultValues: caught an exception while setting the display directory!" );
2297         }
2298 
2299 		// INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() );
2300 		//SetStandardDir( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) );
2301 	}
2302 }
2303 
2304 sal_Bool FileDialogHelper_Impl::isShowFilterExtensionEnabled() const
2305 {
2306 	return !maFilters.empty();
2307 }
2308 
2309 void FileDialogHelper_Impl::addFilterPair( const OUString& rFilter,
2310 										   const OUString& rFilterWithExtension )
2311 {
2312 	maFilters.push_back( FilterPair( rFilter, rFilterWithExtension ) );
2313 
2314 }
2315 
2316 OUString FileDialogHelper_Impl::getFilterName( const OUString& rFilterWithExtension ) const
2317 {
2318 	OUString sRet;
2319 	for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2320 	{
2321 		if ( (*pIter).Second == rFilterWithExtension )
2322 		{
2323 			sRet = (*pIter).First;
2324 			break;
2325 		}
2326 	}
2327 	return sRet;
2328 }
2329 
2330 OUString FileDialogHelper_Impl::getFilterWithExtension( const OUString& rFilter ) const
2331 {
2332 	OUString sRet;
2333 	for( ::std::vector< FilterPair >::const_iterator pIter = maFilters.begin(); pIter != maFilters.end(); ++pIter )
2334 	{
2335 		if ( (*pIter).First == rFilter )
2336 		{
2337 			sRet = (*pIter).Second;
2338 			break;
2339 		}
2340 	}
2341 	return sRet;
2342 }
2343 
2344 void FileDialogHelper_Impl::SetContext( FileDialogHelper::Context _eNewContext )
2345 {
2346 	meContext = _eNewContext;
2347 
2348 	sal_Int32		nNewHelpId = 0;
2349 	OUString		aConfigId;
2350 
2351 	switch( _eNewContext )
2352 	{
2353 // #104952#	dependency to SVX not allowed! When used again, another solution has to be found
2354 //		case FileDialogHelper::SW_INSERT_GRAPHIC:
2355 //		case FileDialogHelper::SC_INSERT_GRAPHIC:
2356 //		case FileDialogHelper::SD_INSERT_GRAPHIC:		nNewHelpId = SID_INSERT_GRAPHIC;		break;
2357 		case FileDialogHelper::SW_INSERT_SOUND:
2358 		case FileDialogHelper::SC_INSERT_SOUND:
2359 		case FileDialogHelper::SD_INSERT_SOUND:			nNewHelpId = SID_INSERT_SOUND;			break;
2360 		case FileDialogHelper::SW_INSERT_VIDEO:
2361 		case FileDialogHelper::SC_INSERT_VIDEO:
2362 		case FileDialogHelper::SD_INSERT_VIDEO:			nNewHelpId = SID_INSERT_VIDEO;			break;
2363               default: break;
2364 	}
2365 
2366 	const OUString*	pConfigId = GetLastFilterConfigId( _eNewContext );
2367 	if( pConfigId )
2368 		LoadLastUsedFilter( *pConfigId );
2369 }
2370 
2371 // ------------------------------------------------------------------------
2372 // -----------			FileDialogHelper		---------------------------
2373 // ------------------------------------------------------------------------
2374 
2375 FileDialogHelper::FileDialogHelper(
2376     sal_Int64 nFlags,
2377     const String& rFact,
2378     SfxFilterFlags nMust,
2379     SfxFilterFlags nDont )
2380 {
2381 	mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags );
2382 	mxImp = mpImp;
2383 
2384 	// create the list of filters
2385 	mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2386 }
2387 
2388 FileDialogHelper::FileDialogHelper(
2389     sal_Int64 nFlags,
2390     const String& rFact,
2391 	sal_Int16 nDialog,
2392     SfxFilterFlags nMust,
2393     SfxFilterFlags nDont,
2394 	const String& rStandardDir,
2395 	const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList)
2396 {
2397 	mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags, nDialog, NULL , rStandardDir, rBlackList );
2398 	mxImp = mpImp;
2399 
2400 	// create the list of filters
2401 	mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2402 }
2403 
2404 FileDialogHelper::FileDialogHelper(
2405     sal_Int64 nFlags,
2406     const String& rFact,
2407 	sal_Int16 nDialog,
2408     SfxFilterFlags nMust,
2409     SfxFilterFlags nDont )
2410 {
2411 	mpImp = new FileDialogHelper_Impl( this, getDialogType( nFlags ), nFlags, nDialog );
2412 	mxImp = mpImp;
2413 
2414 	// create the list of filters
2415 	mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2416 }
2417 
2418 // ------------------------------------------------------------------------
2419 FileDialogHelper::FileDialogHelper( sal_Int64 nFlags )
2420 {
2421 	sal_Int16 nDialogType = getDialogType( nFlags );
2422 
2423 	mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags );
2424 	mxImp = mpImp;
2425 }
2426 
2427 // ------------------------------------------------------------------------
2428 FileDialogHelper::FileDialogHelper(
2429     sal_Int16 nDialogType,
2430     sal_Int64 nFlags,
2431     const String& rFact,
2432     SfxFilterFlags nMust,
2433     SfxFilterFlags nDont )
2434 {
2435 	mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags );
2436 	mxImp = mpImp;
2437 
2438 	// create the list of filters
2439 	mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2440 }
2441 
2442 // ------------------------------------------------------------------------
2443 FileDialogHelper::FileDialogHelper(
2444     sal_Int16 nDialogType,
2445     sal_Int64 nFlags,
2446     const String& rFact,
2447 	sal_Int16 nDialog,
2448     SfxFilterFlags nMust,
2449     SfxFilterFlags nDont,
2450 	const String& rStandardDir,
2451 	const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList)
2452 {
2453 	mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, nDialog, NULL, rStandardDir, rBlackList );
2454 	mxImp = mpImp;
2455 
2456 	// create the list of filters
2457 	mpImp->addFilters( nFlags, SfxObjectShell::GetServiceNameFromFactory(rFact), nMust, nDont );
2458 }
2459 
2460 // ------------------------------------------------------------------------
2461 FileDialogHelper::FileDialogHelper(
2462     sal_Int16 nDialogType,
2463     sal_Int64 nFlags,
2464     Window* _pPreferredParent )
2465 {
2466 	mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent );
2467 	mxImp = mpImp;
2468 }
2469 
2470 // ------------------------------------------------------------------------
2471 FileDialogHelper::FileDialogHelper(
2472     sal_Int16 nDialogType,
2473     sal_Int64 nFlags,
2474 	const ::rtl::OUString& aFilterUIName,
2475 	const ::rtl::OUString& aExtName,
2476 	const ::rtl::OUString& rStandardDir,
2477 	const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList,
2478     Window* _pPreferredParent )
2479 {
2480 	mpImp = new FileDialogHelper_Impl( this, nDialogType, nFlags, SFX2_IMPL_DIALOG_CONFIG, _pPreferredParent,rStandardDir, rBlackList );
2481 	mxImp = mpImp;
2482 
2483 	// the wildcard here is expected in form "*.extension"
2484 	::rtl::OUString aWildcard;
2485 	if ( aExtName.indexOf( (sal_Unicode)'*' ) != 0 )
2486 	{
2487 		if ( aExtName.getLength() && aExtName.indexOf( (sal_Unicode)'.' ) != 0 )
2488 			aWildcard = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*." ) );
2489 		else
2490 			aWildcard = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*" ) );
2491 	}
2492 
2493 	aWildcard += aExtName;
2494 
2495 	::rtl::OUString aUIString =
2496 		::sfx2::addExtension( aFilterUIName, aWildcard, ( WB_OPEN == ( nFlags & WB_OPEN ) ), *mpImp );
2497 	AddFilter( aUIString, aWildcard );
2498 }
2499 
2500 // ------------------------------------------------------------------------
2501 FileDialogHelper::~FileDialogHelper()
2502 {
2503 	mpImp->dispose();
2504 	mxImp.clear();
2505 }
2506 
2507 // ------------------------------------------------------------------------
2508 void FileDialogHelper::CreateMatcher( const String& rFactory )
2509 {
2510 	mpImp->createMatcher( SfxObjectShell::GetServiceNameFromFactory(rFactory) );
2511 }
2512 
2513 // ------------------------------------------------------------------------
2514 void FileDialogHelper::SetControlHelpIds( const sal_Int16* _pControlId, const char** _pHelpId )
2515 {
2516 	mpImp->setControlHelpIds( _pControlId, _pHelpId );
2517 }
2518 
2519 void FileDialogHelper::SetContext( Context _eNewContext )
2520 {
2521 	mpImp->SetContext( _eNewContext );
2522 }
2523 
2524 // ------------------------------------------------------------------------
2525 IMPL_LINK( FileDialogHelper, ExecuteSystemFilePicker, void*, EMPTYARG )
2526 {
2527     m_nError = mpImp->execute();
2528     if ( m_aDialogClosedLink.IsSet() )
2529         m_aDialogClosedLink.Call( this );
2530 
2531     return 0L;
2532 }
2533 
2534 // ------------------------------------------------------------------------
2535 // rDirPath has to be a directory
2536 ErrCode FileDialogHelper::Execute( SvStringsDtor*& rpURLList,
2537 								   SfxItemSet *&   rpSet,
2538 								   String&		   rFilter,
2539 								   const String&   rDirPath )
2540 {
2541 	SetDisplayFolder( rDirPath );
2542 	return mpImp->execute( rpURLList, rpSet, rFilter );
2543 }
2544 
2545 
2546 // ------------------------------------------------------------------------
2547 ErrCode FileDialogHelper::Execute()
2548 {
2549 	return mpImp->execute();
2550 }
2551 
2552 // ------------------------------------------------------------------------
2553 ErrCode FileDialogHelper::Execute( SfxItemSet *&   rpSet,
2554 								   String&		   rFilter )
2555 {
2556 	ErrCode nRet;
2557 	SvStringsDtor* pURLList;
2558 
2559 	nRet = mpImp->execute( pURLList, rpSet, rFilter );
2560 
2561 	delete pURLList;
2562 
2563 	return nRet;
2564 }
2565 
2566 void FileDialogHelper::StartExecuteModal( const Link& rEndDialogHdl )
2567 {
2568     m_aDialogClosedLink = rEndDialogHdl;
2569     m_nError = ERRCODE_NONE;
2570     if ( mpImp->isSystemFilePicker() )
2571         Application::PostUserEvent( LINK( this, FileDialogHelper, ExecuteSystemFilePicker ) );
2572     else
2573         mpImp->implStartExecute();
2574 }
2575 
2576 // ------------------------------------------------------------------------
2577 
2578 short FileDialogHelper::GetDialogType() const
2579 {
2580     return mpImp ? mpImp->m_nDialogType : 0;
2581 }
2582 
2583 // ------------------------------------------------------------------------
2584 
2585 sal_Bool FileDialogHelper::IsPasswordEnabled() const
2586 {
2587     return mpImp ? mpImp->isPasswordEnabled() : sal_False;
2588 }
2589 
2590 // ------------------------------------------------------------------------
2591 
2592 String FileDialogHelper::GetRealFilter() const
2593 {
2594     String sFilter;
2595     if ( mpImp )
2596         mpImp->getRealFilter( sFilter );
2597     return sFilter;
2598 }
2599 
2600 // ------------------------------------------------------------------------
2601 void FileDialogHelper::SetTitle( const String& rNewTitle )
2602 {
2603     if ( mpImp->mxFileDlg.is() )
2604         mpImp->mxFileDlg->setTitle( rNewTitle );
2605 }
2606 
2607 // ------------------------------------------------------------------------
2608 String FileDialogHelper::GetPath() const
2609 {
2610 	OUString aPath;
2611 
2612     if ( mpImp->mlLastURLs.size() > 0)
2613         return mpImp->mlLastURLs[0];
2614 
2615 	if ( mpImp->mxFileDlg.is() )
2616 	{
2617 		Sequence < OUString > aPathSeq = mpImp->mxFileDlg->getFiles();
2618 
2619 		if ( aPathSeq.getLength() == 1 )
2620 		{
2621 			aPath = aPathSeq[0];
2622 		}
2623 	}
2624 
2625 	return aPath;
2626 }
2627 
2628 // ------------------------------------------------------------------------
2629 Sequence < OUString > FileDialogHelper::GetMPath() const
2630 {
2631     if ( mpImp->mlLastURLs.size() > 0)
2632         return mpImp->mlLastURLs.getAsConstList();
2633 
2634 	if ( mpImp->mxFileDlg.is() )
2635 		return mpImp->mxFileDlg->getFiles();
2636 	else
2637 	{
2638 		Sequence < OUString > aEmpty;
2639 		return aEmpty;
2640 	}
2641 }
2642 
2643 // ------------------------------------------------------------------------
2644 Sequence< ::rtl::OUString > FileDialogHelper::GetSelectedFiles() const
2645 {
2646     // a) the new way (optional!)
2647     uno::Sequence< ::rtl::OUString > aResultSeq;
2648     uno::Reference< XFilePicker2 > xPickNew(mpImp->mxFileDlg, UNO_QUERY);
2649     if (xPickNew.is())
2650     {
2651         aResultSeq = xPickNew->getSelectedFiles();
2652     }
2653     // b) the olde way ... non optional.
2654     else
2655     {
2656         uno::Reference< XFilePicker > xPickOld(mpImp->mxFileDlg, UNO_QUERY_THROW);
2657         Sequence< OUString > lFiles = xPickOld->getFiles();
2658         ::sal_Int32          nFiles = lFiles.getLength();
2659         if ( nFiles > 1 )
2660         {
2661             aResultSeq = Sequence< ::rtl::OUString >( nFiles-1 );
2662 
2663             INetURLObject aPath( lFiles[0] );
2664             aPath.setFinalSlash();
2665 
2666             for (::sal_Int32 i = 1; i < nFiles; i++)
2667             {
2668                 if (i == 1)
2669                     aPath.Append( lFiles[i] );
2670                 else
2671                     aPath.setName( lFiles[i] );
2672 
2673                 aResultSeq[i-1] = ::rtl::OUString(aPath.GetMainURL( INetURLObject::NO_DECODE ));
2674             }
2675         }
2676         else
2677             aResultSeq = lFiles;
2678     }
2679 
2680     return aResultSeq;
2681 }
2682 
2683 // ------------------------------------------------------------------------
2684 String FileDialogHelper::GetDisplayDirectory() const
2685 {
2686 	return mpImp->getPath();
2687 }
2688 
2689 // ------------------------------------------------------------------------
2690 String FileDialogHelper::GetCurrentFilter() const
2691 {
2692 	return mpImp->getFilter();
2693 }
2694 
2695 // ------------------------------------------------------------------------
2696 ErrCode FileDialogHelper::GetGraphic( Graphic& rGraphic ) const
2697 {
2698 	return mpImp->getGraphic( rGraphic );
2699 }
2700 
2701 // ------------------------------------------------------------------------
2702 static int impl_isFolder( const OUString& rPath )
2703 {
2704 	uno::Reference< task::XInteractionHandler > xHandler;
2705 	try
2706 	{
2707         uno::Reference< lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
2708         xHandler.set( xFactory->createInstance( DEFINE_CONST_OUSTRING( "com.sun.star.task.InteractionHandler" ) ),
2709                       uno::UNO_QUERY_THROW );
2710 	}
2711     catch ( Exception const & )
2712 	{
2713 	}
2714 
2715 	::rtl::Reference< ::comphelper::StillReadWriteInteraction > aHandler = new ::comphelper::StillReadWriteInteraction( xHandler );
2716 
2717 	try
2718 	{
2719 		::ucbhelper::Content aContent(
2720 			rPath, new ::ucbhelper::CommandEnvironment( static_cast< task::XInteractionHandler* > ( aHandler.get() ), uno::Reference< ucb::XProgressHandler >() ) );
2721 		if ( aContent.isFolder() )
2722 			return 1;
2723 
2724 		return 0;
2725 	}
2726     catch ( Exception const & )
2727 	{
2728 	}
2729 
2730     return -1;
2731 }
2732 
2733 void FileDialogHelper::SetDisplayDirectory( const String& _rPath )
2734 {
2735     if ( !_rPath.Len() )
2736         return;
2737 
2738     // if the given path isn't a folder, we cut off the last part
2739     // and take it as filename and the rest of the path should be
2740     // the folder
2741 
2742     INetURLObject aObj( _rPath );
2743 
2744     ::rtl::OUString sFileName = aObj.GetName( INetURLObject::DECODE_WITH_CHARSET );
2745     aObj.removeSegment();
2746     ::rtl::OUString sPath = aObj.GetMainURL( INetURLObject::NO_DECODE );
2747 
2748     int nIsFolder = impl_isFolder( _rPath );
2749     if ( nIsFolder == 0 ||
2750          ( nIsFolder == -1 && impl_isFolder( sPath ) == 1 ) )
2751     {
2752         mpImp->setFileName( sFileName );
2753         mpImp->displayFolder( sPath );
2754     }
2755     else
2756     {
2757         INetURLObject aObjPathName( _rPath );
2758         ::rtl::OUString sFolder( aObjPathName.GetMainURL( INetURLObject::NO_DECODE ) );
2759         if ( sFolder.getLength() == 0 )
2760         {
2761             // _rPath is not a valid path -> fallback to home directory
2762             vos:: OSecurity  aSecurity;
2763             aSecurity.getHomeDir( sFolder );
2764         }
2765         mpImp->displayFolder( sFolder );
2766     }
2767 }
2768 
2769 // ------------------------------------------------------------------------
2770 void FileDialogHelper::SetDisplayFolder( const String& _rURL )
2771 {
2772     mpImp->displayFolder( _rURL );
2773 }
2774 
2775 // ------------------------------------------------------------------------
2776 void FileDialogHelper::SetFileName( const String& _rFileName )
2777 {
2778     mpImp->setFileName( _rFileName );
2779 }
2780 
2781 // ------------------------------------------------------------------------
2782 void FileDialogHelper::AddFilter( const String& rFilterName,
2783 								  const String& rExtension )
2784 {
2785 	mpImp->addFilter( rFilterName, rExtension );
2786 }
2787 
2788 // ------------------------------------------------------------------------
2789 void FileDialogHelper::SetCurrentFilter( const String& rFilter )
2790 {
2791 	String sFilter( rFilter );
2792 	if ( mpImp->isShowFilterExtensionEnabled() )
2793 		sFilter = mpImp->getFilterWithExtension( rFilter );
2794 	mpImp->setFilter( sFilter );
2795 }
2796 
2797 // ------------------------------------------------------------------------
2798 uno::Reference < XFilePicker > FileDialogHelper::GetFilePicker() const
2799 {
2800 	return mpImp->mxFileDlg;
2801 }
2802 
2803 // ------------------------------------------------------------------------
2804 sal_Int16 FileDialogHelper::getDialogType( sal_Int64 nFlags ) const
2805 {
2806 	sal_Int16 nDialogType = FILEOPEN_SIMPLE;
2807 
2808 	if ( nFlags & WB_SAVEAS )
2809 	{
2810 		if ( nFlags & SFXWB_PASSWORD )
2811 			nDialogType = FILESAVE_AUTOEXTENSION_PASSWORD;
2812 		else
2813 			nDialogType = FILESAVE_SIMPLE;
2814 	}
2815 	else if ( nFlags & SFXWB_GRAPHIC )
2816 	{
2817 		if ( nFlags & SFXWB_SHOWSTYLES )
2818 			nDialogType = FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE;
2819 		else
2820 			nDialogType = FILEOPEN_LINK_PREVIEW;
2821 	}
2822 	else if ( SFXWB_INSERT != ( nFlags & SFXWB_INSERT ) )
2823 		nDialogType = FILEOPEN_READONLY_VERSION;
2824 
2825 	return nDialogType;
2826 }
2827 
2828 // ------------------------------------------------------------------------
2829 // XFilePickerListener Methods
2830 // ------------------------------------------------------------------------
2831 void SAL_CALL FileDialogHelper::FileSelectionChanged( const FilePickerEvent& aEvent )
2832 {
2833 	mpImp->handleFileSelectionChanged( aEvent );
2834 }
2835 
2836 // ------------------------------------------------------------------------
2837 void SAL_CALL FileDialogHelper::DirectoryChanged( const FilePickerEvent& aEvent )
2838 {
2839 	mpImp->handleDirectoryChanged( aEvent );
2840 }
2841 
2842 // ------------------------------------------------------------------------
2843 OUString SAL_CALL FileDialogHelper::HelpRequested( const FilePickerEvent& aEvent )
2844 {
2845 	return mpImp->handleHelpRequested( aEvent );
2846 }
2847 
2848 // ------------------------------------------------------------------------
2849 void SAL_CALL FileDialogHelper::ControlStateChanged( const FilePickerEvent& aEvent )
2850 {
2851 	mpImp->handleControlStateChanged( aEvent );
2852 }
2853 
2854 // ------------------------------------------------------------------------
2855 void SAL_CALL FileDialogHelper::DialogSizeChanged()
2856 {
2857     mpImp->handleDialogSizeChanged();
2858 }
2859 
2860 // ------------------------------------------------------------------------
2861 void SAL_CALL FileDialogHelper::DialogClosed( const DialogClosedEvent& _rEvent )
2862 {
2863     m_nError = ( RET_OK == _rEvent.DialogResult ) ? ERRCODE_NONE : ERRCODE_ABORT;
2864     if ( m_aDialogClosedLink.IsSet() )
2865         m_aDialogClosedLink.Call( this );
2866 }
2867 
2868 // ------------------------------------------------------------------------
2869 // ------------------------------------------------------------------------
2870 // ------------------------------------------------------------------------
2871 
2872 ErrCode FileOpenDialog_Impl( sal_Int64 nFlags,
2873                              const String& rFact,
2874                              SvStringsDtor *& rpURLList,
2875                              String& rFilter,
2876                              SfxItemSet *& rpSet,
2877                              const String* pPath,
2878 							 sal_Int16 nDialog,
2879 							 const String& rStandardDir,
2880 							 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
2881 {
2882 	ErrCode nRet;
2883 	FileDialogHelper aDialog( nFlags, rFact, nDialog, 0, 0, rStandardDir, rBlackList );
2884 
2885     String aPath;
2886     if ( pPath )
2887         aPath = *pPath;
2888 
2889     nRet = aDialog.Execute( rpURLList, rpSet, rFilter, aPath );
2890 	DBG_ASSERT( rFilter.SearchAscii(": ") == STRING_NOTFOUND, "Old filter name used!");
2891 
2892 	return nRet;
2893 }
2894 
2895 
2896 // ------------------------------------------------------------------------
2897 String EncodeSpaces_Impl( const String& rSource )
2898 {
2899 	String sRet( rSource );
2900 	sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( " " ), DEFINE_CONST_UNICODE( "%20" ) );
2901 	return sRet;
2902 }
2903 
2904 // ------------------------------------------------------------------------
2905 String DecodeSpaces_Impl( const String& rSource )
2906 {
2907 	String sRet( rSource );
2908 	sRet.SearchAndReplaceAll( DEFINE_CONST_UNICODE( "%20" ), DEFINE_CONST_UNICODE( " " ) );
2909 	return sRet;
2910 }
2911 
2912 // ------------------------------------------------------------------------
2913 
2914 }	// end of namespace sfx2
2915 
2916