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 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 //-----------------------------------------------------------------------------
IMPL_LINK(SvtFilePicker,DialogClosedHdl,Dialog *,pDlg)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 //------------------------------------------------------------------------------------
getWinBits(WinBits & rExtraBits)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 //------------------------------------------------------------------------------------
notify(sal_Int16 _nEventId,sal_Int16 _nControlId)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:
FilterTitleMatch__anon99727fb80111::FilterTitleMatch371 FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { }
372
373 //............................................................................
operator ()__anon99727fb80111::FilterTitleMatch374 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 }
operator ()__anon99727fb80111::FilterTitleMatch391 bool operator () ( const UnoFilterEntry& _rEntry )
392 {
393 return _rEntry.First == rTitle ? true : false;
394 }
395 };
396 }
397
398 //------------------------------------------------------------------------------------
FilterNameExists(const::rtl::OUString & rTitle)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 //------------------------------------------------------------------------------------
FilterNameExists(const UnoFilterList & _rGroupedFilters)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 //------------------------------------------------------------------------------------
ensureFilterList(const::rtl::OUString & _rInitialCurrentFilter)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 //------------------------------------------------------------------------------------
SvtFilePicker(const Reference<XMultiServiceFactory> & xFactory)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
~SvtFilePicker()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 //------------------------------------------------------------------------------------
implExecutePicker()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 //------------------------------------------------------------------------------------
implCreateDialog(Window * _pParent)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 //------------------------------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(SvtFilePicker,OCommonPicker,SvtFilePicker_Base)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 //------------------------------------------------------------------------------------
execute()527 sal_Int16 SAL_CALL SvtFilePicker::execute( ) throw (RuntimeException)
528 {
529 return OCommonPicker::execute();
530 }
531
532 //------------------------------------------------------------------------------------
533 // XAsynchronousExecutableDialog functions
534 //------------------------------------------------------------------------------------
535
536 //------------------------------------------------------------------------------------
setDialogTitle(const::rtl::OUString & _rTitle)537 void SAL_CALL SvtFilePicker::setDialogTitle( const ::rtl::OUString& _rTitle ) throw (RuntimeException)
538 {
539 setTitle( _rTitle );
540 }
541
542 //------------------------------------------------------------------------------------
startExecuteModal(const Reference<::com::sun::star::ui::dialogs::XDialogClosedListener> & xListener)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
setMultiSelectionMode(sal_Bool bMode)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
setDefaultName(const rtl::OUString & aName)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
setDisplayDirectory(const rtl::OUString & aDirectory)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
getDisplayDirectory()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
getFiles()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
setValue(sal_Int16 nElementID,sal_Int16 nControlAction,const Any & rValue)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
getValue(sal_Int16 nElementID,sal_Int16 nControlAction)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 //------------------------------------------------------------------------------------
setLabel(sal_Int16 nLabelID,const rtl::OUString & rValue)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 //------------------------------------------------------------------------------------
getLabel(sal_Int16 nLabelID)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 //------------------------------------------------------------------------------------
enableControl(sal_Int16 nElementID,sal_Bool bEnable)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
addFilePickerListener(const Reference<XFilePickerListener> & xListener)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 //------------------------------------------------------------------------------------
removeFilePickerListener(const Reference<XFilePickerListener> &)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
getSupportedImageFormats()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 //------------------------------------------------------------------------------------
getTargetColorDepth()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 //------------------------------------------------------------------------------------
getAvailableWidth()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 //------------------------------------------------------------------------------------
getAvailableHeight()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 //------------------------------------------------------------------------------------
setImage(sal_Int16 aImageFormat,const Any & rImage)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 //------------------------------------------------------------------------------------
setShowState(sal_Bool bShowState)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 //------------------------------------------------------------------------------------
getShowState()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
appendFilterGroup(const::rtl::OUString & sGroupTitle,const Sequence<StringPair> & aFilters)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
appendFilter(const rtl::OUString & aTitle,const rtl::OUString & aFilter)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 //------------------------------------------------------------------------------------
setCurrentFilter(const rtl::OUString & aTitle)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 //------------------------------------------------------------------------------------
getCurrentFilter()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
initialize(const Sequence<Any> & _rArguments)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 //-------------------------------------------------------------------------
implHandleInitializationArgument(const::rtl::OUString & _rName,const Any & _rValue)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 */
getImplementationName()1135 rtl::OUString SAL_CALL SvtFilePicker::getImplementationName() throw( RuntimeException )
1136 {
1137 return impl_getStaticImplementationName();
1138 }
1139
1140 /* XServiceInfo */
supportsService(const rtl::OUString & sServiceName)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 */
getSupportedServiceNames()1156 Sequence< rtl::OUString > SAL_CALL SvtFilePicker::getSupportedServiceNames() throw( RuntimeException )
1157 {
1158 return impl_getStaticSupportedServiceNames();
1159 }
1160
1161 /* Helper for XServiceInfo */
impl_getStaticSupportedServiceNames()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 */
impl_getStaticImplementationName()1171 rtl::OUString SvtFilePicker::impl_getStaticImplementationName()
1172 {
1173 return rtl::OUString::createFromAscii( "com.sun.star.svtools.OfficeFilePicker" );
1174 }
1175
1176 /* Helper for registry */
impl_createInstance(const Reference<XComponentContext> & rxContext)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