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