xref: /AOO41X/main/fpicker/source/office/OfficeFilePicker.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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 #include "OfficeFilePicker.hxx"
28 #include "iodlg.hxx"
29 
30 #ifndef _LIST_
31 #include <list>
32 #endif
33 #ifndef _FUNCTIONAL_
34 #include <functional>
35 #endif
36 #ifndef _ALGORITHM_
37 #include <algorithm>
38 #endif
39 #include <tools/urlobj.hxx>
40 #include <tools/debug.hxx>
41 #define _SVSTDARR_STRINGSDTOR
42 #include "svl/svstdarr.hxx"
43 #include <com/sun/star/uno/Any.hxx>
44 #include <com/sun/star/ui/dialogs/FilePickerEvent.hpp>
45 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
46 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
47 #include <com/sun/star/beans/PropertyValue.hpp>
48 #include <com/sun/star/beans/XPropertySet.hpp>
49 #include <com/sun/star/awt/XWindow.hpp>
50 #include <com/sun/star/beans/StringPair.hpp>
51 #include <com/sun/star/uno/Sequence.hxx>
52 #include <com/sun/star/beans/NamedValue.hpp>
53 #include <unotools/ucbhelper.hxx>
54 #include <unotools/pathoptions.hxx>
55 #include <comphelper/sequence.hxx>
56 #include <cppuhelper/typeprovider.hxx>
57 #include "vos/mutex.hxx"
58 #ifndef _SV_APP_HXX
59 #include "vcl/svapp.hxx"
60 #endif
61 
62 // define ----------------------------------------------------------------
63 
64 #define MAKE_ANY    ::com::sun::star::uno::makeAny
65 
66 // using ----------------------------------------------------------------
67 
68 using namespace     ::com::sun::star::container;
69 using namespace     ::com::sun::star::lang;
70 using namespace     ::com::sun::star::ui::dialogs;
71 using namespace     ::com::sun::star::uno;
72 using namespace     ::com::sun::star::beans;
73 using namespace     ::com::sun::star::awt;
74 using namespace     ::utl;
75 
76 //=====================================================================
77 
78 //=====================================================================
79 
80 struct FilterEntry
81 {
82 protected:
83     ::rtl::OUString     m_sTitle;
84     ::rtl::OUString     m_sFilter;
85 
86     UnoFilterList       m_aSubFilters;
87 
88 public:
89     FilterEntry( const ::rtl::OUString& _rTitle, const ::rtl::OUString& _rFilter )
90         :m_sTitle( _rTitle )
91         ,m_sFilter( _rFilter )
92     {
93     }
94 
95     FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters );
96 
97     ::rtl::OUString     getTitle() const { return m_sTitle; }
98     ::rtl::OUString     getFilter() const { return m_sFilter; }
99 
100     /// determines if the filter has sub filter (i.e., the filter is a filter group in real)
101     sal_Bool            hasSubFilters( ) const;
102 
103     /** retrieves the filters belonging to the entry
104     @return
105         the number of sub filters
106     */
107     sal_Int32           getSubFilters( UnoFilterList& _rSubFilterList );
108 
109     // helpers for iterating the sub filters
110     const UnoFilterEntry*   beginSubFilters() const { return m_aSubFilters.getConstArray(); }
111     const UnoFilterEntry*   endSubFilters() const { return m_aSubFilters.getConstArray() + m_aSubFilters.getLength(); }
112 };
113 
114 //=====================================================================
115 
116 //---------------------------------------------------------------------
117 FilterEntry::FilterEntry( const ::rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters )
118     :m_sTitle( _rTitle )
119     ,m_aSubFilters( _rSubFilters )
120 {
121 }
122 
123 //---------------------------------------------------------------------
124 sal_Bool FilterEntry::hasSubFilters( ) const
125 {
126     return ( 0 < m_aSubFilters.getLength() );
127 }
128 
129 //---------------------------------------------------------------------
130 sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList )
131 {
132     _rSubFilterList = m_aSubFilters;
133     return m_aSubFilters.getLength();
134 }
135 
136 // struct ElementEntry_Impl ----------------------------------------------
137 
138 struct ElementEntry_Impl
139 {
140     sal_Int16       m_nElementID;
141     sal_Int16       m_nControlAction;
142     Any         m_aValue;
143     rtl::OUString       m_aLabel;
144     sal_Bool        m_bEnabled      : 1;
145 
146     sal_Bool        m_bHasValue     : 1;
147     sal_Bool        m_bHasLabel     : 1;
148     sal_Bool        m_bHasEnabled   : 1;
149 
150                     ElementEntry_Impl( sal_Int16 nId );
151 
152     void            setValue( const Any& rVal ) { m_aValue = rVal; m_bHasValue = sal_True; }
153     void            setAction( sal_Int16 nAction ) { m_nControlAction = nAction; }
154     void            setLabel( const rtl::OUString& rVal ) { m_aLabel = rVal; m_bHasLabel = sal_True; }
155     void            setEnabled( sal_Bool bEnabled ) { m_bEnabled = bEnabled; m_bHasEnabled = sal_True; }
156 };
157 
158 ElementEntry_Impl::ElementEntry_Impl( sal_Int16 nId )
159     : m_nElementID( nId )
160     , m_nControlAction( 0 )
161     , m_bEnabled( sal_False )
162     , m_bHasValue( sal_False )
163     , m_bHasLabel( sal_False )
164     , m_bHasEnabled( sal_False )
165 {}
166 
167 //------------------------------------------------------------------------------------
168 void SvtFilePicker::prepareExecute()
169 {
170     // set the default directory
171     // --**-- doesn't match the spec yet
172     if ( m_aDisplayDirectory.getLength() > 0 || m_aDefaultName.getLength() > 0 )
173     {
174         if ( m_aDisplayDirectory.getLength() > 0 )
175         {
176 
177             INetURLObject aPath( m_aDisplayDirectory );
178             if ( m_aDefaultName.getLength() > 0 )
179             {
180                 aPath.insertName( m_aDefaultName );
181                 getDialog()->SetHasFilename( true );
182             }
183             String sPath = aPath.GetMainURL( INetURLObject::NO_DECODE );
184             getDialog()->SetPath( aPath.GetMainURL( INetURLObject::NO_DECODE ) );
185         }
186         else if ( m_aDefaultName.getLength() > 0 )
187         {
188             getDialog()->SetPath( m_aDefaultName );
189             getDialog()->SetHasFilename( true );
190         }
191     }
192     else
193     {
194         // Default-Standard-Dir setzen
195         INetURLObject aStdDirObj( SvtPathOptions().GetWorkPath() );
196         getDialog()->SetPath( aStdDirObj.GetMainURL( INetURLObject::NO_DECODE ) );
197     }
198 
199     // set the control values and set the control labels, too
200     if ( m_pElemList && !m_pElemList->empty() )
201     {
202         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
203 
204         ElementList::iterator aListIter;
205         for ( aListIter = m_pElemList->begin();
206               aListIter != m_pElemList->end(); ++aListIter )
207         {
208             ElementEntry_Impl& rEntry = *aListIter;
209             if ( rEntry.m_bHasValue )
210                 aAccess.setValue( rEntry.m_nElementID, rEntry.m_nControlAction, rEntry.m_aValue );
211             if ( rEntry.m_bHasLabel )
212                 aAccess.setLabel( rEntry.m_nElementID, rEntry.m_aLabel );
213             if ( rEntry.m_bHasEnabled )
214                 aAccess.enableControl( rEntry.m_nElementID, rEntry.m_bEnabled );
215         }
216 
217         getDialog()->updateListboxLabelSizes();
218     }
219 
220     if ( m_pFilterList && !m_pFilterList->empty() )
221     {
222         for (   FilterList::iterator aListIter = m_pFilterList->begin();
223                 aListIter != m_pFilterList->end();
224                 ++aListIter
225             )
226         {
227             if ( aListIter->hasSubFilters() )
228             {   // it's a filter group
229                 UnoFilterList aSubFilters;
230                 aListIter->getSubFilters( aSubFilters );
231 
232                 getDialog()->AddFilterGroup( aListIter->getTitle(), aSubFilters );
233              }
234             else
235                 // it's a single filter
236                 getDialog()->AddFilter( aListIter->getTitle(), aListIter->getFilter() );
237         }
238     }
239 
240     // set the default filter
241     if ( m_aCurrentFilter.getLength() > 0 )
242         getDialog()->SetCurFilter( m_aCurrentFilter );
243 
244 }
245 
246 //-----------------------------------------------------------------------------
247 IMPL_LINK( SvtFilePicker, DialogClosedHdl, Dialog*, pDlg )
248 {
249     if ( m_xDlgClosedListener.is() )
250     {
251         sal_Int16 nRet = static_cast< sal_Int16 >( pDlg->GetResult() );
252         ::com::sun::star::ui::dialogs::DialogClosedEvent aEvent( *this, nRet );
253         m_xDlgClosedListener->dialogClosed( aEvent );
254         m_xDlgClosedListener.clear();
255     }
256     return 0;
257 }
258 
259 //------------------------------------------------------------------------------------
260 // SvtFilePicker
261 //------------------------------------------------------------------------------------
262 
263 //------------------------------------------------------------------------------------
264 WinBits SvtFilePicker::getWinBits( WinBits& rExtraBits )
265 {
266     // set the winbits for creating the filedialog
267     WinBits nBits = 0L;
268     rExtraBits = 0L;
269 
270     // set the standard bits acording to the service name
271     if ( m_nServiceType == TemplateDescription::FILEOPEN_SIMPLE )
272     {
273         nBits = WB_OPEN;
274     }
275     else if ( m_nServiceType == TemplateDescription::FILESAVE_SIMPLE )
276     {
277         nBits = WB_SAVEAS;
278     }
279     else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION )
280     {
281         nBits = WB_SAVEAS;
282         rExtraBits = SFX_EXTRA_AUTOEXTENSION;
283     }
284     else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD )
285     {
286         nBits = WB_SAVEAS | SFXWB_PASSWORD;
287         rExtraBits = SFX_EXTRA_AUTOEXTENSION;
288     }
289     else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS )
290     {
291         nBits = WB_SAVEAS | SFXWB_PASSWORD;
292         rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_FILTEROPTIONS;
293     }
294     else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE )
295     {
296         nBits = WB_SAVEAS;
297         rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_TEMPLATES;
298     }
299     else if ( m_nServiceType == TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION )
300     {
301         nBits = WB_SAVEAS;
302         rExtraBits = SFX_EXTRA_AUTOEXTENSION | SFX_EXTRA_SELECTION;
303     }
304 
305     else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE )
306     {
307         nBits = WB_OPEN;
308         rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW | SFX_EXTRA_IMAGE_TEMPLATE;
309     }
310     else if ( m_nServiceType == TemplateDescription::FILEOPEN_PLAY )
311     {
312         nBits = WB_OPEN;
313         rExtraBits = SFX_EXTRA_PLAYBUTTON;
314     }
315     else if ( m_nServiceType == TemplateDescription::FILEOPEN_READONLY_VERSION )
316     {
317         nBits = WB_OPEN | SFXWB_READONLY;
318         rExtraBits = SFX_EXTRA_SHOWVERSIONS;
319     }
320     else if ( m_nServiceType == TemplateDescription::FILEOPEN_LINK_PREVIEW )
321     {
322         nBits = WB_OPEN;
323         rExtraBits = SFX_EXTRA_INSERTASLINK | SFX_EXTRA_SHOWPREVIEW;
324     }
325     if ( m_bMultiSelection && ( ( nBits & WB_OPEN ) == WB_OPEN ) )
326         nBits |= SFXWB_MULTISELECTION;
327 
328     return nBits;
329 }
330 
331 //------------------------------------------------------------------------------------
332 void SvtFilePicker::notify( sal_Int16 _nEventId, sal_Int16 _nControlId )
333 {
334     if ( !m_xListener.is() )
335         return;
336 
337     FilePickerEvent aEvent( *this, _nControlId );
338 
339     switch ( _nEventId )
340     {
341         case FILE_SELECTION_CHANGED:
342             m_xListener->fileSelectionChanged( aEvent );
343             break;
344         case DIRECTORY_CHANGED:
345             m_xListener->directoryChanged( aEvent );
346             break;
347         case HELP_REQUESTED:
348             m_xListener->helpRequested( aEvent );
349             break;
350         case CTRL_STATE_CHANGED:
351             m_xListener->controlStateChanged( aEvent );
352             break;
353         case DIALOG_SIZE_CHANGED:
354             m_xListener->dialogSizeChanged();
355             break;
356         default:
357             DBG_ERRORFILE( "SvtFilePicker::notify(): Unknown event id!" );
358             break;
359     }
360 }
361 
362 //------------------------------------------------------------------------------------
363 namespace {
364     //................................................................................
365     struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool >
366     {
367     protected:
368         const ::rtl::OUString& rTitle;
369 
370     public:
371         FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { }
372 
373         //............................................................................
374         bool operator () ( const FilterEntry& _rEntry )
375         {
376             sal_Bool bMatch;
377             if ( !_rEntry.hasSubFilters() )
378                 // a real filter
379                 bMatch = ( _rEntry.getTitle() == rTitle );
380             else
381                 // a filter group -> search the sub filters
382                 bMatch =
383                     _rEntry.endSubFilters() != ::std::find_if(
384                         _rEntry.beginSubFilters(),
385                         _rEntry.endSubFilters(),
386                         *this
387                     );
388 
389             return bMatch ? true : false;
390         }
391         bool operator () ( const UnoFilterEntry& _rEntry )
392         {
393             return _rEntry.First == rTitle ? true : false;
394         }
395     };
396 }
397 
398 //------------------------------------------------------------------------------------
399 sal_Bool SvtFilePicker::FilterNameExists( const ::rtl::OUString& rTitle )
400 {
401     sal_Bool bRet = sal_False;
402 
403     if ( m_pFilterList )
404         bRet =
405             m_pFilterList->end() != ::std::find_if(
406                 m_pFilterList->begin(),
407                 m_pFilterList->end(),
408                 FilterTitleMatch( rTitle )
409             );
410 
411     return bRet;
412 }
413 
414 //------------------------------------------------------------------------------------
415 sal_Bool SvtFilePicker::FilterNameExists( const UnoFilterList& _rGroupedFilters )
416 {
417     sal_Bool bRet = sal_False;
418 
419     if ( m_pFilterList )
420     {
421         const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray();
422         const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength();
423         for ( ; pStart != pEnd; ++pStart )
424             if ( m_pFilterList->end() != ::std::find_if( m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch( pStart->First ) ) )
425                 break;
426 
427         bRet = pStart != pEnd;
428     }
429 
430     return bRet;
431 }
432 
433 //------------------------------------------------------------------------------------
434 void SvtFilePicker::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter )
435 {
436     if ( !m_pFilterList )
437     {
438         m_pFilterList = new FilterList;
439 
440         // set the first filter to the current filter
441         if ( ! m_aCurrentFilter.getLength() )
442             m_aCurrentFilter = _rInitialCurrentFilter;
443     }
444 }
445 
446 //------------------------------------------------------------------------------------
447 // class SvtFilePicker
448 //------------------------------------------------------------------------------------
449 SvtFilePicker::SvtFilePicker( const Reference < XMultiServiceFactory >& xFactory )
450     :OCommonPicker( xFactory )
451     ,m_pFilterList      ( NULL )
452     ,m_pElemList        ( NULL )
453     ,m_bMultiSelection  ( sal_False )
454     ,m_nServiceType     ( TemplateDescription::FILEOPEN_SIMPLE )
455 {
456 }
457 
458 SvtFilePicker::~SvtFilePicker()
459 {
460     if ( m_pFilterList && !m_pFilterList->empty() )
461         m_pFilterList->erase( m_pFilterList->begin(), m_pFilterList->end() );
462     delete m_pFilterList;
463 
464     if ( m_pElemList && !m_pElemList->empty() )
465         m_pElemList->erase( m_pElemList->begin(), m_pElemList->end() );
466     delete m_pElemList;
467 }
468 
469 //------------------------------------------------------------------------------------
470 sal_Int16 SvtFilePicker::implExecutePicker( )
471 {
472     getDialog()->SetFileCallback( this );
473 
474     prepareExecute();
475 
476     getDialog()->EnableAutocompletion( sal_True );
477     // now we are ready to execute the dialog
478     sal_Int16 nRet = getDialog()->Execute();
479 
480     // the execution of the dialog yields, so it is possible the at this point the window or the dialog is closed
481     if ( getDialog() )
482         getDialog()->SetFileCallback( NULL );
483 
484     return nRet;
485 }
486 
487 //------------------------------------------------------------------------------------
488 SvtFileDialog* SvtFilePicker::implCreateDialog( Window* _pParent )
489 {
490     WinBits nExtraBits;
491     WinBits nBits = getWinBits( nExtraBits );
492 
493     SvtFileDialog* dialog = new SvtFileDialog( _pParent, nBits, nExtraBits );
494 
495     // Set StandardDir if present
496     if ( m_aStandardDir.getLength() > 0)
497     {
498         String sStandardDir = String( m_aStandardDir );
499         dialog->SetStandardDir( sStandardDir );
500         dialog->SetBlackList( m_aBlackList );
501     }
502 
503     return dialog;
504 }
505 
506 //------------------------------------------------------------------------------------
507 // disambiguate XInterface
508 //------------------------------------------------------------------------------------
509 IMPLEMENT_FORWARD_XINTERFACE2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base )
510 
511 //------------------------------------------------------------------------------------
512 // disambiguate XTypeProvider
513 //------------------------------------------------------------------------------------
514 IMPLEMENT_FORWARD_XTYPEPROVIDER2( SvtFilePicker, OCommonPicker, SvtFilePicker_Base )
515 
516 //------------------------------------------------------------------------------------
517 // XExecutableDialog functions
518 //------------------------------------------------------------------------------------
519 
520 //------------------------------------------------------------------------------------
521 void SAL_CALL SvtFilePicker::setTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
522 {
523     OCommonPicker::setTitle( _rTitle );
524 }
525 
526 //------------------------------------------------------------------------------------
527 sal_Int16 SAL_CALL SvtFilePicker::execute(  ) throw (RuntimeException)
528 {
529     return OCommonPicker::execute();
530 }
531 
532 //------------------------------------------------------------------------------------
533 // XAsynchronousExecutableDialog functions
534 //------------------------------------------------------------------------------------
535 
536 //------------------------------------------------------------------------------------
537 void SAL_CALL SvtFilePicker::setDialogTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
538 {
539     setTitle( _rTitle );
540 }
541 
542 //------------------------------------------------------------------------------------
543 void SAL_CALL SvtFilePicker::startExecuteModal( const Reference< ::com::sun::star::ui::dialogs::XDialogClosedListener >& xListener ) throw (RuntimeException)
544 {
545     m_xDlgClosedListener = xListener;
546     prepareDialog();
547     prepareExecute();
548     getDialog()->EnableAutocompletion( sal_True );
549     getDialog()->StartExecuteModal( LINK( this, SvtFilePicker, DialogClosedHdl ) );
550 }
551 
552 //------------------------------------------------------------------------------------
553 // XFilePicker functions
554 //------------------------------------------------------------------------------------
555 
556 void SAL_CALL SvtFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( RuntimeException )
557 {
558     checkAlive();
559 
560     ::vos::OGuard aGuard( Application::GetSolarMutex() );
561     m_bMultiSelection = bMode;
562 }
563 
564 void SAL_CALL SvtFilePicker::setDefaultName( const rtl::OUString& aName ) throw( RuntimeException )
565 {
566     checkAlive();
567 
568     ::vos::OGuard aGuard( Application::GetSolarMutex() );
569     m_aDefaultName = aName;
570 }
571 
572 void SAL_CALL SvtFilePicker::setDisplayDirectory( const rtl::OUString& aDirectory )
573     throw( IllegalArgumentException, RuntimeException )
574 {
575     checkAlive();
576 
577     ::vos::OGuard aGuard( Application::GetSolarMutex() );
578     m_aDisplayDirectory = aDirectory;
579 }
580 
581 rtl::OUString SAL_CALL SvtFilePicker::getDisplayDirectory() throw( RuntimeException )
582 {
583     checkAlive();
584 
585     ::vos::OGuard aGuard( Application::GetSolarMutex() );
586     if ( getDialog() )
587     {
588         rtl::OUString aPath = getDialog()->GetPath();
589 
590         // #97148# ----
591         if( m_aOldHideDirectory == aPath )
592             return m_aOldDisplayDirectory;
593         m_aOldHideDirectory = aPath;
594 
595         // #102204# -----
596         if( !getDialog()->ContentIsFolder( aPath ) )
597         {
598             INetURLObject aFolder( aPath );
599             aFolder.CutLastName();
600             aPath = aFolder.GetMainURL( INetURLObject::NO_DECODE );
601         }
602         m_aOldDisplayDirectory = aPath;
603         return aPath;
604     }
605     else
606         return m_aDisplayDirectory;
607 }
608 
609 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getFiles() throw( RuntimeException )
610 {
611     checkAlive();
612 
613     ::vos::OGuard aGuard( Application::GetSolarMutex() );
614     if ( ! getDialog() )
615     {
616         Sequence< rtl::OUString > aEmpty;
617         return aEmpty;
618     }
619 
620     // if there is more than one path we have to return the path to the
621     // files first and then the list of the selected entries
622 
623     SvStringsDtor* pPathList = getDialog()->GetPathList();
624     sal_uInt16 i, nCount = pPathList->Count();
625     sal_uInt16 nTotal = nCount > 1 ? nCount+1: nCount;
626 
627     Sequence< rtl::OUString > aPath( nTotal );
628 
629     if ( nCount == 1 )
630         aPath[0] = rtl::OUString( *pPathList->GetObject( 0 ) );
631     else if ( nCount > 1 )
632     {
633         INetURLObject aObj( *pPathList->GetObject( 0 ) );
634         aObj.removeSegment();
635         aPath[0] = aObj.GetMainURL( INetURLObject::NO_DECODE );
636 
637         for ( i = 0; i < nCount; /* i++ is done below */ )
638         {
639             aObj.SetURL( *pPathList->GetObject(i++) );
640             aPath[i] = aObj.getName();
641         }
642     }
643 
644     delete pPathList;
645     return aPath;
646 }
647 
648 //------------------------------------------------------------------------------------
649 // XFilePickerControlAccess functions
650 //------------------------------------------------------------------------------------
651 
652 void SAL_CALL SvtFilePicker::setValue( sal_Int16 nElementID,
653                                        sal_Int16 nControlAction,
654                                        const Any& rValue )
655     throw( RuntimeException )
656 {
657     checkAlive();
658 
659     ::vos::OGuard aGuard( Application::GetSolarMutex() );
660     if ( getDialog() )
661     {
662         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
663         aAccess.setValue( nElementID, nControlAction, rValue );
664     }
665     else
666     {
667         if ( !m_pElemList )
668             m_pElemList = new ElementList;
669 
670         sal_Bool bFound = sal_False;
671         ElementList::iterator aListIter;
672 
673         for ( aListIter = m_pElemList->begin();
674               aListIter != m_pElemList->end(); ++aListIter )
675         {
676             ElementEntry_Impl& rEntry = *aListIter;
677             if ( ( rEntry.m_nElementID == nElementID ) &&
678                  ( !rEntry.m_bHasValue || ( rEntry.m_nControlAction == nControlAction ) ) )
679             {
680                 rEntry.setAction( nControlAction );
681                 rEntry.setValue( rValue );
682                 bFound = sal_True;
683             }
684         }
685 
686         if ( !bFound )
687         {
688             ElementEntry_Impl aNew( nElementID );
689             aNew.setAction( nControlAction );
690             aNew.setValue( rValue );
691             m_pElemList->insert( m_pElemList->end(), aNew );
692         }
693     }
694 }
695 
696 //------------------------------------------------------------------------------------
697 
698 Any SAL_CALL SvtFilePicker::getValue( sal_Int16 nElementID, sal_Int16 nControlAction )
699     throw( RuntimeException )
700 {
701     checkAlive();
702 
703     ::vos::OGuard aGuard( Application::GetSolarMutex() );
704     Any      aAny;
705 
706     // execute() called?
707     if ( getDialog() )
708     {
709         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
710         aAny = aAccess.getValue( nElementID, nControlAction );
711     }
712     else if ( m_pElemList && !m_pElemList->empty() )
713     {
714         ElementList::iterator aListIter;
715         for ( aListIter = m_pElemList->begin();
716               aListIter != m_pElemList->end(); ++aListIter )
717         {
718             ElementEntry_Impl& rEntry = *aListIter;
719             if ( ( rEntry.m_nElementID == nElementID ) &&
720                  ( rEntry.m_bHasValue ) &&
721                  ( rEntry.m_nControlAction == nControlAction ) )
722             {
723                 aAny = rEntry.m_aValue;
724                 break;
725             }
726         }
727     }
728 
729     return aAny;
730 }
731 
732 
733 //------------------------------------------------------------------------------------
734 void SAL_CALL SvtFilePicker::setLabel( sal_Int16 nLabelID, const rtl::OUString& rValue )
735     throw ( RuntimeException )
736 {
737     checkAlive();
738 
739     ::vos::OGuard aGuard( Application::GetSolarMutex() );
740     if ( getDialog() )
741     {
742         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
743         aAccess.setLabel( nLabelID, rValue );
744     }
745     else
746     {
747         if ( !m_pElemList )
748             m_pElemList = new ElementList;
749 
750         sal_Bool bFound = sal_False;
751         ElementList::iterator aListIter;
752 
753         for ( aListIter = m_pElemList->begin();
754               aListIter != m_pElemList->end(); ++aListIter )
755         {
756             ElementEntry_Impl& rEntry = *aListIter;
757             if ( rEntry.m_nElementID == nLabelID )
758             {
759                 rEntry.setLabel( rValue );
760                 bFound = sal_True;
761             }
762         }
763 
764         if ( !bFound )
765         {
766             ElementEntry_Impl aNew( nLabelID );
767             aNew.setLabel( rValue );
768             m_pElemList->insert( m_pElemList->end(), aNew );
769         }
770     }
771 }
772 
773 //------------------------------------------------------------------------------------
774 rtl::OUString SAL_CALL SvtFilePicker::getLabel( sal_Int16 nLabelID )
775     throw ( RuntimeException )
776 {
777     checkAlive();
778 
779     ::vos::OGuard aGuard( Application::GetSolarMutex() );
780     rtl::OUString aLabel;
781 
782     if ( getDialog() )
783     {
784         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
785         aLabel = aAccess.getLabel( nLabelID );
786     }
787     else if ( m_pElemList && !m_pElemList->empty() )
788     {
789         ElementList::iterator aListIter;
790         for ( aListIter = m_pElemList->begin();
791               aListIter != m_pElemList->end(); ++aListIter )
792         {
793             ElementEntry_Impl& rEntry = *aListIter;
794             if ( rEntry.m_nElementID == nLabelID )
795             {
796                 if ( rEntry.m_bHasLabel )
797                     aLabel = rEntry.m_aLabel;
798                 break;
799             }
800         }
801     }
802 
803     return aLabel;
804 }
805 
806 //------------------------------------------------------------------------------------
807 void SAL_CALL SvtFilePicker::enableControl( sal_Int16 nElementID, sal_Bool bEnable )
808     throw( RuntimeException )
809 {
810     checkAlive();
811 
812     ::vos::OGuard aGuard( Application::GetSolarMutex() );
813     if ( getDialog() )
814     {
815         ::svt::OControlAccess aAccess( getDialog(), getDialog()->GetView() );
816         aAccess.enableControl( nElementID, bEnable );
817     }
818     else
819     {
820         if ( !m_pElemList )
821             m_pElemList = new ElementList;
822 
823         sal_Bool bFound = sal_False;
824         ElementList::iterator aListIter;
825 
826         for ( aListIter = m_pElemList->begin();
827               aListIter != m_pElemList->end(); ++aListIter )
828         {
829             ElementEntry_Impl& rEntry = *aListIter;
830             if ( rEntry.m_nElementID == nElementID )
831             {
832                 rEntry.setEnabled( bEnable );
833                 bFound = sal_True;
834             }
835         }
836 
837         if ( !bFound )
838         {
839             ElementEntry_Impl aNew( nElementID );
840             aNew.setEnabled( bEnable );
841             m_pElemList->insert( m_pElemList->end(), aNew );
842         }
843     }
844 }
845 
846 //------------------------------------------------------------------------------------
847 // XFilePickerNotifier functions
848 //------------------------------------------------------------------------------------
849 
850 void SAL_CALL SvtFilePicker::addFilePickerListener( const Reference< XFilePickerListener >& xListener ) throw ( RuntimeException )
851 {
852     checkAlive();
853 
854     ::vos::OGuard aGuard( Application::GetSolarMutex() );
855     m_xListener = xListener;
856 }
857 
858 //------------------------------------------------------------------------------------
859 void SAL_CALL SvtFilePicker::removeFilePickerListener( const Reference< XFilePickerListener >& ) throw ( RuntimeException )
860 {
861     checkAlive();
862 
863     ::vos::OGuard aGuard( Application::GetSolarMutex() );
864     m_xListener.clear();
865 }
866 
867 //------------------------------------------------------------------------------------
868 // XFilePreview functions
869 //------------------------------------------------------------------------------------
870 
871 Sequence< sal_Int16 > SAL_CALL SvtFilePicker::getSupportedImageFormats()
872     throw ( RuntimeException )
873 {
874     checkAlive();
875 
876     ::vos::OGuard aGuard( Application::GetSolarMutex() );
877     Sequence< sal_Int16 > aFormats( 1 );
878 
879     aFormats[0] = FilePreviewImageFormats::BITMAP;
880 
881     return aFormats;
882 }
883 
884 //------------------------------------------------------------------------------------
885 sal_Int32 SAL_CALL SvtFilePicker::getTargetColorDepth() throw ( RuntimeException )
886 {
887     checkAlive();
888 
889     ::vos::OGuard aGuard( Application::GetSolarMutex() );
890     sal_Int32 nDepth = 0;
891 
892     if ( getDialog() )
893         nDepth = getDialog()->getTargetColorDepth();
894 
895     return nDepth;
896 }
897 
898 //------------------------------------------------------------------------------------
899 sal_Int32 SAL_CALL SvtFilePicker::getAvailableWidth() throw ( RuntimeException )
900 {
901     checkAlive();
902 
903     ::vos::OGuard aGuard( Application::GetSolarMutex() );
904     sal_Int32 nWidth = 0;
905 
906     if ( getDialog() )
907         nWidth = getDialog()->getAvailableWidth();
908 
909     return nWidth;
910 }
911 
912 //------------------------------------------------------------------------------------
913 sal_Int32 SAL_CALL SvtFilePicker::getAvailableHeight() throw ( RuntimeException )
914 {
915     checkAlive();
916 
917     ::vos::OGuard aGuard( Application::GetSolarMutex() );
918     sal_Int32 nHeigth = 0;
919 
920     if ( getDialog() )
921         nHeigth = getDialog()->getAvailableHeight();
922 
923     return nHeigth;
924 }
925 
926 //------------------------------------------------------------------------------------
927 void SAL_CALL SvtFilePicker::setImage( sal_Int16 aImageFormat, const Any& rImage )
928     throw ( IllegalArgumentException, RuntimeException )
929 {
930     checkAlive();
931 
932     ::vos::OGuard aGuard( Application::GetSolarMutex() );
933     if ( getDialog() )
934         getDialog()->setImage( aImageFormat, rImage );
935 }
936 
937 //------------------------------------------------------------------------------------
938 sal_Bool SAL_CALL SvtFilePicker::setShowState( sal_Bool bShowState )
939     throw ( RuntimeException )
940 {
941     checkAlive();
942 
943     ::vos::OGuard aGuard( Application::GetSolarMutex() );
944     sal_Bool bRet = sal_False;
945 
946     if ( getDialog() )
947         bRet = getDialog()->setShowState( bShowState );
948 
949     return bRet;
950 }
951 
952 //------------------------------------------------------------------------------------
953 sal_Bool SAL_CALL SvtFilePicker::getShowState() throw ( RuntimeException )
954 {
955     checkAlive();
956 
957     ::vos::OGuard aGuard( Application::GetSolarMutex() );
958     sal_Bool bRet = sal_False;
959 
960     if ( getDialog() )
961         bRet = getDialog()->getShowState();
962 
963     return bRet;
964 }
965 
966 //------------------------------------------------------------------------------------
967 // XFilterGroupManager functions
968 //------------------------------------------------------------------------------------
969 
970 void SAL_CALL SvtFilePicker::appendFilterGroup( const ::rtl::OUString& sGroupTitle,
971                                                 const Sequence< StringPair >& aFilters )
972     throw ( IllegalArgumentException, RuntimeException )
973 {
974     checkAlive();
975 
976     ::vos::OGuard aGuard( Application::GetSolarMutex() );
977 
978     // check the names
979     if ( FilterNameExists( aFilters ) )
980         throw IllegalArgumentException(
981             rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("filter name exists")),
982             static_cast< OWeakObject * >(this), 1);
983 
984     // ensure that we have a filter list
985     ::rtl::OUString sInitialCurrentFilter;
986     if ( aFilters.getLength() )
987         sInitialCurrentFilter = aFilters[0].First;
988     ensureFilterList( sInitialCurrentFilter );
989 
990     // append the filter
991     m_pFilterList->insert( m_pFilterList->end(), FilterEntry( sGroupTitle, aFilters ) );
992 }
993 
994 //------------------------------------------------------------------------------------
995 // XFilterManager functions
996 //------------------------------------------------------------------------------------
997 
998 void SAL_CALL SvtFilePicker::appendFilter( const rtl::OUString& aTitle,
999                                            const rtl::OUString& aFilter )
1000     throw( IllegalArgumentException, RuntimeException )
1001 {
1002     checkAlive();
1003 
1004     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1005     // check the name
1006     if ( FilterNameExists( aTitle ) )
1007         // TODO: a more precise exception message
1008         throw IllegalArgumentException();
1009 
1010     // ensure that we have a filter list
1011     ensureFilterList( aTitle );
1012 
1013     // append the filter
1014     m_pFilterList->insert( m_pFilterList->end(), FilterEntry( aTitle, aFilter ) );
1015 }
1016 
1017 //------------------------------------------------------------------------------------
1018 void SAL_CALL SvtFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
1019     throw( IllegalArgumentException, RuntimeException )
1020 {
1021     checkAlive();
1022 
1023     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1024     if ( ! FilterNameExists( aTitle ) )
1025         throw IllegalArgumentException();
1026 
1027     m_aCurrentFilter = aTitle;
1028 
1029     if ( getDialog() )
1030         getDialog()->SetCurFilter( aTitle );
1031 }
1032 
1033 //------------------------------------------------------------------------------------
1034 rtl::OUString SAL_CALL SvtFilePicker::getCurrentFilter()
1035     throw( RuntimeException )
1036 {
1037     checkAlive();
1038 
1039     ::vos::OGuard aGuard( Application::GetSolarMutex() );
1040     rtl::OUString aFilter = getDialog() ? rtl::OUString( getDialog()->GetCurFilter() ) :
1041                                             rtl::OUString( m_aCurrentFilter );
1042     return aFilter;
1043 }
1044 
1045 
1046 //------------------------------------------------------------------------------------
1047 // XInitialization functions
1048 //------------------------------------------------------------------------------------
1049 
1050 void SAL_CALL SvtFilePicker::initialize( const Sequence< Any >& _rArguments )
1051     throw ( Exception, RuntimeException )
1052 {
1053     checkAlive();
1054 
1055     Sequence< Any > aArguments( _rArguments.getLength());
1056 
1057     m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE;
1058 
1059     if ( _rArguments.getLength() >= 1 )
1060     {
1061         // compatibility: one argument, type sal_Int16 , specifies the service type
1062         int index = 0;
1063 
1064         if (_rArguments[0] >>= m_nServiceType)
1065         {
1066             // skip the first entry if it was the ServiceType, because it's not needed in OCommonPicker::initialize and it's not a NamedValue
1067             NamedValue emptyNamedValue;
1068             aArguments[0] <<= emptyNamedValue;
1069             index = 1;
1070 
1071         }
1072         for ( int i = index; i < _rArguments.getLength(); i++)
1073         {
1074             NamedValue namedValue;
1075             aArguments[i] <<= _rArguments[i];
1076 
1077             if (aArguments[i] >>= namedValue )
1078             {
1079 
1080                 if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StandardDir" ) ) ) )
1081                 {
1082                     ::rtl::OUString sStandardDir;
1083 
1084                     namedValue.Value >>= sStandardDir;
1085 
1086                     // Set the directory for the "back to the default dir" button
1087                         if ( sStandardDir.getLength() > 0 )
1088                     {
1089                         m_aStandardDir = sStandardDir;
1090                     }
1091                 }
1092                 else if ( namedValue.Name.equals( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BlackList" ) ) ) )
1093                 {
1094                     namedValue.Value >>= m_aBlackList;
1095                 }
1096             }
1097         }
1098     }
1099 
1100     // let the base class analyze the sequence (will call into implHandleInitializationArgument)
1101     OCommonPicker::initialize( aArguments );
1102 }
1103 
1104 //-------------------------------------------------------------------------
1105 sal_Bool SvtFilePicker::implHandleInitializationArgument( const ::rtl::OUString& _rName, const Any& _rValue ) SAL_THROW( ( Exception, RuntimeException ) )
1106 {
1107     if ( _rName.equalsAscii( "TemplateDescription" ) )
1108     {
1109         m_nServiceType = TemplateDescription::FILEOPEN_SIMPLE;
1110         OSL_VERIFY( _rValue >>= m_nServiceType );
1111         return sal_True;
1112     }
1113     if ( _rName.equalsAscii( "StandardDir" ) )
1114     {
1115         OSL_VERIFY( _rValue >>= m_aStandardDir );
1116         return sal_True;
1117     }
1118 
1119     if ( _rName.equalsAscii( "BlackList" ) )
1120     {
1121         OSL_VERIFY( _rValue >>= m_aBlackList );
1122         return sal_True;
1123     }
1124 
1125 
1126 
1127     return OCommonPicker::implHandleInitializationArgument( _rName, _rValue );
1128 }
1129 
1130 //------------------------------------------------------------------------------------
1131 // XServiceInfo
1132 //------------------------------------------------------------------------------------
1133 
1134 /* XServiceInfo */
1135 rtl::OUString SAL_CALL SvtFilePicker::getImplementationName() throw( RuntimeException )
1136 {
1137     return impl_getStaticImplementationName();
1138 }
1139 
1140 /* XServiceInfo */
1141 sal_Bool SAL_CALL SvtFilePicker::supportsService( const rtl::OUString& sServiceName ) throw( RuntimeException )
1142 {
1143     Sequence< rtl::OUString > seqServiceNames = getSupportedServiceNames();
1144     const rtl::OUString* pArray = seqServiceNames.getConstArray();
1145     for ( sal_Int32 i = 0; i < seqServiceNames.getLength(); i++ )
1146     {
1147         if ( sServiceName == pArray[i] )
1148         {
1149             return sal_True ;
1150         }
1151     }
1152     return sal_False ;
1153 }
1154 
1155 /* XServiceInfo */
1156 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getSupportedServiceNames() throw( RuntimeException )
1157 {
1158     return impl_getStaticSupportedServiceNames();
1159 }
1160 
1161 /* Helper for XServiceInfo */
1162 Sequence< rtl::OUString > SvtFilePicker::impl_getStaticSupportedServiceNames()
1163 {
1164     Sequence< rtl::OUString > seqServiceNames( 1 );
1165     rtl::OUString* pArray = seqServiceNames.getArray();
1166     pArray[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.OfficeFilePicker" );
1167     return seqServiceNames ;
1168 }
1169 
1170 /* Helper for XServiceInfo */
1171 rtl::OUString SvtFilePicker::impl_getStaticImplementationName()
1172 {
1173     return rtl::OUString::createFromAscii( "com.sun.star.svtools.OfficeFilePicker" );
1174 }
1175 
1176 /* Helper for registry */
1177 Reference< XInterface > SAL_CALL SvtFilePicker::impl_createInstance(
1178     const Reference< XComponentContext >& rxContext) throw( Exception )
1179 {
1180     Reference< XMultiServiceFactory > xServiceManager (rxContext->getServiceManager(), UNO_QUERY_THROW);
1181     return Reference< XInterface >( *new SvtFilePicker( xServiceManager ) );
1182 }
1183