Bump for 4.0-11
[LibreOffice.git] / fpicker / source / aqua / SalAquaFilePicker.mm
blobfc7562b7d3c97b79e5fc526a2976d36310bcacce
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  */
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
22 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
23 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
24 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
25 #include <cppuhelper/interfacecontainer.h>
26 #include <osl/diagnose.h>
27 #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
28 #include <com/sun/star/ui/dialogs/ControlActions.hpp>
29 #include <com/sun/star/uno/Any.hxx>
30 #include <FPServiceInfo.hxx>
31 #include <osl/mutex.hxx>
32 #include <vcl/svapp.hxx>
34 #include "resourceprovider.hxx"
36 #include <osl/file.hxx>
37 #include "CFStringUtilities.hxx"
38 #include "NSString_OOoAdditions.hxx"
39 #include "NSURL_OOoAdditions.hxx"
41 #include <iostream>
43 #include "SalAquaFilePicker.hxx"
45 #include <objc/objc-runtime.h>
47 #pragma mark DEFINES
49 #define LABEL_TOGGLE( elem ) \
50 case elem : \
51 aLabel = aResProvider.getResString( CHECKBOX_##elem ); \
52     setLabel( CHECKBOX_##elem, aLabel ); \
53     break
55 #define CLASS_NAME "SalAquaFilePicker"
57 //------------------------------------------------------------------------
58 // namespace directives
59 //------------------------------------------------------------------------
61 using namespace ::com::sun::star;
62 using namespace ::com::sun::star::ui::dialogs;
63 using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
64 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
65 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
66 using namespace ::com::sun::star::lang;
67 using namespace ::com::sun::star::beans;
68 using namespace ::com::sun::star::uno;
70 //------------------------------------------------------------------------
71 // helper functions
72 //------------------------------------------------------------------------
74 namespace
76     // controling event notifications
77     const bool STARTUP_SUSPENDED = true;
78     const bool STARTUP_ALIVE     = false;
80     uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames()
81     {
82         uno::Sequence<rtl::OUString> aRet(3);
83         aRet[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.FilePicker" ));
84         aRet[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.SystemFilePicker" ));
85         aRet[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.dialogs.AquaFilePicker" ));
86         return aRet;
87     }
90 #pragma mark Constructor
91 //-----------------------------------------------------------------------------------------
92 // constructor
93 //-----------------------------------------------------------------------------------------
95 SalAquaFilePicker::SalAquaFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
96 cppu::WeakComponentImplHelper8<XFilterManager, XFilterGroupManager, XFilePickerControlAccess, XFilePickerNotifier,
97  lang::XInitialization, util::XCancellable, lang::XEventListener, lang::XServiceInfo>( m_rbHelperMtx )
98 , m_xServiceMgr( xServiceMgr )
99 , m_pFilterHelper( NULL )
101     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
103     m_pDelegate = [[AquaFilePickerDelegate alloc] initWithFilePicker:this];
104     m_pControlHelper->setFilePickerDelegate(m_pDelegate);
106     DBG_PRINT_EXIT(CLASS_NAME, __func__);
109 SalAquaFilePicker::~SalAquaFilePicker()
111     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
113     if (NULL != m_pFilterHelper)
114         delete m_pFilterHelper;
116     [m_pDelegate release];
118     DBG_PRINT_EXIT(CLASS_NAME, __func__);
122 #pragma mark XFilePickerNotifier
123 //------------------------------------------------------------------------------------
124 // XFilePickerNotifier
125 //------------------------------------------------------------------------------------
127 void SAL_CALL SalAquaFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
128     throw( uno::RuntimeException )
130     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
132     SolarMutexGuard aGuard;
133     m_xListener = xListener;
135     DBG_PRINT_EXIT(CLASS_NAME, __func__);
138 void SAL_CALL SalAquaFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& )
139     throw( uno::RuntimeException )
141     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
143     SolarMutexGuard aGuard;
144     m_xListener.clear();
146     DBG_PRINT_EXIT(CLASS_NAME, __func__);
149 #pragma mark XAsynchronousExecutableDialog
150 //-----------------------------------------------------------------------------------------
151 // XExecutableDialog functions
152 //-----------------------------------------------------------------------------------------
153 void SAL_CALL SalAquaFilePicker::setTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
155     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
157     SolarMutexGuard aGuard;
158     implsetTitle(aTitle);
160     DBG_PRINT_EXIT(CLASS_NAME, __func__);
163 sal_Int16 SAL_CALL SalAquaFilePicker::execute() throw( uno::RuntimeException )
165     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
167     SolarMutexGuard aGuard;
169     sal_Int16 retVal = 0;
171     implInitialize();
173     // if m_pDialog is nil after initialization, something must have gone wrong before
174     // or there was no initialization (see issue http://www.openoffice.org/issues/show_bug.cgi?id=100214)
175     if (m_pDialog == nil) {
176         m_nDialogType = NAVIGATIONSERVICES_OPEN;
177     }
179     if (m_pFilterHelper) {
180         m_pFilterHelper->SetFilters();
181     }
183     if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
184         if (m_sSaveFileName.getLength() == 0) {
185             //if no filename is set, NavigationServices will set the name to "untitled". We don't want this!
186             //So let's try to get the window title to get the real untitled name
187             NSWindow *frontWindow = [NSApp keyWindow];
188             if (NULL != frontWindow) {
189                 NSString *windowTitle = [frontWindow title];
190                 if (windowTitle != nil) {
191                     rtl::OUString ouName = [windowTitle OUString];
192                     //a window title will typically be something like "Untitled1 - OpenOffice.org Writer"
193                     //but we only want the "Untitled1" part of it
194                     sal_Int32 indexOfDash = ouName.indexOf(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")));
195                     if (indexOfDash > -1) {
196                         m_sSaveFileName = ouName.copy(0,indexOfDash);
197                         if (m_sSaveFileName.getLength() > 0) {
198                             setDefaultName(m_sSaveFileName);
199                         }
200                     } else {
201                         OSL_TRACE("no dash present in window title");
202                     }
203                 } else {
204                     OSL_TRACE("couldn't get window title");
205                 }
206             } else {
207                 OSL_TRACE("no front window found");
208             }
209         }
210     }
212     //Set the delegate to be notified of certain events
214     // I don't know why, but with gcc 4.2.1, this line results in the warning:
215     // class 'AquaFilePickerDelegate' does not implement the 'NSOpenSavePanelDelegate' protocol
216     // So instead of:
217     // [m_pDialog setDelegate:m_pDelegate];
218     // do:
219     objc_msgSend(m_pDialog, @selector(setDelegate:), m_pDelegate);
221     int nStatus = runandwaitforresult();
223     [m_pDialog setDelegate:nil];
225     switch( nStatus )
226     {
227         case NSOKButton:
228             OSL_TRACE("The dialog returned OK");
229             retVal = ExecutableDialogResults::OK;
230             break;
232         case NSCancelButton:
233             OSL_TRACE("The dialog was cancelled by the user!");
234             retVal = ExecutableDialogResults::CANCEL;
235             break;
237         default:
238             throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The dialog returned with an unknown result!")), static_cast< XFilePicker* >( this ));
239             break;
240     }
242     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
244     return retVal;
248 #pragma mark XFilePicker
249 //-----------------------------------------------------------------------------------------
250 // XFilePicker functions
251 //-----------------------------------------------------------------------------------------
253 void SAL_CALL SalAquaFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( uno::RuntimeException )
255     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "multiSelectable?", bMode);
257     SolarMutexGuard aGuard;
259     if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
260         [(NSOpenPanel*)m_pDialog setAllowsMultipleSelection:YES];
261         OSL_TRACE("dialog allows multi-selection? %d", [(NSOpenPanel*)m_pDialog allowsMultipleSelection]);
262     }
264     DBG_PRINT_EXIT(CLASS_NAME, __func__);
267 void SAL_CALL SalAquaFilePicker::setDefaultName( const rtl::OUString& aName )
268 throw( uno::RuntimeException )
270     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "name", aName);
272     SolarMutexGuard aGuard;
274     m_sSaveFileName = aName;
276     DBG_PRINT_EXIT(CLASS_NAME, __func__);
279 void SAL_CALL SalAquaFilePicker::setDisplayDirectory( const rtl::OUString& rDirectory )
280 throw( lang::IllegalArgumentException, uno::RuntimeException )
282     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", rDirectory);
284     SolarMutexGuard aGuard;
286     implsetDisplayDirectory(rDirectory);
288     DBG_PRINT_EXIT(CLASS_NAME, __func__);
291 rtl::OUString SAL_CALL SalAquaFilePicker::getDisplayDirectory() throw( uno::RuntimeException )
293     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
295     rtl::OUString retVal = implgetDisplayDirectory();
297     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
298     return retVal;
301 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getFiles() throw( uno::RuntimeException )
303     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
305     SolarMutexGuard aGuard;
307     // OSL_TRACE("starting work");
308     /*
309      * If more than one file is selected in an OpenDialog, then the first result
310      * is the directory and the remaining results contain just the files' names
311      * without the basedir path.
312      */
313     NSArray *files = nil;
314     if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
315         files = [(NSOpenPanel*)m_pDialog URLs];
316     }
317     else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
318         files = [NSArray arrayWithObjects:[m_pDialog URL], nil];
319     }
321     long nFiles = [files count];
322     OSL_TRACE("# of items: %d", nFiles);
324     uno::Sequence< rtl::OUString > aSelectedFiles(nFiles > 1 ? nFiles + 1 : nFiles);
326     for(int nIndex = 0; nIndex < nFiles; nIndex += 1)
327     {
328         NSURL *url = [files objectAtIndex:nIndex];
329         OSL_TRACE("handling %s", [[url description] UTF8String]);
330         InfoType info = FULLPATH;
331         if (nFiles > 1) {
332             //just get the file's name (only in OpenDialog)
333             info = FILENAME;
334         }
335         OUString sFileOrDirURL = [url OUStringForInfo:info];
337         //get the directory information, only on the first file processed
338         if (nIndex == 0) {
339             OUString sDirectoryURL = [url OUStringForInfo:PATHWITHOUTLASTCOMPONENT];
341             if (nFiles > 1) {
342                 aSelectedFiles[0] = OUString(sDirectoryURL);
343             }
344         }
346         short nSequenceIndex = nFiles > 1 ? nIndex + 1 : nIndex;
347         aSelectedFiles[nSequenceIndex] = sFileOrDirURL;
349         OSL_TRACE("Returned file in getFiles: \"%s\".", OUStringToOString(sFileOrDirURL, RTL_TEXTENCODING_UTF8).getStr());
350     }
352     DBG_PRINT_EXIT(CLASS_NAME, __func__);
353     return aSelectedFiles;
356 #pragma mark XFilterManager
357 //-----------------------------------------------------------------------------------------
358 // XFilterManager functions
359 //-----------------------------------------------------------------------------------------
361 void SAL_CALL SalAquaFilePicker::appendFilter( const rtl::OUString& aTitle, const rtl::OUString& aFilter )
362 throw( lang::IllegalArgumentException, uno::RuntimeException )
364     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
366     SolarMutexGuard aGuard;
368     ensureFilterHelper();
369     m_pFilterHelper->appendFilter( aTitle, aFilter );
370     m_pControlHelper->setFilterControlNeeded(YES);
372     DBG_PRINT_EXIT(CLASS_NAME, __func__);
375 void SAL_CALL SalAquaFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
376 throw( lang::IllegalArgumentException, uno::RuntimeException )
378     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
379     OSL_TRACE( "Setting current filter to %s",
380                OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
382     SolarMutexGuard aGuard;
384     ensureFilterHelper();
385     m_pFilterHelper->setCurrentFilter(aTitle);
386     updateFilterUI();
388     updateSaveFileNameExtension();
390     DBG_PRINT_EXIT(CLASS_NAME, __func__);
393 rtl::OUString SAL_CALL SalAquaFilePicker::getCurrentFilter() throw( uno::RuntimeException )
395     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
396     SolarMutexGuard aGuard;
398     ensureFilterHelper();
400     DBG_PRINT_EXIT(CLASS_NAME, __func__);
401     return m_pFilterHelper->getCurrentFilter();
404 #pragma mark XFilterGroupManager
405 //-----------------------------------------------------------------------------------------
406 // XFilterGroupManager functions
407 //-----------------------------------------------------------------------------------------
409 void SAL_CALL SalAquaFilePicker::appendFilterGroup( const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters )
410 throw( lang::IllegalArgumentException, uno::RuntimeException )
412     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
413     SolarMutexGuard aGuard;
415     ensureFilterHelper();
416     m_pFilterHelper->appendFilterGroup(sGroupTitle, aFilters);
417     m_pControlHelper->setFilterControlNeeded(YES);
418     DBG_PRINT_EXIT(CLASS_NAME, __func__);
421 #pragma mark XFilePickerControlAccess
422 //------------------------------------------------------------------------------------
423 // XFilePickerControlAccess functions
424 //------------------------------------------------------------------------------------
426 void SAL_CALL SalAquaFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
427 throw( uno::RuntimeException )
429     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
431     SolarMutexGuard aGuard;
433     m_pControlHelper->setValue(nControlId, nControlAction, rValue);
435     if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION && m_nDialogType == NAVIGATIONSERVICES_SAVE) {
436         updateSaveFileNameExtension();
437     }
439     DBG_PRINT_EXIT(CLASS_NAME, __func__);
442 uno::Any SAL_CALL SalAquaFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
443 throw( uno::RuntimeException )
445     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
447     uno::Any aValue = m_pControlHelper->getValue(nControlId, nControlAction);
449     DBG_PRINT_EXIT(CLASS_NAME, __func__);
450     return aValue;
453 void SAL_CALL SalAquaFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
454 throw( uno::RuntimeException )
456     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
458     m_pControlHelper->enableControl(nControlId, bEnable);
460     DBG_PRINT_EXIT(CLASS_NAME, __func__);
463 void SAL_CALL SalAquaFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel )
464 throw( uno::RuntimeException )
466     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
468     SolarMutexGuard aGuard;
470     NSString* sLabel = [NSString stringWithOUString:aLabel];
471     m_pControlHelper->setLabel( nControlId, sLabel ) ;
473     DBG_PRINT_EXIT(CLASS_NAME, __func__);
476 rtl::OUString SAL_CALL SalAquaFilePicker::getLabel( sal_Int16 nControlId )
477 throw( uno::RuntimeException )
479     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
480     DBG_PRINT_EXIT(CLASS_NAME, __func__);
482     return m_pControlHelper->getLabel(nControlId);
485 #pragma mark XInitialization
486 //------------------------------------------------------------------------------------
487 // XInitialization
488 //------------------------------------------------------------------------------------
490 void SAL_CALL SalAquaFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments )
491 throw( uno::Exception, uno::RuntimeException )
493     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "arguments size", aArguments.getLength());
495     SolarMutexGuard aGuard;
497     // parameter checking
498     uno::Any aAny;
499     if( 0 == aArguments.getLength() )
500         throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "no arguments" )),
501                                              static_cast<XFilePicker*>( this ), 1 );
503     aAny = aArguments[0];
505     if( ( aAny.getValueType() != ::getCppuType( ( sal_Int16* )0 ) ) &&
506         (aAny.getValueType() != ::getCppuType( ( sal_Int8* )0 ) ) )
507         throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "invalid argument type" )),
508                                              static_cast<XFilePicker*>( this ), 1 );
510     sal_Int16 templateId = -1;
511     aAny >>= templateId;
513     switch( templateId )
514     {
515         case FILEOPEN_SIMPLE:
516             m_nDialogType = NAVIGATIONSERVICES_OPEN;
517             OSL_TRACE( "Template: FILEOPEN_SIMPLE" );
518             break;
519         case FILESAVE_SIMPLE:
520             m_nDialogType = NAVIGATIONSERVICES_SAVE;
521             OSL_TRACE( "Template: FILESAVE_SIMPLE" );
522             break;
523         case FILESAVE_AUTOEXTENSION_PASSWORD:
524             m_nDialogType = NAVIGATIONSERVICES_SAVE;
525             OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD" );
526             break;
527         case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
528             m_nDialogType = NAVIGATIONSERVICES_SAVE;
529             OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS" );
530             break;
531         case FILESAVE_AUTOEXTENSION_SELECTION:
532             m_nDialogType = NAVIGATIONSERVICES_SAVE;
533             OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_SELECTION" );
534             break;
535         case FILESAVE_AUTOEXTENSION_TEMPLATE:
536             m_nDialogType = NAVIGATIONSERVICES_SAVE;
537             OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_TEMPLATE" );
538             break;
539         case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
540             m_nDialogType = NAVIGATIONSERVICES_OPEN;
541             OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE" );
542             break;
543         case FILEOPEN_PLAY:
544             m_nDialogType = NAVIGATIONSERVICES_OPEN;
545             OSL_TRACE( "Template: FILEOPEN_PLAY" );
546             break;
547         case FILEOPEN_READONLY_VERSION:
548             m_nDialogType = NAVIGATIONSERVICES_OPEN;
549             OSL_TRACE( "Template: FILEOPEN_READONLY_VERSION" );
550             break;
551         case FILEOPEN_LINK_PREVIEW:
552             m_nDialogType = NAVIGATIONSERVICES_OPEN;
553             OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW" );
554             break;
555         case FILESAVE_AUTOEXTENSION:
556             m_nDialogType = NAVIGATIONSERVICES_SAVE;
557             OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION" );
558             break;
559         default:
560             throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Unknown template" )),
561                                                  static_cast< XFilePicker* >( this ),
562                                                  1 );
563     }
565     m_pControlHelper->initialize(templateId);
567     implInitialize();
569     DBG_PRINT_EXIT(CLASS_NAME, __func__);
572 #pragma mark XCancellable
573 //------------------------------------------------------------------------------------
574 // XCancellable
575 //------------------------------------------------------------------------------------
577 void SAL_CALL SalAquaFilePicker::cancel() throw( uno::RuntimeException )
579     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
581     SolarMutexGuard aGuard;
583     if (m_pDialog != nil) {
584         [m_pDialog cancel:nil];
585     }
587     DBG_PRINT_EXIT(CLASS_NAME, __func__);
590 #pragma mark XEventListener
591 //------------------------------------------------
592 // XEventListener
593 //------------------------------------------------
595 void SAL_CALL SalAquaFilePicker::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
597     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
599     SolarMutexGuard aGuard;
601     uno::Reference<XFilePickerListener> xFilePickerListener( aEvent.Source, ::com::sun::star::uno::UNO_QUERY );
603     if( xFilePickerListener.is() )
604         removeFilePickerListener( xFilePickerListener );
606     DBG_PRINT_EXIT(CLASS_NAME, __func__);
609 #pragma mark XServiceInfo
610 // -------------------------------------------------
611 // XServiceInfo
612 // -------------------------------------------------
614 rtl::OUString SAL_CALL SalAquaFilePicker::getImplementationName()
615 throw( uno::RuntimeException )
617     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
619     rtl::OUString retVal(RTL_CONSTASCII_USTRINGPARAM( FILE_PICKER_IMPL_NAME ));
621     DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
623     return retVal;
626 sal_Bool SAL_CALL SalAquaFilePicker::supportsService( const rtl::OUString& sServiceName )
627 throw( uno::RuntimeException )
629     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "service name", sServiceName);
631     sal_Bool retVal = sal_False;
633     uno::Sequence <rtl::OUString> supportedServicesNames = FilePicker_getSupportedServiceNames();
635     for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) {
636         if( supportedServicesNames[n].compareTo( sServiceName ) == 0) {
637             retVal = sal_True;
638             break;
639         }
640     }
642     DBG_PRINT_EXIT(CLASS_NAME, __func__);
644     return retVal;
647 uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getSupportedServiceNames()
648 throw( uno::RuntimeException )
650     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
651     DBG_PRINT_EXIT(CLASS_NAME, __func__);
653     return FilePicker_getSupportedServiceNames();
656 #pragma mark Misc/Private
657 //-----------------------------------------------------------------------------------------
658 // FilePicker Event functions
659 //-----------------------------------------------------------------------------------------
661 void SAL_CALL SalAquaFilePicker::fileSelectionChanged( FilePickerEvent aEvent )
663     OSL_TRACE( "file selection changed");
664     if (m_xListener.is())
665         m_xListener->fileSelectionChanged( aEvent );
668 void SAL_CALL SalAquaFilePicker::directoryChanged( FilePickerEvent aEvent )
670     OSL_TRACE("directory changed");
671     if (m_xListener.is())
672         m_xListener->directoryChanged( aEvent );
675 void SAL_CALL SalAquaFilePicker::controlStateChanged( FilePickerEvent aEvent )
677     OSL_TRACE("control state changed");
678     if (m_xListener.is())
679         m_xListener->controlStateChanged( aEvent );
682 void SAL_CALL SalAquaFilePicker::dialogSizeChanged()
684     OSL_TRACE("dialog size changed");
685     if (m_xListener.is())
686         m_xListener->dialogSizeChanged();
689 //------------------------------------------------------------------------------------
691 #define MAP_TOGGLE( elem ) \
692 case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
693     pWidget = m_pToggles[elem]; \
694     break
696 #define MAP_BUTTON( elem ) \
697 case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
698     pWidget = m_pButtons[elem]; \
699     break
700 #undef MAP_LIST
701 #define MAP_LIST( elem ) \
702 case ExtendedFilePickerElementIds::LISTBOX_##elem: \
703     pWidget = m_pListControls[elem]; if (isAList != NULL) *isAList = sal_True; \
704     break
706 #define MAP_LIST_LABEL( elem ) \
707 case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
708     pWidget = m_pListControls[elem]; \
709     break
711 //--------------------------------------------------
712 // Misc
713 //-------------------------------------------------
714 void SalAquaFilePicker::ensureFilterHelper() {
715     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
717     SolarMutexGuard aGuard;
719     if (NULL == m_pFilterHelper) {
720         m_pFilterHelper = new FilterHelper;
721         m_pControlHelper->setFilterHelper(m_pFilterHelper);
722         [m_pDelegate setFilterHelper:m_pFilterHelper];
723     }
725     DBG_PRINT_EXIT(CLASS_NAME, __func__);
728 void SalAquaFilePicker::implInitialize()
730     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
732     //call super
733     SalAquaPicker::implInitialize();
735     DBG_PRINT_EXIT(CLASS_NAME, __func__);
738 void SalAquaFilePicker::updateFilterUI() {
739     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
741     m_pControlHelper->updateFilterUI();
743     DBG_PRINT_EXIT(CLASS_NAME, __func__);
746 void SalAquaFilePicker::updateSaveFileNameExtension() {
747     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
749     if (m_nDialogType != NAVIGATIONSERVICES_SAVE) {
750         return;
751     }
753     // we need to set this here again because initial setting does
754     //[m_pDialog setExtensionHidden:YES];
756     SolarMutexGuard aGuard;
758     if (m_pControlHelper->isAutoExtensionEnabled() == false) {
759         OSL_TRACE("allowing other file types");
760         [m_pDialog setAllowedFileTypes:nil];
761         [m_pDialog setAllowsOtherFileTypes:YES];
762     } else {
763         ensureFilterHelper();
765         OUStringList aStringList = m_pFilterHelper->getCurrentFilterSuffixList();
766         if( aStringList.empty()) // #i9328#
767             return;
769         rtl::OUString suffix = (*(aStringList.begin())).copy(1);
770         NSString *requiredFileType = [NSString stringWithOUString:suffix];
772 #if defined(LIBO_WERROR) && defined(__clang__) && MACOSX_SDK_VERSION >= 1070
773 #pragma GCC diagnostic push
774 #pragma GCC diagnostic warning "-Wdeprecated-declarations"
775 #endif
776         [m_pDialog setRequiredFileType:requiredFileType];
777 #if defined(LIBO_WERROR) && defined(__clang__) && MACOSX_SDK_VERSION >= 1070
778 #pragma GCC diagnostic pop
779 #endif
781         OSL_TRACE("disallowing other file types");
782         [m_pDialog setAllowsOtherFileTypes:NO];
783     }
785     DBG_PRINT_EXIT(CLASS_NAME, __func__);
788 void SalAquaFilePicker::filterControlChanged() {
789     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
791     if (m_pDialog == nil) {
792         return;
793     }
795     SolarMutexGuard aGuard;
797     updateSaveFileNameExtension();
799     [m_pDialog validateVisibleColumns];
801     FilePickerEvent evt;
802     evt.ElementId = LISTBOX_FILTER;
803     controlStateChanged( evt );
805     DBG_PRINT_EXIT(CLASS_NAME, __func__);
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */