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