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__anonb5467c4f0111::FilterTitleMatch381 FilterTitleMatch( const ::rtl::OUString& _rTitle ) : rTitle( _rTitle ) { }
382
383 //............................................................................
operator ()__anonb5467c4f0111::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 ()__anonb5467c4f0111::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