1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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"
43 #include "SalAquaFilePicker.hxx"
45 #include <objc/objc-runtime.h>
49 #define LABEL_TOGGLE( elem ) \
51 aLabel = aResProvider.getResString( CHECKBOX_##elem ); \
52 setLabel( CHECKBOX_##elem, aLabel ); \
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 //------------------------------------------------------------------------
72 //------------------------------------------------------------------------
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()
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" ));
90 #pragma mark Constructor
91 //-----------------------------------------------------------------------------------------
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;
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;
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;
179 if (m_pFilterHelper) {
180 m_pFilterHelper->SetFilters();
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);
201 OSL_TRACE("no dash present in window title");
204 OSL_TRACE("couldn't get window title");
207 OSL_TRACE("no front window found");
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
217 // [m_pDialog setDelegate:m_pDelegate];
219 objc_msgSend(m_pDialog, @selector(setDelegate:), m_pDelegate);
221 int nStatus = runandwaitforresult();
223 [m_pDialog setDelegate:nil];
228 OSL_TRACE("The dialog returned OK");
229 retVal = ExecutableDialogResults::OK;
233 OSL_TRACE("The dialog was cancelled by the user!");
234 retVal = ExecutableDialogResults::CANCEL;
238 throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("The dialog returned with an unknown result!")), static_cast< XFilePicker* >( this ));
242 DBG_PRINT_EXIT(CLASS_NAME, __func__, 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]);
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);
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");
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.
313 NSArray *files = nil;
314 if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
315 files = [(NSOpenPanel*)m_pDialog URLs];
317 else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
318 files = [NSArray arrayWithObjects:[m_pDialog URL], nil];
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)
328 NSURL *url = [files objectAtIndex:nIndex];
329 OSL_TRACE("handling %s", [[url description] UTF8String]);
330 InfoType info = FULLPATH;
332 //just get the file's name (only in OpenDialog)
335 OUString sFileOrDirURL = [url OUStringForInfo:info];
337 //get the directory information, only on the first file processed
339 OUString sDirectoryURL = [url OUStringForInfo:PATHWITHOUTLASTCOMPONENT];
342 aSelectedFiles[0] = OUString(sDirectoryURL);
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());
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);
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();
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__);
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 //------------------------------------------------------------------------------------
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
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;
515 case FILEOPEN_SIMPLE:
516 m_nDialogType = NAVIGATIONSERVICES_OPEN;
517 OSL_TRACE( "Template: FILEOPEN_SIMPLE" );
519 case FILESAVE_SIMPLE:
520 m_nDialogType = NAVIGATIONSERVICES_SAVE;
521 OSL_TRACE( "Template: FILESAVE_SIMPLE" );
523 case FILESAVE_AUTOEXTENSION_PASSWORD:
524 m_nDialogType = NAVIGATIONSERVICES_SAVE;
525 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD" );
527 case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
528 m_nDialogType = NAVIGATIONSERVICES_SAVE;
529 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS" );
531 case FILESAVE_AUTOEXTENSION_SELECTION:
532 m_nDialogType = NAVIGATIONSERVICES_SAVE;
533 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_SELECTION" );
535 case FILESAVE_AUTOEXTENSION_TEMPLATE:
536 m_nDialogType = NAVIGATIONSERVICES_SAVE;
537 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_TEMPLATE" );
539 case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
540 m_nDialogType = NAVIGATIONSERVICES_OPEN;
541 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE" );
544 m_nDialogType = NAVIGATIONSERVICES_OPEN;
545 OSL_TRACE( "Template: FILEOPEN_PLAY" );
547 case FILEOPEN_READONLY_VERSION:
548 m_nDialogType = NAVIGATIONSERVICES_OPEN;
549 OSL_TRACE( "Template: FILEOPEN_READONLY_VERSION" );
551 case FILEOPEN_LINK_PREVIEW:
552 m_nDialogType = NAVIGATIONSERVICES_OPEN;
553 OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW" );
555 case FILESAVE_AUTOEXTENSION:
556 m_nDialogType = NAVIGATIONSERVICES_SAVE;
557 OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION" );
560 throw lang::IllegalArgumentException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Unknown template" )),
561 static_cast< XFilePicker* >( this ),
565 m_pControlHelper->initialize(templateId);
569 DBG_PRINT_EXIT(CLASS_NAME, __func__);
572 #pragma mark XCancellable
573 //------------------------------------------------------------------------------------
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];
587 DBG_PRINT_EXIT(CLASS_NAME, __func__);
590 #pragma mark XEventListener
591 //------------------------------------------------
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 // -------------------------------------------------
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);
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) {
642 DBG_PRINT_EXIT(CLASS_NAME, __func__);
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]; \
696 #define MAP_BUTTON( elem ) \
697 case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
698 pWidget = m_pButtons[elem]; \
701 #define MAP_LIST( elem ) \
702 case ExtendedFilePickerElementIds::LISTBOX_##elem: \
703 pWidget = m_pListControls[elem]; if (isAList != NULL) *isAList = sal_True; \
706 #define MAP_LIST_LABEL( elem ) \
707 case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
708 pWidget = m_pListControls[elem]; \
711 //--------------------------------------------------
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];
725 DBG_PRINT_EXIT(CLASS_NAME, __func__);
728 void SalAquaFilePicker::implInitialize()
730 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
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) {
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];
763 ensureFilterHelper();
765 OUStringList aStringList = m_pFilterHelper->getCurrentFilterSuffixList();
766 if( aStringList.empty()) // #i9328#
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"
776 [m_pDialog setRequiredFileType:requiredFileType];
777 #if defined(LIBO_WERROR) && defined(__clang__) && MACOSX_SDK_VERSION >= 1070
778 #pragma GCC diagnostic pop
781 OSL_TRACE("disallowing other file types");
782 [m_pDialog setAllowsOtherFileTypes:NO];
785 DBG_PRINT_EXIT(CLASS_NAME, __func__);
788 void SalAquaFilePicker::filterControlChanged() {
789 DBG_PRINT_ENTRY(CLASS_NAME, __func__);
791 if (m_pDialog == nil) {
795 SolarMutexGuard aGuard;
797 updateSaveFileNameExtension();
799 [m_pDialog validateVisibleColumns];
802 evt.ElementId = LISTBOX_FILTER;
803 controlStateChanged( evt );
805 DBG_PRINT_EXIT(CLASS_NAME, __func__);
808 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */