xref: /aoo41x/main/fpicker/source/office/iodlg.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
30 
31 // includes --------------------------------------------------------------
32 
33 #include "iodlg.hxx"
34 #include <tools/stream.hxx>
35 #include <tools/urlobj.hxx>
36 #include <vcl/fixed.hxx>
37 #include <vcl/lstbox.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <vcl/svapp.hxx>
40 #include <vcl/timer.hxx>
41 #include <unotools/ucbhelper.hxx>
42 #include <ucbhelper/contentbroker.hxx>
43 #include "svtools/ehdl.hxx"
44 #include "svl/urihelper.hxx"
45 #include "unotools/pathoptions.hxx"
46 #include "unotools/viewoptions.hxx"
47 #include "svtools/fileview.hxx"
48 #include "unotools/inetoptions.hxx"
49 #include "svtools/sfxecode.hxx"
50 #include "svl/svarray.hxx"
51 #include "svtools/svtabbx.hxx"
52 
53 #define _SVSTDARR_USHORTS
54 #define _SVSTDARR_STRINGSDTOR
55 #include "svl/svstdarr.hxx"
56 #include <toolkit/helper/vclunohelper.hxx>
57 #include <unotools/localfilehelper.hxx>
58 
59 #ifndef _SVTOOLS_HRC
60 #include "svtools/svtools.hrc"
61 #endif
62 #ifndef _SVT_HELPID_HRC
63 #include "svtools/helpid.hrc"
64 #endif
65 #ifndef _SVTOOLS_IODLGIMPL_HRC
66 #include "iodlg.hrc"
67 #endif
68 #include "rtl/instance.hxx"
69 #include "asyncfilepicker.hxx"
70 #include "iodlgimp.hxx"
71 #include "svtools/inettbc.hxx"
72 #include "unotools/syslocale.hxx"
73 #include "svtools/QueryFolderName.hxx"
74 #ifndef  _RTL_USTRING_HXX
75 #include <rtl/ustring.hxx>
76 #endif
77 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
78 #include <com/sun/star/ucb/XContentProviderManager.hpp>
79 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
80 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
81 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
82 #include <com/sun/star/beans/PropertyValue.hpp>
83 #include <com/sun/star/sdbc/XResultSet.hpp>
84 #include <com/sun/star/sdbc/XRow.hpp>
85 #include <com/sun/star/util/URL.hpp>
86 #include <com/sun/star/uno/Exception.hpp>
87 #include <com/sun/star/uno/Reference.hxx>
88 #include <com/sun/star/util/XURLTransformer.hpp>
89 #include <com/sun/star/uno/RuntimeException.hpp>
90 #include <com/sun/star/beans/XPropertySet.hpp>
91 
92 #ifndef _UNOTOOLS_PROCESSFACTORY_HXX
93 #include <comphelper/processfactory.hxx>
94 #endif
95 #include <osl/file.h>
96 #include <vcl/waitobj.hxx>
97 
98 // #97148# ------------------------------------
99 #include <com/sun/star/task/XInteractionHandler.hpp>
100 #include "com/sun/star/ucb/InteractiveAugmentedIOException.hpp"
101 #include "fpinteraction.hxx"
102 #include <osl/process.h>
103 #include <comphelper/interaction.hxx>
104 
105 #include <algorithm>
106 #include <functional>
107 
108 //#define AUTOSELECT_USERFILTER
109 	// define this for the experimental feature of user-filter auto selection
110 	// means if the user enters e.g. *.doc<enter>, and there is a filter which is responsible for *.doc files (only),
111 	// then this filter is selected automatically
112 
113 using namespace ::com::sun::star::beans;
114 using namespace ::com::sun::star::frame;
115 using namespace ::com::sun::star::ui::dialogs;
116 using namespace ::com::sun::star::uno;
117 using namespace ::com::sun::star::lang;
118 using namespace ::com::sun::star::ucb;
119 using namespace ::com::sun::star::container;
120 using namespace ::com::sun::star::task;
121 using namespace ::com::sun::star::sdbc;
122 using namespace ::utl;
123 using namespace ::svt;
124 
125 using namespace ExtendedFilePickerElementIds;
126 using namespace CommonFilePickerElementIds;
127 using namespace InternalFilePickerElementIds;
128 
129 #define IODLG_CONFIGNAME		String(RTL_CONSTASCII_USTRINGPARAM("FileDialog"))
130 #define IMPGRF_CONFIGNAME		String(RTL_CONSTASCII_USTRINGPARAM("ImportGraphicDialog"))
131 
132 #define GET_DECODED_NAME(aObj) \
133 	aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET )
134 
135 // Zeit die beim Traveln in der Filterbox gewartet wird,
136 // bis in der Browsebox gefiltert wird ( in ms ).
137 #define TRAVELFILTER_TIMEOUT	750
138 
139 #define WIDTH_ADDITION	15
140 
141 // functions -------------------------------------------------------------
142 
143 namespace
144 {
145 
146 	//-----------------------------------------------------------------------------
147 	String getMostCurrentFilter( SvtExpFileDlg_Impl* pImpl )
148 	{
149 		DBG_ASSERT( pImpl, "invalid impl pointer" );
150 		const SvtFileDialogFilter_Impl* pFilter = pImpl->_pUserFilter;
151 
152 		if ( !pFilter )
153 			pFilter = pImpl->GetCurFilter();
154 
155 		// Filtern.
156 		if ( !pFilter )
157 			return String();
158 
159 		return pFilter->GetType();
160 	}
161 
162 	//-----------------------------------------------------------------------------
163 	sal_Bool restoreCurrentFilter( SvtExpFileDlg_Impl* _pImpl )
164 	{
165 		DBG_ASSERT( _pImpl->GetCurFilter(), "restoreCurrentFilter: no current filter!" );
166 		DBG_ASSERT( _pImpl->GetCurFilterDisplayName().Len(), "restoreCurrentFilter: no current filter (no display name)!" );
167 
168 		_pImpl->SelectFilterListEntry( _pImpl->GetCurFilterDisplayName() );
169 
170 #ifdef DBG_UTIL
171 		String sSelectedDisplayName;
172 		DBG_ASSERT(	( _pImpl->GetSelectedFilterEntry( sSelectedDisplayName ) == _pImpl->GetCurFilter() )
173 				&&	( sSelectedDisplayName == _pImpl->GetCurFilterDisplayName() ),
174 			"restoreCurrentFilter: inconsistence!" );
175 #endif
176 		return _pImpl->m_bNeedDelayedFilterExecute;
177 	}
178 
179 	//-----------------------------------------------------------------------------
180     String GetFsysExtension_Impl( const String& rFile, const String& rLastFilterExt )
181 	{
182         xub_StrLen nDotPos = rFile.SearchBackward( '.' );
183         if ( nDotPos != STRING_NOTFOUND )
184         {
185             if ( rLastFilterExt.Len() )
186             {
187                 if ( rFile.Copy( nDotPos + 1 ).EqualsIgnoreCaseAscii( rLastFilterExt ) )
188                     return String( rLastFilterExt );
189             }
190             else
191                 return String( rFile.Copy( nDotPos ) );
192         }
193 		return String();
194 	}
195 
196 	//-----------------------------------------------------------------------------
197 	void SetFsysExtension_Impl( String& rFile, const String& rExtension )
198 	{
199 		const sal_Unicode* p0 = rFile.GetBuffer();
200 		const sal_Unicode* p1 = p0 + rFile.Len() - 1;
201 		while ( p1 >= p0 && *p1 != sal_Unicode( '.' ) )
202 			p1--;
203 		if ( p1 >= p0 )
204 			// remove old extension
205 			rFile.Erase(
206                 sal::static_int_cast< xub_StrLen >(
207                     p1 - p0 + 1 - ( rExtension.Len() > 0 ? 0 : 1 ) ) );
208 		else if ( rExtension.Len() )
209 			// no old extension
210 			rFile += sal_Unicode( '.' );
211 		rFile += rExtension;
212 	}
213 
214 	//-----------------------------------------------------------------------------
215 	// move the control with the given offset
216 	void lcl_MoveControl( Control* _pControl, sal_Int32 _nDeltaX, sal_Int32 _nDeltaY, sal_Int32* _pMaxY = NULL )
217 	{
218 		if ( _pControl )
219 		{
220 			Point aNewPos = _pControl->GetPosPixel();
221 
222 			// adjust the vertical position
223 			aNewPos.Y() += _nDeltaY;
224 			if ( _pMaxY && ( aNewPos.Y() > *_pMaxY ) )
225 				*_pMaxY = aNewPos.Y();
226 
227 			// adjust the horizontal position
228 			aNewPos.X() += _nDeltaX;
229 
230 			_pControl->SetPosPixel( aNewPos );
231 		}
232 	}
233 
234     //-------------------------------------------------------------------------
235     void lcl_autoUpdateFileExtension( SvtFileDialog* _pDialog, const String& _rLastFilterExt )
236 	{
237 		// if auto extension is enabled ....
238 		if ( _pDialog->isAutoExtensionEnabled() )
239 		{
240 			// automatically switch to the extension of the (maybe just newly selected) extension
241 			String aNewFile = _pDialog->getCurrentFileText( );
242             String aExt = GetFsysExtension_Impl( aNewFile, _rLastFilterExt );
243 
244 			// but only if there already is an extension
245 			if ( aExt.Len() )
246 			{
247 				// check if it is a real file extension, and not only the "post-dot" part in
248 				// a directory name
249 				// 28.03.2002 - 98337 - fs@openoffice.org
250 				sal_Bool bRealExtensions = sal_True;
251 				if ( STRING_NOTFOUND != aExt.Search( '/' ) )
252 					bRealExtensions = sal_False;
253 				else if ( STRING_NOTFOUND != aExt.Search( '\\' ) )
254 					bRealExtensions = sal_False;
255 				else
256 				{
257 					// no easy way to tell, because the part containing the dot already is the last
258 					// segment of the complete file name
259 					// So we have to check if the file name denotes a folder or a file.
260 					// For performance reasons, we do this for file urls only
261 					INetURLObject aURL( aNewFile );
262 					if ( INET_PROT_NOT_VALID == aURL.GetProtocol() )
263 					{
264 						String sURL;
265 						if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aNewFile, sURL ) )
266 							aURL = INetURLObject( sURL );
267 					}
268 					if ( INET_PROT_FILE == aURL.GetProtocol() )
269 					{
270 						// #97148# & #102204# -----
271 						try
272 						{
273 							bRealExtensions = !_pDialog->ContentIsFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
274 						}
275 						catch( ::com::sun::star::uno::Exception& )
276 						{
277 							DBG_WARNING( "Exception in lcl_autoUpdateFileExtension" );
278 						}
279 					}
280 				}
281 
282 				if ( bRealExtensions )
283 				{
284 					SetFsysExtension_Impl( aNewFile, _pDialog->GetDefaultExt() );
285 					_pDialog->setCurrentFileText( aNewFile );
286 				}
287 			}
288 		}
289 	}
290 
291 	//-------------------------------------------------------------------------
292 	sal_Bool lcl_getHomeDirectory( const String& _rForURL, String& /* [out] */ _rHomeDir )
293 	{
294 		_rHomeDir.Erase();
295 
296 		// now ask the content broker for a provider for this scheme
297         //=================================================================
298 		try
299 		{
300 			// get the content provider manager
301 			::ucbhelper::ContentBroker* pBroker = ::ucbhelper::ContentBroker::get();
302 			Reference< XContentProviderManager > xProviderManager;
303 			if ( pBroker )
304 				xProviderManager = pBroker->getContentProviderManagerInterface();
305 
306             //=================================================================
307 			// get the provider for the current scheme
308 			Reference< XContentProvider > xProvider;
309 			if ( xProviderManager.is() )
310 				xProvider = xProviderManager->queryContentProvider( _rForURL );
311 
312 			DBG_ASSERT( xProvider.is(), "lcl_getHomeDirectory: could not find a (valid) content provider for the current URL!" );
313 			Reference< XPropertySet > xProviderProps( xProvider, UNO_QUERY );
314 			if ( xProviderProps.is() )
315 			{
316 				Reference< XPropertySetInfo > xPropInfo = xProviderProps->getPropertySetInfo();
317 				const ::rtl::OUString sHomeDirPropertyName( RTL_CONSTASCII_USTRINGPARAM( "HomeDirectory" ) );
318 				if ( !xPropInfo.is() || xPropInfo->hasPropertyByName( sHomeDirPropertyName ) )
319 				{
320 					::rtl::OUString sHomeDirectory;
321 					xProviderProps->getPropertyValue( sHomeDirPropertyName ) >>= sHomeDirectory;
322 					_rHomeDir = sHomeDirectory;
323 				}
324 			}
325 		}
326 		catch( const Exception& )
327 		{
328 			DBG_ERROR( "lcl_getHomeDirectory: caught an exception!" );
329 		}
330 		return 0 < _rHomeDir.Len();
331 	}
332 
333     //---------------------------------------------------------------------
334 	static String lcl_ensureFinalSlash( const String& _rDir )
335 	{
336 		INetURLObject aWorkPathObj( _rDir, INET_PROT_FILE );
337 		aWorkPathObj.setFinalSlash();
338 		return  aWorkPathObj.GetMainURL( INetURLObject::NO_DECODE );
339 	}
340 
341     //---------------------------------------------------------------------
342     void    convertStringListToUrls( const String& _rColonSeparatedList, ::std::vector< String >& _rTokens, bool _bFinalSlash )
343     {
344         const sal_Unicode s_cSeparator =
345 #if defined(WNT) || defined(OS2)
346             ';'
347 #else
348             ':'
349 #endif
350             ;
351         xub_StrLen nTokens = _rColonSeparatedList.GetTokenCount( s_cSeparator );
352         _rTokens.resize( 0 ); _rTokens.reserve( nTokens );
353         for ( xub_StrLen i=0; i<nTokens; ++i )
354         {
355             // the current token in the list
356             String sCurrentToken = _rColonSeparatedList.GetToken( i, s_cSeparator );
357             if ( !sCurrentToken.Len() )
358                 continue;
359 
360             INetURLObject aCurrentURL;
361 
362             String sURL;
363             if ( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCurrentToken, sURL ) )
364                 aCurrentURL = INetURLObject( sURL );
365             else
366             {
367                 // smart URL parsing, assuming FILE protocol
368                 aCurrentURL = INetURLObject( sCurrentToken, INET_PROT_FILE );
369             }
370 
371             if ( _bFinalSlash )
372                 aCurrentURL.setFinalSlash( );
373             else
374                 aCurrentURL.removeFinalSlash( );
375             _rTokens.push_back( aCurrentURL.GetMainURL( INetURLObject::NO_DECODE ) );
376         }
377     }
378 
379     //---------------------------------------------------------------------
380     struct RemoveFinalSlash : public ::std::unary_function< String, void >
381     {
382         void operator()( String& _rURL )
383         {
384             INetURLObject aURL( _rURL );
385 #if defined(WNT) || defined(OS2)
386             if ( aURL.getSegmentCount() > 1 )
387 #endif
388                 aURL.removeFinalSlash( );
389             _rURL = aURL.GetMainURL( INetURLObject::NO_DECODE );
390         }
391     };
392 
393     // -----------------------------------------------------------------------
394     /** retrieves the value of an environment variable
395         @return <TRUE/> if and only if the retrieved string value is not empty
396     */
397     bool getEnvironmentValue( const sal_Char* _pAsciiEnvName, ::rtl::OUString& _rValue )
398     {
399         _rValue = ::rtl::OUString();
400         ::rtl::OUString sEnvName = ::rtl::OUString::createFromAscii( _pAsciiEnvName );
401         osl_getEnvironment( sEnvName.pData, &_rValue.pData );
402         return _rValue.getLength() != 0;
403     }
404 }
405 
406 //***************************************************************************
407 // ControlChain_Impl
408 //***************************************************************************
409 
410 struct ControlChain_Impl
411 {
412 	Window* 		   _pControl;
413 	ControlChain_Impl* _pNext;
414 	sal_Bool			   _bHasOwnerShip;
415 
416 	ControlChain_Impl( Window* pControl, ControlChain_Impl* pNext );
417 	~ControlChain_Impl();
418 };
419 
420 //***************************************************************************
421 
422 ControlChain_Impl::ControlChain_Impl
423 (
424 	Window* pControl,
425 	ControlChain_Impl* pNext
426 )
427 	: _pControl( pControl ),
428 	  _pNext( pNext ),
429 	  _bHasOwnerShip( sal_True )
430 {
431 }
432 
433 //***************************************************************************
434 
435 ControlChain_Impl::~ControlChain_Impl()
436 {
437 	if ( _bHasOwnerShip )
438 	{
439 		delete _pControl;
440 	}
441 	delete _pNext;
442 }
443 
444 //*****************************************************************************
445 // ResMgrHolder
446 //*****************************************************************************
447 namespace
448 {
449 	struct ResMgrHolder
450 	{
451 		ResMgr * operator ()()
452 		{
453 			return ResMgr::CreateResMgr (CREATEVERSIONRESMGR_NAME(fps_office));
454 		}
455 
456 		static ResMgr * getOrCreate()
457 		{
458 			return rtl_Instance<
459 				ResMgr, ResMgrHolder,
460 				osl::MutexGuard, osl::GetGlobalMutex >::create (
461 					ResMgrHolder(), osl::GetGlobalMutex());
462 		}
463 	};
464 
465 	struct SvtResId : public ResId
466 	{
467 		SvtResId (sal_uInt16 nId) : ResId (nId, *ResMgrHolder::getOrCreate()) {}
468 	};
469 }
470 
471 //*****************************************************************************
472 // SvtFileDialog
473 //*****************************************************************************
474 SvtFileDialog::SvtFileDialog
475 (
476 	Window* _pParent,
477 	WinBits nBits,
478 	WinBits nExtraBits
479 ) :
480 	ModalDialog( _pParent, SvtResId( DLG_SVT_EXPLORERFILE ) )
481 
482     ,_pUserControls( NULL )
483     ,_pCbReadOnly( NULL )
484 	,_pCbLinkBox( NULL)
485     ,_pCbPreviewBox( NULL )
486     ,_pCbSelection( NULL )
487     ,_pPbPlay( NULL )
488     ,_pPrevWin( NULL )
489     ,_pPrevBmp( NULL )
490     ,_pFileView( NULL )
491     ,_pFileNotifier( NULL )
492     ,_pImp( new SvtExpFileDlg_Impl( nBits ) )
493     ,_nExtraBits( nExtraBits )
494     ,_bIsInExecute( sal_False )
495     ,m_bInExecuteAsync( false )
496 	,m_bHasFilename( false )
497 {
498 	Init_Impl( nBits );
499 }
500 
501 //*****************************************************************************
502 
503 SvtFileDialog::SvtFileDialog ( Window* _pParent, WinBits nBits )
504     :ModalDialog( _pParent, SvtResId( DLG_SVT_EXPLORERFILE ) )
505     ,_pUserControls( NULL )
506     ,_pCbReadOnly( NULL )
507 	,_pCbLinkBox( NULL)
508     ,_pCbPreviewBox( NULL )
509     ,_pCbSelection( NULL )
510     ,_pPbPlay( NULL )
511     ,_pPrevWin( NULL )
512     ,_pPrevBmp( NULL )
513     ,_pFileView( NULL )
514     ,_pFileNotifier( NULL )
515     ,_pImp( new SvtExpFileDlg_Impl( nBits ) )
516     ,_nExtraBits( 0L )
517     ,_bIsInExecute( sal_False )
518 	,m_bHasFilename( false )
519 {
520 	Init_Impl( nBits );
521 }
522 
523 //*****************************************************************************
524 
525 SvtFileDialog::~SvtFileDialog()
526 {
527 	if ( _pImp->_aIniKey.Len() )
528 	{
529 		// save window state
530 		SvtViewOptions aDlgOpt( E_DIALOG, _pImp->_aIniKey );
531         aDlgOpt.SetWindowState( String( GetWindowState(), osl_getThreadTextEncoding() ) );
532 		String sUserData = _pFileView->GetConfigString();
533 		aDlgOpt.SetUserItem( ::rtl::OUString::createFromAscii( "UserData" ),
534 							 makeAny( ::rtl::OUString( sUserData ) ) );
535 	}
536 
537 	_pFileView->SetSelectHdl( Link() );
538 
539 	delete _pImp;
540 	delete _pFileView;
541 
542 	delete _pCbReadOnly;
543 	delete _pCbLinkBox;
544     delete _pCbPreviewBox;
545     delete _pCbSelection;
546     delete _pPbPlay;
547     delete _pPrevWin;
548     delete _pPrevBmp;
549 
550 	delete _pUserControls;
551 }
552 
553 //*****************************************************************************
554 
555 void SvtFileDialog::Init_Impl
556 (
557 	WinBits nStyle
558 )
559 {
560 	sal_Bool bIsHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
561 	m_aImages = ImageList( SvtResId( bIsHighContrast ? RID_FILEPICKER_IMAGES_HC : RID_FILEPICKER_IMAGES ) );
562 
563 	_pImp->_nStyle = nStyle;
564 	_pImp->_a6Size = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
565 	_pImp->_eMode = ( nStyle & WB_SAVEAS ) ? FILEDLG_MODE_SAVE : FILEDLG_MODE_OPEN;
566 	_pImp->_eDlgType = FILEDLG_TYPE_FILEDLG;
567 
568 	if ( ( nStyle & SFXWB_PATHDIALOG ) == SFXWB_PATHDIALOG )
569 		_pImp->_eDlgType = FILEDLG_TYPE_PATHDLG;
570 
571 	// Set the directory for the "back to the default dir" button
572 	INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() );
573 	SetStandardDir( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) );
574 
575 	// Reichweite bestimmen.
576 	if ( !( nStyle & SFXWB_NOREMOTE ) )
577 	{
578 		_pImp->_nState |= FILEDLG_STATE_REMOTE;
579 	}
580 
581 	// Kontrollelement erzeugen, wobei die Reihenfolge die Tab-Steuerung
582 	// bestimmt.
583 	_pImp->_pFtFileName = new FixedText( this, SvtResId( FT_EXPLORERFILE_FILENAME ) );
584 
585     SvtURLBox* pURLBox = new SvtURLBox( this );
586     pURLBox->SetUrlFilter( &m_aURLFilter );
587     _pImp->_pEdFileName = pURLBox;
588 
589     Edit aDummy( this, SvtResId( ED_EXPLORERFILE_FILENAME ) );
590     _pImp->_pEdFileName->SetPosSizePixel( aDummy.GetPosPixel(), aDummy.GetSizePixel() );
591     _pImp->_pEdFileName->Show();
592     pURLBox->SetSelectHdl( LINK( this, SvtFileDialog, EntrySelectHdl_Impl ) );
593     pURLBox->SetOpenHdl( STATIC_LINK( this, SvtFileDialog, OpenHdl_Impl ) );
594 
595     // in folder picker mode, only auto-complete directories (no files)
596     bool bIsFolderPicker = ( _pImp->_eDlgType == FILEDLG_TYPE_PATHDLG );
597     pURLBox->SetOnlyDirectories( bIsFolderPicker );
598 
599     // in save mode, don't use the autocompletion as selection in the edit part
600     bool bSaveMode = ( FILEDLG_MODE_SAVE == _pImp->_eMode );
601     pURLBox->SetNoURLSelection( bSaveMode );
602 
603     _pImp->_pEdFileName->SetHelpId( HID_FILEDLG_AUTOCOMPLETEBOX );
604 
605     _pImp->_pFtFileType = new FixedText( this, SvtResId( FT_EXPLORERFILE_FILETYPE ) );
606 	_pImp->CreateFilterListControl( this, SvtResId( LB_EXPLORERFILE_FILETYPE ) );
607 
608 	// move the filter listbox to the space occupied by the version listbox
609     // if that box isn't needed
610     if ( !( _nExtraBits & SFX_EXTRA_SHOWVERSIONS ) &&
611          !( _nExtraBits & SFX_EXTRA_TEMPLATES ) &&
612          !( _nExtraBits & SFX_EXTRA_IMAGE_TEMPLATE ) )
613 	{
614 		{
615 			FixedText aSharedListBoxLabel( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) );
616 			_pImp->_pFtFileType->SetPosPixel( aSharedListBoxLabel.GetPosPixel() );
617 		}
618 
619 		{
620 			ListBox aSharedListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) );
621 			_pImp->GetFilterListControl()->SetPosPixel( aSharedListBox.GetPosPixel() );
622 		}
623 	}
624 
625 	_pImp->_pFtCurrentPath = new FixedText( this, SvtResId( FT_EXPLORERFILE_CURRENTPATH ) );
626     WinBits nTmpStyle = _pImp->_pFtCurrentPath->GetStyle();
627     nTmpStyle |= WB_PATHELLIPSIS;
628     _pImp->_pFtCurrentPath->SetStyle( nTmpStyle );
629 
630     _pImp->_pBtnFileOpen = new PushButton( this, SvtResId( BTN_EXPLORERFILE_OPEN ) );
631 	_pImp->_pBtnCancel = new CancelButton( this, SvtResId( BTN_EXPLORERFILE_CANCEL ) );
632 	_pImp->_pBtnHelp = new HelpButton( this, SvtResId( BTN_EXPLORERFILE_HELP ) );
633 
634 	_pImp->_pBtnUp = new SvtUpButton_Impl( this, SvtResId( BTN_EXPLORERFILE_UP ) );
635 	_pImp->_pBtnNewFolder = new ImageButton( this, SvtResId( BTN_EXPLORERFILE_NEWFOLDER ) );
636 	_pImp->_pBtnNewFolder->SetStyle( _pImp->_pBtnNewFolder->GetStyle() | WB_NOPOINTERFOCUS );
637     _pImp->_pBtnStandard = new SvtTravelButton_Impl( this, SvtResId( BTN_EXPLORERFILE_STANDARD ) );
638 
639 	_pImp->_pBtnUp->SetAccessibleName( _pImp->_pBtnUp->GetQuickHelpText() );
640 	_pImp->_pBtnNewFolder->SetAccessibleName( _pImp->_pBtnNewFolder->GetQuickHelpText() );
641 	_pImp->_pBtnStandard->SetAccessibleName( _pImp->_pBtnStandard->GetQuickHelpText() );
642 
643 	if ( ( nStyle & SFXWB_MULTISELECTION ) == SFXWB_MULTISELECTION )
644 		_pImp->_bMultiSelection = sal_True;
645 
646 	_pFileView = new SvtFileView( this, SvtResId( CTL_EXPLORERFILE_FILELIST ),
647 									   FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType,
648 									   _pImp->_bMultiSelection );
649     _pFileView->SetUrlFilter( &m_aURLFilter );
650 	_pFileView->EnableAutoResize();
651 
652 	_pFileView->SetHelpId( HID_FILEDLG_STANDARD );
653 	_pFileView->SetStyle( _pFileView->GetStyle() | WB_TABSTOP );
654 
655 	// Positionen und Groessen der Knoepfe bestimmen.
656 	Image aNewFolderImg( GetButtonImage( IMG_FILEDLG_CREATEFOLDER ) );
657 	_pImp->_pBtnNewFolder->SetModeImage( aNewFolderImg );
658 
659 	Size aSize( aNewFolderImg.GetSizePixel() );
660 	aSize.Width() += FILEDIALOG_DEF_IMAGEBORDER;
661 	aSize.Height() += FILEDIALOG_DEF_IMAGEBORDER;
662 	_pImp->_pBtnNewFolder->SetSizePixel( aSize );
663 	_pImp->_pBtnUp->SetSizePixel( aSize );
664 	_pImp->_pBtnStandard->SetSizePixel( aSize );
665 
666 	Size aDlgSize = GetOutputSizePixel();
667 	long n6AppFontInPixel =
668 			LogicToPixel( Size( 6, 0 ), MAP_APPFONT ).Width();
669 	long n3AppFontInPixel =
670 			LogicToPixel( Size( 3, 0 ), MAP_APPFONT ).Width();
671 
672     // calculate the length of all buttons
673 	const sal_uInt16 nBtnCount = 3; // "previous level", "new folder" and "standard dir"
674 	long nDelta = n6AppFontInPixel; // right border
675 	nDelta += ( nBtnCount * aSize.Width() ); // button count * button width
676 	nDelta += ( n3AppFontInPixel + n3AppFontInPixel / 2 ); // spacing 1*big 1*small
677 
678     Point aPos(
679         aDlgSize.Width() - nDelta,
680         _pImp->_pBtnUp->GetPosPixel().Y()
681     );
682     Size aCurPathSize(
683         aPos.X() - n6AppFontInPixel,
684         _pImp->_pFtCurrentPath->GetOutputSizePixel().Height()
685     );
686 	_pImp->_pFtCurrentPath->SetOutputSizePixel( aCurPathSize );
687 	_pImp->_pBtnUp->SetPosPixel( aPos );
688 	aPos.X() += aSize.Width();
689 	aPos.X() += n3AppFontInPixel;
690 	_pImp->_pBtnNewFolder->SetPosPixel( aPos );
691 	aPos.X() += aSize.Width();
692 	aPos.X() += n3AppFontInPixel / 2;
693 	_pImp->_pBtnStandard->SetPosPixel( aPos );
694 	nDelta = aSize.Height();
695 	nDelta -= aCurPathSize.Height();
696 	nDelta /= 2;
697 	Point aCurPathPos = _pImp->_pFtCurrentPath->GetPosPixel();
698 	aCurPathPos.Y() += nDelta;
699 	_pImp->_pFtCurrentPath->SetPosPixel( aCurPathPos );
700 
701     if ( nStyle & SFXWB_READONLY )
702     {
703         _pCbReadOnly = new CheckBox( this, SvtResId( CB_EXPLORERFILE_READONLY ) );
704         _pCbReadOnly->SetHelpId( HID_FILEOPEN_READONLY );
705         _pCbReadOnly->SetText( SvtResId( STR_SVT_FILEPICKER_READONLY ) );
706         AddControl( _pCbReadOnly );
707         ReleaseOwnerShip( _pCbReadOnly );
708         _pCbReadOnly->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
709     }
710 
711     if ( nStyle & SFXWB_PASSWORD )
712     {
713         _pImp->_pCbPassword = new CheckBox( this, SvtResId( CB_EXPLORERFILE_PASSWORD ) );
714         _pImp->_pCbPassword->SetText( SvtResId( STR_SVT_FILEPICKER_PASSWORD ) );
715         AddControl( _pImp->_pCbPassword );
716         ReleaseOwnerShip( _pImp->_pCbPassword );
717         _pImp->_pCbPassword->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
718     }
719 
720     // set the ini file for extracting the size
721     _pImp->_aIniKey = IODLG_CONFIGNAME;
722 
723     AddControls_Impl( );
724 
725 	// Zahl der Pixel bestimmen, um die die anderen Elemente in der Position
726 	// Angepasst werden muessen.
727 	aPos.Y() += aSize.Height();
728 	aPos.Y() += LogicToPixel( Size( 0, 6 ), MAP_APPFONT ).Height();
729 	long nYOffset = aPos.Y();
730 	aPos = _pFileView->GetPosPixel();
731 	nYOffset -= aPos.Y();
732 
733 	// Positionen der uebrigen Elemente anpassen.
734 	aPos.Y() += nYOffset;
735 	_pFileView->SetPosPixel( aPos );
736 
737 	lcl_MoveControl( _pImp->_pFtFileName, 0, nYOffset );
738 	lcl_MoveControl( _pImp->_pEdFileName, 0, nYOffset );
739 
740 	lcl_MoveControl( _pImp->_pFtFileVersion, 0, nYOffset );
741 	lcl_MoveControl( _pImp->_pLbFileVersion, 0, nYOffset );
742 
743 	lcl_MoveControl( _pImp->_pFtTemplates, 0, nYOffset );
744 	lcl_MoveControl( _pImp->_pLbTemplates, 0, nYOffset );
745 
746 	lcl_MoveControl( _pImp->_pFtImageTemplates, 0, nYOffset );
747 	lcl_MoveControl( _pImp->_pLbImageTemplates, 0, nYOffset );
748 
749 	lcl_MoveControl( _pImp->_pFtFileType, 0, nYOffset );
750 	lcl_MoveControl( _pImp->GetFilterListControl(), 0, nYOffset );
751 
752 	lcl_MoveControl( _pImp->_pBtnFileOpen, 0, nYOffset );
753 	lcl_MoveControl( _pImp->_pBtnCancel, 0, nYOffset );
754 
755 	lcl_MoveControl( _pImp->_pBtnHelp, 0, nYOffset + 3 );
756 		// a little more spacing between Cancel- and HelpButton
757 
758 	// Groesse des Dialoges anpassen.
759 	aSize = GetSizePixel();
760 	aSize.Height() += nYOffset;
761 	SetSizePixel( aSize );
762 
763 	// Beschriftungen dem Modus anpassen.
764 	sal_uInt16 nResId = STR_EXPLORERFILE_OPEN;
765 	sal_uInt16 nButtonResId = 0;
766 
767 	if ( nStyle & WB_SAVEAS )
768 	{
769 		nResId = STR_EXPLORERFILE_SAVE;
770 		nButtonResId = STR_EXPLORERFILE_BUTTONSAVE;
771 	}
772 
773 	if ( ( nStyle & SFXWB_PATHDIALOG ) == SFXWB_PATHDIALOG )
774 	{
775 		_pImp->_pFtFileName->SetText( SvtResId( STR_PATHNAME ) );
776 		nResId = STR_PATHSELECT;
777 		nButtonResId = STR_BUTTONSELECT;
778 	}
779 
780 	SetText( SvtResId( nResId ) );
781 
782 	if ( nButtonResId )
783 		_pImp->_pBtnFileOpen->SetText( SvtResId( nButtonResId ) );
784 
785 	if ( FILEDLG_TYPE_FILEDLG != _pImp->_eDlgType )
786 	{
787 		_pImp->_pFtFileType->Hide();
788 		_pImp->GetFilterListControl()->Hide();
789 	}
790 
791 	// Einstellungen der Steuerelemente vornehmen.
792 	_pImp->_pBtnNewFolder->SetClickHdl( STATIC_LINK( this, SvtFileDialog, NewFolderHdl_Impl ) );
793 	_pImp->_pBtnFileOpen->SetClickHdl( STATIC_LINK( this, SvtFileDialog, OpenHdl_Impl ) );
794 	_pImp->_pBtnCancel->SetClickHdl( LINK( this, SvtFileDialog, CancelHdl_Impl ) );
795 	_pImp->SetFilterListSelectHdl( STATIC_LINK( this, SvtFileDialog, FilterSelectHdl_Impl ) );
796 	_pImp->_pEdFileName->SetGetFocusHdl( STATIC_LINK( this, SvtFileDialog, FileNameGetFocusHdl_Impl ) );
797 	_pImp->_pEdFileName->SetModifyHdl( STATIC_LINK( this, SvtFileDialog, FileNameModifiedHdl_Impl ) );
798 	_pFileView->SetSelectHdl( LINK( this, SvtFileDialog, SelectHdl_Impl ) );
799 	_pFileView->SetDoubleClickHdl( LINK( this, SvtFileDialog, DblClickHdl_Impl ) );
800 	_pFileView->SetOpenDoneHdl( LINK( this, SvtFileDialog, OpenDoneHdl_Impl ) );
801 
802 	// Resourcen freigeben.
803 	FreeResource();
804 
805 	// Timer fuer Filterbox Travel setzen
806 	_pImp->_aFilterTimer.SetTimeout( TRAVELFILTER_TIMEOUT );
807 	_pImp->_aFilterTimer.SetTimeoutHdl( STATIC_LINK( this, SvtFileDialog, FilterSelectHdl_Impl ) );
808 
809 	if ( WB_SAVEAS & nStyle )
810 	{
811 		// different help ids if in save-as mode
812 		// 90744 - 09.08.2001 - frank.schoenheit@sun.com
813 		SetHelpId( HID_FILESAVE_DIALOG );
814 
815 		_pImp->_pEdFileName->SetHelpId( HID_FILESAVE_FILEURL );
816 		_pImp->_pBtnFileOpen->SetHelpId( HID_FILESAVE_DOSAVE );
817 		_pImp->_pBtnNewFolder->SetHelpId( HID_FILESAVE_CREATEDIRECTORY );
818 		_pImp->_pBtnStandard->SetHelpId( HID_FILESAVE_DEFAULTDIRECTORY );
819 		_pImp->_pBtnUp->SetHelpId( HID_FILESAVE_LEVELUP );
820 		_pImp->GetFilterListControl()->SetHelpId( HID_FILESAVE_FILETYPE );
821 		_pFileView->SetHelpId( HID_FILESAVE_FILEVIEW );
822 
823 		// formerly, there was only _pLbFileVersion, which was used for 3 different
824 		// use cases. For reasons of maintainability, I introduced extra members (_pLbTemplates, _pLbImageTemplates)
825 		// for the extra use cases, and separated _pLbFileVersion
826 		// I did not find out in which cases the help ID is really needed HID_FILESAVE_TEMPLATE - all
827 		// tests I made lead to a dialog where _no_ of the three list boxes was present.
828 		// 96930 - 15.08.2002 - fs@openoffice.org
829 		if ( _pImp->_pLbFileVersion )
830 			_pImp->_pLbFileVersion->SetHelpId( HID_FILESAVE_TEMPLATE );
831 		if ( _pImp->_pLbTemplates )
832 			_pImp->_pLbTemplates->SetHelpId( HID_FILESAVE_TEMPLATE );
833 		if ( _pImp->_pLbImageTemplates )
834 			_pImp->_pLbImageTemplates->SetHelpId( HID_FILESAVE_TEMPLATE );
835 
836 		if ( _pImp->_pCbPassword ) _pImp->_pCbPassword->SetHelpId( HID_FILESAVE_SAVEWITHPASSWORD );
837 		if ( _pImp->_pCbAutoExtension ) _pImp->_pCbAutoExtension->SetHelpId( HID_FILESAVE_AUTOEXTENSION );
838 		if ( _pImp->_pCbOptions ) _pImp->_pCbOptions->SetHelpId( HID_FILESAVE_CUSTOMIZEFILTER );
839 		if ( _pCbSelection ) _pCbSelection->SetHelpId( HID_FILESAVE_SELECTION );
840 	}
841 
842 	// correct the z-order of the controls
843 	implArrangeControls();
844 
845     // special URLs, such as favourites and "restricted" paths
846     implInitializeSpecialURLLists( );
847 
848     /// read our settings from the configuration
849     m_aConfiguration = OConfigurationTreeRoot::createWithServiceFactory(
850         ::comphelper::getProcessServiceFactory(),
851         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI/FilePicker" ) )
852     );
853 }
854 
855 //*****************************************************************************
856 
857 IMPL_STATIC_LINK( SvtFileDialog, NewFolderHdl_Impl, PushButton*, EMPTYARG )
858 {
859     pThis->_pFileView->EndInplaceEditing( false );
860 
861     INetURLObject aObj( pThis->_pFileView->GetViewURL() );
862 	String sFolderName = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET, RTL_TEXTENCODING_UTF8 );
863     svtools::QueryFolderNameDialog aDlg( pThis, sFolderName, String( SvtResId( STR_SVT_NEW_FOLDER ) ) );
864     sal_Bool bHandled = sal_False;
865 
866 	while ( !bHandled )
867 	{
868 		if ( aDlg.Execute() == RET_OK )
869 			bHandled = pThis->_pFileView->CreateNewFolder( aDlg.GetName() );
870 		else
871 			bHandled = sal_True;
872 	}
873 
874 	return 0;
875 }
876 
877 //*****************************************************************************
878 
879 IMPL_STATIC_LINK_NOINSTANCE( SvtFileDialog, ViewHdl_Impl, ImageButton*, EMPTYARG )
880 {
881 	return 0;
882 }
883 
884 //*****************************************************************************
885 //-----------------------------------------------------------------------------
886 sal_Bool SvtFileDialog::createNewUserFilter( const String& _rNewFilter, sal_Bool _bAllowUserDefExt )
887 {
888 	// delete the old user filter and create a new one
889 	DELETEZ( _pImp->_pUserFilter );
890 	_pImp->_pUserFilter = new SvtFileDialogFilter_Impl( _rNewFilter, _rNewFilter );
891 
892 	// remember the extension
893 	sal_Bool bIsAllFiles = _rNewFilter.EqualsAscii( FILEDIALOG_FILTER_ALL );
894 	if ( bIsAllFiles )
895 		EraseDefaultExt();
896 	else
897 		SetDefaultExt( _rNewFilter.Copy( 2 ) );
898 		// TODO: this is nonsense. In the whole file there are a lotta places where we assume that a user filter
899 		// is always "*.<something>". But changing this would take some more time than I have now ...
900 		// 05.12.2001 - 95486 - fs@openoffice.org
901 
902 	// now, the default extension is set to the one of the user filter (or empty)
903 	// if the former is not allowed (_bAllowUserDefExt = <FALSE/>), we have to use the ext of the current filter
904 	// (if possible)
905 	sal_Bool bUseCurFilterExt = sal_True;
906 	String sUserFilter = _pImp->_pUserFilter->GetType();
907 	xub_StrLen nSepPos = sUserFilter.SearchBackward( '.' );
908 	if ( STRING_NOTFOUND != nSepPos )
909 	{
910 		String sUserExt = sUserFilter.Copy( nSepPos + 1 );
911 		if	(	( STRING_NOTFOUND == sUserExt.Search( '*' ) )
912 			&&	( STRING_NOTFOUND == sUserExt.Search( '?' ) )
913 			)
914 			bUseCurFilterExt = sal_False;
915 	}
916 
917 	if ( !_bAllowUserDefExt || bUseCurFilterExt )
918 	{
919 		if ( _pImp->GetCurFilter( ) )
920             SetDefaultExt( _pImp->GetCurFilter( )->GetExtension() );
921 		else
922 			EraseDefaultExt();
923 	}
924 
925 	// outta here
926 	return bIsAllFiles;
927 }
928 
929 //-----------------------------------------------------------------------------
930 #define FLT_NONEMPTY		0x0001
931 #define FLT_CHANGED			0x0002
932 #define FLT_USERFILTER		0x0004
933 #define FLT_ALLFILESFILTER	0x0008
934 
935 //-----------------------------------------------------------------------------
936 sal_uInt16 SvtFileDialog::adjustFilter( const String& _rFilter )
937 {
938 	sal_uInt16 nReturn = 0;
939 
940 	const sal_Bool bNonEmpty = ( _rFilter.Len() != 0 );
941 	if ( bNonEmpty )
942 	{
943 		nReturn |= FLT_NONEMPTY;
944 
945 		sal_Bool bFilterChanged = sal_True;
946 
947 		// search for a corresponding filter
948 		SvtFileDialogFilter_Impl* pFilter = FindFilter_Impl( _rFilter, sal_False, bFilterChanged );
949 
950 #ifdef AUTOSELECT_USERFILTER
951 		// if we found a filter which without allowing multi-extensions -> select it
952 		if ( pFilter )
953 		{
954 			_pImp->SelectFilterListEntry( pFilter->GetName() );
955 			_pImp->SetCurFilter( pFilter );
956 		}
957 #endif // AUTOSELECT_USERFILTER
958 
959 		// look for multi-ext filters if necessary
960 		if ( !pFilter )
961 			pFilter = FindFilter_Impl( _rFilter, sal_True, bFilterChanged );
962 
963 		if ( bFilterChanged )
964 			nReturn |= FLT_CHANGED;
965 
966 		if ( !pFilter )
967 		{
968 			nReturn |= FLT_USERFILTER;
969 			// no filter found : use it as user defined filter
970 #ifdef AUTOSELECT_USERFILTER
971 			if ( createNewUserFilter( _rFilter, sal_True ) )
972 #else
973 			if ( createNewUserFilter( _rFilter, sal_False ) )
974 #endif
975 			{	// it's the "all files" filter
976 				nReturn |= FLT_ALLFILESFILTER;
977 
978 #ifdef AUTOSELECT_USERFILTER
979 				// select the "all files" entry
980 				String sAllFilesFilter( SvtResId( STR_FILTERNAME_ALL ) );
981 				if ( _pImp->HasFilterListEntry( sAllFilesFilter ) )
982 				{
983 					_pImp->SelectFilterListEntry( sAllFilesFilter );
984 					_pImp->SetCurFilter( _pImp->GetSelectedFilterEntry( sAllFilesFilter ) );
985 				}
986 				else
987 					_pImp->SetNoFilterListSelection( );	// there is no "all files" entry
988 #endif // AUTOSELECT_USERFILTER
989 			}
990 #ifdef AUTOSELECT_USERFILTER
991 			else
992 				_pImp->SetNoFilterListSelection( );
993 #endif // AUTOSELECT_USERFILTER
994 		}
995 	}
996 
997 	return nReturn;
998 }
999 
1000 //-----------------------------------------------------------------------------
1001 IMPL_LINK( SvtFileDialog, CancelHdl_Impl, void*, EMPTYARG )
1002 {
1003     if ( m_pCurrentAsyncAction.is() )
1004     {
1005         m_pCurrentAsyncAction->cancel();
1006         onAsyncOperationFinished();
1007     }
1008     else
1009     {
1010         EndDialog( sal_False );
1011     }
1012     return 1L;
1013 }
1014 
1015 //-----------------------------------------------------------------------------
1016 IMPL_STATIC_LINK( SvtFileDialog, OpenHdl_Impl, void*, pVoid )
1017 {
1018 	if ( pThis->_pImp->_bMultiSelection && pThis->_pFileView->GetSelectionCount() > 1 )
1019 	{
1020 		// bei Multiselektion spezielles Open
1021 		pThis->OpenMultiSelection_Impl();
1022 		return 0;
1023 	}
1024 
1025 	String aFileName;
1026     String aOldPath( pThis->_pFileView->GetViewURL() );
1027 	if ( pThis->_pImp->_bDoubleClick || pThis->_pFileView->HasChildPathFocus() )
1028 		// Selection done by doubleclicking in the view, get filename from the view
1029 		aFileName = pThis->_pFileView->GetCurrentURL();
1030 
1031 	if ( !aFileName.Len() )
1032 	{
1033 		// if an entry is selected in the view ....
1034 		if ( pThis->_pFileView->GetSelectionCount() )
1035 		{	// -> use this one. This will allow us to step down this folder
1036 			// #i8928# - 2002-12-20 - fs@openoffice.org
1037 			aFileName = pThis->_pFileView->GetCurrentURL();
1038 		}
1039 	}
1040 
1041 	if ( !aFileName.Len() )
1042 	{
1043 		if ( pThis->_pImp->_eMode == FILEDLG_MODE_OPEN && pThis->_pImp->_pEdFileName->IsTravelSelect() )
1044 			// OpenHdl called from URLBox; travelling through the list of URLs should not cause an opening
1045 			return 0;		            // MBA->PB: seems to be called never ?!
1046 
1047 		// get the URL from from the edit field ( if not empty )
1048 		if ( pThis->_pImp->_pEdFileName->GetText().Len() )
1049 		{
1050 			String aText = pThis->_pImp->_pEdFileName->GetText();
1051 
1052 			// did we reach the root?
1053 			if ( !INetURLObject( aOldPath ).getSegmentCount() )
1054 			{
1055 				if ( ( aText.Len() == 2 && aText.EqualsAscii( ".." ) ) ||
1056 					 ( aText.Len() == 3 && ( aText.EqualsAscii( "..\\" ) || aText.EqualsAscii( "../" ) ) ) )
1057 					// don't go higher than the root
1058 					return 0;
1059 			}
1060 
1061 #if defined( UNX ) || defined( FS_PRIV_DEBUG )
1062 			if ( ( 1 == aText.Len() ) && ( '~' == aText.GetBuffer()[0] ) )
1063 			{
1064 				// go to the home directory
1065 				if ( lcl_getHomeDirectory( pThis->_pFileView->GetViewURL(), aFileName ) )
1066 					// in case we got a home dir, reset the text of the edit
1067 					pThis->_pImp->_pEdFileName->SetText( String() );
1068 			}
1069 			if ( !aFileName.Len() )
1070 #endif
1071 			{
1072 				// get url from autocomplete edit
1073         		aFileName = pThis->_pImp->_pEdFileName->GetURL();
1074 			}
1075 		}
1076 		else if ( pVoid == pThis->_pImp->_pBtnFileOpen )
1077 			// OpenHdl was called for the "Open" Button; if edit field is empty, use selected element in the view
1078 			aFileName = pThis->_pFileView->GetCurrentURL();
1079 	}
1080 
1081 	// MBA->PB: ?!
1082 	if ( !aFileName.Len() && pVoid == pThis->_pImp->_pEdFileName && pThis->_pImp->_pUserFilter )
1083 	{
1084 		DELETEZ( pThis->_pImp->_pUserFilter );
1085 		return 0;
1086 	}
1087 
1088 	sal_uInt16 nLen = aFileName.Len();
1089 	if ( !nLen )
1090 	{
1091 		// if the dialog was opened to select a folder, the last selected folder should be selected
1092 		if( pThis->_pImp->_eDlgType == FILEDLG_TYPE_PATHDLG )
1093 		{
1094 			aFileName =	pThis->_pImp->_pFtCurrentPath->GetText();
1095 			nLen = aFileName.Len();
1096 		}
1097 		else
1098 			// no file selected !
1099 			return 0;
1100 	}
1101 
1102 	// mark input as selected
1103 	pThis->_pImp->_pEdFileName->SetSelection( Selection( 0, nLen ) );
1104 
1105 	// if a path with wildcards is given, divide the string into path and wildcards
1106 	String aFilter;
1107 	if ( !pThis->IsolateFilterFromPath_Impl( aFileName, aFilter ) )
1108 		return 0;
1109 
1110 	// if a filter was retrieved, there were wildcards !
1111 	sal_uInt16 nNewFilterFlags = pThis->adjustFilter( aFilter );
1112 	if ( nNewFilterFlags & FLT_CHANGED )
1113 	{
1114 		// cut off all text before wildcard in edit and select wildcard
1115 		pThis->_pImp->_pEdFileName->SetText( aFilter );
1116 		pThis->_pImp->_pEdFileName->SetSelection( Selection( 0, aFilter.Len() ) );
1117 	}
1118 
1119     {
1120 	    INetURLObject aFileObject( aFileName );
1121 	    if ( ( aFileObject.GetProtocol() == INET_PROT_NOT_VALID ) && aFileName.Len() )
1122 	    {
1123 		    String sCompleted = SvtURLBox::ParseSmart( aFileName, pThis->_pFileView->GetViewURL(), SvtPathOptions().GetWorkPath() );
1124 		    if ( sCompleted.Len() )
1125 			    aFileName = sCompleted;
1126 	    }
1127     }
1128 
1129 	// Pr"ufen, ob es sich um einen Ordner handelt.
1130     sal_Bool bIsFolder = sal_False;
1131 
1132     // first thing before doing anyhing with the content: Reset it. When the user presses "open" (or "save" or "export",
1133     // for that matter), s/he wants the complete handling, including all possible error messages, even if s/he
1134     // does the same thing for the same content twice, s/he wants both fails to be displayed.
1135     // Without the reset, it could be that the content cached all relevant information, and will not display any
1136     // error messages for the same content a second time ....
1137     pThis->m_aContent.bindTo( ::rtl::OUString( ) );
1138 
1139     // #97148# & #102204# ---------
1140 	if ( aFileName.Len() )
1141 	{
1142         // Make sure we have own Interaction Handler in place. We do not need
1143         // to intercept interactions here, but to record the fact that there
1144         // was an interaction.
1145         SmartContent::InteractionHandlerType eInterActionHandlerType
1146             = pThis->m_aContent.queryCurrentInteractionHandler();
1147         if ( ( eInterActionHandlerType == SmartContent::IHT_NONE ) ||
1148              ( eInterActionHandlerType == SmartContent::IHT_DEFAULT ) )
1149             pThis->m_aContent.enableOwnInteractionHandler(
1150                 OFilePickerInteractionHandler::E_NOINTERCEPTION );
1151 
1152 		bIsFolder = pThis->m_aContent.isFolder( aFileName );
1153 
1154         // access denied to the given resource - and interaction was already
1155         // used => break following operations
1156         OFilePickerInteractionHandler* pHandler
1157             = pThis->m_aContent.getOwnInteractionHandler();
1158 
1159         OSL_ENSURE( pHandler, "Got no Interaction Handler!!!" );
1160 
1161         if ( pHandler->wasAccessDenied() )
1162             return 0;
1163 
1164 		if ( pThis->m_aContent.isInvalid() &&
1165              ( pThis->_pImp->_eMode == FILEDLG_MODE_OPEN ) )
1166         {
1167             if ( !pHandler->wasUsed() )
1168                 ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTS );
1169 
1170 			return 0;
1171         }
1172 
1173         // restore previous Interaction Handler
1174         if ( eInterActionHandlerType == SmartContent::IHT_NONE )
1175             pThis->m_aContent.disableInteractionHandler();
1176         else if ( eInterActionHandlerType == SmartContent::IHT_DEFAULT )
1177             pThis->m_aContent.enableDefaultInteractionHandler();
1178  	}
1179 
1180     if  (   !bIsFolder                                      // no existent folder
1181 		&&	pThis->_pImp->_pCbAutoExtension					// auto extension is enabled in general
1182 		&&	pThis->_pImp->_pCbAutoExtension->IsChecked()	// auto extension is really to be used
1183 		&&	pThis->GetDefaultExt().Len()					// there is a default extension
1184 		&&	pThis->GetDefaultExt() != '*'					// the default extension is not "all"
1185         && !(   FILEDLG_MODE_SAVE == pThis->_pImp->_eMode       // we're saving a file
1186             &&  pThis->_pFileView->GetSelectionCount()          // there is a selected file in the file view -> it will later on
1187             )                                                   //    (in SvtFileDialog::GetPathList) be taken as file to save to
1188                                                                 // (#114818# - 2004-03-17 - fs@openoffice.org)
1189         && FILEDLG_MODE_OPEN != pThis->_pImp->_eMode // pb: #i83408# don't append extension on open
1190         )
1191 	{
1192         // check extension and append the default extension if necessary
1193         appendDefaultExtension(aFileName,
1194                                pThis->GetDefaultExt(),
1195                                pThis->_pImp->GetCurFilter()->GetType());
1196 	}
1197 
1198 	sal_Bool bOpenFolder = ( FILEDLG_TYPE_PATHDLG == pThis->_pImp->_eDlgType ) &&
1199 					   !pThis->_pImp->_bDoubleClick && pVoid != pThis->_pImp->_pEdFileName;
1200 	if ( bIsFolder )
1201 	{
1202 		if ( bOpenFolder )
1203 		{
1204 			pThis->_aPath = aFileName;
1205 		}
1206         else
1207         {
1208 		    if ( aFileName != pThis->_pFileView->GetViewURL() )
1209 		    {
1210                 if ( !pThis->m_aURLFilter.isUrlAllowed( aFileName ) )
1211                 {
1212                     pThis->simulateAccessDenied( aFileName );
1213     			    return 0;
1214                 }
1215 
1216                 pThis->OpenURL_Impl( aFileName );
1217 		    }
1218 		    else
1219             {
1220                 if ( nNewFilterFlags & FLT_CHANGED )
1221                     pThis->ExecuteFilter();
1222             }
1223 
1224             return 0;
1225         }
1226 	}
1227     else if ( !( nNewFilterFlags & FLT_NONEMPTY ) )
1228 	{
1229 		// Ggf. URL speichern.
1230         pThis->_aPath = aFileName;
1231 	}
1232 	else
1233 	{
1234 		// Ggf. neu filtern.
1235 		if ( nNewFilterFlags & FLT_CHANGED )
1236 			pThis->ExecuteFilter();
1237 		return 0;
1238 	}
1239 
1240     INetURLObject aFileObj( aFileName );
1241     if ( aFileObj.HasError() )
1242     {
1243         ErrorHandler::HandleError( ERRCODE_IO_GENERAL );
1244         return 0;
1245     }
1246 
1247     // if restrictions for the allowed folders are in place, we need to do a check here
1248     if ( !pThis->m_aURLFilter.isUrlAllowed( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
1249     {
1250         pThis->simulateAccessDenied( aFileName );
1251         return 0;
1252     }
1253 
1254 	switch ( pThis->_pImp->_eMode )
1255 	{
1256 		case FILEDLG_MODE_SAVE:
1257 		{
1258 			if ( ::utl::UCBContentHelper::Exists( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) ) )
1259 			{
1260 				QueryBox aBox( pThis, WB_YES_NO, SvtResId( STR_SVT_ALREADYEXISTOVERWRITE ) );
1261 				if ( aBox.Execute() != RET_YES )
1262 					return 0;
1263 			}
1264 			else
1265 			{
1266 				String aCurPath;
1267 				if ( ::utl::LocalFileHelper::ConvertURLToSystemPath( aFileName, aCurPath ) )
1268 				{
1269 					// if content does not exist: at least its path must exist
1270 					INetURLObject aPathObj = aFileObj;
1271 					aPathObj.removeSegment();
1272 					// #97148# & #102204# ------------
1273 					sal_Bool bFolder = pThis->m_aContent.isFolder( aPathObj.GetMainURL( INetURLObject::NO_DECODE ) );
1274 					if ( !bFolder )
1275 					{
1276 						ErrorHandler::HandleError( ERRCODE_IO_NOTEXISTSPATH );
1277 						return 0;
1278 					}
1279 				}
1280 			}
1281 		}
1282 		break;
1283 
1284 		case FILEDLG_MODE_OPEN:
1285 		{
1286 			// do an existence check herein, again
1287 			// 16.11.2001 - 93107 - frank.schoenheit@sun.com
1288 
1289 			if ( INET_PROT_FILE == aFileObj.GetProtocol( ) )
1290 			{
1291 				sal_Bool bExists = sal_False;
1292 				// #102204# --------------
1293 				bExists = pThis->m_aContent.is( aFileObj.GetMainURL( INetURLObject::NO_DECODE ) );
1294 
1295 
1296 				if ( !bExists )
1297 				{
1298 					String sError( SvtResId( RID_FILEOPEN_NOTEXISTENTFILE ) );
1299 
1300 					String sInvalidFile( aFileObj.GetMainURL( INetURLObject::DECODE_TO_IURI ) );
1301 					if ( INET_PROT_FILE == aFileObj.GetProtocol() )
1302 					{	// if it's a file URL, transform the URL into system notation
1303 						::rtl::OUString sURL( sInvalidFile );
1304 						::rtl::OUString sSystem;
1305 						osl_getSystemPathFromFileURL( sURL.pData, &sSystem.pData );
1306 						sInvalidFile = sSystem;
1307 					}
1308 					sError.SearchAndReplaceAscii( "$name$", sInvalidFile );
1309 
1310 					ErrorBox aError( pThis, WB_OK, sError );
1311 					aError.Execute();
1312 					return 0;
1313 				}
1314 			}
1315 		}
1316 		break;
1317 
1318 		default:
1319 			DBG_ERROR("SvtFileDialog, OpenHdl_Impl: invalid mode!");
1320 	}
1321 
1322 	// Interessenten benachrichtigen.
1323 	long nRet;
1324 
1325 	if ( pThis->_aOKHdl.IsSet() )
1326 		nRet = pThis->_aOKHdl.Call( pThis );
1327 	else
1328 		nRet = pThis->OK();
1329 
1330 	if ( nRet )
1331 	{
1332 		pThis->EndDialog( sal_True );
1333 	}
1334 
1335 	return nRet;
1336 }
1337 
1338 //*****************************************************************************
1339 
1340 void SvtFileDialog::EnableAutocompletion( sal_Bool _bEnable )
1341 {
1342     _pImp->_pEdFileName->EnableAutocompletion( _bEnable );
1343 }
1344 
1345 //*****************************************************************************
1346 
1347 IMPL_STATIC_LINK( SvtFileDialog, FilterSelectHdl_Impl, ListBox*, pBox )
1348 {
1349 	DBG_ASSERT( pBox, "SvtFileDialog:keine Instanz" );
1350 
1351 	// wurde der Handler vom Travel-Timer gefeuert?
1352 	if ( pBox == (ListBox*)&pThis->_pImp->_aFilterTimer )
1353 	{
1354 		// Anzeige erneut filtern.
1355 		pThis->ExecuteFilter();
1356 		return 0;
1357 	}
1358 
1359 	String sSelectedFilterDisplayName;
1360 	SvtFileDialogFilter_Impl* pSelectedFilter = pThis->_pImp->GetSelectedFilterEntry( sSelectedFilterDisplayName );
1361 	if ( !pSelectedFilter )
1362 	{	// there is no current selection. This happens if for instance the user selects a group separator using
1363 		// the keyboard, and then presses enter: When the selection happens, we immediately deselect the entry,
1364 		// so in this situation there is no current selection.
1365 		if ( restoreCurrentFilter( pThis->_pImp ) )
1366 			pThis->ExecuteFilter();
1367 	}
1368 	else
1369 	{
1370 		if ( pSelectedFilter->isGroupSeparator() )
1371 		{	// group separators can't be selected
1372 			// return to the previously selected entry
1373 			if ( pThis->_pImp->IsFilterListTravelSelect() )
1374 			{
1375 				pThis->_pImp->SetNoFilterListSelection( );
1376 
1377 				// stop the timer for executing the filter
1378 				if ( pThis->_pImp->_aFilterTimer.IsActive() )
1379 					pThis->_pImp->m_bNeedDelayedFilterExecute = sal_True;
1380 				pThis->_pImp->_aFilterTimer.Stop();
1381 			}
1382 			else
1383 			{
1384 				if ( restoreCurrentFilter( pThis->_pImp ) )
1385 					pThis->ExecuteFilter();
1386 			}
1387 		}
1388 		else if	(	( pSelectedFilter != pThis->_pImp->GetCurFilter() )
1389 				||	pThis->_pImp->_pUserFilter
1390 				)
1391 		{
1392             // Store the old filter for the auto extension handling
1393             String sLastFilterExt = pThis->_pImp->GetCurFilter()->GetExtension();
1394 			DELETEZ( pThis->_pImp->_pUserFilter );
1395 
1396             // Ggf. Filter des Benutzers entfernen.
1397 			pThis->_pImp->SetCurFilter( pSelectedFilter, sSelectedFilterDisplayName );
1398 
1399 			// Ggf. Endung anzeigen.
1400             pThis->SetDefaultExt( pSelectedFilter->GetExtension() );
1401 			sal_uInt16 nSepPos = pThis->GetDefaultExt().Search( FILEDIALOG_DEF_EXTSEP );
1402 
1403 			if ( nSepPos != STRING_NOTFOUND )
1404 				pThis->EraseDefaultExt( nSepPos );
1405 
1406 			// update the extension of the current file if necessary
1407             lcl_autoUpdateFileExtension( pThis, sLastFilterExt );
1408 
1409 			// wenn der Benutzer schnell durch die Filterbox
1410 			// travelt, nicht sofort Filtern
1411 			if ( pThis->_pImp->IsFilterListTravelSelect() )
1412 			{
1413 				// FilterSelectHdl_Impl soll in
1414 				// TRAVELFILTER_TIMEOUT ms neu gefeuert werden
1415 				pThis->_pImp->_aFilterTimer.Start();
1416 			}
1417 			else
1418 			{
1419 				// evtl. vorher gestarteten Timer stoppen
1420 				pThis->_pImp->_aFilterTimer.Stop();
1421 
1422 				// Anzeige erneut filtern.
1423 				pThis->ExecuteFilter();
1424 			}
1425 		}
1426 	}
1427 
1428 	return 0;
1429 }
1430 
1431 //*****************************************************************************
1432 
1433 IMPL_STATIC_LINK( SvtFileDialog, FileNameGetFocusHdl_Impl, void*, EMPTYARG )
1434 {
1435 	pThis->_pFileView->SetNoSelection();
1436 	pThis->_pFileView->Update();
1437 	return 0;
1438 }
1439 
1440 //*****************************************************************************
1441 
1442 IMPL_STATIC_LINK( SvtFileDialog, FileNameModifiedHdl_Impl, void*, EMPTYARG )
1443 {
1444 	FileNameGetFocusHdl_Impl( pThis, NULL );
1445 	return 0;
1446 }
1447 
1448 //*****************************************************************************
1449 
1450 SvtFileDialogFilter_Impl* SvtFileDialog::FindFilter_Impl
1451 (
1452 	const String& _rFilter,
1453 	sal_Bool _bMultiExt,/*	sal_True - auch Filter mit mehreren Endungen
1454 							beruecksichtigen
1455 							sal_False - keine ...
1456 						*/
1457 	sal_Bool& _rFilterChanged
1458 )
1459 
1460 /*	[Beschreibung]
1461 
1462 	Die Methode sucht in den eingef"ugten Filtern nach der
1463 	spezifizierten Endung.
1464 */
1465 
1466 {
1467 	SvtFileDialogFilter_Impl* pFoundFilter = NULL;
1468 	SvtFileDialogFilterList_Impl* pList = _pImp->_pFilter;
1469 	sal_uInt16 nFilter = pList->Count();
1470 
1471 	while ( nFilter-- )
1472 	{
1473 		SvtFileDialogFilter_Impl* pFilter = pList->GetObject( nFilter );
1474 		const String& rType = pFilter->GetType();
1475 		String aSingleType = rType;
1476 
1477 		if ( _bMultiExt )
1478 		{
1479 			sal_uInt16 nIdx = 0;
1480 			while ( !pFoundFilter && nIdx != STRING_NOTFOUND )
1481 			{
1482 				aSingleType = rType.GetToken( 0, FILEDIALOG_DEF_EXTSEP, nIdx );
1483 #ifdef UNX
1484 				if ( aSingleType.CompareTo( _rFilter ) == COMPARE_EQUAL )
1485 #else
1486 				if ( aSingleType.CompareIgnoreCaseToAscii( _rFilter ) == COMPARE_EQUAL )
1487 #endif
1488 					pFoundFilter = pFilter;
1489 			}
1490 		}
1491 #ifdef UNX
1492 		else if ( rType.CompareTo( _rFilter ) == COMPARE_EQUAL )
1493 #else
1494 		else if ( rType.CompareIgnoreCaseToAscii( _rFilter ) == COMPARE_EQUAL )
1495 #endif
1496 			pFoundFilter = pFilter;
1497 
1498 		if ( pFoundFilter )
1499 		{
1500 			// Filter aktivieren.
1501 			_rFilterChanged = _pImp->_pUserFilter || ( _pImp->GetCurFilter() != pFilter );
1502 
1503 			createNewUserFilter( _rFilter, sal_False );
1504 
1505 			break;
1506 		}
1507 	}
1508 	return pFoundFilter;
1509 }
1510 
1511 //*****************************************************************************
1512 
1513 void SvtFileDialog::ExecuteFilter()
1514 {
1515 	_pImp->m_bNeedDelayedFilterExecute = sal_False;
1516     executeAsync( AsyncPickerAction::eExecuteFilter, String(), getMostCurrentFilter( _pImp ) );
1517 }
1518 
1519 //*****************************************************************************
1520 
1521 void SvtFileDialog::OpenMultiSelection_Impl()
1522 
1523 /*	[Beschreibung]
1524 
1525 	OpenHandler f"ur MultiSelektion
1526 */
1527 
1528 {
1529 	String aPath;
1530 	sal_uLong nCount = _pFileView->GetSelectionCount();
1531 	SvLBoxEntry* pEntry = nCount ? _pFileView->FirstSelected() : NULL;
1532 
1533 	if ( nCount && pEntry )
1534 		_aPath = _pFileView->GetURL( pEntry );
1535 
1536 	// Interessenten benachrichtigen.
1537 	long nRet;
1538 
1539 	if ( _aOKHdl.IsSet() )
1540 		nRet = _aOKHdl.Call( this );
1541 	else
1542 		nRet = OK();
1543 
1544 	if ( nRet )
1545 		EndDialog( sal_True );
1546 }
1547 
1548 //*****************************************************************************
1549 
1550 void SvtFileDialog::UpdateControls( const String& rURL )
1551 {
1552    	_pImp->_pEdFileName->SetBaseURL( rURL );
1553 
1554 	INetURLObject aObj( rURL );
1555 
1556     //=========================================================================
1557 	{
1558 		String sText;
1559 		DBG_ASSERT( INET_PROT_NOT_VALID != aObj.GetProtocol(), "SvtFileDialog::UpdateControls: Invalid URL!" );
1560 
1561 		if ( aObj.getSegmentCount() )
1562 		{
1563 			::utl::LocalFileHelper::ConvertURLToSystemPath( rURL, sText );
1564 			if ( sText.Len() )
1565 			{
1566 				// no Fsys path for server file system ( only UCB has mountpoints! )
1567 				if ( INET_PROT_FILE != aObj.GetProtocol() )
1568                     sText = rURL.Copy( static_cast< sal_uInt16 >(
1569                         INetURLObject::GetScheme( aObj.GetProtocol() ).getLength() ) );
1570 			}
1571 
1572 			if ( !sText.Len() && aObj.getSegmentCount() )
1573 				sText = rURL;
1574 		}
1575 
1576 		// path mode ?
1577 		if ( FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType )
1578 			// -> set new path in the edit field
1579 			_pImp->_pEdFileName->SetText( sText );
1580 
1581 		// in the "current path" field, truncate the trailing slash
1582 		if ( aObj.hasFinalSlash() )
1583 		{
1584 			aObj.removeFinalSlash();
1585 			String sURL( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1586 			if ( !::utl::LocalFileHelper::ConvertURLToSystemPath( sURL, sText ) )
1587 				sText = sURL;
1588 		}
1589 
1590         if ( !sText.Len() && rURL.Len() )
1591             // happens, for instance, for URLs which the INetURLObject does not know to belong to a hierarchical scheme
1592             sText = rURL;
1593 		_pImp->_pFtCurrentPath->SetText( sText );
1594 	}
1595 
1596     //=========================================================================
1597     _aPath = rURL;
1598     if ( _pFileNotifier )
1599 		_pFileNotifier->notify( DIRECTORY_CHANGED, 0 );
1600 }
1601 
1602 //*****************************************************************************
1603 
1604 IMPL_LINK( SvtFileDialog, SelectHdl_Impl, SvTabListBox*, pBox )
1605 {
1606 	SvLBoxEntry* pEntry = pBox->FirstSelected();
1607 	DBG_ASSERT( pEntry, "SelectHandler without selected entry" );
1608 	SvtContentEntry* pUserData = (SvtContentEntry*)pEntry->GetUserData();
1609 
1610 	if ( pUserData )
1611 	{
1612 		INetURLObject aObj( pUserData->maURL );
1613 		if ( FILEDLG_TYPE_PATHDLG == _pImp->_eDlgType )
1614 		{
1615 			if ( aObj.GetProtocol() == INET_PROT_FILE )
1616 			{
1617 				if ( !pUserData->mbIsFolder )
1618 					aObj.removeSegment();
1619 				String aName = aObj.getFSysPath( (INetURLObject::FSysStyle)(INetURLObject::FSYS_DETECT & ~INetURLObject::FSYS_VOS) );
1620 				_pImp->_pEdFileName->SetText( aName );
1621 				_pImp->_pEdFileName->SetSelection( Selection( 0, aName.Len() ) );
1622 				_aPath = pUserData->maURL;
1623 			}
1624 			else if ( !pUserData->mbIsFolder )
1625 			{
1626 				_pImp->_pEdFileName->SetText( pUserData->maURL );
1627 				_pImp->_pEdFileName->SetSelection( Selection( 0, pUserData->maURL.Len() ) );
1628 				_aPath = pUserData->maURL;
1629 			}
1630 			else
1631 				_pImp->_pEdFileName->SetText( UniString() );
1632 		}
1633 		else
1634 		{
1635 			if ( !pUserData->mbIsFolder )
1636 			{
1637 				String aName = pBox->GetEntryText( pEntry, 0 );
1638 				_pImp->_pEdFileName->SetText( aName );
1639 				_pImp->_pEdFileName->SetSelection( Selection( 0, aName.Len() ) );
1640 				_aPath = pUserData->maURL;
1641 			}
1642 		}
1643 	}
1644 
1645 	if ( _pImp->_bMultiSelection && _pFileView->GetSelectionCount() > 1 )
1646 	{
1647 		// bei Multiselektion den Datei-Edit leeren
1648 		_pImp->_pEdFileName->SetText( String() );
1649 	}
1650 
1651 	FileSelect();
1652 
1653 	return 0;
1654 }
1655 
1656 //*****************************************************************************
1657 
1658 IMPL_LINK( SvtFileDialog, DblClickHdl_Impl, SvTabListBox*, EMPTYARG )
1659 {
1660 	_pImp->_bDoubleClick = sal_True;
1661 	OpenHdl_Impl( this, NULL );
1662 	_pImp->_bDoubleClick = sal_False;
1663 
1664 	return 0;
1665 }
1666 
1667 //*****************************************************************************
1668 
1669 IMPL_LINK( SvtFileDialog, EntrySelectHdl_Impl, ComboBox*, EMPTYARG )
1670 {
1671 	FileSelect();
1672 
1673     return 0;
1674 }
1675 
1676 //*****************************************************************************
1677 
1678 IMPL_LINK( SvtFileDialog, OpenDoneHdl_Impl, SvtFileView*, pView )
1679 {
1680     String sCurrentFolder( pView->GetViewURL() );
1681     // check if we can create new folders
1682     EnableControl( _pImp->_pBtnNewFolder, ContentCanMakeFolder( sCurrentFolder ) && m_aURLFilter.isUrlAllowed( sCurrentFolder, false ) );
1683 
1684     // check if we can travel one level up
1685     bool bCanTravelUp = ContentHasParentFolder( pView->GetViewURL() );
1686     if ( bCanTravelUp )
1687     {
1688         // additional check: the parent folder should not be prohibited
1689         INetURLObject aCurrentFolder( sCurrentFolder );
1690         DBG_ASSERT( INET_PROT_NOT_VALID != aCurrentFolder.GetProtocol(),
1691             "SvtFileDialog::OpenDoneHdl_Impl: invalid current URL!" );
1692 
1693         aCurrentFolder.removeSegment();
1694         bCanTravelUp &= m_aURLFilter.isUrlAllowed( aCurrentFolder.GetMainURL( INetURLObject::NO_DECODE ) );
1695     }
1696     EnableControl( _pImp->_pBtnUp, bCanTravelUp );
1697 
1698 	return 0;
1699 }
1700 
1701 //*****************************************************************************
1702 
1703 IMPL_LINK( SvtFileDialog, AutoExtensionHdl_Impl, CheckBox*, EMPTYARG )
1704 {
1705 	if ( _pFileNotifier )
1706 		_pFileNotifier->notify( CTRL_STATE_CHANGED,
1707                                 CHECKBOX_AUTOEXTENSION );
1708 
1709 	// update the extension of the current file if necessary
1710     lcl_autoUpdateFileExtension( this, _pImp->GetCurFilter()->GetExtension() );
1711 
1712     return 0;
1713 }
1714 
1715 //*****************************************************************************
1716 
1717 IMPL_LINK( SvtFileDialog, ClickHdl_Impl, CheckBox*, pCheckBox )
1718 {
1719     if ( ! _pFileNotifier )
1720         return 0;
1721 
1722     sal_Int16 nId = -1;
1723 
1724     if ( pCheckBox == _pImp->_pCbOptions )
1725         nId = CHECKBOX_FILTEROPTIONS;
1726     else if ( pCheckBox == _pCbSelection )
1727         nId = CHECKBOX_SELECTION;
1728     else if ( pCheckBox == _pCbReadOnly )
1729         nId = CHECKBOX_READONLY;
1730     else if ( pCheckBox == _pImp->_pCbPassword )
1731         nId = CHECKBOX_PASSWORD;
1732     else if ( pCheckBox == _pCbLinkBox )
1733         nId = CHECKBOX_LINK;
1734     else if ( pCheckBox == _pCbPreviewBox )
1735         nId = CHECKBOX_PREVIEW;
1736 
1737 	if ( nId != -1 )
1738         _pFileNotifier->notify( CTRL_STATE_CHANGED, nId );
1739 
1740     return 0;
1741 }
1742 
1743 //*****************************************************************************
1744 
1745 IMPL_LINK( SvtFileDialog, PlayButtonHdl_Impl, PushButton*, EMPTYARG )
1746 {
1747     if ( _pFileNotifier )
1748         _pFileNotifier->notify( CTRL_STATE_CHANGED,
1749                                 PUSHBUTTON_PLAY );
1750 
1751     return 0;
1752 }
1753 
1754 //*****************************************************************************
1755 
1756 long SvtFileDialog::Notify( NotifyEvent& rNEvt )
1757 
1758 /*	[Beschreibung]
1759 
1760 	Die Methode wird gerufen, <BACKSPACE> abzufangen.
1761 */
1762 
1763 {
1764 	sal_uInt16 nType = rNEvt.GetType();
1765 	long nRet = 0;
1766 
1767 	if ( EVENT_KEYINPUT == nType && rNEvt.GetKeyEvent() )
1768 	{
1769 		const KeyCode& rKeyCode = rNEvt.GetKeyEvent()->GetKeyCode();
1770 		sal_uInt16 nCode = rKeyCode.GetCode();
1771 
1772 		if ( !rKeyCode.GetModifier() &&
1773 			 KEY_BACKSPACE == nCode && !_pImp->_pEdFileName->HasChildPathFocus() )
1774 		{
1775 			nRet = 0; //! (long)_pFileView->DoBeamerKeyInput( *rNEvt.GetKeyEvent() );
1776 
1777 			if ( !nRet && _pImp->_pBtnUp->IsEnabled() )
1778 			{
1779 				PrevLevel_Impl();
1780 				nRet = 1;
1781 			}
1782 		}
1783 //		else if ( rKeyCode.IsMod1() && ( KEY_C == nCode || KEY_V == nCode || KEY_X == nCode ) )
1784 //		{
1785 /* (mhu)
1786 			String aVerb = KEY_C == nCode ? UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_COPY)) :
1787 				( KEY_V == nCode ? UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_PASTE)) : UniString(RTL_CONSTASCII_USTRINGPARAM(SVT_MENUPART_VERB_CUT)) );
1788 //(dv)			if ( !CntPopupMenu::DoVerbCommand( aVerb, _pFileView->GetView() ) )
1789 //(dv)				Sound::Beep();
1790 */
1791 //		}
1792 	}
1793 	return nRet ? nRet : ModalDialog::Notify( rNEvt );
1794 }
1795 
1796 //*****************************************************************************
1797 
1798 long SvtFileDialog::OK()
1799 {
1800 	return sal_True;
1801 }
1802 
1803 //*****************************************************************************
1804 
1805 class SvtDefModalDialogParent_Impl
1806 {
1807 private:
1808 	Window*	_pOld;
1809 
1810 public:
1811 	SvtDefModalDialogParent_Impl( Window *pNew ) :
1812 		_pOld( Application::GetDefDialogParent() )
1813 		{ Application::SetDefDialogParent( pNew ); }
1814 
1815 	~SvtDefModalDialogParent_Impl() { Application::SetDefDialogParent( _pOld ); }
1816 };
1817 
1818 //*****************************************************************************
1819 
1820 //---------------------------------------------------------------------
1821 void SvtFileDialog::updateListboxLabelSizes()
1822 {
1823     sal_Int16 nLineControlId[5] = {
1824         LISTBOX_VERSION, LISTBOX_TEMPLATE, LISTBOX_IMAGE_TEMPLATE, LISTBOX_FILTER, EDIT_FILEURL
1825     };
1826 
1827     // determine the maximum width needed for the listbox labels
1828     long nMaxWidth = 0;
1829     for ( sal_Int32 i=0; i<5; ++i )
1830     {
1831         FixedText* pLabel = static_cast< FixedText* >( getControl( nLineControlId[i], sal_True ) );
1832         if ( !pLabel )
1833             continue;
1834         nMaxWidth = ::std::max( pLabel->GetTextWidth( pLabel->GetText() ), nMaxWidth );
1835     }
1836 
1837     // ensure that all labels are wide enough
1838     for ( sal_Int32 i=0; i<5; ++i )
1839     {
1840         FixedText* pLabel = static_cast< FixedText* >( getControl( nLineControlId[i], sal_True ) );
1841         ListBox* pListbox = static_cast< ListBox* >( getControl( nLineControlId[i], sal_False ) );
1842         if ( !pLabel || !pListbox )
1843             continue;
1844         Size aCurrentSize( pLabel->GetSizePixel() );
1845         if ( aCurrentSize.Width() >= nMaxWidth )
1846             continue;
1847 
1848         long nChange = nMaxWidth - aCurrentSize.Width();
1849         pLabel->SetSizePixel( Size( nMaxWidth, aCurrentSize.Height() ) );
1850 
1851         aCurrentSize = pListbox->GetSizePixel();
1852         pListbox->SetSizePixel( Size( aCurrentSize.Width() - nChange, aCurrentSize.Height() ) );
1853         lcl_MoveControl( pListbox, nChange, 0 );
1854     }
1855 }
1856 
1857 namespace
1858 {
1859 
1860 bool implIsInvalid( const String & rURL )
1861 {
1862 	SmartContent aContent( rURL );
1863 	aContent.enableOwnInteractionHandler( ::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST );
1864 	aContent.isFolder();	// do this _before_ asking isInvalid! Otherwise result might be wrong.
1865 	return aContent.isInvalid();
1866 }
1867 
1868 }
1869 
1870 //---------------------------------------------------------------------
1871 String SvtFileDialog::implGetInitialURL( const String& _rPath, const String& _rFallback )
1872 {
1873 	// an URL parser for the fallback
1874 	INetURLObject aURLParser;
1875 
1876 	// set the path
1877 	bool bWasAbsolute = sal_False;
1878 	aURLParser = aURLParser.smartRel2Abs( _rPath, bWasAbsolute );
1879 
1880 	// is it a valid folder?
1881 	m_aContent.bindTo( aURLParser.GetMainURL( INetURLObject::NO_DECODE ) );
1882 	sal_Bool bIsFolder = m_aContent.isFolder( );	// do this _before_ asking isInvalid!
1883 	sal_Bool bIsInvalid = m_aContent.isInvalid();
1884 
1885 	if ( bIsInvalid && m_bHasFilename && !aURLParser.hasFinalSlash() )
1886 	{	// check if the parent folder exists
1887 		// #108429# - 2003-03-26 - fs@openoffice.org
1888 		INetURLObject aParent( aURLParser );
1889 		aParent.removeSegment( );
1890 		aParent.setFinalSlash( );
1891 		bIsInvalid = implIsInvalid( aParent.GetMainURL( INetURLObject::NO_DECODE ) );
1892 	}
1893 
1894 	if ( bIsInvalid )
1895 	{
1896 		INetURLObject aFallback( _rFallback );
1897 		bIsInvalid = implIsInvalid( aFallback.GetMainURL( INetURLObject::NO_DECODE ) );
1898 
1899 	    if ( !bIsInvalid )
1900 			aURLParser = aFallback;
1901 	}
1902 
1903     if ( bIsInvalid )
1904 	{
1905 		INetURLObject aParent( aURLParser );
1906 		while ( bIsInvalid && aParent.removeSegment() )
1907 		{
1908 			aParent.setFinalSlash( );
1909 			bIsInvalid = implIsInvalid( aParent.GetMainURL( INetURLObject::NO_DECODE ) );
1910 		}
1911 
1912 	    if ( !bIsInvalid )
1913 			aURLParser = aParent;
1914 	}
1915 
1916 	if ( !bIsInvalid && bIsFolder )
1917 	{
1918 		aURLParser.setFinalSlash();
1919 	}
1920 	return aURLParser.GetMainURL( INetURLObject::NO_DECODE );
1921 }
1922 
1923 //---------------------------------------------------------------------
1924 short SvtFileDialog::Execute()
1925 {
1926     if ( !PrepareExecute() )
1927         return 0;
1928 
1929 	// Start des Dialogs.
1930     _bIsInExecute = sal_True;
1931 	short nResult = ModalDialog::Execute();
1932     _bIsInExecute = sal_False;
1933 
1934     DBG_ASSERT( !m_pCurrentAsyncAction.is(), "SvtFilePicker::Execute: still running an async action!" );
1935         // the dialog should not be cancellable while an async action is running - firs, the action
1936         // needs to be cancelled
1937 
1938 	// letztes Verzeichnis merken
1939 	if ( RET_OK == nResult )
1940 	{
1941 		INetURLObject aURL( _aPath );
1942 		if ( aURL.GetProtocol() == INET_PROT_FILE )
1943 		{
1944 			// nur bei File-URL's und nicht bei virtuelle Folder
1945 			// das ausgew"ahlte Verzeichnis merken
1946 			sal_Int32 nLevel = aURL.getSegmentCount();
1947 			// #97148# & #102204# ------
1948 			sal_Bool bDir = m_aContent.isFolder( aURL.GetMainURL( INetURLObject::NO_DECODE ) );
1949             // sal_Bool bClassPath = ( ( _pImp->_nStyle & SFXWB_CLASSPATH ) == SFXWB_CLASSPATH );
1950 			if ( nLevel > 1 && ( FILEDLG_TYPE_FILEDLG == _pImp->_eDlgType || !bDir ) )
1951 				aURL.removeSegment();
1952 		}
1953 	}
1954 
1955     return nResult;
1956 }
1957 
1958 //---------------------------------------------------------------------
1959 void SvtFileDialog::StartExecuteModal( const Link& rEndDialogHdl )
1960 {
1961     PrepareExecute();
1962 
1963     // Start des Dialogs.
1964 //    _bIsInExecute = sal_True;
1965     ModalDialog::StartExecuteModal( rEndDialogHdl );
1966 }
1967 
1968 //-----------------------------------------------------------------------------
1969 void SvtFileDialog::onAsyncOperationStarted()
1970 {
1971     EnableUI( sal_False );
1972     // the cancel button must be always enabled
1973     _pImp->_pBtnCancel->Enable( sal_True );
1974     _pImp->_pBtnCancel->GrabFocus();
1975 }
1976 
1977 //-----------------------------------------------------------------------------
1978 void SvtFileDialog::onAsyncOperationFinished()
1979 {
1980     EnableUI( sal_True );
1981     m_pCurrentAsyncAction = NULL;
1982     if ( !m_bInExecuteAsync )
1983         _pImp->_pEdFileName->GrabFocus();
1984         // (if m_bInExecuteAsync is true, then the operation was finished within the minium wait time,
1985         // and to the user, the operation appears to be synchronous)
1986 }
1987 
1988 //-------------------------------------------------------------------------
1989 void SvtFileDialog::displayIOException( const String& _rURL, IOErrorCode _eCode )
1990 {
1991     try
1992     {
1993         // create make a human-readable string from the URL
1994         String sDisplayPath( _rURL );
1995         ::utl::LocalFileHelper::ConvertURLToSystemPath( _rURL, sDisplayPath );
1996 
1997         // build an own exception which tells "access denied"
1998         InteractiveAugmentedIOException aException;
1999         aException.Arguments.realloc( 2 );
2000         aException.Arguments[ 0 ] <<= ::rtl::OUString( sDisplayPath );
2001         aException.Arguments[ 1 ] <<= PropertyValue(
2002             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Uri" ) ),
2003             -1, aException.Arguments[ 0 ], PropertyState_DIRECT_VALUE
2004         );
2005             // (formerly, it was sufficient to put the URL first parameter. Nowadays,
2006             // the services expects the URL in a PropertyValue named "Uri" ...)
2007         aException.Code = _eCode;
2008         aException.Classification = InteractionClassification_ERROR;
2009 
2010         // let and interaction handler handle this exception
2011         ::comphelper::OInteractionRequest* pRequest = NULL;
2012         Reference< ::com::sun::star::task::XInteractionRequest > xRequest = pRequest =
2013             new ::comphelper::OInteractionRequest( makeAny( aException ) );
2014         pRequest->addContinuation( new ::comphelper::OInteractionAbort( ) );
2015 
2016         Reference< XInteractionHandler > xHandler(
2017             ::comphelper::getProcessServiceFactory()->createInstance(
2018                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.task.InteractionHandler") )
2019             ),
2020             UNO_QUERY
2021         );
2022         if ( xHandler.is() )
2023             xHandler->handle( xRequest );
2024     }
2025     catch( const Exception& )
2026     {
2027         DBG_ERROR( "iodlg::displayIOException: caught an exception!" );
2028     }
2029 }
2030 
2031 //-----------------------------------------------------------------------------
2032 void SvtFileDialog::EnableUI( sal_Bool _bEnable )
2033 {
2034     Enable( _bEnable );
2035 
2036     if ( _bEnable )
2037     {
2038         for ( ::std::set< Control* >::iterator aLoop = m_aDisabledControls.begin();
2039               aLoop != m_aDisabledControls.end();
2040               ++aLoop
2041             )
2042         {
2043             (*aLoop)->Enable( sal_False );
2044         }
2045     }
2046 }
2047 
2048 //-----------------------------------------------------------------------------
2049 void SvtFileDialog::EnableControl( Control* _pControl, sal_Bool _bEnable )
2050 {
2051     if ( !_pControl )
2052     {
2053         DBG_ERRORFILE( "SvtFileDialog::EnableControl: invalid control!" );
2054         return;
2055     }
2056 
2057     _pControl->Enable( _bEnable );
2058 
2059     if ( _bEnable )
2060     {
2061         ::std::set< Control* >::iterator aPos = m_aDisabledControls.find( _pControl );
2062         if ( m_aDisabledControls.end() != aPos )
2063             m_aDisabledControls.erase( aPos );
2064     }
2065     else
2066         m_aDisabledControls.insert( _pControl );
2067 }
2068 
2069 //----------------------------------------------------------------------------
2070 
2071 short SvtFileDialog::PrepareExecute()
2072 {
2073     rtl::OUString aEnvValue;
2074     if ( getEnvironmentValue( "WorkDirMustContainRemovableMedia", aEnvValue ) &&
2075          aEnvValue.equalsAscii( "1" ) )
2076     {
2077         try
2078         {
2079             INetURLObject aStdDir( GetStandardDir() );
2080             ::ucbhelper::Content aCnt( rtl::OUString( aStdDir.GetMainURL(
2081                                                     INetURLObject::NO_DECODE ) ),
2082                                  Reference< XCommandEnvironment >() );
2083             Sequence< rtl::OUString > aProps(2);
2084             aProps[0] = rtl::OUString::createFromAscii( "IsVolume" );
2085             aProps[1] = rtl::OUString::createFromAscii( "IsRemoveable" );
2086 
2087             Reference< XResultSet > xResultSet
2088                 = aCnt.createCursor( aProps, ::ucbhelper::INCLUDE_FOLDERS_ONLY );
2089             if ( xResultSet.is() )
2090             {
2091                 Reference< XRow > xRow( xResultSet, UNO_QUERY );
2092 
2093                 bool bEmpty = true;
2094                 if ( !xResultSet->next() )
2095                 {
2096                     // folder is empty
2097                     bEmpty = true;
2098                 }
2099                 else
2100                 {
2101 // @@@ KSO 05/18/2006: support for removable media currently hardcoded/incomplete in OSL
2102 //
2103 //                    do
2104 //                    {
2105 //                        // check, whether child is a removable volume
2106 //                        if ( xRow->getBoolean( 1 ) && !xRow->wasNull() )
2107 //                        {
2108 //                            if ( xRow->getBoolean( 2 ) && !xRow->wasNull() )
2109 //                            {
2110                                 bEmpty = false;
2111 //                                break;
2112 //                            }
2113 //                        }
2114 //                    }
2115 //                    while ( xResultSet->next() );
2116                 }
2117 
2118                 if ( bEmpty )
2119                 {
2120                     ErrorBox aBox( this, WB_OK, SvtResId( STR_SVT_NOREMOVABLEDEVICE ) );
2121                     aBox.Execute();
2122                     return 0;
2123                 }
2124             }
2125         }
2126         catch ( ContentCreationException const & )
2127         {
2128         }
2129         catch ( CommandAbortedException const & )
2130         {
2131         }
2132     }
2133 
2134     // #102204# ---------------
2135 	if ( ( _pImp->_nStyle & WB_SAVEAS ) && m_bHasFilename )
2136 		// when doing a save-as, we do not want the handler to handle "this file does not exist" messages
2137 		// - finally we're going to save that file, aren't we?
2138 		// #105812# - 2002-12-02 - fs@openoffice.org
2139         m_aContent.enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST);
2140     else
2141         m_aContent.enableDefaultInteractionHandler();
2142 
2143 	// #53016# evtl. nur ein Filename ohne Pfad?
2144 	String aFileNameOnly;
2145 	if( _aPath.Len() && (_pImp->_eMode == FILEDLG_MODE_SAVE)
2146 					 && (_aPath.Search(':') == STRING_NOTFOUND)
2147 					 && (_aPath.Search('\\') == STRING_NOTFOUND)
2148 					 && (_aPath.Search('/') == STRING_NOTFOUND))
2149 	{
2150 		aFileNameOnly = _aPath;
2151 		_aPath.Erase();
2152 	}
2153 
2154 	// kein Startpfad angegeben?
2155 	if ( !_aPath.Len() )
2156 	{
2157 		// dann das Standard-Dir verwenden
2158 		_aPath = lcl_ensureFinalSlash( _pImp->GetStandardDir() );
2159 
2160 		// #53016# vorgegebener Dateiname an Pfad anh"angen
2161 		if ( aFileNameOnly.Len() )
2162 			_aPath += aFileNameOnly;
2163 	}
2164 
2165 	//.....................................................................
2166 	_aPath = implGetInitialURL( _aPath, GetStandardDir() );
2167 
2168 	if ( _pImp->_nStyle & WB_SAVEAS && !m_bHasFilename )
2169 		// when doing a save-as, we do not want the handler to handle "this file does not exist" messages
2170 		// - finally we're going to save that file, aren't we?
2171         m_aContent.enableOwnInteractionHandler(::svt::OFilePickerInteractionHandler::E_DOESNOTEXIST);
2172 
2173 	//.....................................................................
2174 	// care for possible restrictions on the paths we're allowed to show
2175     if ( !m_aURLFilter.isUrlAllowed( _aPath ) )
2176         _aPath = m_aURLFilter.getFilter()[0];
2177 
2178 	// Ggf. Filter anzeigen.
2179 	_pImp->InitFilterList();
2180 
2181 	// Initialen Filter einstellen.
2182 	sal_uInt16 nFilterCount = GetFilterCount();
2183 	String aAll( SvtResId( STR_FILTERNAME_ALL ) );
2184 	sal_Bool bHasAll = _pImp->HasFilterListEntry( aAll );
2185 	if ( _pImp->GetCurFilter() || nFilterCount == 1 || ( nFilterCount == 2 && bHasAll ) )
2186 	{
2187 		// Ggf. einzigen Filter als aktuellen Filter setzen oder den einzigen
2188 		// Filter, der nicht auf alle Dateien verweist.
2189 		if ( !_pImp->GetCurFilter() )
2190 		{
2191 			sal_uInt16 nPos = 0;
2192 			if ( 2 == nFilterCount && bHasAll )
2193 			{
2194 				nPos = nFilterCount;
2195 				while ( nPos-- )
2196 				{
2197 					if ( GetFilterName( nPos ) != aAll )
2198 						break;
2199 				}
2200 			}
2201 			SvtFileDialogFilter_Impl* pNewCurFilter = _pImp->_pFilter->GetObject( nPos );
2202 			DBG_ASSERT( pNewCurFilter, "SvtFileDialog::Execute: invalid filter pos!" );
2203 			_pImp->SetCurFilter( pNewCurFilter, pNewCurFilter->GetName() );
2204 		}
2205 
2206 		// Anzeige anpassen.
2207 		_pImp->SelectFilterListEntry( _pImp->GetCurFilter()->GetName() );
2208         SetDefaultExt( _pImp->GetCurFilter()->GetExtension() );
2209 		sal_uInt16 nSepPos = GetDefaultExt().Search( FILEDIALOG_DEF_EXTSEP );
2210 		if ( nSepPos != STRING_NOTFOUND )
2211 			EraseDefaultExt( nSepPos );
2212 	}
2213 	else
2214 	{
2215 		// Ggf. Filter fuer alle Dateien setzen bzw. erzeugen.
2216 		if ( !bHasAll )
2217 		{
2218 			SvtFileDialogFilter_Impl* pAllFilter = implAddFilter( aAll, UniString(RTL_CONSTASCII_USTRINGPARAM(FILEDIALOG_FILTER_ALL)) );
2219 			_pImp->InsertFilterListEntry( pAllFilter );
2220 			_pImp->SetCurFilter( pAllFilter, aAll );
2221 		}
2222 		_pImp->SelectFilterListEntry( aAll );
2223 	}
2224 
2225 	_pImp->_pDefaultFilter = _pImp->GetCurFilter();
2226 
2227 	// HACK #50065#
2228 	// ggf. Filter isolieren.
2229 	String aFilter;
2230 
2231 	if ( !IsolateFilterFromPath_Impl( _aPath, aFilter ) )
2232 		return 0;
2233 
2234 	sal_uInt16 nNewFilterFlags = adjustFilter( aFilter );
2235 	if ( nNewFilterFlags & ( FLT_NONEMPTY | FLT_USERFILTER ) )
2236 	{
2237 		_pImp->_pEdFileName->SetText( aFilter );
2238 	}
2239 	// HACK #50065#
2240 
2241 	// Instanz fuer den gesetzten Pfad erzeugen und anzeigen.
2242 	INetURLObject aFolderURL( _aPath );
2243 	String aFileName( aFolderURL.getName( INetURLObject::LAST_SEGMENT, false ) );
2244 	xub_StrLen nFileNameLen = aFileName.Len();
2245 	bool bFileToSelect = nFileNameLen != 0;
2246 	if ( bFileToSelect && aFileName.GetChar( nFileNameLen - 1 ) != INET_PATH_TOKEN )
2247 	{
2248 		_pImp->_pEdFileName->SetText( GET_DECODED_NAME( aFolderURL ) );
2249 		aFolderURL.removeSegment();
2250 	}
2251 
2252 	INetURLObject aObj = aFolderURL;
2253 	if ( aObj.GetProtocol() == INET_PROT_FILE )
2254 	{
2255 		// Ordner als aktuelles Verzeichnis setzen.
2256 		aObj.setFinalSlash();
2257 	}
2258 
2259 	UpdateControls( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
2260 
2261     // Somebody might want to enable some controls acording to the current filter
2262     FilterSelect();
2263 
2264 	// Zustand der Steuerelemente anpassen.
2265 //	EndListeningAll();
2266 
2267     ViewHdl_Impl( this, NULL );
2268     OpenURL_Impl( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
2269 
2270 	_pFileView->Show();
2271 	SvtDefModalDialogParent_Impl aDefParent( this );
2272 
2273 	// ggf. Gr"osse aus Ini lesen und setzen
2274 	InitSize();
2275 
2276     return 1;
2277 }
2278 
2279 //-----------------------------------------------------------------------------
2280 void SvtFileDialog::implInitializeSpecialURLLists( )
2281 {
2282     m_aURLFilter = ::svt::RestrictedPaths();
2283 
2284     ::std::vector< String > aFavourites;
2285     if ( m_aURLFilter.hasFilter() )
2286     {
2287         // if we have restrictions, then the "favourites" are the restricted folders only
2288         aFavourites = m_aURLFilter.getFilter();
2289         // for approved URLs, we needed the final slashes, for
2290         // favourites, we do not want to have them
2291         ::std::for_each( aFavourites.begin(), aFavourites.end(), RemoveFinalSlash() );
2292     }
2293     else
2294     {
2295         ::rtl::OUString sFavouritesList;
2296         if ( getEnvironmentValue( "PathFavourites", sFavouritesList ) )
2297             convertStringListToUrls( sFavouritesList, aFavourites, false );
2298     }
2299 
2300     DBG_ASSERT( _pImp->_pBtnStandard, "SvtFileDialog::implInitializeSpecialURLLists: how this?" );
2301     if ( _pImp->_pBtnStandard )
2302         _pImp->_pBtnStandard->SetFavouriteLocations( aFavourites );
2303 }
2304 
2305 //-----------------------------------------------------------------------------
2306 void SvtFileDialog::executeAsync( ::svt::AsyncPickerAction::Action _eAction,
2307                                     const String& _rURL, const String& _rFilter )
2308 {
2309     DBG_ASSERT( !m_pCurrentAsyncAction.is(), "SvtFileDialog::executeAsync: previous async action not yet finished!" );
2310 
2311     m_pCurrentAsyncAction = new AsyncPickerAction( this, _pFileView, _eAction );
2312 
2313     bool bReallyAsync = true;
2314     m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FillAsynchronously" ) ) ) >>= bReallyAsync;
2315 
2316     sal_Int32 nMinTimeout = 0;
2317     m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Timeout/Min" ) ) ) >>= nMinTimeout;
2318     sal_Int32 nMaxTimeout = 0;
2319     m_aConfiguration.getNodeValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Timeout/Max" ) ) ) >>= nMaxTimeout;
2320 
2321     m_bInExecuteAsync = true;
2322     m_pCurrentAsyncAction->execute( _rURL, _rFilter, bReallyAsync ? nMinTimeout : -1, nMaxTimeout, GetBlackList() );
2323     m_bInExecuteAsync = false;
2324 }
2325 
2326 //*****************************************************************************
2327 
2328 void SvtFileDialog::FileSelect()
2329 {
2330 	if ( _pFileNotifier )
2331 		_pFileNotifier->notify( FILE_SELECTION_CHANGED, 0 );
2332 }
2333 
2334 //*****************************************************************************
2335 
2336 void SvtFileDialog::FilterSelect()
2337 {
2338 	if ( _pFileNotifier )
2339 		_pFileNotifier->notify( CTRL_STATE_CHANGED,
2340                                 LISTBOX_FILTER );
2341 }
2342 
2343 //*****************************************************************************
2344 
2345 void SvtFileDialog::SetStandardDir( const String& rStdDir )
2346 
2347 /*	[Beschreibung]
2348 
2349 	Die Methode setzt den Pfad f"ur den Standardknopf.
2350 */
2351 
2352 {
2353     INetURLObject aObj( rStdDir );
2354     DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid protocol!" );
2355 	aObj.setFinalSlash();
2356 	_pImp->SetStandardDir( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
2357 }
2358 
2359 void SvtFileDialog::SetBlackList( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rBlackList )
2360 {
2361 	_pImp->SetBlackList( rBlackList );
2362 }
2363 
2364 //*****************************************************************************
2365 
2366 const ::com::sun::star::uno::Sequence< ::rtl::OUString >& SvtFileDialog::GetBlackList() const
2367 {
2368 	return _pImp->GetBlackList();
2369 }
2370 //*****************************************************************************
2371 
2372 const String& SvtFileDialog::GetStandardDir() const
2373 
2374 /*	[Beschreibung]
2375 
2376 	Diese Methode gibt den eingestellten Standardpfad zur"uck.
2377 */
2378 
2379 {
2380 	return _pImp->GetStandardDir();
2381 }
2382 
2383 //*****************************************************************************
2384 
2385 void SvtFileDialog::PrevLevel_Impl()
2386 {
2387     _pFileView->EndInplaceEditing( false );
2388 
2389     String sDummy;
2390     executeAsync( AsyncPickerAction::ePrevLevel, sDummy, sDummy );
2391 }
2392 
2393 //*****************************************************************************
2394 
2395 void SvtFileDialog::OpenURL_Impl( const String& _rURL )
2396 {
2397     _pFileView->EndInplaceEditing( false );
2398 
2399     DBG_ASSERT( m_aURLFilter.isUrlAllowed( _rURL ), "SvtFileDialog::OpenURL_Impl: forbidden URL! Should have been handled by the caller!" );
2400     executeAsync( AsyncPickerAction::eOpenURL, _rURL, getMostCurrentFilter( _pImp ) );
2401 }
2402 
2403 //*****************************************************************************
2404 SvtFileDialogFilter_Impl* SvtFileDialog::implAddFilter( const String& _rFilter, const String& _rType )
2405 {
2406 	SvtFileDialogFilter_Impl* pNewFilter = new SvtFileDialogFilter_Impl( _rFilter, _rType );
2407 	_pImp->_pFilter->C40_INSERT( SvtFileDialogFilter_Impl, pNewFilter, (sal_uInt16)0 );
2408 
2409 	if ( !_pImp->GetCurFilter() )
2410 		_pImp->SetCurFilter( pNewFilter, _rFilter );
2411 
2412 	return pNewFilter;
2413 }
2414 
2415 //*****************************************************************************
2416 
2417 void SvtFileDialog::AddFilter( const String& _rFilter, const String& _rType )
2418 {
2419 	DBG_ASSERT( !IsInExecute(), "SvtFileDialog::AddFilter: currently executing!" );
2420 	implAddFilter ( _rFilter, _rType );
2421 }
2422 
2423 //*****************************************************************************
2424 void SvtFileDialog::AddFilterGroup( const String& _rFilter, const Sequence< StringPair >& _rFilters )
2425 {
2426 	DBG_ASSERT( !IsInExecute(), "SvtFileDialog::AddFilter: currently executing!" );
2427 
2428 	implAddFilter( _rFilter, String() );
2429 	const StringPair* pSubFilters		=				_rFilters.getConstArray();
2430 	const StringPair* pSubFiltersEnd	= pSubFilters +	_rFilters.getLength();
2431 	for ( ; pSubFilters != pSubFiltersEnd; ++pSubFilters )
2432 		implAddFilter( pSubFilters->First, pSubFilters->Second );
2433 }
2434 
2435 //*****************************************************************************
2436 
2437 //-----------------------------------------------------------------------------
2438 void SvtFileDialog::SetCurFilter( const String& rFilter )
2439 {
2440 	DBG_ASSERT( !IsInExecute(), "SvtFileDialog::SetCurFilter: currently executing!" );
2441 
2442 	// Entsprechenden Filter suchen.
2443 	sal_uInt16 nPos = _pImp->_pFilter->Count();
2444 
2445     while ( nPos-- )
2446 	{
2447 		SvtFileDialogFilter_Impl* pFilter = _pImp->_pFilter->GetObject( nPos );
2448 		if ( pFilter->GetName() == rFilter )
2449 		{
2450 			_pImp->SetCurFilter( pFilter, rFilter );
2451 			break;
2452 		}
2453 	}
2454 }
2455 
2456 //*****************************************************************************
2457 
2458 String SvtFileDialog::GetCurFilter() const
2459 {
2460 	String aFilter;
2461 
2462 	const SvtFileDialogFilter_Impl* pCurrentFilter = _pImp->GetCurFilter();
2463     if ( pCurrentFilter )
2464 		aFilter = pCurrentFilter->GetName();
2465 
2466     return aFilter;
2467 }
2468 
2469 String SvtFileDialog::getCurFilter( ) const
2470 {
2471 	return GetCurFilter();
2472 }
2473 
2474 //*****************************************************************************
2475 
2476 sal_uInt16 SvtFileDialog::GetFilterCount() const
2477 {
2478 	return _pImp->_pFilter->Count();
2479 }
2480 
2481 //*****************************************************************************
2482 
2483 const String& SvtFileDialog::GetFilterName( sal_uInt16 nPos ) const
2484 {
2485 	DBG_ASSERT( nPos < GetFilterCount(), "invalid index" );
2486 	return _pImp->_pFilter->GetObject( nPos )->GetName();
2487 }
2488 
2489 //*****************************************************************************
2490 
2491 void SvtFileDialog::InitSize()
2492 {
2493 	if ( ! _pImp->_aIniKey.Len() )
2494         return;
2495 
2496 	Size aDlgSize = GetResizeOutputSizePixel();
2497 	SetMinOutputSizePixel( aDlgSize );
2498 
2499 	if ( !_pImp->_nFixDeltaHeight )
2500 	{
2501 		// Fixgr"ossen errechnen und merken
2502 		Point aPnt = _pFileView->GetPosPixel();
2503 		long nBoxH = _pFileView->GetSizePixel().Height();
2504 		long nH = GetSizePixel().Height();
2505 		_pImp->_nFixDeltaHeight = nH - nBoxH;
2506 	}
2507 
2508 	// initialize from config
2509 	SvtViewOptions aDlgOpt( E_DIALOG, _pImp->_aIniKey );
2510 
2511 	if ( aDlgOpt.Exists() )
2512 	{
2513 		SetWindowState( ByteString( String( aDlgOpt.GetWindowState() ), osl_getThreadTextEncoding() ) );
2514 
2515 		Any aUserData = aDlgOpt.GetUserItem( ::rtl::OUString::createFromAscii( "UserData" ) );
2516 		::rtl::OUString sCfgStr;
2517 		if ( aUserData >>= sCfgStr )
2518 			_pFileView->SetConfigString( String( sCfgStr ) );
2519 	}
2520 }
2521 
2522 //*****************************************************************************
2523 
2524 SvStringsDtor* SvtFileDialog::GetPathList() const
2525 {
2526 	SvStringsDtor*	pList = new SvStringsDtor;
2527 	sal_uLong			nCount = _pFileView->GetSelectionCount();
2528 	SvLBoxEntry*	pEntry = nCount ? _pFileView->FirstSelected() : NULL;
2529 
2530 	if ( ! pEntry )
2531 	{
2532 		String* pURL;
2533 
2534         if ( _pImp->_pEdFileName->GetText().Len() && _bIsInExecute )
2535             pURL = new String( _pImp->_pEdFileName->GetURL() );
2536         else
2537             pURL = new String( _aPath );
2538 
2539         pList->Insert( pURL, pList->Count() );
2540 	}
2541 	else
2542 	{
2543 		while ( pEntry )
2544 		{
2545 			String* pURL = new String( _pFileView->GetURL( pEntry ) );
2546 			pList->Insert( pURL, pList->Count() );
2547 			pEntry = _pFileView->NextSelected( pEntry );
2548 		}
2549 	}
2550 
2551 	return pList;
2552 }
2553 
2554 //*****************************************************************************
2555 
2556 void SvtFileDialog::implArrangeControls()
2557 {
2558     // this is the list of controls in the order they should be tabbed
2559     // from topleft to bottomright
2560     // pb: #136070# new order so all LabeledBy relations are correct now
2561     Control* pControls[] =
2562     {
2563         _pImp->_pFtCurrentPath,
2564         _pImp->_pBtnUp, _pImp->_pBtnNewFolder, _pImp->_pBtnStandard,        // image buttons
2565         _pFileView,                                                         // the file view
2566         _pImp->_pFtFileName, _pImp->_pEdFileName,
2567         _pImp->_pFtFileVersion, _pImp->_pLbFileVersion,
2568         _pImp->_pFtTemplates, _pImp->_pLbTemplates,
2569         _pImp->_pFtImageTemplates, _pImp->_pLbImageTemplates,
2570         _pImp->_pFtFileType, _pImp->GetFilterListControl(),                 // edit fields/list boxes
2571         _pImp->_pCbPassword, _pImp->_pCbAutoExtension, _pImp->_pCbOptions,  // checkboxes
2572         _pCbReadOnly, _pCbLinkBox, _pCbPreviewBox, _pCbSelection, _pPbPlay, // check boxes (continued)
2573         _pImp->_pBtnFileOpen, _pImp->_pBtnCancel, _pImp->_pBtnHelp          // buttons
2574 
2575         // (including the FixedTexts is important - not for tabbing order (they're irrelevant there),
2576         // but for working keyboard shortcuts)
2577         // 96861 - 23.01.2002 - fs@openoffice.org
2578     };
2579 
2580     // loop through all these controls and adjust the z-order
2581     Window* pPreviousWin = NULL;
2582     Control** pCurrent = pControls;
2583     for ( sal_Int32 i = 0; i < sal_Int32(sizeof( pControls ) / sizeof( pControls[ 0 ] )); ++i, ++pCurrent )
2584     {
2585         if ( !*pCurrent )
2586             // this control is not available in the current operation mode -> skip
2587             continue;
2588 
2589         if ( pPreviousWin )
2590             (*pCurrent)->SetZOrder( pPreviousWin, WINDOW_ZORDER_BEHIND );
2591         else
2592             (*pCurrent)->SetZOrder( NULL, WINDOW_ZORDER_FIRST );
2593 
2594         pPreviousWin = *pCurrent;
2595     }
2596 
2597     // FileName edit not the first control but it should have the focus initially
2598     _pImp->_pEdFileName->GrabFocus();
2599 }
2600 
2601 //*****************************************************************************
2602 
2603 sal_Bool SvtFileDialog::IsolateFilterFromPath_Impl( String& rPath, String& rFilter )
2604 {
2605 	String aEmpty;
2606 	String aReversePath( rPath );
2607 	aReversePath.Reverse();
2608 	sal_uInt16 nQuestionMarkPos = rPath.Search( '?' );
2609 
2610 	if ( nQuestionMarkPos != STRING_NOTFOUND )
2611 	{
2612 		// Fragezeichen als Wildcard nur bei Files
2613 		INetProtocol eProt = INetURLObject::CompareProtocolScheme( rPath );
2614 
2615 		if ( INET_PROT_NOT_VALID != eProt && INET_PROT_FILE != eProt )
2616 			nQuestionMarkPos = STRING_NOTFOUND;
2617 	}
2618 	sal_uInt16 nWildCardPos = Min( rPath.Search( FILEDIALOG_DEF_WILDCARD ), nQuestionMarkPos );
2619 	rFilter = aEmpty;
2620 
2621 	if ( nWildCardPos != STRING_NOTFOUND )
2622 	{
2623 		sal_uInt16 nPathTokenPos = aReversePath.Search( INET_PATH_TOKEN );
2624 
2625 		if ( nPathTokenPos == STRING_NOTFOUND )
2626 		{
2627 			String aDelim(
2628 #if defined(WNT) || defined(OS2)
2629 					'\\'
2630 #else
2631 					'/'
2632 #endif
2633 			);
2634 
2635 			nPathTokenPos = aReversePath.Search( aDelim );
2636 #if defined(OS2)
2637 			if ( nPathTokenPos == STRING_NOTFOUND )
2638 			{
2639 				nPathTokenPos = aReversePath.Search( '/' );
2640 			}
2641 #endif
2642 #if !defined( UNX )
2643 			if ( nPathTokenPos == STRING_NOTFOUND )
2644 			{
2645 				nPathTokenPos = aReversePath.Search( ':' );
2646 			}
2647 #endif
2648 		}
2649 
2650 		// Syntax pr"ufen.
2651 		if ( nPathTokenPos != STRING_NOTFOUND )
2652 		{
2653 			if ( nPathTokenPos < (rPath.Len() - nWildCardPos - 1) )
2654 			{
2655 				ErrorHandler::HandleError( ERRCODE_SFX_INVALIDSYNTAX );
2656 				return sal_False;
2657 			}
2658 
2659 			// Filter abschneiden.
2660 			rFilter = aReversePath;
2661 			rFilter.Erase( nPathTokenPos );
2662 			rFilter.Reverse();
2663 
2664 			// Ordner bestimmen.
2665 			rPath = aReversePath;
2666 			rPath.Erase( 0, nPathTokenPos );
2667 			rPath.Reverse();
2668 		}
2669 		else
2670 		{
2671 			rFilter = rPath;
2672 			rPath = aEmpty;
2673 		}
2674 	}
2675 
2676 	return sal_True;
2677 }
2678 
2679 //*****************************************************************************
2680 
2681 //-----------------------------------------------------------------------------
2682 void SvtFileDialog::implUpdateImages( )
2683 {
2684 	// determine high contrast mode
2685 	{
2686 		sal_Bool bIsHighContrast = GetSettings().GetStyleSettings().GetHighContrastMode();
2687 		m_aImages = ImageList( SvtResId( bIsHighContrast ? RID_FILEPICKER_IMAGES_HC : RID_FILEPICKER_IMAGES ) );
2688 	}
2689 
2690 	// set the appropriate images on the buttons
2691 	if ( _pImp->_pBtnUp )
2692 		_pImp->_pBtnUp->SetModeImage( GetButtonImage( IMG_FILEDLG_BTN_UP ) );
2693 
2694 	if ( _pImp->_pBtnStandard )
2695 		_pImp->_pBtnStandard->SetModeImage( GetButtonImage( IMG_FILEDLG_BTN_STD ) );
2696 
2697 	if ( _pImp->_pBtnNewFolder )
2698 		_pImp->_pBtnNewFolder->SetModeImage( GetButtonImage( IMG_FILEDLG_CREATEFOLDER ) );
2699 }
2700 
2701 //-----------------------------------------------------------------------------
2702 void SvtFileDialog::DataChanged( const DataChangedEvent& _rDCEvt )
2703 {
2704 	if ( DATACHANGED_SETTINGS == _rDCEvt.GetType() )
2705 		implUpdateImages( );
2706 
2707 	ModalDialog::DataChanged( _rDCEvt );
2708 }
2709 
2710 //-----------------------------------------------------------------------------
2711 void SvtFileDialog::Resize()
2712 {
2713 	if ( IsRollUp() )
2714 		return;
2715 
2716 	Size aDlgSize = GetResizeOutputSizePixel();
2717 	Size aOldSize = _pImp->_aDlgSize;
2718 	_pImp->_aDlgSize = aDlgSize;
2719 	long nWinDeltaW = 0;
2720 
2721 	if ( _pPrevWin &&
2722          _pPrevWin->GetPosPixel().X() > _pFileView->GetPosPixel().X() )
2723 	{
2724 		nWinDeltaW = _pPrevWin->GetOutputSizePixel().Width() + _pImp->_a6Size.Width();
2725 	}
2726 
2727 	Size aNewSize = _pFileView->GetSizePixel();
2728 	Point aBoxPos( _pFileView->GetPosPixel() );
2729 	long nDeltaY = aNewSize.Height();
2730 	long nDeltaX = aNewSize.Width();
2731 	aNewSize.Height() = aDlgSize.Height() - _pImp->_nFixDeltaHeight;
2732 	aNewSize.Width() = aDlgSize.Width() - aBoxPos.X() - _pImp->_a6Size.Width() - nWinDeltaW;
2733 	if ( aOldSize.Height() )
2734 		nDeltaY = _pImp->_aDlgSize.Height() - aOldSize.Height();
2735 	else
2736 		nDeltaY = aNewSize.Height() - nDeltaY;
2737 	nDeltaX = aNewSize.Width() - nDeltaX;
2738 
2739 	if ( nWinDeltaW )
2740 		nWinDeltaW = nDeltaX * 2 / 3;
2741 	aNewSize.Width() -= nWinDeltaW;
2742 	nDeltaX -= nWinDeltaW;
2743 
2744 	_pFileView->SetSizePixel( aNewSize );
2745 
2746 	if ( !nDeltaY && !nDeltaX )
2747 		// Dieses Resize wurde nur zum Ein - oder Ausblenden des Indicators aufgerufen
2748 		return;
2749 
2750 	// -------------
2751 	// move controls
2752 
2753 	// controls to move vertically
2754 	{
2755 		Control* aMoveControlsVert[] =
2756 		{
2757 			_pImp->_pFtFileName, _pImp->_pEdFileName, _pImp->_pFtFileVersion, _pImp->_pLbFileVersion,
2758 			_pImp->_pFtTemplates, _pImp->_pLbTemplates, _pImp->_pFtImageTemplates, _pImp->_pLbImageTemplates,
2759 			_pImp->_pFtFileType, _pImp->GetFilterListControl(), _pCbReadOnly, _pCbLinkBox, _pCbPreviewBox,
2760 			_pPbPlay, _pImp->_pCbPassword, _pImp->_pCbAutoExtension, _pImp->_pCbOptions, _pCbSelection
2761 		};
2762 		Control** ppMoveControls = aMoveControlsVert;
2763 		Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsVert ) / sizeof( aMoveControlsVert[0] );
2764 		for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls )
2765 			lcl_MoveControl( *ppMoveControls, 0, nDeltaY );
2766 	}
2767 
2768 	// controls to move vertically and horizontally
2769 	{
2770 		Control* aMoveControlsBoth[] =
2771 		{
2772 			_pImp->_pBtnFileOpen, _pImp->_pBtnCancel, _pImp->_pBtnHelp
2773 		};
2774 		Control** ppMoveControls = aMoveControlsBoth;
2775 		Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsBoth ) / sizeof( aMoveControlsBoth[0] );
2776 		for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls )
2777 			lcl_MoveControl( *ppMoveControls, nDeltaX, nDeltaY );
2778 	}
2779 
2780 	// controls to move horizontally
2781 	{
2782 		Control* aMoveControlsHor[] =
2783 		{
2784 			_pImp->_pBtnUp, _pImp->_pBtnNewFolder, _pImp->_pBtnStandard
2785 		};
2786 		Control** ppMoveControls = aMoveControlsHor;
2787 		Control** ppMoveControlsEnd = ppMoveControls + sizeof( aMoveControlsHor ) / sizeof( aMoveControlsHor[0] );
2788 		for ( ; ppMoveControls != ppMoveControlsEnd; ++ppMoveControls )
2789 			lcl_MoveControl( *ppMoveControls, nDeltaX, 0 );
2790 	}
2791 
2792 	// ---------------
2793 	// resize controls
2794 	{
2795 		Control* aSizeControls[] =
2796 		{
2797 			_pImp->_pEdFileName, _pImp->_pLbFileVersion, _pImp->_pLbTemplates, _pImp->_pLbImageTemplates,
2798 			_pImp->GetFilterListControl(), _pImp->_pFtCurrentPath,
2799 		};
2800 		sal_Int32 nSizeControls = sizeof( aSizeControls ) / sizeof( aSizeControls[0] );
2801 		Control** ppSizeControls = aSizeControls;
2802 		for ( sal_Int32 j=0; j<nSizeControls; ++j, ++ppSizeControls )
2803 		{
2804 			if ( *ppSizeControls )
2805 			{
2806 				aNewSize = (*ppSizeControls)->GetSizePixel();
2807 				aNewSize.Width() += nDeltaX;
2808 				(*ppSizeControls)->SetSizePixel( aNewSize );
2809 			}
2810 		}
2811 	}
2812 
2813 	// zus"atzliche Controls ausrichten
2814 	if ( _pPrevWin &&
2815          _pPrevWin->GetPosPixel().X() > _pFileView->GetPosPixel().X() )
2816 	{
2817 		// Controls vom Typ Window speziell ausrichten
2818 		// auch die Gr"osse anpassen
2819 		Point aNewPos = _pPrevWin->GetPosPixel();
2820 		aNewPos.X() += nDeltaX;
2821 		_pPrevWin->SetPosPixel( aNewPos );
2822         _pPrevBmp->SetPosPixel( aNewPos );
2823 		aNewSize = _pPrevWin->GetOutputSizePixel();
2824 		aNewSize.Width() += nWinDeltaW;
2825 		aNewSize.Height() += nDeltaY;
2826 		if ( !aOldSize.Height() )
2827 			aNewSize.Height() -= ( _pImp->_a6Size.Height() / 2 );
2828 		_pPrevWin->SetOutputSizePixel( aNewSize );
2829 		_pPrevBmp->SetOutputSizePixel( aNewSize );
2830         _pPrevBmp->Invalidate();
2831 	}
2832 
2833     if ( _pFileNotifier )
2834 		_pFileNotifier->notify( DIALOG_SIZE_CHANGED, 0 );
2835 }
2836 
2837 //*****************************************************************************
2838 
2839 //-----------------------------------------------------------------------------
2840 Control* SvtFileDialog::getControl( sal_Int16 _nControlId, sal_Bool _bLabelControl ) const
2841 {
2842 	Control* pReturn = NULL;
2843 
2844 	switch ( _nControlId )
2845 	{
2846 		case CONTROL_FILEVIEW:
2847 			pReturn = _bLabelControl ? NULL : static_cast< Control* >( _pFileView );
2848 			break;
2849 
2850 		case EDIT_FILEURL:
2851 			pReturn =	_bLabelControl
2852 					?	static_cast< Control* >( _pImp->_pFtFileName )
2853 					:	static_cast< Control* >( _pImp->_pEdFileName );
2854 			break;
2855 
2856 		case EDIT_FILEURL_LABEL:
2857 			pReturn = static_cast< Control* >( _pImp->_pFtFileName );
2858 			break;
2859 
2860 		case CHECKBOX_AUTOEXTENSION:
2861 			pReturn = _pImp->_pCbAutoExtension;
2862 			break;
2863 
2864 		case CHECKBOX_PASSWORD:
2865 			pReturn = _pImp->_pCbPassword;
2866 			break;
2867 
2868 		case CHECKBOX_FILTEROPTIONS:
2869 			pReturn = _pImp->_pCbOptions;
2870 			break;
2871 
2872 		case CHECKBOX_READONLY:
2873 			pReturn = _pCbReadOnly;
2874 			break;
2875 
2876 		case CHECKBOX_LINK:
2877 			pReturn = _pCbLinkBox;
2878 			break;
2879 
2880 		case CHECKBOX_PREVIEW:
2881 			pReturn = _pCbPreviewBox;
2882 			break;
2883 
2884 		case CHECKBOX_SELECTION:
2885 			pReturn = _pCbSelection;
2886 			break;
2887 
2888 		case LISTBOX_FILTER:
2889 			pReturn = _bLabelControl ? _pImp->_pFtFileType : _pImp->GetFilterListControl();
2890 			break;
2891 
2892 		case LISTBOX_FILTER_LABEL:
2893 			pReturn = _pImp->_pFtFileType;
2894 			break;
2895 
2896 		case FIXEDTEXT_CURRENTFOLDER:
2897 			pReturn = _pImp->_pFtCurrentPath;
2898 			break;
2899 
2900 		case LISTBOX_VERSION:
2901 			pReturn =	_bLabelControl
2902 					?	static_cast< Control* >( _pImp->_pFtFileVersion )
2903 					:	static_cast< Control* >( _pImp->_pLbFileVersion );
2904 			break;
2905 
2906 		case LISTBOX_TEMPLATE:
2907 			pReturn =	_bLabelControl
2908 					?	static_cast< Control* >( _pImp->_pFtTemplates )
2909 					:	static_cast< Control* >( _pImp->_pLbTemplates );
2910 			break;
2911 
2912 		case LISTBOX_IMAGE_TEMPLATE:
2913 			pReturn =	_bLabelControl
2914 					?	static_cast< Control* >( _pImp->_pFtImageTemplates )
2915 					:	static_cast< Control* >( _pImp->_pLbImageTemplates );
2916 			break;
2917 
2918 		case LISTBOX_VERSION_LABEL:
2919 			pReturn = _pImp->_pFtFileVersion;
2920 			break;
2921 
2922 		case LISTBOX_TEMPLATE_LABEL:
2923 			pReturn = _pImp->_pFtTemplates;
2924 			break;
2925 
2926 		case LISTBOX_IMAGE_TEMPLATE_LABEL:
2927 			pReturn = _pImp->_pFtImageTemplates;
2928 			break;
2929 
2930 		case PUSHBUTTON_OK:
2931 			pReturn = _pImp->_pBtnFileOpen;
2932 			break;
2933 
2934 		case PUSHBUTTON_CANCEL:
2935 			pReturn = _pImp->_pBtnCancel;
2936 			break;
2937 
2938 		case PUSHBUTTON_PLAY:
2939 			pReturn = _pPbPlay;
2940 			break;
2941 
2942 		case PUSHBUTTON_HELP:
2943 			pReturn = _pImp->_pBtnHelp;
2944 			break;
2945 
2946 		case TOOLBOXBUTOON_DEFAULT_LOCATION:
2947 			pReturn = _pImp->_pBtnStandard;
2948 			break;
2949 
2950 		case TOOLBOXBUTOON_LEVEL_UP:
2951 			pReturn = _pImp->_pBtnUp;
2952 			break;
2953 
2954 		case TOOLBOXBUTOON_NEW_FOLDER:
2955 			pReturn = _pImp->_pBtnNewFolder;
2956 			break;
2957 
2958         case LISTBOX_FILTER_SELECTOR:
2959             // only exists on SalGtkFilePicker
2960             break;
2961 
2962 		default:
2963 			DBG_ERRORFILE( "SvtFileDialog::getControl: invalid id!" );
2964 	}
2965 	return pReturn;
2966 }
2967 
2968 // -----------------------------------------------------------------------
2969 void SvtFileDialog::enableControl( sal_Int16 _nControlId, sal_Bool _bEnable )
2970 {
2971     Control* pControl = getControl( _nControlId, sal_False );
2972     if ( pControl )
2973         EnableControl( pControl, _bEnable );
2974     Control* pLabel = getControl( _nControlId, sal_True );
2975     if ( pLabel )
2976         EnableControl( pLabel, _bEnable );
2977 }
2978 
2979 // -----------------------------------------------------------------------
2980 void SvtFileDialog::AddControls_Impl( )
2981 {
2982 	// create the "insert as link" checkbox, if needed
2983     if ( _nExtraBits & SFX_EXTRA_INSERTASLINK )
2984 	{
2985 		_pCbLinkBox = new CheckBox( this );
2986         _pCbLinkBox ->SetText( SvtResId( STR_SVT_FILEPICKER_INSERT_AS_LINK ) );
2987 		_pCbLinkBox ->SetHelpId( HID_FILEDLG_LINK_CB );
2988 		AddControl( _pCbLinkBox  );
2989 		ReleaseOwnerShip( _pCbLinkBox );
2990 		_pCbLinkBox->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
2991 	}
2992 
2993 	// create the "show preview" checkbox ( and the preview window, too ), if needed
2994 	if ( _nExtraBits & SFX_EXTRA_SHOWPREVIEW  )
2995     {
2996     	_pImp->_aIniKey = IMPGRF_CONFIGNAME;
2997 		// because the "<All Formats> (*.bmp,*...)" entry is to wide,
2998 		// we need to disable the auto width feature of the filter box
2999 		_pImp->DisableFilterBoxAutoWidth();
3000 
3001         // "Vorschau"
3002 	    _pCbPreviewBox = new CheckBox( this );
3003 	    _pCbPreviewBox->SetText( SvtResId( STR_SVT_FILEPICKER_SHOW_PREVIEW ) );
3004 	    _pCbPreviewBox->SetHelpId( HID_FILEDLG_PREVIEW_CB );
3005 	    AddControl( _pCbPreviewBox );
3006 		ReleaseOwnerShip( _pCbPreviewBox );
3007 		_pCbPreviewBox->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
3008 
3009 	    // Preview-Fenster erst hier erzeugen
3010 	    _pPrevWin = new Window( this, WinBits( WB_BORDER ) );
3011 	    AddControl( _pPrevWin );
3012 		ReleaseOwnerShip( _pPrevWin );
3013         _pPrevWin->Hide();
3014 
3015         _pPrevBmp = new FixedBitmap( this, WinBits( WB_BORDER ) );
3016 	    _pPrevBmp->SetBackground( Wallpaper( Color( COL_WHITE ) ) );
3017         _pPrevBmp->Show();
3018 		_pPrevBmp->SetAccessibleName(SvtResId(STR_PREVIEW));
3019     }
3020 
3021     if ( _nExtraBits & SFX_EXTRA_AUTOEXTENSION )
3022     {
3023 		_pImp->_pCbAutoExtension = new CheckBox( this, SvtResId( CB_AUTO_EXTENSION ) );
3024 	    _pImp->_pCbAutoExtension->SetText( SvtResId( STR_SVT_FILEPICKER_AUTO_EXTENSION ) );
3025 		_pImp->_pCbAutoExtension->Check( sal_True );
3026 		AddControl( _pImp->_pCbAutoExtension );
3027 		ReleaseOwnerShip( _pImp->_pCbAutoExtension );
3028 		_pImp->_pCbAutoExtension->SetClickHdl( LINK( this, SvtFileDialog, AutoExtensionHdl_Impl ) );
3029     }
3030 
3031     if ( _nExtraBits & SFX_EXTRA_FILTEROPTIONS )
3032 	{
3033 		_pImp->_pCbOptions = new CheckBox( this, SvtResId( CB_OPTIONS ) );
3034 	    _pImp->_pCbOptions->SetText( SvtResId( STR_SVT_FILEPICKER_FILTER_OPTIONS ) );
3035 		AddControl( _pImp->_pCbOptions );
3036 		ReleaseOwnerShip( _pImp->_pCbOptions );
3037 		_pImp->_pCbOptions->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
3038 	}
3039 
3040     if ( _nExtraBits & SFX_EXTRA_SELECTION )
3041 	{
3042         _pCbSelection = new CheckBox( this, SvtResId( CB_OPTIONS ) );
3043 	    _pCbSelection->SetText( SvtResId( STR_SVT_FILEPICKER_SELECTION ) );
3044 		AddControl( _pCbSelection );
3045 		ReleaseOwnerShip( _pCbSelection );
3046 		_pCbSelection->SetClickHdl( LINK( this, SvtFileDialog, ClickHdl_Impl ) );
3047 	}
3048 
3049     if ( _nExtraBits & SFX_EXTRA_PLAYBUTTON )
3050 	{
3051 		_pPbPlay = new PushButton( this );
3052 	    _pPbPlay->SetText( SvtResId( STR_SVT_FILEPICKER_PLAY ) );
3053 		_pPbPlay->SetHelpId( HID_FILESAVE_DOPLAY );
3054 		AddControl( _pPbPlay );
3055 		ReleaseOwnerShip( _pPbPlay );
3056 		_pPbPlay->SetClickHdl( LINK( this, SvtFileDialog, PlayButtonHdl_Impl ) );
3057 	}
3058 
3059 	if ( _nExtraBits & SFX_EXTRA_SHOWVERSIONS )
3060 	{
3061 		_pImp->_pFtFileVersion = new FixedText(	this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) );
3062 		_pImp->_pFtFileVersion->SetText( SvtResId( STR_SVT_FILEPICKER_VERSION ) );
3063 
3064 		_pImp->_pLbFileVersion = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) );
3065 		_pImp->_pLbFileVersion->SetHelpId( HID_FILEOPEN_VERSION );
3066 	}
3067     else if ( _nExtraBits & SFX_EXTRA_TEMPLATES )
3068 	{
3069 		_pImp->_pFtTemplates = new FixedText( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) );
3070 		_pImp->_pFtTemplates->SetText( SvtResId( STR_SVT_FILEPICKER_TEMPLATES ) );
3071 
3072 		_pImp->_pLbTemplates = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) );
3073 		_pImp->_pLbTemplates->SetHelpId( HID_FILEOPEN_VERSION );
3074 			// This is strange. During the re-factoring during 96930, I discovered that this help id
3075 			// is set in the "Templates mode". This was hidden in the previous implementation.
3076 			// Shouldn't this be a more meaningfull help id.
3077 			// 96930 - 15.08.2002 - fs@openoffice.org
3078 	}
3079     else if ( _nExtraBits & SFX_EXTRA_IMAGE_TEMPLATE )
3080 	{
3081 		_pImp->_pFtImageTemplates = new FixedText( this, SvtResId( FT_EXPLORERFILE_SHARED_LISTBOX ) );
3082 		_pImp->_pFtImageTemplates->SetText( SvtResId( STR_SVT_FILEPICKER_IMAGE_TEMPLATE ) );
3083 
3084 		_pImp->_pLbImageTemplates = new ListBox( this, SvtResId( LB_EXPLORERFILE_SHARED_LISTBOX ) );
3085 		_pImp->_pLbImageTemplates->SetHelpId( HID_FILEOPEN_IMAGE_TEMPLATE );
3086 	}
3087 }
3088 
3089 // -----------------------------------------------------------------------
3090 sal_Int32 SvtFileDialog::getTargetColorDepth()
3091 {
3092     if ( _pPrevBmp )
3093         return _pPrevBmp->GetBitCount();
3094     else
3095         return 0;
3096 }
3097 
3098 // -----------------------------------------------------------------------
3099 sal_Int32 SvtFileDialog::getAvailableWidth()
3100 {
3101     if ( _pPrevBmp )
3102         return _pPrevBmp->GetOutputSizePixel().Width();
3103     else
3104         return 0;
3105 }
3106 
3107 // -----------------------------------------------------------------------
3108 sal_Int32 SvtFileDialog::getAvailableHeight()
3109 {
3110     if ( _pPrevBmp )
3111         return _pPrevBmp->GetOutputSizePixel().Height();
3112     else
3113         return 0;
3114 }
3115 
3116 // -----------------------------------------------------------------------
3117 void SvtFileDialog::setImage( sal_Int16 /*aImageFormat*/, const Any& rImage )
3118 {
3119     if ( ! _pPrevBmp || ! _pPrevBmp->IsVisible() )
3120         return;
3121 
3122     Sequence < sal_Int8 > aBmpSequence;
3123 
3124     if ( rImage >>= aBmpSequence )
3125     {
3126         Bitmap          aBmp;
3127         SvMemoryStream  aData( aBmpSequence.getArray(),
3128                                aBmpSequence.getLength(),
3129                                STREAM_READ );
3130         aData >> aBmp;
3131 
3132         _pPrevBmp->SetBitmap( aBmp );
3133     }
3134     else
3135     {
3136         Bitmap aEmpty;
3137         _pPrevBmp->SetBitmap( aEmpty );
3138     }
3139 }
3140 
3141 // -----------------------------------------------------------------------
3142 sal_Bool SvtFileDialog::setShowState( sal_Bool /*bShowState*/ )
3143 {
3144 	// #97633 for the system filedialog it's
3145 	// usefull to make the preview switchable
3146 	// because the preview occupies
3147 	// half of the size of the file listbox
3148 	// which is not the case here,
3149 	// so we (TRA/FS) decided not to make
3150 	// the preview window switchable because
3151 	// else we would have to change the layout
3152 	// of the file dialog dynamically
3153 	// support for set/getShowState is opionally
3154 	// see com::sun::star::ui::dialogs::XFilePreview
3155 	/*
3156     if ( _pPrevBmp )
3157     {
3158         _pPrevBmp->Show( bShowState );
3159         return sal_True;
3160     }
3161     else
3162         return sal_False;
3163 	*/
3164 
3165 	return sal_False;
3166 }
3167 
3168 // -----------------------------------------------------------------------
3169 String SvtFileDialog::getCurrentFileText( ) const
3170 {
3171 	String sReturn;
3172 	if ( _pImp && _pImp->_pEdFileName )
3173 		sReturn = _pImp->_pEdFileName->GetText();
3174 	return sReturn;
3175 }
3176 
3177 // -----------------------------------------------------------------------
3178 void SvtFileDialog::setCurrentFileText( const String& _rText, bool _bSelectAll )
3179 {
3180 	if ( _pImp && _pImp->_pEdFileName )
3181     {
3182 	    _pImp->_pEdFileName->SetText( _rText );
3183         if ( _bSelectAll )
3184             _pImp->_pEdFileName->SetSelection( Selection( 0, _rText.Len() ) );
3185     }
3186 }
3187 
3188 // -----------------------------------------------------------------------
3189 sal_Bool SvtFileDialog::isAutoExtensionEnabled()
3190 {
3191 	return _pImp->_pCbAutoExtension && _pImp->_pCbAutoExtension->IsChecked();
3192 }
3193 
3194 // -----------------------------------------------------------------------
3195 sal_Bool SvtFileDialog::getShowState()
3196 {
3197     if ( _pPrevBmp )
3198         return _pPrevBmp->IsVisible();
3199     else
3200         return sal_False;
3201 }
3202 
3203 // -----------------------------------------------------------------------
3204 void SvtFileDialog::ReleaseOwnerShip( Window* pUserControl )
3205 
3206 /*
3207   [Beschreibung]
3208   Die Methode sorgt dafuer das das spezifizierte Element nicht mehr im Besitz
3209   der Instanz ist.
3210 */
3211 
3212 {
3213 	ControlChain_Impl* pElement = _pUserControls;
3214 	while ( pElement )
3215 	{
3216 		if ( pElement->_pControl == pUserControl )
3217 		{
3218 			pElement->_bHasOwnerShip = sal_False;
3219 			break;
3220 		}
3221 		pElement = pElement->_pNext;
3222 	}
3223 }
3224 
3225 //***************************************************************************
3226 
3227 sal_Bool SvtFileDialog::AddControl( Window* pControl, sal_Bool bNewLine )
3228 {
3229 	// control already exists
3230 	ControlChain_Impl* pElement = _pUserControls;
3231 	while ( pElement )
3232 	{
3233 		if ( pElement->_pControl == pControl )
3234 			return sal_False;
3235 		pElement = pElement->_pNext;
3236 	}
3237 
3238 	// Check if controls have already been added.
3239 	Size aNewControlSize( pControl->GetOutputSizePixel() );
3240 	Size aDlgSize( GetOutputSizePixel() );
3241 	WindowType nType = pControl->GetType();
3242 	if ( !aNewControlSize.Height() )
3243 	{
3244 		// Detect a size.
3245 		Size aSize( 0, 10 );
3246 		if ( nType == WINDOW_PUSHBUTTON )
3247 		{
3248 			Size aDefSiz = LogicToPixel( Size( 50, 14 ), MAP_APPFONT );
3249 			long nTextWidth = pControl->GetTextWidth( pControl->GetText() );
3250 			aSize.Width() = nTextWidth + WIDTH_ADDITION;
3251 
3252 			// PushButton:	Mindestbreite 50 logische Einheiten,
3253 			//				H"ohe immer 14 logische Einheiten
3254 			if ( aDefSiz.Width() > aSize.Width() )
3255 				aSize.Width() = aDefSiz.Width();
3256 			aSize.Height() = aDefSiz.Height();
3257 			aNewControlSize = aSize;
3258 		}
3259 		else
3260 			aNewControlSize = LogicToPixel( aSize, MAP_APPFONT );
3261 		if ( nType != WINDOW_PUSHBUTTON )
3262 			aNewControlSize.Width() = pControl->GetTextWidth( pControl->GetText() ) + WIDTH_ADDITION;
3263 		if ( nType == WINDOW_CHECKBOX )
3264 			aNewControlSize.Width() += WIDTH_ADDITION;
3265 		if ( nType == WINDOW_WINDOW )
3266 		{
3267 			aNewControlSize.Height() = GetOutputSizePixel().Height() - 18;
3268 			aNewControlSize.Width() = 200;
3269 			aDlgSize.Width() += 210;
3270 			SetOutputSizePixel( aDlgSize );
3271 		}
3272 		pControl->SetOutputSizePixel( aNewControlSize );
3273 	}
3274 	Point aNewControlPos;
3275 	Size* pNewDlgSize = NULL;
3276 	sal_Bool bNewRow = bNewLine;
3277 	sal_Bool bFirstNewRow = sal_False;
3278 
3279 	if ( nType == WINDOW_WINDOW )
3280 	{
3281 		aNewControlPos.X() = aDlgSize.Width() - 210;
3282 		aNewControlPos.Y() = 8;
3283 	}
3284 	else if ( _pUserControls )
3285 	{
3286 		Point aNewControlRange( _pUserControls->_pControl->GetPosPixel() );
3287 		long nPrevControlHeight = _pUserControls->_pControl->GetSizePixel().Height();
3288 		aNewControlRange +=
3289 			Point( _pUserControls->_pControl->GetOutputSizePixel().Width(), 0 );
3290 		aNewControlPos = aNewControlRange;
3291 		if ( nPrevControlHeight > aNewControlSize.Height() )
3292 		{
3293 			long nY = nPrevControlHeight;
3294 			nY -= aNewControlSize.Height();
3295 			nY /= 2;
3296 			aNewControlPos.Y() += nY;
3297 		}
3298 		aNewControlPos += LogicToPixel( Point( 3, 0 ), MAP_APPFONT );
3299 		aNewControlRange += LogicToPixel( Point( 9, 0 ), MAP_APPFONT );
3300 		aNewControlRange += Point( aNewControlSize.Width(), 0 );
3301 
3302 		// Check if a new row has to be created.
3303 		if ( aNewControlRange.X() > aDlgSize.Width() )
3304 			bNewRow = sal_True;
3305 	}
3306 	else
3307 	{
3308 		// Create a new row if there was no usercontrol before.
3309 		bNewRow = sal_True;
3310 		bFirstNewRow = sal_True;
3311 	}
3312 
3313 	// Check if a new row has to be created.
3314 	Size aBorderSize = LogicToPixel( Size( 6, 6 ), MAP_APPFONT );
3315 	long nLeftBorder = aBorderSize.Width();
3316 	long nLowerBorder = aBorderSize.Height();
3317 	if ( bNewRow )
3318 	{
3319 		// Set control at the beginning of a new line.
3320 		long nSmallBorderHeight = nLowerBorder / 2;
3321 		aNewControlPos = Point( nLeftBorder, 0 );
3322 		aNewControlPos += Point( 0, aDlgSize.Height() );
3323 		aNewControlPos.Y() -= nSmallBorderHeight;
3324 		// Set new size.
3325 		pNewDlgSize = new Size( aDlgSize );
3326 		pNewDlgSize->Height() -= nSmallBorderHeight;
3327 		pNewDlgSize->Height() += aNewControlSize.Height();
3328 		pNewDlgSize->Height() += nLowerBorder;
3329 	}
3330 	else
3331 	{
3332 		// Check if the window has to be resized.
3333 		Size aNewControlRange( 0, aNewControlPos.Y() );
3334 		aNewControlRange.Height() += aNewControlSize.Height();
3335 		aNewControlRange.Height() += nLowerBorder;
3336 		if ( aNewControlRange.Height() > aDlgSize.Height() )
3337 			pNewDlgSize = new Size( aDlgSize.Width(), aNewControlRange.Height() );
3338 	}
3339 
3340 	// Update view.
3341 	if ( pNewDlgSize )
3342 	{
3343 		SetOutputSizePixel( *pNewDlgSize );
3344 		delete pNewDlgSize;
3345 	}
3346 	pControl->SetPosPixel( aNewControlPos );
3347 	pControl->Show();
3348 	_pUserControls = new ControlChain_Impl( pControl, _pUserControls );
3349 
3350 	return sal_True;
3351 }
3352 
3353 sal_Bool SvtFileDialog::ContentHasParentFolder( const rtl::OUString& rURL )
3354 {
3355 	m_aContent.bindTo( rURL );
3356 
3357 	if ( m_aContent.isInvalid() )
3358 		return sal_False;
3359 
3360 	return m_aContent.hasParentFolder( ) && m_aContent.isValid();
3361 }
3362 
3363 sal_Bool SvtFileDialog::ContentCanMakeFolder( const rtl::OUString& rURL )
3364 {
3365 	m_aContent.bindTo( rURL );
3366 
3367 	if ( m_aContent.isInvalid() )
3368 		return sal_False;
3369 
3370 	return m_aContent.canCreateFolder( ) && m_aContent.isValid();
3371 }
3372 
3373 sal_Bool SvtFileDialog::ContentGetTitle( const rtl::OUString& rURL, String& rTitle )
3374 {
3375 	m_aContent.bindTo( rURL );
3376 
3377 	if ( m_aContent.isInvalid() )
3378 		return sal_False;
3379 
3380 	::rtl::OUString sTitle;
3381 	m_aContent.getTitle( sTitle );
3382 	rTitle = sTitle;
3383 
3384 	return m_aContent.isValid();
3385 }
3386 
3387 void SvtFileDialog::appendDefaultExtension(String& _rFileName,
3388                                            const String& _rFilterDefaultExtension,
3389                                            const String& _rFilterExtensions)
3390 {
3391     String aTemp(_rFileName);
3392     aTemp.ToLowerAscii();
3393     String aType(_rFilterExtensions);
3394     aType.ToLowerAscii();
3395 
3396     if ( ! aType.EqualsAscii(FILEDIALOG_FILTER_ALL) )
3397     {
3398         sal_uInt16 nWildCard = aType.GetTokenCount( FILEDIALOG_DEF_EXTSEP );
3399         sal_uInt16 nIndex, nPos = 0;
3400 
3401         for ( nIndex = 0; nIndex < nWildCard; nIndex++ )
3402         {
3403             String aExt(aType.GetToken( 0, FILEDIALOG_DEF_EXTSEP, nPos ));
3404             // take care of a leading *
3405             sal_uInt16 nExtOffset = (aExt.GetBuffer()[0] == '*' ? 1 : 0);
3406             sal_Unicode* pExt = aExt.GetBufferAccess() + nExtOffset;
3407             xub_StrLen nExtLen = aExt.Len() - nExtOffset;
3408             xub_StrLen nOffset = aTemp.Len() - nExtLen;
3409             // minimize search by starting at last possible index
3410             if ( aTemp.Search(pExt, nOffset) == nOffset )
3411                 break;
3412         }
3413 
3414         if ( nIndex >= nWildCard )
3415         {
3416             _rFileName += '.';
3417             _rFileName += _rFilterDefaultExtension;
3418         }
3419     }
3420 }
3421 
3422 // -----------------------------------------------------------------------
3423 
3424 // QueryFolderNameDialog -------------------------------------------------------
3425 
3426 namespace svtools {
3427 
3428 QueryFolderNameDialog::QueryFolderNameDialog
3429 (
3430 	Window* _pParent,
3431 	const String& rTitle,
3432 	const String& rDefaultText,
3433 	String* pGroupName
3434 ) :
3435 	ModalDialog( _pParent, SvtResId( DLG_SVT_QUERYFOLDERNAME ) ),
3436 
3437 	aNameText	( this, SvtResId( FT_SVT_QUERYFOLDERNAME_DLG_NAME ) ),
3438 	aNameEdit	( this, SvtResId( ED_SVT_QUERYFOLDERNAME_DLG_NAME ) ),
3439 	aNameLine	( this, SvtResId( FL_SVT_QUERYFOLDERNAME_DLG_NAME ) ),
3440 	aOKBtn		( this, SvtResId( BT_SVT_QUERYFOLDERNAME_DLG_OK ) ),
3441 	aCancelBtn	( this, SvtResId( BT_SVT_QUERYFOLDERNAME_DLG_CANCEL ) )
3442 {
3443 	FreeResource();
3444 	SetText( rTitle );
3445 	aNameEdit.SetText( rDefaultText );
3446 	aNameEdit.SetSelection( Selection( 0, rDefaultText.Len() ) );
3447 	aOKBtn.SetClickHdl( LINK( this, QueryFolderNameDialog, OKHdl ) );
3448 	aNameEdit.SetModifyHdl( LINK( this, QueryFolderNameDialog, NameHdl ) );
3449 
3450 	if ( pGroupName )
3451 		aNameLine.SetText( *pGroupName );
3452 };
3453 
3454 // -----------------------------------------------------------------------
3455 IMPL_LINK( QueryFolderNameDialog, OKHdl, Button *, EMPTYARG )
3456 {
3457 	// trim the strings
3458 	aNameEdit.SetText( aNameEdit.GetText().EraseLeadingChars().EraseTrailingChars() );
3459 	EndDialog( RET_OK );
3460 	return 1;
3461 }
3462 
3463 // -----------------------------------------------------------------------
3464 IMPL_LINK( QueryFolderNameDialog, NameHdl, Edit *, EMPTYARG )
3465 {
3466 	// trim the strings
3467 	String aName = aNameEdit.GetText();
3468 	aName.EraseLeadingChars().EraseTrailingChars();
3469 	if ( aName.Len() )
3470 	{
3471 		if ( !aOKBtn.IsEnabled() )
3472 			aOKBtn.Enable( sal_True );
3473 	}
3474 	else
3475 	{
3476 		if ( aOKBtn.IsEnabled() )
3477 			aOKBtn.Enable( sal_False );
3478 	}
3479 
3480 	return 0;
3481 }
3482 
3483 }
3484