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