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