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