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