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