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 //------------------------------------------------------------------------
25 // includes
26 //------------------------------------------------------------------------
27
28 #include <com/sun/star/lang/DisposedException.hpp>
29 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
30 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
31 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
32 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
33 #include <cppuhelper/interfacecontainer.h>
34 #include <osl/diagnose.h>
35 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
36 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <FPServiceInfo.hxx>
39 #include <vos/mutex.hxx>
40 #include <vcl/svapp.hxx>
41
42 #ifndef _TOOLS_URLOBJ_HXX
43 #include <tools/urlobj.hxx>
44 #endif
45 #include "resourceprovider.hxx"
46
47 #ifndef _SV_RC_H
48 #include <tools/rc.hxx>
49 #endif
50 #include <osl/file.hxx>
51 #include "CFStringUtilities.hxx"
52 #include "NSString_OOoAdditions.hxx"
53 #include "NSURL_OOoAdditions.hxx"
54
55 #include <iostream>
56
57 #include "SalAquaFilePicker.hxx"
58
59
60 #pragma mark DEFINES
61
62 #define LABEL_TOGGLE( elem ) \
63 case elem : \
64 aLabel = aResProvider.getResString( CHECKBOX_##elem ); \
65 setLabel( CHECKBOX_##elem, aLabel ); \
66 break
67
68 #define CLASS_NAME "SalAquaFilePicker"
69
70 //------------------------------------------------------------------------
71 // namespace directives
72 //------------------------------------------------------------------------
73
74 using namespace ::com::sun::star;
75 using namespace ::com::sun::star::ui::dialogs;
76 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
77 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
78 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
79 using namespace ::com::sun::star::lang;
80 using namespace ::com::sun::star::beans;
81 using namespace ::com::sun::star::uno;
82
83 //------------------------------------------------------------------------
84 // helper functions
85 //------------------------------------------------------------------------
86
87 namespace
88 {
89 // controlling event notifications
90 const bool STARTUP_SUSPENDED = true;
91 const bool STARTUP_ALIVE = false;
92
FilePicker_getSupportedServiceNames()93 uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames()
94 {
95 uno::Sequence<rtl::OUString> aRet(3);
96 aRet[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.FilePicker" );
97 aRet[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFilePicker" );
98 aRet[2] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.AquaFilePicker" );
99 return aRet;
100 }
101 }
102
103 #pragma mark Constructor
104 //-----------------------------------------------------------------------------------------
105 // constructor
106 //-----------------------------------------------------------------------------------------
107
SalAquaFilePicker(const uno::Reference<lang::XMultiServiceFactory> & xServiceMgr)108 SalAquaFilePicker::SalAquaFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
109 cppu::WeakComponentImplHelper8<XFilterManager, XFilterGroupManager, XFilePickerControlAccess, XFilePickerNotifier,
110 lang::XInitialization, util::XCancellable, lang::XEventListener, lang::XServiceInfo>( m_rbHelperMtx )
111 , m_xServiceMgr( xServiceMgr )
112 , m_pFilterHelper( NULL )
113 {
114 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
115
116 m_pDelegate = [[AquaFilePickerDelegate alloc] initWithFilePicker:this];
117 m_pControlHelper->setFilePickerDelegate(m_pDelegate);
118
119 DBG_PRINT_EXIT(CLASS_NAME, __func__);
120 }
121
~SalAquaFilePicker()122 SalAquaFilePicker::~SalAquaFilePicker()
123 {
124 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
125
126 if (NULL != m_pFilterHelper)
127 delete m_pFilterHelper;
128
129 [m_pDelegate release];
130
131 DBG_PRINT_EXIT(CLASS_NAME, __func__);
132 }
133
134
135 #pragma mark XFilePickerNotifier
136 //------------------------------------------------------------------------------------
137 // XFilePickerNotifier
138 //------------------------------------------------------------------------------------
139
addFilePickerListener(const uno::Reference<XFilePickerListener> & xListener)140 void SAL_CALL SalAquaFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
141 {
142 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
143
144 ::vos::OGuard aGuard( Application::GetSolarMutex() );
145 m_xListener = xListener;
146
147 DBG_PRINT_EXIT(CLASS_NAME, __func__);
148 }
149
removeFilePickerListener(const uno::Reference<XFilePickerListener> &)150 void SAL_CALL SalAquaFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& )
151 {
152 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
153
154 ::vos::OGuard aGuard( Application::GetSolarMutex() );
155 m_xListener.clear();
156
157 DBG_PRINT_EXIT(CLASS_NAME, __func__);
158 }
159
160 #pragma mark XAsynchronousExecutableDialog
161 //-----------------------------------------------------------------------------------------
162 // XExecutableDialog functions
163 //-----------------------------------------------------------------------------------------
setTitle(const rtl::OUString & aTitle)164 void SAL_CALL SalAquaFilePicker::setTitle( const rtl::OUString& aTitle )
165 {
166 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
167
168 ::vos::OGuard aGuard( Application::GetSolarMutex() );
169 implsetTitle(aTitle);
170
171 DBG_PRINT_EXIT(CLASS_NAME, __func__);
172 }
173
execute()174 sal_Int16 SAL_CALL SalAquaFilePicker::execute()
175 {
176 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
177
178 ::vos::OGuard aGuard( Application::GetSolarMutex() );
179
180 sal_Int16 retVal = 0;
181
182 implInitialize();
183
184 // if m_pDialog is nil after initialization, something must have gone wrong before
185 // or there was no initialization (see issue http://www.openoffice.org/issues/show_bug.cgi?id=100214)
186 if (m_pDialog == nil) {
187 //throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog was not properly initialized!"), static_cast< XFilePicker* >( this ));
188 m_nDialogType = NAVIGATIONSERVICES_OPEN;
189 }
190
191 if (m_pFilterHelper) {
192 m_pFilterHelper->SetFilters();
193 }
194
195 if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
196 if (m_sSaveFileName.getLength() == 0) {
197 //if no filename is set, NavigationServices will set the name to "untitled". We don't want this!
198 //So let's try to get the window title to get the real untitled name
199 NSWindow *frontWindow = [NSApp keyWindow];
200 if (NULL != frontWindow) {
201 NSString *windowTitle = [frontWindow title];
202 if (windowTitle != nil) {
203 rtl::OUString ouName = [windowTitle OUString];
204 //a window title will typically be something like "Untitled1 - OpenOffice.org Writer"
205 //but we only want the "Untitled1" part of it
206 sal_Int32 indexOfDash = ouName.indexOf(rtl::OUString::createFromAscii(" - "));
207 if (indexOfDash > -1) {
208 m_sSaveFileName = ouName.copy(0,indexOfDash);
209 if (m_sSaveFileName.getLength() > 0) {
210 setDefaultName(m_sSaveFileName);
211 }
212 } else {
213 OSL_TRACE("no dash present in window title");
214 }
215 } else {
216 OSL_TRACE("couldn't get window title");
217 }
218 } else {
219 OSL_TRACE("no front window found");
220 }
221 }
222 }
223
224 //Set the delegate to be notified of certain events
225 [m_pDialog setDelegate:m_pDelegate];
226
227 int nStatus = runandwaitforresult();
228
229 [m_pDialog setDelegate:nil];
230
231 switch( nStatus )
232 {
233 case NSOKButton:
234 OSL_TRACE("The dialog returned OK");
235 retVal = ExecutableDialogResults::OK;
236 break;
237
238 case NSCancelButton:
239 OSL_TRACE("The dialog was cancelled by the user!");
240 retVal = ExecutableDialogResults::CANCEL;
241 break;
242
243 default:
244 throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog returned with an unknown result!"), static_cast< XFilePicker* >( this ));
245 break;
246 }
247
248 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
249
250 return retVal;
251 }
252
253
254 #pragma mark XFilePicker
255 //-----------------------------------------------------------------------------------------
256 // XFilePicker functions
257 //-----------------------------------------------------------------------------------------
258
setMultiSelectionMode(sal_Bool bMode)259 void SAL_CALL SalAquaFilePicker::setMultiSelectionMode( sal_Bool bMode )
260 {
261 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "multiSelectable?", bMode);
262
263 ::vos::OGuard aGuard( Application::GetSolarMutex() );
264
265 if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
266 [(NSOpenPanel*)m_pDialog setAllowsMultipleSelection:YES];
267 OSL_TRACE("dialog allows multi-selection? %d", [(NSOpenPanel*)m_pDialog allowsMultipleSelection]);
268 }
269
270 DBG_PRINT_EXIT(CLASS_NAME, __func__);
271 }
272
setDefaultName(const rtl::OUString & aName)273 void SAL_CALL SalAquaFilePicker::setDefaultName( const rtl::OUString& aName )
274 {
275 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "name", aName);
276
277 ::vos::OGuard aGuard( Application::GetSolarMutex() );
278
279 m_sSaveFileName = aName;
280
281 DBG_PRINT_EXIT(CLASS_NAME, __func__);
282 }
283
setDisplayDirectory(const rtl::OUString & rDirectory)284 void SAL_CALL SalAquaFilePicker::setDisplayDirectory( const rtl::OUString& rDirectory )
285 {
286 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", rDirectory);
287
288 ::vos::OGuard aGuard( Application::GetSolarMutex() );
289
290 implsetDisplayDirectory(rDirectory);
291
292 DBG_PRINT_EXIT(CLASS_NAME, __func__);
293 }
294
getDisplayDirectory()295 rtl::OUString SAL_CALL SalAquaFilePicker::getDisplayDirectory()
296 {
297 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
298
299 rtl::OUString retVal = implgetDisplayDirectory();
300
301 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
302 return retVal;
303 }
304
getFiles()305 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getFiles()
306 {
307 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
308
309 ::vos::OGuard aGuard( Application::GetSolarMutex() );
310
311 // OSL_TRACE("starting work");
312 /*
313 * If more than one file is selected in an OpenDialog, then the first result
314 * is the directory and the remaining results contain just the files' names
315 * without the basedir path.
316 */
317 NSArray *files = nil;
318 if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
319 files = [(NSOpenPanel*)m_pDialog URLs];
320 }
321 else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
322 files = [NSArray arrayWithObjects:[m_pDialog URL], nil];
323 }
324
325 long nFiles = [files count];
326 OSL_TRACE("# of items: %d", nFiles);
327
328 uno::Sequence< rtl::OUString > aSelectedFiles(nFiles > 1 ? nFiles + 1 : nFiles);
329
330 for(int nIndex = 0; nIndex < nFiles; nIndex += 1)
331 {
332 NSURL *url = [files objectAtIndex:nIndex];
333 OSL_TRACE("handling %s", [[url description] UTF8String]);
334 InfoType info = FULLPATH;
335 if (nFiles > 1) {
336 //just get the file's name (only in OpenDialog)
337 info = FILENAME;
338 }
339 OUString sFileOrDirURL = [url OUStringForInfo:info];
340
341 //get the directory information, only on the first file processed
342 if (nIndex == 0) {
343 OUString sDirectoryURL = [url OUStringForInfo:PATHWITHOUTLASTCOMPONENT];
344
345 if (nFiles > 1) {
346 aSelectedFiles[0] = OUString(sDirectoryURL);
347 }
348 }
349
350 short nSequenceIndex = nFiles > 1 ? nIndex + 1 : nIndex;
351 aSelectedFiles[nSequenceIndex] = sFileOrDirURL;
352
353 OSL_TRACE("Returned file in getFiles: \"%s\".", OUStringToOString(sFileOrDirURL, RTL_TEXTENCODING_UTF8).getStr());
354 }
355
356 DBG_PRINT_EXIT(CLASS_NAME, __func__);
357 return aSelectedFiles;
358 }
359
360 #pragma mark XFilterManager
361 //-----------------------------------------------------------------------------------------
362 // XFilterManager functions
363 //-----------------------------------------------------------------------------------------
364
appendFilter(const rtl::OUString & aTitle,const rtl::OUString & aFilter)365 void SAL_CALL SalAquaFilePicker::appendFilter( const rtl::OUString& aTitle, const rtl::OUString& aFilter )
366 {
367 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
368
369 ::vos::OGuard aGuard( Application::GetSolarMutex() );
370
371 ensureFilterHelper();
372 m_pFilterHelper->appendFilter( aTitle, aFilter );
373 m_pControlHelper->setFilterControlNeeded(YES);
374
375 DBG_PRINT_EXIT(CLASS_NAME, __func__);
376 }
377
setCurrentFilter(const rtl::OUString & aTitle)378 void SAL_CALL SalAquaFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
379 {
380 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
381 OSL_TRACE( "Setting current filter to %s",
382 OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
383
384 ::vos::OGuard aGuard( Application::GetSolarMutex() );
385
386 ensureFilterHelper();
387 m_pFilterHelper->setCurrentFilter(aTitle);
388 updateFilterUI();
389
390 updateSaveFileNameExtension();
391
392 DBG_PRINT_EXIT(CLASS_NAME, __func__);
393 }
394
getCurrentFilter()395 rtl::OUString SAL_CALL SalAquaFilePicker::getCurrentFilter()
396 {
397 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
398 ::vos::OGuard aGuard( Application::GetSolarMutex() );
399
400 ensureFilterHelper();
401
402 DBG_PRINT_EXIT(CLASS_NAME, __func__);
403 return m_pFilterHelper->getCurrentFilter();
404 }
405
406 #pragma mark XFilterGroupManager
407 //-----------------------------------------------------------------------------------------
408 // XFilterGroupManager functions
409 //-----------------------------------------------------------------------------------------
410
appendFilterGroup(const rtl::OUString & sGroupTitle,const uno::Sequence<beans::StringPair> & aFilters)411 void SAL_CALL SalAquaFilePicker::appendFilterGroup( const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters )
412 {
413 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
414 ::vos::OGuard aGuard( Application::GetSolarMutex() );
415
416 ensureFilterHelper();
417 m_pFilterHelper->appendFilterGroup(sGroupTitle, aFilters);
418 m_pControlHelper->setFilterControlNeeded(YES);
419 DBG_PRINT_EXIT(CLASS_NAME, __func__);
420 }
421
422 #pragma mark XFilePickerControlAccess
423 //------------------------------------------------------------------------------------
424 // XFilePickerControlAccess functions
425 //------------------------------------------------------------------------------------
426
setValue(sal_Int16 nControlId,sal_Int16 nControlAction,const uno::Any & rValue)427 void SAL_CALL SalAquaFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
428 {
429 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
430
431 ::vos::OGuard aGuard( Application::GetSolarMutex() );
432
433 m_pControlHelper->setValue(nControlId, nControlAction, rValue);
434
435 if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION && m_nDialogType == NAVIGATIONSERVICES_SAVE) {
436 updateSaveFileNameExtension();
437 }
438
439 DBG_PRINT_EXIT(CLASS_NAME, __func__);
440 }
441
getValue(sal_Int16 nControlId,sal_Int16 nControlAction)442 uno::Any SAL_CALL SalAquaFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
443 {
444 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
445
446 uno::Any aValue = m_pControlHelper->getValue(nControlId, nControlAction);
447
448 DBG_PRINT_EXIT(CLASS_NAME, __func__);
449 return aValue;
450 }
451
enableControl(sal_Int16 nControlId,sal_Bool bEnable)452 void SAL_CALL SalAquaFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
453 {
454 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
455
456 m_pControlHelper->enableControl(nControlId, bEnable);
457
458 DBG_PRINT_EXIT(CLASS_NAME, __func__);
459 }
460
setLabel(sal_Int16 nControlId,const::rtl::OUString & aLabel)461 void SAL_CALL SalAquaFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel )
462 {
463 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
464
465 ::vos::OGuard aGuard( Application::GetSolarMutex() );
466
467 NSString* sLabel = [NSString stringWithOUString:aLabel];
468 m_pControlHelper->setLabel( nControlId, sLabel ) ;
469
470 DBG_PRINT_EXIT(CLASS_NAME, __func__);
471 }
472
getLabel(sal_Int16 nControlId)473 rtl::OUString SAL_CALL SalAquaFilePicker::getLabel( sal_Int16 nControlId )
474 {
475 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
476 DBG_PRINT_EXIT(CLASS_NAME, __func__);
477
478 return m_pControlHelper->getLabel(nControlId);
479 }
480
481 #pragma mark XInitialization
482 //------------------------------------------------------------------------------------
483 // XInitialization
484 //------------------------------------------------------------------------------------
485
initialize(const uno::Sequence<uno::Any> & aArguments)486 void SAL_CALL SalAquaFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments )
487 {
488 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "arguments size", aArguments.getLength());
489
490 ::vos::OGuard aGuard( Application::GetSolarMutex() );
491
492 // parameter checking
493 uno::Any aAny;
494 if( 0 == aArguments.getLength() )
495 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "no arguments" ),
496 static_cast<XFilePicker*>( this ), 1 );
497
498 aAny = aArguments[0];
499
500 if( ( aAny.getValueType() != ::getCppuType( ( sal_Int16* )0 ) ) &&
501 (aAny.getValueType() != ::getCppuType( ( sal_Int8* )0 ) ) )
502 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "invalid argument type" ),
503 static_cast<XFilePicker*>( this ), 1 );
504
505 sal_Int16 templateId = -1;
506 aAny >>= templateId;
507
508 switch( templateId )
509 {
510 case FILEOPEN_SIMPLE:
511 m_nDialogType = NAVIGATIONSERVICES_OPEN;
512 OSL_TRACE( "Template: FILEOPEN_SIMPLE" );
513 break;
514 case FILESAVE_SIMPLE:
515 m_nDialogType = NAVIGATIONSERVICES_SAVE;
516 OSL_TRACE( "Template: FILESAVE_SIMPLE" );
517 break;
518 case FILESAVE_AUTOEXTENSION_PASSWORD:
519 m_nDialogType = NAVIGATIONSERVICES_SAVE;
520 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD" );
521 break;
522 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
523 m_nDialogType = NAVIGATIONSERVICES_SAVE;
524 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS" );
525 break;
526 case FILESAVE_AUTOEXTENSION_SELECTION:
527 m_nDialogType = NAVIGATIONSERVICES_SAVE;
528 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_SELECTION" );
529 break;
530 case FILESAVE_AUTOEXTENSION_TEMPLATE:
531 m_nDialogType = NAVIGATIONSERVICES_SAVE;
532 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_TEMPLATE" );
533 break;
534 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
535 m_nDialogType = NAVIGATIONSERVICES_OPEN;
536 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE" );
537 break;
538 case FILEOPEN_PLAY:
539 m_nDialogType = NAVIGATIONSERVICES_OPEN;
540 OSL_TRACE( "Template: FILEOPEN_PLAY" );
541 break;
542 case FILEOPEN_READONLY_VERSION:
543 m_nDialogType = NAVIGATIONSERVICES_OPEN;
544 OSL_TRACE( "Template: FILEOPEN_READONLY_VERSION" );
545 break;
546 case FILEOPEN_LINK_PREVIEW:
547 m_nDialogType = NAVIGATIONSERVICES_OPEN;
548 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW" );
549 break;
550 case FILESAVE_AUTOEXTENSION:
551 m_nDialogType = NAVIGATIONSERVICES_SAVE;
552 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION" );
553 break;
554 default:
555 throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "Unknown template" ),
556 static_cast< XFilePicker* >( this ),
557 1 );
558 }
559
560 m_pControlHelper->initialize(templateId);
561
562 implInitialize();
563
564 DBG_PRINT_EXIT(CLASS_NAME, __func__);
565 }
566
567 #pragma mark XCancellable
568 //------------------------------------------------------------------------------------
569 // XCancellable
570 //------------------------------------------------------------------------------------
571
cancel()572 void SAL_CALL SalAquaFilePicker::cancel()
573 {
574 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
575
576 ::vos::OGuard aGuard( Application::GetSolarMutex() );
577
578 if (m_pDialog != nil) {
579 [m_pDialog cancel:nil];
580 }
581
582 DBG_PRINT_EXIT(CLASS_NAME, __func__);
583 }
584
585 #pragma mark XEventListener
586 //------------------------------------------------
587 // XEventListener
588 //------------------------------------------------
589
disposing(const lang::EventObject & aEvent)590 void SAL_CALL SalAquaFilePicker::disposing( const lang::EventObject& aEvent )
591 {
592 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
593
594 ::vos::OGuard aGuard( Application::GetSolarMutex() );
595
596 uno::Reference<XFilePickerListener> xFilePickerListener( aEvent.Source, ::com::sun::star::uno::UNO_QUERY );
597
598 if( xFilePickerListener.is() )
599 removeFilePickerListener( xFilePickerListener );
600
601 DBG_PRINT_EXIT(CLASS_NAME, __func__);
602 }
603
604 #pragma mark XServiceInfo
605 // -------------------------------------------------
606 // XServiceInfo
607 // -------------------------------------------------
608
getImplementationName()609 rtl::OUString SAL_CALL SalAquaFilePicker::getImplementationName()
610 {
611 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
612
613 rtl::OUString retVal = rtl::OUString::createFromAscii( FILE_PICKER_IMPL_NAME );
614
615 DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
616
617 return retVal;
618 }
619
supportsService(const rtl::OUString & sServiceName)620 sal_Bool SAL_CALL SalAquaFilePicker::supportsService( const rtl::OUString& sServiceName )
621 {
622 DBG_PRINT_ENTRY(CLASS_NAME, __func__, "service name", sServiceName);
623
624 sal_Bool retVal = sal_False;
625
626 uno::Sequence <rtl::OUString> supportedServicesNames = FilePicker_getSupportedServiceNames();
627
628 for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) {
629 if( supportedServicesNames[n].compareTo( sServiceName ) == 0) {
630 retVal = sal_True;
631 break;
632 }
633 }
634
635 DBG_PRINT_EXIT(CLASS_NAME, __func__);
636
637 return retVal;
638 }
639
getSupportedServiceNames()640 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getSupportedServiceNames()
641 {
642 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
643 DBG_PRINT_EXIT(CLASS_NAME, __func__);
644
645 return FilePicker_getSupportedServiceNames();
646 }
647
648 #pragma mark Misc/Private
649 //-----------------------------------------------------------------------------------------
650 // FilePicker Event functions
651 //-----------------------------------------------------------------------------------------
652
fileSelectionChanged(FilePickerEvent aEvent)653 void SAL_CALL SalAquaFilePicker::fileSelectionChanged( FilePickerEvent aEvent )
654 {
655 OSL_TRACE( "file selection changed");
656 if (m_xListener.is())
657 m_xListener->fileSelectionChanged( aEvent );
658 }
659
directoryChanged(FilePickerEvent aEvent)660 void SAL_CALL SalAquaFilePicker::directoryChanged( FilePickerEvent aEvent )
661 {
662 OSL_TRACE("directory changed");
663 if (m_xListener.is())
664 m_xListener->directoryChanged( aEvent );
665 }
666
controlStateChanged(FilePickerEvent aEvent)667 void SAL_CALL SalAquaFilePicker::controlStateChanged( FilePickerEvent aEvent )
668 {
669 OSL_TRACE("control state changed");
670 if (m_xListener.is())
671 m_xListener->controlStateChanged( aEvent );
672 }
673
dialogSizeChanged()674 void SAL_CALL SalAquaFilePicker::dialogSizeChanged()
675 {
676 OSL_TRACE("dialog size changed");
677 if (m_xListener.is())
678 m_xListener->dialogSizeChanged();
679 }
680
681 //------------------------------------------------------------------------------------
682
683 #define MAP_TOGGLE( elem ) \
684 case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
685 pWidget = m_pToggles[elem]; \
686 break
687
688 #define MAP_BUTTON( elem ) \
689 case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
690 pWidget = m_pButtons[elem]; \
691 break
692 #undef MAP_LIST
693 #define MAP_LIST( elem ) \
694 case ExtendedFilePickerElementIds::LISTBOX_##elem: \
695 pWidget = m_pListControls[elem]; if (isAList != NULL) *isAList = sal_True; \
696 break
697
698 #define MAP_LIST_LABEL( elem ) \
699 case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
700 pWidget = m_pListControls[elem]; \
701 break
702
703 //--------------------------------------------------
704 // Misc
705 //-------------------------------------------------
ensureFilterHelper()706 void SalAquaFilePicker::ensureFilterHelper() {
707 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
708
709 ::vos::OGuard aGuard( Application::GetSolarMutex() );
710
711 if (NULL == m_pFilterHelper) {
712 m_pFilterHelper = new FilterHelper;
713 m_pControlHelper->setFilterHelper(m_pFilterHelper);
714 [m_pDelegate setFilterHelper:m_pFilterHelper];
715 }
716
717 DBG_PRINT_EXIT(CLASS_NAME, __func__);
718 }
719
implInitialize()720 void SalAquaFilePicker::implInitialize()
721 {
722 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
723
724 //call super
725 SalAquaPicker::implInitialize();
726
727 DBG_PRINT_EXIT(CLASS_NAME, __func__);
728 }
729
updateFilterUI()730 void SalAquaFilePicker::updateFilterUI() {
731 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
732
733 m_pControlHelper->updateFilterUI();
734
735 DBG_PRINT_EXIT(CLASS_NAME, __func__);
736 }
737
updateSaveFileNameExtension()738 void SalAquaFilePicker::updateSaveFileNameExtension() {
739 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
740
741 if (m_nDialogType != NAVIGATIONSERVICES_SAVE) {
742 return;
743 }
744
745 // we need to set this here again because initial setting does
746 //[m_pDialog setExtensionHidden:YES];
747
748 ::vos::OGuard aGuard( Application::GetSolarMutex() );
749
750 if (m_pControlHelper->isAutoExtensionEnabled() == false) {
751 OSL_TRACE("allowing other file types");
752 [m_pDialog setAllowedFileTypes:nil];
753 [m_pDialog setAllowsOtherFileTypes:YES];
754 } else {
755 ensureFilterHelper();
756
757 OUStringList aStringList = m_pFilterHelper->getCurrentFilterSuffixList();
758 if( aStringList.empty()) // #i9328#
759 return;
760
761 rtl::OUString suffix = (*(aStringList.begin())).copy(1);
762 NSString *requiredFileType = [NSString stringWithOUString:suffix];
763
764 [m_pDialog setRequiredFileType:requiredFileType];
765
766 OSL_TRACE("disallowing other file types");
767 [m_pDialog setAllowsOtherFileTypes:NO];
768 }
769
770 DBG_PRINT_EXIT(CLASS_NAME, __func__);
771 }
772
filterControlChanged()773 void SalAquaFilePicker::filterControlChanged() {
774 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
775
776 if (m_pDialog == nil) {
777 return;
778 }
779
780 ::vos::OGuard aGuard( Application::GetSolarMutex() );
781
782 updateSaveFileNameExtension();
783
784 [m_pDialog validateVisibleColumns];
785
786 FilePickerEvent evt;
787 evt.ElementId = LISTBOX_FILTER;
788 controlStateChanged( evt );
789
790 DBG_PRINT_EXIT(CLASS_NAME, __func__);
791 }
792