summaryrefslogtreecommitdiff
path: root/fpicker/source/aqua
diff options
context:
space:
mode:
Diffstat (limited to 'fpicker/source/aqua')
-rw-r--r--fpicker/source/aqua/AquaFilePickerDelegate.hxx60
-rw-r--r--fpicker/source/aqua/AquaFilePickerDelegate.mm126
-rw-r--r--fpicker/source/aqua/CFStringUtilities.cxx124
-rw-r--r--fpicker/source/aqua/CFStringUtilities.hxx164
-rw-r--r--fpicker/source/aqua/ControlHelper.cxx1022
-rw-r--r--fpicker/source/aqua/ControlHelper.hxx198
-rw-r--r--fpicker/source/aqua/FPServiceInfo.hxx53
-rw-r--r--fpicker/source/aqua/FPentry.cxx174
-rw-r--r--fpicker/source/aqua/FilterHelper.cxx543
-rw-r--r--fpicker/source/aqua/FilterHelper.hxx163
-rw-r--r--fpicker/source/aqua/NSString_OOoAdditions.hxx47
-rw-r--r--fpicker/source/aqua/NSString_OOoAdditions.mm80
-rw-r--r--fpicker/source/aqua/NSURL_OOoAdditions.hxx46
-rw-r--r--fpicker/source/aqua/NSURL_OOoAdditions.mm85
-rw-r--r--fpicker/source/aqua/SalAquaConstants.h66
-rw-r--r--fpicker/source/aqua/SalAquaFilePicker.cxx815
-rw-r--r--fpicker/source/aqua/SalAquaFilePicker.hxx255
-rw-r--r--fpicker/source/aqua/SalAquaFolderPicker.cxx292
-rw-r--r--fpicker/source/aqua/SalAquaFolderPicker.hxx141
-rw-r--r--fpicker/source/aqua/SalAquaPicker.cxx267
-rw-r--r--fpicker/source/aqua/SalAquaPicker.hxx109
-rw-r--r--fpicker/source/aqua/exports.map8
-rw-r--r--fpicker/source/aqua/fps-aqua-ucd.txt13
-rw-r--r--fpicker/source/aqua/fps_aqua.xml78
-rw-r--r--fpicker/source/aqua/makefile.mk89
-rw-r--r--fpicker/source/aqua/resourceprovider.cxx243
-rw-r--r--fpicker/source/aqua/resourceprovider.hxx70
27 files changed, 5331 insertions, 0 deletions
diff --git a/fpicker/source/aqua/AquaFilePickerDelegate.hxx b/fpicker/source/aqua/AquaFilePickerDelegate.hxx
new file mode 100644
index 000000000000..6e5afc8bb5cc
--- /dev/null
+++ b/fpicker/source/aqua/AquaFilePickerDelegate.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AquaFilePickerDelegate.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _AQUAFILEPICKERDELEGATE_HXX_
+#define _AQUAFILEPICKERDELEGATE_HXX_
+
+#include <premac.h>
+#include <Cocoa/Cocoa.h>
+#include <postmac.h>
+
+class SalAquaFilePicker;
+class FilterHelper;
+
+@interface AquaFilePickerDelegate : NSObject
+{
+ SalAquaFilePicker* filePicker;
+ FilterHelper* filterHelper;
+}
+
+- (id)initWithFilePicker:(SalAquaFilePicker*)fPicker;
+
+- (void)setFilterHelper:(FilterHelper*)filterHelper;
+
+- (MacOSBOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
+- (void)panelSelectionDidChange:(id)sender;
+- (void)panel:(id)sender directoryDidChange:(NSString *)path;
+
+- (void)filterSelectedAtIndex:(id)sender;
+- (void)autoextensionChanged:(id)sender;
+
+@end
+
+#endif
diff --git a/fpicker/source/aqua/AquaFilePickerDelegate.mm b/fpicker/source/aqua/AquaFilePickerDelegate.mm
new file mode 100644
index 000000000000..d73e5d82ff16
--- /dev/null
+++ b/fpicker/source/aqua/AquaFilePickerDelegate.mm
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AquaFilePickerDelegate.mm,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/uno/Any.hxx>
+
+#ifndef _SALAQUAFILEPICKER_HXX_
+#include "SalAquaFilePicker.hxx"
+#endif
+
+#ifndef _FILTERHELPER_HXX_
+#include "FilterHelper.hxx"
+#endif
+
+#include "AquaFilePickerDelegate.hxx"
+
+@implementation AquaFilePickerDelegate
+
+- (id)initWithFilePicker:(SalAquaFilePicker*)fPicker
+{
+ if ((self = [super init])) {
+ filePicker = fPicker;
+ filterHelper = NULL;
+ return self;
+ }
+ return nil;
+}
+
+- (void)setFilterHelper:(FilterHelper*)helper
+{
+ filterHelper = helper;
+}
+
+#pragma mark NSSavePanel delegate methods
+
+- (MacOSBOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
+{
+ if( filterHelper == NULL )
+ return true;
+ if( filename == nil )
+ return false;
+ return filterHelper->filenameMatchesFilter(filename);
+}
+
+- (void)panelSelectionDidChange:(id)sender
+{
+ if (filePicker != NULL) {
+ ::com::sun::star::ui::dialogs::FilePickerEvent evt;
+ filePicker->fileSelectionChanged(evt);
+ }
+}
+
+- (void)panel:(id)sender directoryDidChange:(NSString *)path
+{
+ if (filePicker != NULL) {
+ ::com::sun::star::ui::dialogs::FilePickerEvent evt;
+ filePicker->directoryChanged(evt);
+ }
+}
+
+
+#pragma mark UIActions
+- (void)filterSelectedAtIndex:(id)sender
+{
+ if (sender == nil) {
+ return;
+ }
+
+ if ([sender class] != [NSPopUpButton class]) {
+ return;
+ }
+
+ if (filterHelper == NULL) {
+ return;
+ }
+
+ NSPopUpButton *popup = (NSPopUpButton*)sender;
+ unsigned int selectedIndex = [popup indexOfSelectedItem];
+
+ filterHelper->SetFilterAtIndex(selectedIndex);
+
+ filePicker->filterControlChanged();
+}
+
+- (void)autoextensionChanged:(id)sender
+{
+ if (sender == nil) {
+ return;
+ }
+
+ if ([sender class] != [NSButton class]) {
+ return;
+ }
+ uno::Any aValue;
+ aValue <<= ([((NSButton*)sender) state] == NSOnState);
+
+ filePicker->setValue(::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, 0, aValue);
+}
+
+@end
diff --git a/fpicker/source/aqua/CFStringUtilities.cxx b/fpicker/source/aqua/CFStringUtilities.cxx
new file mode 100644
index 000000000000..be752f3bda38
--- /dev/null
+++ b/fpicker/source/aqua/CFStringUtilities.cxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: CFStringUtilities.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <osl/diagnose.h>
+#include "CFStringUtilities.hxx"
+
+rtl::OUString CFStringToOUString(const CFStringRef sOrig) {
+ //DBG_PRINT_ENTRY("CFStringUtilities", __func__, "sOrig", sOrig);
+
+ if (NULL == sOrig) {
+ return rtl::OUString();
+ }
+
+ CFRetain(sOrig);
+ CFIndex nFileNameLength = CFStringGetLength(sOrig);
+ //OSL_TRACE("FH: string length: %d", (int)(nFileNameLength));
+ UniChar unichars[nFileNameLength+1];
+ //'close' the string buffer correctly
+ unichars[nFileNameLength] = '\0';
+
+ CFStringGetCharacters (sOrig, CFRangeMake(0,nFileNameLength), unichars);
+
+ //we no longer need the original string
+ CFRelease(sOrig);
+
+ //DBG_PRINT_EXIT("CFStringUtilities", __func__, unichars);
+
+ return rtl::OUString(unichars);
+}
+
+CFStringRef CFStringCreateWithOUString(const rtl::OUString& aString) {
+ //DBG_PRINT_ENTRY("CFStringUtilities", __func__);
+
+ CFStringRef ref = CFStringCreateWithCharacters(kCFAllocatorDefault, aString.getStr(), aString.getLength());
+
+ //DBG_PRINT_EXIT("CFStringUtilities", __func__, ref);
+
+ return ref;
+}
+
+rtl::OUString FSRefToOUString(FSRef fsRef, InfoType info)
+{
+ //DBG_PRINT_ENTRY("CFStringUtilities", __func__);
+
+ CFURLRef aUrlRef = CFURLCreateFromFSRef(NULL, &fsRef);
+
+ rtl::OUString sResult = CFURLRefToOUString(aUrlRef, info);
+
+ //we no longer need the CFURLRef
+ CFRelease(aUrlRef);
+
+ //DBG_PRINT_EXIT("CFStringUtilities", __func__, OUStringToOString(sResult, RTL_TEXTENCODING_UTF8).getStr());
+
+ return sResult;
+}
+
+rtl::OUString CFURLRefToOUString(CFURLRef aUrlRef, InfoType info)
+{
+ //DBG_PRINT_ENTRY("CFStringUtilities", __func__);
+
+ CFStringRef sURLString = NULL;
+
+ switch(info) {
+ case FULLPATH:
+ OSL_TRACE("Extracting the full path of an item");
+ sURLString = CFURLGetString(aUrlRef);
+ CFRetain(sURLString);
+ break;
+ case FILENAME:
+ OSL_TRACE("Extracting the file name of an item");
+ CFStringRef fullString = CFURLGetString(aUrlRef);
+ CFURLRef dirRef = CFURLCreateCopyDeletingLastPathComponent(NULL,aUrlRef);
+ CFIndex dirLength = CFStringGetLength(CFURLGetString(dirRef));
+ CFRelease(dirRef);
+ CFIndex fullLength = CFStringGetLength(fullString);
+ CFRange substringRange = CFRangeMake(dirLength, fullLength - dirLength);
+ sURLString = CFStringCreateWithSubstring(NULL, fullString, substringRange);
+ break;
+ case PATHWITHOUTLASTCOMPONENT:
+ OSL_TRACE("Extracting the last but one component of an item's path");
+ CFURLRef directoryRef = CFURLCreateCopyDeletingLastPathComponent(NULL,aUrlRef);
+ sURLString = CFURLGetString(directoryRef);
+ CFRetain(sURLString);
+ CFRelease(directoryRef);
+ break;
+ default:
+ break;
+ }
+
+ rtl::OUString sResult = CFStringToOUString(sURLString);
+
+ CFRelease(sURLString);
+
+ //DBG_PRINT_EXIT("CFStringUtilities", __func__, OUStringToOString(sResult, RTL_TEXTENCODING_UTF8).getStr());
+
+ return sResult;
+}
diff --git a/fpicker/source/aqua/CFStringUtilities.hxx b/fpicker/source/aqua/CFStringUtilities.hxx
new file mode 100644
index 000000000000..e08ea10e56a5
--- /dev/null
+++ b/fpicker/source/aqua/CFStringUtilities.hxx
@@ -0,0 +1,164 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: CFStringUtilities.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CFSTRINGUTILITIES_HXX_
+#define _CFSTRINGUTILITIES_HXX_
+
+#include <premac.h>
+#include <Carbon/Carbon.h>
+#include <Cocoa/Cocoa.h>
+#include <postmac.h>
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+#include <osl/diagnose.h>
+
+enum InfoType {
+ FULLPATH,
+ FILENAME,
+ PATHWITHOUTLASTCOMPONENT
+};
+
+rtl::OUString CFStringToOUString(const CFStringRef sOrig);
+rtl::OUString FSRefToOUString(FSRef fsRef, InfoType info = FULLPATH);
+rtl::OUString CFURLRefToOUString(CFURLRef aUrlRef, InfoType info);
+CFStringRef CFStringCreateWithOUString(const rtl::OUString& aString);
+
+//debug utils
+#define PARAMFILLER "\n "
+
+inline void DBG_PRINT_ENTRY() {
+ OSL_TRACE(">>> %s", __func__);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname) {
+ OSL_TRACE(">>> %s::%s", classname, methodname);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const char* value1) {
+ OSL_TRACE(">>> %s::%s%s%s = %s", classname, methodname, PARAMFILLER, param1, value1);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const rtl::OUString& value1) {
+ OSL_TRACE(">>> %s::%s%s%s = %s", classname, methodname, PARAMFILLER, param1, OUStringToOString(value1, RTL_TEXTENCODING_UTF8).getStr());
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const CFStringRef value1) {
+ OSL_TRACE(">>> %s::%s%s%s =", classname, methodname, PARAMFILLER, param1);
+#if OSL_DEBUG_LEVEL > 1
+ CFShow(value1);
+#endif
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const NSString* value1) {
+ OSL_TRACE(">>> %s::%s%s%s =", classname, methodname, PARAMFILLER, param1);
+#if OSL_DEBUG_LEVEL > 1
+ NSLog(value1);
+#endif
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const int value1) {
+ OSL_TRACE(">>> %s::%s%s%s = %d", classname, methodname, PARAMFILLER, param1, value1);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const char* value1, const char* param2, const int value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %s%s%s = %d", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const char* value1, const char* param2, const char* value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %s%s%s = %s", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const int value1, const char* param2, const int value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %d%s%s = %d", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const int value1, const char* param2, const char* value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %d%s%s = %s", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const int value1, const char* param2, const CFStringRef value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %d%s%s =", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+#if OSL_DEBUG_LEVEL > 1
+ CFShow(value2);
+#endif
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const int value1, const char* param2, const NSString* value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %d%s%s =", classname, methodname, PARAMFILLER, param1, value1, PARAMFILLER, param2, value2);
+#if OSL_DEBUG_LEVEL > 1
+ NSLog(value2);
+#endif
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const rtl::OUString& value1, const char* param2, const rtl::OUString& value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %s%s%s = %s", classname, methodname, PARAMFILLER, param1, OUStringToOString(value1, RTL_TEXTENCODING_UTF8).getStr(), PARAMFILLER, param2, OUStringToOString(value2, RTL_TEXTENCODING_UTF8).getStr());
+}
+
+inline void DBG_PRINT_ENTRY(const char * classname, const char * methodname, const char* param1, const rtl::OUString& value1, const char* param2, const int value2) {
+ OSL_TRACE(">>> %s::%s%s%s = %s%s%s = %d", classname, methodname, PARAMFILLER, param1, OUStringToOString(value1, RTL_TEXTENCODING_UTF8).getStr(), PARAMFILLER, param2, value2);
+}
+
+//exit method debugs
+
+inline void DBG_PRINT_EXIT() {
+ OSL_TRACE("<<< %s", __func__);
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname) {
+ OSL_TRACE("<<< %s::%s", classname, methodname);
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname, const char* retVal) {
+ OSL_TRACE("<<< %s::%s%sreturnValue = %s", classname, methodname, PARAMFILLER, retVal);
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname, int retVal) {
+ OSL_TRACE("<<< %s::%s%sreturnValue = %d", classname, methodname, PARAMFILLER, retVal);
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname, const CFStringRef retVal) {
+ OSL_TRACE("<<< %s::%s%sreturnValue = ", classname, methodname, PARAMFILLER);
+#if OSL_DEBUG_LEVEL > 1
+ CFShow(retVal);
+#endif
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname, const NSString* retVal) {
+ OSL_TRACE("<<< %s::%s%sreturnValue = ", classname, methodname, PARAMFILLER);
+#if OSL_DEBUG_LEVEL > 1
+ NSLog(retVal);
+#endif
+}
+
+inline void DBG_PRINT_EXIT(const char * classname, const char * methodname, const rtl::OUString& retVal) {
+ OSL_TRACE("<<< %s::%s%sreturnValue = %s", classname, methodname, PARAMFILLER, OUStringToOString(retVal, RTL_TEXTENCODING_UTF8).getStr());
+}
+
+#endif //_CFSTRINGUTILITIES_HXX_
diff --git a/fpicker/source/aqua/ControlHelper.cxx b/fpicker/source/aqua/ControlHelper.cxx
new file mode 100644
index 000000000000..4ff3d1c33835
--- /dev/null
+++ b/fpicker/source/aqua/ControlHelper.cxx
@@ -0,0 +1,1022 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ControlHelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ControlActions.hpp>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include "CFStringUtilities.hxx"
+#include "resourceprovider.hxx"
+#include "NSString_OOoAdditions.hxx"
+
+#include "ControlHelper.hxx"
+
+#pragma mark DEFINES
+#define CLASS_NAME "ControlHelper"
+#define POPUP_WIDTH_MIN 200
+#define POPUP_WIDTH_MAX 350
+
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+using namespace ::rtl;
+
+#pragma mark Constructor / Destructor
+//------------------------------------------------------------------------------------
+// Constructor / Destructor
+//------------------------------------------------------------------------------------
+ControlHelper::ControlHelper()
+: m_pUserPane(NULL)
+, m_pFilterControl(nil)
+, m_bUserPaneNeeded( false )
+, m_bIsUserPaneLaidOut(false)
+, m_bIsFilterControlNeeded(false)
+, m_pFilterHelper(NULL)
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ int i;
+
+ for( i = 0; i < TOGGLE_LAST; i++ ) {
+ m_bToggleVisibility[i] = false;
+ }
+
+ for( i = 0; i < LIST_LAST; i++ ) {
+ m_bListVisibility[i] = false;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+ControlHelper::~ControlHelper()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ if (NULL != m_pUserPane) {
+ [m_pUserPane release];
+ }
+
+ for(std::list<NSControl *>::iterator control = m_aActiveControls.begin(); control != m_aActiveControls.end(); control++) {
+ NSControl* pControl = (*control);
+ NSString* sLabelName = m_aMapListLabels[pControl];
+ if (sLabelName != nil) {
+ [sLabelName release];
+ }
+ if ([pControl class] == [NSPopUpButton class]) {
+ NSTextField* pField = m_aMapListLabelFields[(NSPopUpButton*)pControl];
+ if (pField != nil) {
+ [pField release];
+ }
+ }
+ [pControl release];
+ }
+
+ if (m_pFilterControl != NULL) {
+ [m_pFilterControl setTarget:nil];
+ }
+
+ [pool release];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XInitialization delegate
+//------------------------------------------------
+// XInitialization delegate
+//------------------------------------------------
+void ControlHelper::initialize( sal_Int16 nTemplateId )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "templateId", nTemplateId);
+
+ switch( nTemplateId )
+ {
+ case FILESAVE_AUTOEXTENSION_PASSWORD:
+ m_bToggleVisibility[AUTOEXTENSION] = true;
+ m_bToggleVisibility[PASSWORD] = true;
+ break;
+ case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
+ m_bToggleVisibility[AUTOEXTENSION] = true;
+ m_bToggleVisibility[PASSWORD] = true;
+ m_bToggleVisibility[FILTEROPTIONS] = true;
+ break;
+ case FILESAVE_AUTOEXTENSION_SELECTION:
+ m_bToggleVisibility[AUTOEXTENSION] = true;
+ m_bToggleVisibility[SELECTION] = true;
+ break;
+ case FILESAVE_AUTOEXTENSION_TEMPLATE:
+ m_bToggleVisibility[AUTOEXTENSION] = true;
+ m_bListVisibility[TEMPLATE] = true;
+ break;
+ case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
+ m_bToggleVisibility[LINK] = true;
+ m_bToggleVisibility[PREVIEW] = true;
+ m_bListVisibility[IMAGE_TEMPLATE] = true;
+ break;
+ case FILEOPEN_READONLY_VERSION:
+ m_bToggleVisibility[READONLY] = true;
+ m_bListVisibility[VERSION] = true;
+ break;
+ case FILEOPEN_LINK_PREVIEW:
+ m_bToggleVisibility[LINK] = true;
+ m_bToggleVisibility[PREVIEW] = true;
+ break;
+ case FILESAVE_AUTOEXTENSION:
+ m_bToggleVisibility[AUTOEXTENSION] = true;
+ break;
+ }
+
+ createControls();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XFilePickerControlAccess delegates
+//------------------------------------------------------------------------------------
+// XFilePickerControlAccess functions
+//------------------------------------------------------------------------------------
+
+void ControlHelper::enableControl( const sal_Int16 nControlId, const sal_Bool bEnable ) const
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "enable", bEnable);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_PREVIEW) {
+ OSL_TRACE(" preview checkbox cannot be changed");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ NSControl* pControl = getControl(nControlId);
+
+ if( pControl != nil ) {
+ if( bEnable ) {
+ OSL_TRACE( "enable" );
+ } else {
+ OSL_TRACE( "disable" );
+ }
+ [pControl setEnabled:bEnable];
+ } else {
+ OSL_TRACE("enable unknown control %d", nControlId );
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+OUString ControlHelper::getLabel( sal_Int16 nControlId )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSControl* pControl = getControl( nControlId );
+
+ if( pControl == nil ) {
+ OSL_TRACE("Get label for unknown control %d", nControlId);
+ return OUString();
+ }
+
+ rtl::OUString retVal;
+ if ([pControl class] == [NSPopUpButton class]) {
+ NSString *temp = m_aMapListLabels[pControl];
+ if (temp != nil)
+ retVal = [temp OUString];
+ }
+ else {
+ NSString* sLabel = [[pControl cell] title];
+ retVal = [sLabel OUString];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+
+ return retVal;
+}
+
+void ControlHelper::setLabel( sal_Int16 nControlId, const NSString* aLabel )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "label", aLabel);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ NSControl* pControl = getControl(nControlId);
+
+ if (nil != pControl) {
+ if ([pControl class] == [NSPopUpButton class]) {
+ NSString *sOldName = m_aMapListLabels[pControl];
+ if (sOldName != NULL && sOldName != aLabel) {
+ [sOldName release];
+ }
+
+ m_aMapListLabels[pControl] = [aLabel retain];
+ } else if ([pControl class] == [NSButton class]) {
+ [[pControl cell] setTitle:aLabel];
+ }
+ } else {
+ OSL_TRACE("Control not found to set label for");
+ }
+
+ layoutControls();
+
+ [pool release];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void ControlHelper::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "controlAction", nControlAction);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_PREVIEW) {
+ OSL_TRACE(" value for preview is unchangeable");
+ }
+ else {
+ NSControl* pControl = getControl( nControlId );
+
+ if( pControl == nil ) {
+ OSL_TRACE("enable unknown control %d", nControlId);
+ } else {
+ if( [pControl class] == [NSPopUpButton class] ) {
+ HandleSetListValue(pControl, nControlAction, rValue);
+ } else if( [pControl class] == [NSButton class] ) {
+ sal_Bool bChecked = false;
+ rValue >>= bChecked;
+ OSL_TRACE(" value is a bool: %d", bChecked);
+ [(NSButton*)pControl setState:(bChecked ? NSOnState : NSOffState)];
+ } else
+ {
+ OSL_TRACE("Can't set value on button / list %d %d",
+ nControlId, nControlAction);
+ }
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+uno::Any ControlHelper::getValue( sal_Int16 nControlId, sal_Int16 nControlAction ) const
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId, "controlAction", nControlAction);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ uno::Any aRetval;
+
+ NSControl* pControl = getControl( nControlId );
+
+ if( pControl == nil ) {
+ OSL_TRACE("get value for unknown control %d", nControlId);
+ aRetval <<= sal_True;
+ } else {
+ if( [pControl class] == [NSPopUpButton class] ) {
+ aRetval = HandleGetListValue(pControl, nControlAction);
+ } else if( [pControl class] == [NSButton class] ) {
+ //NSLog(@"control: %@", [[pControl cell] title]);
+ sal_Bool bValue = [(NSButton*)pControl state] == NSOnState ? sal_True : sal_False;
+ aRetval <<= bValue;
+ OSL_TRACE("value is a bool (checkbox): %d", bValue);
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return aRetval;
+}
+
+void ControlHelper::createUserPane()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (m_bUserPaneNeeded == false) {
+ OSL_TRACE("no user pane needed");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ if (nil != m_pUserPane) {
+ OSL_TRACE("user pane already exists");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ if (m_bIsFilterControlNeeded == true && m_pFilterControl == nil) {
+ createFilterControl();
+ }
+
+ NSRect minRect = NSMakeRect(0,0,300,33);
+ m_pUserPane = [[NSView alloc] initWithFrame:minRect];
+
+ int currentHeight = kAquaSpaceBoxFrameViewDiffTop + kAquaSpaceBoxFrameViewDiffBottom;
+ int currentWidth = 300;
+
+ BOOL bPopupControlPresent = NO;
+ BOOL bButtonControlPresent = NO;
+
+ int nCheckboxMaxWidth = 0;
+ int nPopupMaxWidth = 0;
+ int nPopupLabelMaxWidth = 0;
+
+ for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
+ OSL_TRACE("currentHeight: %d", currentHeight);
+
+ NSControl* pControl = *child;
+
+ //let the control calculate its size
+ [pControl sizeToFit];
+
+ NSRect frame = [pControl frame];
+ OSL_TRACE("frame for control %s is {%f, %f, %f, %f}", [[pControl description] UTF8String], frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
+
+ int nControlHeight = frame.size.height;
+ int nControlWidth = frame.size.width;
+
+ // Note: controls are grouped by kind, first all popup menus, then checkboxes
+ if ([pControl class] == [NSPopUpButton class]) {
+ if (bPopupControlPresent == YES) {
+ //this is not the first popup
+ currentHeight += kAquaSpaceBetweenPopupMenus;
+ }
+ else if (child != m_aActiveControls.begin()){
+ currentHeight += kAquaSpaceBetweenControls;
+ }
+
+ bPopupControlPresent = YES;
+
+ // we have to add the label text width
+ NSString *label = m_aMapListLabels[pControl];
+
+ NSTextField *textField = createLabelWithString(label);
+ [textField sizeToFit];
+ m_aMapListLabelFields[(NSPopUpButton*)pControl] = textField;
+ [m_pUserPane addSubview:textField];
+
+ NSRect tfRect = [textField frame];
+ OSL_TRACE("frame for textfield %s is {%f, %f, %f, %f}", [[textField description] UTF8String], tfRect.origin.x, tfRect.origin.y, tfRect.size.width, tfRect.size.height);
+
+ int tfWidth = tfRect.size.width;
+
+ if (nPopupLabelMaxWidth < tfWidth) {
+ nPopupLabelMaxWidth = tfWidth;
+ }
+
+ frame.origin.x += (kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft) + tfWidth;
+
+ if (nControlWidth < POPUP_WIDTH_MIN) {
+ nControlWidth = POPUP_WIDTH_MIN;
+ frame.size.width = nControlWidth;
+ [pControl setFrame:frame];
+ }
+
+ if (nControlWidth > POPUP_WIDTH_MAX) {
+ nControlWidth = POPUP_WIDTH_MAX;
+ frame.size.width = nControlWidth;
+ [pControl setFrame:frame];
+ }
+
+ //set the max size
+ if (nPopupMaxWidth < nControlWidth) {
+ nPopupMaxWidth = nControlWidth;
+ }
+
+ nControlWidth += tfWidth + kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft;
+ if (nControlHeight < kAquaPopupButtonDefaultHeight) {
+ //maybe the popup has no menu item yet, so set a default height
+ nControlHeight = kAquaPopupButtonDefaultHeight;
+ }
+
+ nControlHeight -= kAquaSpacePopupMenuFrameBoundsDiffV;
+ }
+ else if ([pControl class] == [NSButton class]) {
+ if (child != m_aActiveControls.begin()){
+ currentHeight += kAquaSpaceBetweenControls;
+ }
+
+ if (nCheckboxMaxWidth < nControlWidth) {
+ nCheckboxMaxWidth = nControlWidth;
+ }
+
+ bButtonControlPresent = YES;
+ nControlWidth -= 2 * kAquaSpaceSwitchButtonFrameBoundsDiff;
+ nControlHeight -= 2 * kAquaSpaceSwitchButtonFrameBoundsDiff;
+ }
+
+ // if ((nControlWidth + 2 * kAquaSpaceInsideGroupH) > currentWidth) {
+ // currentWidth = nControlWidth + 2 * kAquaSpaceInsideGroupH;
+ // }
+
+ currentHeight += nControlHeight;
+
+ [m_pUserPane addSubview:pControl];
+ }
+
+ OSL_TRACE("height after adding all controls: %d", currentHeight);
+
+ if (bPopupControlPresent && bButtonControlPresent)
+ {
+ //after a popup button (array) and before a different kind of control we need some extra space instead of the standard
+ currentHeight -= kAquaSpaceBetweenControls;
+ currentHeight += kAquaSpaceAfterPopupButtonsV;
+ OSL_TRACE("popup extra space added, currentHeight: %d", currentHeight);
+ }
+
+ int nLongestPopupWidth = nPopupMaxWidth + nPopupLabelMaxWidth + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
+
+ currentWidth = nLongestPopupWidth > nCheckboxMaxWidth ? nLongestPopupWidth : nCheckboxMaxWidth;
+ OSL_TRACE("longest control width: %d", currentWidth);
+
+ currentWidth += 2* kAquaSpaceInsideGroupH;
+
+ if (currentWidth < minRect.size.width)
+ currentWidth = minRect.size.width;
+
+ if (currentHeight < minRect.size.height)
+ currentHeight = minRect.size.height;
+
+ NSRect upRect = NSMakeRect(0, 0, currentWidth, currentHeight );
+ OSL_TRACE("setting user pane rect to {%f, %f, %f, %f}",upRect.origin.x, upRect.origin.y, upRect.size.width, upRect.size.height);
+
+ [m_pUserPane setFrame:upRect];
+
+ layoutControls();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark Private / Misc
+//------------------------------------------------------------------------------------
+// Private / Misc
+//------------------------------------------------------------------------------------
+void ControlHelper::createControls()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ CResourceProvider aResProvider;
+ for (int i = 0; i < LIST_LAST; i++) {
+ if (true == m_bListVisibility[i]) {
+ m_bUserPaneNeeded = true;
+
+ int elementName = getControlElementName([NSPopUpButton class], i);
+ NSString* sLabel = aResProvider.getResString(elementName);
+
+ m_pListControls[i] = [NSPopUpButton new];
+
+#define MAP_LIST_( elem ) \
+ case elem: \
+ setLabel(ExtendedFilePickerElementIds::LISTBOX_##elem, sLabel); \
+ break
+
+ switch(i) {
+ MAP_LIST_(VERSION);
+ MAP_LIST_(TEMPLATE);
+ MAP_LIST_(IMAGE_TEMPLATE);
+ }
+
+ m_aActiveControls.push_back(m_pListControls[i]);
+ } else {
+ m_pListControls[i] = nil;
+ }
+ }
+
+ for (int i = 0/*#i102102*/; i < TOGGLE_LAST; i++) {
+ if (true == m_bToggleVisibility[i]) {
+ m_bUserPaneNeeded = true;
+
+ int elementName = getControlElementName([NSButton class], i);
+ NSString* sLabel = aResProvider.getResString(elementName);
+
+ NSButton *button = [NSButton new];
+ [button setTitle:sLabel];
+
+ [button setButtonType:NSSwitchButton];
+
+ [button setState:NSOffState];
+
+ if (i == AUTOEXTENSION) {
+ [button setTarget:m_pDelegate];
+ [button setAction:@selector(autoextensionChanged:)];
+ }
+
+ m_pToggles[i] = button;
+
+ m_aActiveControls.push_back(m_pToggles[i]);
+ } else {
+ m_pToggles[i] = nil;
+ }
+ }
+
+ //preview is always on with Mac OS X
+ NSControl *pPreviewBox = m_pToggles[PREVIEW];
+ if (pPreviewBox != nil) {
+ [pPreviewBox setEnabled:NO];
+ [(NSButton*)pPreviewBox setState:NSOnState];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#define TOGGLE_ELEMENT( elem ) \
+case elem: \
+ nReturn = CHECKBOX_##elem; \
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn); \
+ return nReturn
+#define LIST_ELEMENT( elem ) \
+case elem: \
+ nReturn = LISTBOX_##elem##_LABEL; \
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn); \
+ return nReturn
+
+int ControlHelper::getControlElementName(const Class aClazz, const int nControlId) const
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aClazz", [[aClazz description] UTF8String], "controlId", nControlId);
+
+ int nReturn = -1;
+ if (aClazz == [NSButton class])
+ {
+ switch (nControlId) {
+ TOGGLE_ELEMENT( AUTOEXTENSION );
+ TOGGLE_ELEMENT( PASSWORD );
+ TOGGLE_ELEMENT( FILTEROPTIONS );
+ TOGGLE_ELEMENT( READONLY );
+ TOGGLE_ELEMENT( LINK );
+ TOGGLE_ELEMENT( PREVIEW );
+ TOGGLE_ELEMENT( SELECTION );
+ }
+ }
+ else if (aClazz == [NSPopUpButton class])
+ {
+ switch (nControlId) {
+ LIST_ELEMENT( VERSION );
+ LIST_ELEMENT( TEMPLATE );
+ LIST_ELEMENT( IMAGE_TEMPLATE );
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn);
+
+ return nReturn;
+}
+
+void ControlHelper::HandleSetListValue(const NSControl* pControl, const sal_Int16 nControlAction, const uno::Any& rValue)
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlAction", nControlAction);
+
+ if ([pControl class] != [NSPopUpButton class]) {
+ OSL_TRACE("not a popup menu");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ NSPopUpButton *pButton = (NSPopUpButton*)pControl;
+ NSMenu *rMenu = [pButton menu];
+ if (nil == rMenu) {
+ OSL_TRACE("button has no menu");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ switch (nControlAction)
+ {
+ case ControlActions::ADD_ITEM:
+ {
+ OSL_TRACE("ADD_ITEMS");
+ OUString sItem;
+ rValue >>= sItem;
+
+ NSString* sCFItem = [NSString stringWithOUString:sItem];
+ OSL_TRACE("Adding menu item: %s", OUStringToOString(sItem, RTL_TEXTENCODING_UTF8).getStr());
+ [pButton addItemWithTitle:sCFItem];
+ }
+ break;
+ case ControlActions::ADD_ITEMS:
+ {
+ OSL_TRACE("ADD_ITEMS");
+ uno::Sequence< OUString > aStringList;
+ rValue >>= aStringList;
+ sal_Int32 nItemCount = aStringList.getLength();
+ for (sal_Int32 i = 0; i < nItemCount; ++i)
+ {
+ NSString* sCFItem = [NSString stringWithOUString:aStringList[i]];
+ OSL_TRACE("Adding menu item: %s", OUStringToOString(aStringList[i], RTL_TEXTENCODING_UTF8).getStr());
+ [pButton addItemWithTitle:sCFItem];
+ }
+ }
+ break;
+ case ControlActions::DELETE_ITEM:
+ {
+ OSL_TRACE("DELETE_ITEM");
+ sal_Int32 nPos = -1;
+ rValue >>= nPos;
+ OSL_TRACE("Deleting item at position %d", (nPos));
+ [rMenu removeItemAtIndex:nPos];
+ }
+ break;
+ case ControlActions::DELETE_ITEMS:
+ {
+ OSL_TRACE("DELETE_ITEMS");
+ int nItems = [rMenu numberOfItems];
+ if (nItems == 0) {
+ OSL_TRACE("no menu items to delete");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+ for(sal_Int32 i = 0; i < nItems; i++) {
+ [rMenu removeItemAtIndex:i];
+ }
+ }
+ break;
+ case ControlActions::SET_SELECT_ITEM:
+ {
+ sal_Int32 nPos = -1;
+ rValue >>= nPos;
+ OSL_TRACE("Selecting item at position %d", nPos);
+ [pButton selectItemAtIndex:nPos];
+ }
+ break;
+ default:
+ OSL_TRACE("undocumented/unimplemented ControlAction for a list");
+ break;
+ }
+
+ layoutControls();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+
+uno::Any ControlHelper::HandleGetListValue(const NSControl* pControl, const sal_Int16 nControlAction) const
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlAction", nControlAction);
+
+ uno::Any aAny;
+
+ if ([pControl class] != [NSPopUpButton class]) {
+ OSL_TRACE("not a popup button");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return aAny;
+ }
+
+ NSPopUpButton *pButton = (NSPopUpButton*)pControl;
+ NSMenu *rMenu = [pButton menu];
+ if (nil == rMenu) {
+ OSL_TRACE("button has no menu");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return aAny;
+ }
+
+ switch (nControlAction)
+ {
+ case ControlActions::GET_ITEMS:
+ {
+ OSL_TRACE("GET_ITEMS");
+ uno::Sequence< OUString > aItemList;
+
+ int nItems = [rMenu numberOfItems];
+ if (nItems > 0) {
+ aItemList.realloc(nItems);
+ }
+ for (int i = 0; i < nItems; i++) {
+ NSString* sCFItem = [pButton itemTitleAtIndex:i];
+ if (nil != sCFItem) {
+ aItemList[i] = [sCFItem OUString];
+ OSL_TRACE("Return value[%d]: %s", (i - 1), OUStringToOString(aItemList[i - 1], RTL_TEXTENCODING_UTF8).getStr());
+ }
+ }
+
+ aAny <<= aItemList;
+ }
+ break;
+ case ControlActions::GET_SELECTED_ITEM:
+ {
+ OSL_TRACE("GET_SELECTED_ITEM");
+ NSString* sCFItem = [pButton titleOfSelectedItem];
+ if (nil != sCFItem) {
+ OUString sString = [sCFItem OUString];
+ OSL_TRACE("Return value: %s", OUStringToOString(sString, RTL_TEXTENCODING_UTF8).getStr());
+ aAny <<= sString;
+ }
+ }
+ break;
+ case ControlActions::GET_SELECTED_ITEM_INDEX:
+ {
+ OSL_TRACE("GET_SELECTED_ITEM_INDEX");
+ sal_Int32 nActive = [pButton indexOfSelectedItem];
+ OSL_TRACE("Return value: %d", nActive);
+ aAny <<= nActive;
+ }
+ break;
+ default:
+ OSL_TRACE("undocumented/unimplemented ControlAction for a list");
+ break;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return aAny;
+}
+
+
+// cf. offapi/com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.idl
+NSControl* ControlHelper::getControl( const sal_Int16 nControlId ) const
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "controlId", nControlId);
+
+ NSControl* pWidget = nil;
+
+#define MAP_TOGGLE( elem ) \
+case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
+ pWidget = m_pToggles[elem]; \
+ break
+
+#define MAP_BUTTON( elem ) \
+case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
+ pWidget = m_pButtons[elem]; \
+ break
+
+#define MAP_LIST( elem ) \
+case ExtendedFilePickerElementIds::LISTBOX_##elem: \
+ pWidget = m_pListControls[elem]; \
+ break
+
+#define MAP_LIST_LABEL( elem ) \
+case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
+ pWidget = m_pListControls[elem]; \
+ break
+
+ switch( nControlId )
+ {
+ MAP_TOGGLE( AUTOEXTENSION );
+ MAP_TOGGLE( PASSWORD );
+ MAP_TOGGLE( FILTEROPTIONS );
+ MAP_TOGGLE( READONLY );
+ MAP_TOGGLE( LINK );
+ MAP_TOGGLE( PREVIEW );
+ MAP_TOGGLE( SELECTION );
+ //MAP_BUTTON( PLAY );
+ MAP_LIST( VERSION );
+ MAP_LIST( TEMPLATE );
+ MAP_LIST( IMAGE_TEMPLATE );
+ MAP_LIST_LABEL( VERSION );
+ MAP_LIST_LABEL( TEMPLATE );
+ MAP_LIST_LABEL( IMAGE_TEMPLATE );
+ default:
+ OSL_TRACE("Handle unknown control %d", nControlId);
+ break;
+ }
+#undef MAP
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return pWidget;
+}
+
+void ControlHelper::layoutControls()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (nil == m_pUserPane) {
+ OSL_TRACE("no user pane to layout");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ if (m_bIsUserPaneLaidOut == true) {
+ OSL_TRACE("user pane already laid out");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ NSRect userPaneRect = [m_pUserPane frame];
+ OSL_TRACE("userPane frame: {%f, %f, %f, %f}",userPaneRect.origin.x, userPaneRect.origin.y, userPaneRect.size.width, userPaneRect.size.height);
+
+ int nUsableWidth = userPaneRect.size.width;
+
+ //NOTE: NSView's coordinate system starts in the lower left hand corner but we start adding controls from the top,
+ // so we subtract from the vertical position as we make our way down the pane.
+ int currenttop = userPaneRect.size.height;
+ int nCheckboxMaxWidth = 0;
+ int nPopupMaxWidth = 0;
+ int nPopupLabelMaxWidth = 0;
+
+ //first loop to determine max sizes
+ for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
+ NSControl* pControl = *child;
+
+ NSRect controlRect = [pControl frame];
+ int nControlWidth = controlRect.size.width;
+
+ Class aSubType = [pControl class];
+ if (aSubType == [NSPopUpButton class]) {
+ if (nPopupMaxWidth < nControlWidth) {
+ nPopupMaxWidth = nControlWidth;
+ }
+ NSTextField *label = m_aMapListLabelFields[(NSPopUpButton*)pControl];
+ NSRect labelFrame = [label frame];
+ int nLabelWidth = labelFrame.size.width;
+ if (nPopupLabelMaxWidth < nLabelWidth) {
+ nPopupLabelMaxWidth = nLabelWidth;
+ }
+ } else {
+ if (nCheckboxMaxWidth < nControlWidth) {
+ nCheckboxMaxWidth = nControlWidth;
+ }
+ }
+ }
+
+ int nLongestPopupWidth = nPopupMaxWidth + nPopupLabelMaxWidth + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
+ OSL_TRACE("longest popup width: %d", nLongestPopupWidth);
+
+ NSControl* previousControl = nil;
+
+ int nDistBetweenControls = 0;
+
+ for (::std::list<NSControl*>::iterator child = m_aActiveControls.begin(); child != m_aActiveControls.end(); child++) {
+ NSControl* pControl = *child;
+
+ //get the control's bounds
+ NSRect controlRect = [pControl frame];
+ int nControlHeight = controlRect.size.height;
+ int nControlWidth = controlRect.size.width;
+
+ //subtract the height from the current vertical position, because the control's bounds origin rect will be its lower left hand corner
+ currenttop -= nControlHeight;
+
+ Class aSubType = [pControl class];
+
+ //add space between the previous control and this control according to Apple's HIG
+ nDistBetweenControls = getVerticalDistance(previousControl, pControl);
+ OSL_TRACE("vertical distance: %d", nDistBetweenControls);
+ currenttop -= nDistBetweenControls;
+
+ previousControl = pControl;
+
+ if (aSubType == [NSPopUpButton class]) {
+ //move vertically up some pixels to space the controls between their real (visual) bounds
+ currenttop += kAquaSpacePopupMenuFrameBoundsDiffTop;//from top
+
+ //get the corresponding popup label
+ NSTextField *label = m_aMapListLabelFields[(NSPopUpButton*)pControl];
+ NSRect labelFrame = [label frame];
+ int totalWidth = nPopupMaxWidth + labelFrame.size.width + kAquaSpaceBetweenControls - kAquaSpacePopupMenuFrameBoundsDiffLeft - kAquaSpaceLabelFrameBoundsDiffH;
+ OSL_TRACE("totalWidth: %d", totalWidth);
+ //let's center popups
+ int left = (nUsableWidth + nLongestPopupWidth) / 2 - totalWidth;
+ OSL_TRACE("left: %d", left);
+ labelFrame.origin.x = left;
+ labelFrame.origin.y = currenttop + kAquaSpaceLabelPopupDiffV;
+ OSL_TRACE("setting label at: {%f, %f, %f, %f}",labelFrame.origin.x, labelFrame.origin.y, labelFrame.size.width, labelFrame.size.height);
+ [label setFrame:labelFrame];
+
+ controlRect.origin.x = left + labelFrame.size.width + kAquaSpaceBetweenControls - kAquaSpaceLabelFrameBoundsDiffH - kAquaSpacePopupMenuFrameBoundsDiffLeft;
+ controlRect.origin.y = currenttop;
+ controlRect.size.width = nPopupMaxWidth;
+ OSL_TRACE("setting popup at: {%f, %f, %f, %f}",controlRect.origin.x, controlRect.origin.y, controlRect.size.width, controlRect.size.height);
+ [pControl setFrame:controlRect];
+
+ //add some space to place the vertical position right below the popup's visual bounds
+ currenttop += kAquaSpacePopupMenuFrameBoundsDiffBottom;
+ } else {
+ currenttop += kAquaSpaceSwitchButtonFrameBoundsDiff;//from top
+
+ nControlWidth = nCheckboxMaxWidth;
+ int left = (nUsableWidth - nCheckboxMaxWidth) / 2;
+ controlRect.origin.x = left;
+ controlRect.origin.y = currenttop;
+ controlRect.size.width = nPopupMaxWidth;
+ [pControl setFrame:controlRect];
+ OSL_TRACE("setting checkbox at: {%f, %f, %f, %f}",controlRect.origin.x, controlRect.origin.y, controlRect.size.width, controlRect.size.height);
+
+ currenttop += kAquaSpaceSwitchButtonFrameBoundsDiff;
+ }
+ }
+
+ m_bIsUserPaneLaidOut = true;
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void ControlHelper::createFilterControl() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ CResourceProvider aResProvider;
+ NSString* sLabel = aResProvider.getResString(CommonFilePickerElementIds::LISTBOX_FILTER_LABEL);
+
+ m_pFilterControl = [NSPopUpButton new];
+
+ [m_pFilterControl setAction:@selector(filterSelectedAtIndex:)];
+ [m_pFilterControl setTarget:m_pDelegate];
+
+ NSMenu *menu = [m_pFilterControl menu];
+
+ for (NSStringList::iterator iter = m_pFilterHelper->getFilterNames()->begin(); iter != m_pFilterHelper->getFilterNames()->end(); iter++) {
+ NSString *filterName = *iter;
+ OSL_TRACE("adding filter name: %s", [filterName UTF8String]);
+ if ([filterName isEqualToString:@"-"]) {
+ [menu addItem:[NSMenuItem separatorItem]];
+ }
+ else {
+ [m_pFilterControl addItemWithTitle:filterName];
+ }
+ }
+
+ // always add the filter as first item
+ m_aActiveControls.push_front(m_pFilterControl);
+ m_aMapListLabels[m_pFilterControl] = [sLabel retain];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+NSTextField* ControlHelper::createLabelWithString(const NSString* labelString) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "label", labelString);
+
+ NSTextField *textField = [NSTextField new];
+ [textField setEditable:NO];
+ [textField setSelectable:NO];
+ [textField setDrawsBackground:NO];
+ [textField setBordered:NO];
+ [[textField cell] setTitle:labelString];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return textField;
+}
+
+int ControlHelper::getVerticalDistance(const NSControl* first, const NSControl* second)
+{
+ if (first == nil) {
+ return kAquaSpaceBoxFrameViewDiffTop;
+ }
+ else if (second == nil) {
+ return kAquaSpaceBoxFrameViewDiffBottom;
+ }
+ else {
+ Class firstClass = [first class];
+ Class secondClass = [second class];
+
+ if (firstClass == [NSPopUpButton class]) {
+ if (secondClass == [NSPopUpButton class]) {
+ return kAquaSpaceBetweenPopupMenus;
+ }
+ else {
+ return kAquaSpaceAfterPopupButtonsV;
+ }
+ }
+
+ return kAquaSpaceBetweenControls;
+ }
+}
+
+void ControlHelper::updateFilterUI()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (m_bIsFilterControlNeeded == false || m_pFilterHelper == NULL) {
+ OSL_TRACE("no filter control needed or no filter helper present");
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return;
+ }
+
+ int index = m_pFilterHelper->getCurrentFilterIndex();
+
+ if (m_pFilterControl == nil) {
+ createFilterControl();
+ }
+
+ [m_pFilterControl selectItemAtIndex:index];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
diff --git a/fpicker/source/aqua/ControlHelper.hxx b/fpicker/source/aqua/ControlHelper.hxx
new file mode 100644
index 000000000000..081377a24dc6
--- /dev/null
+++ b/fpicker/source/aqua/ControlHelper.hxx
@@ -0,0 +1,198 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: ControlHelper.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CONTROLHELPER_HXX_
+#define _CONTROLHELPER_HXX_
+
+#include <rtl/ustring.hxx>
+#include <com/sun/star/uno/Any.hxx>
+
+#include <list>
+#include <map>
+
+#include <premac.h>
+#include <Cocoa/Cocoa.h>
+#include <postmac.h>
+#include "SalAquaConstants.h"
+#include "FilterHelper.hxx"
+#include "AquaFilePickerDelegate.hxx"
+
+using namespace com::sun::star;
+using namespace rtl;
+
+class ControlHelper {
+
+public:
+
+ //------------------------------------------------------------------------------------
+ // Constructor / Destructor
+ //------------------------------------------------------------------------------------
+ ControlHelper();
+ virtual ~ControlHelper();
+
+ //------------------------------------------------
+ // XInitialization delegate
+ //------------------------------------------------
+ void initialize( sal_Int16 templateId );
+
+ //------------------------------------------------------------------------------------
+ // XFilePickerControlAccess function delegates
+ //------------------------------------------------------------------------------------
+ void setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue );
+ uno::Any getValue( sal_Int16 nControlId, sal_Int16 nControlAction ) const;
+ void enableControl( sal_Int16 nControlId, sal_Bool bEnable ) const;
+ OUString getLabel( sal_Int16 nControlId );
+ void setLabel( sal_Int16 nControlId, const NSString* aLabel );
+
+ //------------------------------------------------------------------------------------
+ // other stuff
+ //------------------------------------------------------------------------------------
+ void updateFilterUI();
+
+ //------------------------------------------------------------------------------------
+ // Type definitions
+ //------------------------------------------------------------------------------------
+ enum ToggleType {
+ AUTOEXTENSION, //but autoextension is handled differently on MacOSX
+ PASSWORD,
+ FILTEROPTIONS,
+ READONLY,
+ LINK,
+ PREVIEW,
+ SELECTION,
+ TOGGLE_LAST
+ };
+
+ enum ListType {
+ VERSION,
+ TEMPLATE,
+ IMAGE_TEMPLATE,
+ LIST_LAST
+ };
+
+ //------------------------------------------------------------------------------------
+ // inline functions
+ //------------------------------------------------------------------------------------
+ inline NSView* getUserPane() {
+ if (m_bIsUserPaneLaidOut == false) {
+ createUserPane();
+ }
+ return m_pUserPane;
+ }
+
+ inline bool getVisibility(ToggleType tToggle) {
+ return m_bToggleVisibility[tToggle];
+ }
+
+ inline void setFilterControlNeeded(bool bNeeded) {
+ m_bIsFilterControlNeeded = bNeeded;
+ if (bNeeded == true) {
+ m_bUserPaneNeeded = true;
+ }
+ }
+
+ inline void setFilterHelper(FilterHelper* pFilterHelper) {
+ m_pFilterHelper = pFilterHelper;
+ }
+
+ inline void setFilePickerDelegate(AquaFilePickerDelegate* pDelegate) {
+ m_pDelegate = pDelegate;
+ }
+
+ inline bool isAutoExtensionEnabled() {
+ return ([((NSButton*) m_pToggles[AUTOEXTENSION]) state] == NSOnState);
+ }
+
+private:
+ //------------------------------------------------------------------------------------
+ // private member variables
+ //------------------------------------------------------------------------------------
+
+ /** the native view object */
+ NSView* m_pUserPane;
+
+ /** the checkbox controls */
+ NSControl* m_pToggles[ TOGGLE_LAST ];
+
+ /** the visibility flags for the checkboxes */
+ bool m_bToggleVisibility[TOGGLE_LAST];
+
+ /** the special filter control */
+ NSPopUpButton *m_pFilterControl;
+
+ /** the popup menu controls (except for the filter control) */
+ NSControl* m_pListControls[ LIST_LAST ];
+
+ /** a map to store a control's label text */
+ ::std::map<NSControl *, NSString *> m_aMapListLabels;
+
+ /** a map to store a popup menu's label text field */
+ ::std::map<NSPopUpButton *, NSTextField *> m_aMapListLabelFields;
+
+ /** the visibility flags for the popup menus */
+ bool m_bListVisibility[ LIST_LAST ];
+
+ /** indicates if a user pane is needed */
+ bool m_bUserPaneNeeded;
+
+ /** indicates if the user pane was laid out already */
+ bool m_bIsUserPaneLaidOut;
+
+ /** indicates if a filter control is needed */
+ bool m_bIsFilterControlNeeded;
+
+ /** a list with all actively used controls */
+ ::std::list<NSControl*> m_aActiveControls;
+
+ /** the filter helper */
+ FilterHelper *m_pFilterHelper;
+
+ /** the save or open panel's delegate */
+ AquaFilePickerDelegate *m_pDelegate;
+
+ //------------------------------------------------------------------------------------
+ // private methods
+ //------------------------------------------------------------------------------------
+ void HandleSetListValue(const NSControl* pControl, const sal_Int16 nControlAction, const uno::Any& rValue);
+ uno::Any HandleGetListValue(const NSControl* pControl, const sal_Int16 nControlAction) const;
+
+ void createControls();
+ void createFilterControl();
+ void createUserPane();
+ NSTextField* createLabelWithString(const NSString* label);
+
+ int getControlElementName(const Class clazz, const int nControlId) const;
+ NSControl* getControl( const sal_Int16 nControlId ) const;
+ static int getVerticalDistance(const NSControl* first, const NSControl* second);
+
+ void layoutControls();
+};
+
+#endif //_CONTROLHELPER_HXX_
diff --git a/fpicker/source/aqua/FPServiceInfo.hxx b/fpicker/source/aqua/FPServiceInfo.hxx
new file mode 100644
index 000000000000..83d0abc9b50e
--- /dev/null
+++ b/fpicker/source/aqua/FPServiceInfo.hxx
@@ -0,0 +1,53 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FPServiceInfo.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FPSERVICEINFO_HXX_
+#define _FPSERVICEINFO_HXX_
+
+//------------------------------------------------------------------------
+// defines
+//------------------------------------------------------------------------
+
+// the service names
+#define FILE_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.AquaFilePicker"
+#define FOLDER_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.AquaFolderPicker"
+
+// the implementation names
+#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.SalAquaFilePicker"
+#define FOLDER_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.SalAquaFolderPicker"
+
+// the registry key names
+// a key under which this service will be registered,
+// Format: -> "/ImplName/UNO/SERVICES/ServiceName"
+// <Implementation-Name></UNO/SERVICES/><Service-Name>
+#define FILE_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.SalAquaFilePicker/UNO/SERVICES/com.sun.star.ui.dialogs.AquaFilePicker"
+#define FOLDER_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.SalAquaFolderPicker/UNO/SERVICES/com.sun.star.ui.dialogs.AquaFolderPicker"
+
+#endif
diff --git a/fpicker/source/aqua/FPentry.cxx b/fpicker/source/aqua/FPentry.cxx
new file mode 100644
index 000000000000..b29617f49237
--- /dev/null
+++ b/fpicker/source/aqua/FPentry.cxx
@@ -0,0 +1,174 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FPentry.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//----------------------------------------------
+// includes of other projects
+//----------------------------------------------
+
+#include <cppuhelper/factory.hxx>
+#include <com/sun/star/container/XSet.hpp>
+
+// #ifndef _OSL_DIAGNOSE_H_
+// #include <osl/diagnose.h>
+// #endif
+#include "SalAquaFilePicker.hxx"
+#include "SalAquaFolderPicker.hxx"
+
+// #ifndef _SV_SVAPP_HXX
+// #include <vcl/svapp.hxx>
+// #endif
+#include "FPServiceInfo.hxx"
+
+//-----------------------------------------------
+// namespace directives
+//-----------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::container;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::registry;
+using namespace ::cppu;
+using ::com::sun::star::ui::dialogs::XFilePicker;
+using ::com::sun::star::ui::dialogs::XFolderPicker;
+
+//------------------------------------------------
+//
+//------------------------------------------------
+
+static Reference< XInterface > SAL_CALL createFileInstance(
+ const Reference< XMultiServiceFactory >& rServiceManager )
+{
+ return Reference< XInterface >(
+ *new SalAquaFilePicker( rServiceManager ) );
+}
+
+static Reference< XInterface > SAL_CALL createFolderInstance(
+ const Reference< XMultiServiceFactory >& rServiceManager )
+{
+ return Reference< XInterface >(
+ *new SalAquaFolderPicker( rServiceManager ) );
+}
+
+//------------------------------------------------
+// the three uno functions that will be exported
+//------------------------------------------------
+
+extern "C"
+{
+
+//------------------------------------------------
+// component_getImplementationEnvironment
+//------------------------------------------------
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /*ppEnv*/ )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//------------------------------------------------
+//
+//------------------------------------------------
+
+sal_Bool SAL_CALL component_writeInfo( void* /*pServiceManager*/, void* pRegistryKey )
+{
+ sal_Bool bRetVal = sal_True;
+
+ if ( pRegistryKey )
+ {
+ try
+ {
+ Reference< XRegistryKey > pXNewKey( static_cast< XRegistryKey* >( pRegistryKey ) );
+ pXNewKey->createKey( OUString::createFromAscii( FILE_PICKER_REGKEY_NAME ) );
+ pXNewKey->createKey( OUString::createFromAscii( FOLDER_PICKER_REGKEY_NAME ) );
+ }
+ catch( InvalidRegistryException& )
+ {
+ OSL_ENSURE( sal_False, "InvalidRegistryException caught" );
+ bRetVal = sal_False;
+ }
+ }
+
+ return bRetVal;
+}
+
+//------------------------------------------------
+//
+//------------------------------------------------
+
+void* SAL_CALL component_getFactory(
+ const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* /*pRegistryKey*/ )
+{
+ void* pRet = 0;
+
+ if( pSrvManager )
+ {
+ // FIXME: PJ: when we do not need native file and folder picker...
+ if (0) return 0;
+
+ Reference< XSingleServiceFactory > xFactory;
+
+ if (0 == rtl_str_compare(pImplName, FILE_PICKER_IMPL_NAME))
+ {
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray( )[0] =
+ OUString::createFromAscii(FILE_PICKER_SERVICE_NAME);
+
+ xFactory = createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ),
+ OUString::createFromAscii( pImplName ),
+ createFileInstance,
+ aSNS );
+ }
+ else if (0 == rtl_str_compare(pImplName, FOLDER_PICKER_IMPL_NAME))
+ {
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray( )[0] =
+ OUString::createFromAscii(FOLDER_PICKER_SERVICE_NAME);
+
+ xFactory = createSingleFactory(
+ reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ),
+ OUString::createFromAscii( pImplName ),
+ createFolderInstance,
+ aSNS );
+ }
+
+ if ( xFactory.is() )
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+
+} // extern "C"
diff --git a/fpicker/source/aqua/FilterHelper.cxx b/fpicker/source/aqua/FilterHelper.cxx
new file mode 100644
index 000000000000..3e7b04021f3a
--- /dev/null
+++ b/fpicker/source/aqua/FilterHelper.cxx
@@ -0,0 +1,543 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FilterHelper.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include <functional>
+#include <algorithm>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+// #ifndef _OSL_DIAGNOSE_H_
+// #include <osl/diagnose.h>
+// #endif
+#include "CFStringUtilities.hxx"
+#include "NSString_OOoAdditions.hxx"
+
+#include "FilterHelper.hxx"
+
+#pragma mark DEFINES
+#define CLASS_NAME "FilterEntry"
+
+#pragma mark FilterEntry
+//---------------------------------------------------------------------
+FilterEntry::FilterEntry( const rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters )
+:m_sTitle( _rTitle )
+,m_aSubFilters( _rSubFilters )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", _rTitle);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+//---------------------------------------------------------------------
+sal_Bool FilterEntry::hasSubFilters() const
+{
+// OSL_TRACE(">>> FilterEntry::%s", __func__);
+ sal_Bool bReturn = ( 0 < m_aSubFilters.getLength() );
+// OSL_TRACE("<<< FilterEntry::%s retVal: %d", __func__, bReturn);
+ return bReturn;
+}
+
+//---------------------------------------------------------------------
+sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ _rSubFilterList = m_aSubFilters;
+ sal_Int32 nReturn = m_aSubFilters.getLength();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn);
+
+ return nReturn;
+}
+
+#pragma mark statics
+static bool
+isFilterString( const rtl::OUString& rFilterString, const char *pMatch )
+{
+ sal_Int32 nIndex = 0;
+ rtl::OUString aToken;
+ bool bIsFilter = true;
+
+ rtl::OUString aMatch(rtl::OUString::createFromAscii(pMatch));
+
+ do
+ {
+ aToken = rFilterString.getToken( 0, ';', nIndex );
+ if( !aToken.match( aMatch ) )
+ {
+ bIsFilter = false;
+ break;
+ }
+ }
+ while( nIndex >= 0 );
+
+ return bIsFilter;
+}
+
+//=====================================================================
+
+static rtl::OUString
+shrinkFilterName( const rtl::OUString aFilterName, bool bAllowNoStar = false )
+{
+ // DBG_PRINT_ENTRY(CLASS_NAME, "shrinkFilterName", "filterName", aFilterName);
+
+ int i;
+ int nBracketLen = -1;
+ int nBracketEnd = -1;
+ rtl::OUString rFilterName = aFilterName;
+ const sal_Unicode *pStr = rFilterName;
+ rtl::OUString aRealName = rFilterName;
+
+ for( i = aRealName.getLength() - 1; i > 0; i-- )
+ {
+ if( pStr[i] == ')' )
+ nBracketEnd = i;
+ else if( pStr[i] == '(' )
+ {
+ nBracketLen = nBracketEnd - i;
+ if( nBracketEnd <= 0 )
+ continue;
+ if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), "*." ) )
+ aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
+ else if (bAllowNoStar)
+ {
+ if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), ".") )
+ aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
+ }
+ }
+ }
+
+ return aRealName;
+}
+
+//------------------------------------------------------------------------------------
+namespace {
+ //................................................................................
+ struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool >
+ {
+protected:
+ const rtl::OUString rTitle;
+
+public:
+ FilterTitleMatch( const rtl::OUString _rTitle ) : rTitle( _rTitle ) { }
+
+ //............................................................................
+ bool operator () ( const FilterEntry& _rEntry )
+ {
+ sal_Bool bMatch;
+ if( !_rEntry.hasSubFilters() ) {
+ //first try the complete filter name
+ rtl::OUString title = _rEntry.getTitle();
+ bMatch = ( title.equals(rTitle) );
+ if (!bMatch) {
+ //we didn't find a match using the full name, let's give it another
+ //try using the shrunk version
+ rtl::OUString aShrunkName = shrinkFilterName( _rEntry.getTitle() ).trim();
+ bMatch = ( aShrunkName.equals(rTitle) );
+ }
+ }
+ else
+ // a filter group -> search the sub filters
+ bMatch =
+ _rEntry.endSubFilters() != ::std::find_if(
+ _rEntry.beginSubFilters(),
+ _rEntry.endSubFilters(),
+ *this
+ );
+
+ return bMatch ? true : false;
+ }
+
+ bool operator () ( const UnoFilterEntry& _rEntry )
+ {
+ rtl::OUString aShrunkName = shrinkFilterName( _rEntry.First );
+ bool retVal = aShrunkName.equals(rTitle);
+ return retVal;
+ }
+ };
+}
+
+#undef CLASS_NAME
+#define CLASS_NAME "FilterHelper"
+
+FilterHelper::FilterHelper()
+: m_pFilterList(NULL)
+, m_pFilterNames(NULL)
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+FilterHelper::~FilterHelper()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ if (NULL != m_pFilterList) {
+ delete m_pFilterList;
+ }
+
+ if (NULL != m_pFilterNames) {
+ //we called retain when we added the strings to the list, so we should release them now
+ for (NSStringList::iterator iter = m_pFilterNames->begin(); iter != m_pFilterNames->end(); iter++) {
+ [*iter release];
+ }
+ delete m_pFilterNames;
+ }
+
+ [pool release];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+//------------------------------------------------------------------------------------
+sal_Bool FilterHelper::FilterNameExists( const rtl::OUString rTitle )
+{
+ sal_Bool bRet = sal_False;
+
+ if( m_pFilterList )
+ bRet =
+ m_pFilterList->end() != ::std::find_if(
+ m_pFilterList->begin(),
+ m_pFilterList->end(),
+ FilterTitleMatch( rTitle )
+ );
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------------
+sal_Bool FilterHelper::FilterNameExists( const UnoFilterList& _rGroupedFilters )
+{
+ sal_Bool bRet = sal_False;
+
+ if( m_pFilterList )
+ {
+ const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray();
+ const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength();
+ for( ; pStart != pEnd; ++pStart )
+ if( m_pFilterList->end() != ::std::find_if(
+ m_pFilterList->begin(),
+ m_pFilterList->end(),
+ FilterTitleMatch( pStart->First ) ) )
+ break;
+
+ bRet = (pStart != pEnd);
+ }
+
+ return bRet;
+}
+
+//------------------------------------------------------------------------------------
+void FilterHelper::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter )
+{
+ //OSL_TRACE(">>> FilterHelper::%s", __func__);
+ if( NULL == m_pFilterList )
+ {
+ m_pFilterList = new FilterList;
+
+ // set the first filter to the current filter
+ m_aCurrentFilter = _rInitialCurrentFilter;
+ OSL_TRACE("ensureFilterList filter:%s", OUStringToOString(m_aCurrentFilter, RTL_TEXTENCODING_UTF8).getStr());
+ }
+ //OSL_TRACE("<<< FilterHelper::%s", __func__);
+}
+
+void FilterHelper::SetCurFilter( const rtl::OUString& rFilter )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "filter", rFilter);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if(m_aCurrentFilter.equals(rFilter) == false)
+ {
+ m_aCurrentFilter = rFilter;
+ }
+
+ //only for output purposes
+#if OSL_DEBUG_LEVEL > 1
+ FilterList::iterator aFilter = ::std::find_if(m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch(m_aCurrentFilter));
+ if (aFilter != m_pFilterList->end()) {
+ OUStringList suffixes = aFilter->getFilterSuffixList();
+ if (!suffixes.empty()) {
+ OSL_TRACE("Current active suffixes: ");
+ OUStringList::iterator suffIter = suffixes.begin();
+ while(suffIter != suffixes.end()) {
+ OSL_TRACE("%s", OUStringToOString((*suffIter), RTL_TEXTENCODING_UTF8).getStr());
+ suffIter++;
+ }
+ }
+ } else {
+ OSL_TRACE("No filter entry was found for that name!");
+ }
+#endif
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void FilterHelper::SetFilters()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ // set the default filter
+ if( m_aCurrentFilter.getLength() > 0 )
+ {
+ OSL_TRACE( "Setting current filter to %s", OUStringToOString(m_aCurrentFilter, RTL_TEXTENCODING_UTF8).getStr());
+
+ SetCurFilter( m_aCurrentFilter );
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void FilterHelper::appendFilter(const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilterString)
+throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle, "filter", aFilterString);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if( FilterNameExists( aTitle ) ) {
+ throw com::sun::star::lang::IllegalArgumentException();
+ }
+
+ // ensure that we have a filter list
+ ensureFilterList( aTitle );
+
+ // append the filter
+ OUStringList suffixList;
+ fillSuffixList(suffixList, aFilterString);
+ m_pFilterList->push_back(FilterEntry( aTitle, suffixList ) );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void FilterHelper::setCurrentFilter( const ::rtl::OUString& aTitle )
+throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aTitle", OUStringToOString(aTitle, RTL_TEXTENCODING_UTF8).getStr());
+
+ SetCurFilter(aTitle);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+::rtl::OUString SAL_CALL FilterHelper::getCurrentFilter( )
+throw( ::com::sun::star::uno::RuntimeException ) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::rtl::OUString sReturn = (m_aCurrentFilter);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, OUStringToOString(sReturn, RTL_TEXTENCODING_UTF8).getStr());
+
+ return sReturn;
+}
+
+void SAL_CALL FilterHelper::appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters )
+throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) {
+
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", OUStringToOString(sGroupTitle, RTL_TEXTENCODING_UTF8).getStr());
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ //add a separator if this is not the first group to be added
+ sal_Bool bPrependSeparator = m_pFilterList != NULL;
+
+ // ensure that we have a filter list
+ ::rtl::OUString sInitialCurrentFilter;
+ if( aFilters.getLength() > 0)
+ sInitialCurrentFilter = aFilters[0].First;
+ ensureFilterList( sInitialCurrentFilter );
+
+ // append the filter
+ if (bPrependSeparator) {
+ rtl::OUString dash = rtl::OUString::createFromAscii("-");
+ OUStringList emptyList;
+ m_pFilterList->push_back(FilterEntry(dash, emptyList));
+ }
+
+ const com::sun::star::beans::StringPair* pSubFilters = aFilters.getConstArray();
+ const com::sun::star::beans::StringPair* pSubFiltersEnd = pSubFilters + aFilters.getLength();
+ for( ; pSubFilters != pSubFiltersEnd; ++pSubFilters ) {
+ appendFilter(pSubFilters->First, pSubFilters->Second);
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+sal_Bool FilterHelper::filenameMatchesFilter(NSString* sFilename)
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+// OSL_TRACE("filter event handler called");
+
+ if (m_aCurrentFilter == NULL) {
+ OSL_TRACE("filter name is null");
+ return sal_True;
+ }
+
+ NSFileManager *manager = [NSFileManager defaultManager];
+ MacOSBOOL bDir = NO;
+ if ([manager fileExistsAtPath:sFilename isDirectory:&bDir] && bDir == YES) {
+// OSL_TRACE(" folder");
+ return sal_True;
+ }
+
+ NSFileWrapper *wrapper = [[NSFileWrapper alloc] initWithPath:sFilename];
+ MacOSBOOL bIsLink = [wrapper isSymbolicLink];
+ [wrapper release];
+ if (bIsLink) {
+// OSL_TRACE(" symboliclink");
+ return sal_True;
+ }
+
+// OSL_TRACE(" file");
+
+ FilterList::iterator filter = ::std::find_if(m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch(m_aCurrentFilter));
+ if (filter == m_pFilterList->end()) {
+ OSL_TRACE("filter not found in list");
+ return sal_True;
+ }
+
+ OUStringList suffixList = filter->getFilterSuffixList();
+
+ {
+// OSL_TRACE(" starting to work");
+ rtl::OUString aName = [sFilename OUString];
+ rtl::OUString allMatcher = rtl::OUString::createFromAscii(".*");
+ for(OUStringList::iterator iter = suffixList.begin(); iter != suffixList.end(); iter++) {
+ if (aName.matchIgnoreAsciiCase(*iter, aName.getLength() - (*iter).getLength()) || ((*iter).equals(allMatcher))) {
+ return sal_True;
+ }
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return sal_False;
+}
+
+FilterList* FilterHelper::getFilterList() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return m_pFilterList;
+}
+
+NSStringList* FilterHelper::getFilterNames() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (NULL == m_pFilterList)
+ return NULL;
+ if (NULL == m_pFilterNames) {
+ //build filter names list
+ m_pFilterNames = new NSStringList;
+ for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++) {
+ m_pFilterNames->push_back([[NSString stringWithOUString:iter->getTitle()] retain]);
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return m_pFilterNames;
+}
+
+void FilterHelper::SetFilterAtIndex(unsigned index) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "index", index);
+
+ if (m_pFilterList->size() <= index) {
+ index = 0;
+ }
+ FilterEntry entry = m_pFilterList->at(index);
+ SetCurFilter(entry.getTitle());
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void FilterHelper::fillSuffixList(OUStringList& aSuffixList, const ::rtl::OUString& suffixString) {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aSuffixList", suffixString);
+
+ sal_Int32 nIndex = 0;
+ do {
+ rtl::OUString aToken = suffixString.getToken( 0, ';', nIndex );
+ aSuffixList.push_back(aToken.copy(1));
+ } while ( nIndex >= 0 );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+int FilterHelper::getCurrentFilterIndex() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ int result = 0;//default to first filter
+ if (m_aCurrentFilter.getLength() > 0) {
+ int i = 0;
+ for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++, i++) {
+ rtl::OUString aTitle = iter->getTitle();
+ if (m_aCurrentFilter.equals(aTitle)) {
+ result = i;
+ break;
+ } else {
+ aTitle = shrinkFilterName(aTitle).trim();
+ if (m_aCurrentFilter.equals(aTitle)) {
+ result = i;
+ break;
+ }
+ }
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, result);
+
+ return result;
+}
+
+OUStringList FilterHelper::getCurrentFilterSuffixList() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ OUStringList retVal;
+ if (m_aCurrentFilter.getLength() > 0) {
+ for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++) {
+ rtl::OUString aTitle = iter->getTitle();
+ if (m_aCurrentFilter.equals(aTitle)) {
+ retVal = iter->getFilterSuffixList();
+ break;
+ } else {
+ aTitle = shrinkFilterName(aTitle).trim();
+ if (m_aCurrentFilter.equals(aTitle)) {
+ retVal = iter->getFilterSuffixList();
+ break;
+ }
+ }
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return retVal;
+}
diff --git a/fpicker/source/aqua/FilterHelper.hxx b/fpicker/source/aqua/FilterHelper.hxx
new file mode 100644
index 000000000000..b337fcd0276d
--- /dev/null
+++ b/fpicker/source/aqua/FilterHelper.hxx
@@ -0,0 +1,163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: FilterHelper.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _FILTERHELPER_HXX_
+#define _FILTERHELPER_HXX_
+
+// #ifndef _COM_SUN_STAR_UNO_TYPE_HXX_
+// #include <com/sun/star/uno/Type.hxx>
+// #endif
+
+// #ifndef INCLUDED_CPPU_UNOTYPE_HXX
+// #include <cppu/unotype.hxx>
+// #endif
+
+// #ifndef _TYPELIB_TYPECLASS_H_
+// #include "typelib/typeclass.h"
+// #endif
+
+// #ifndef _TYPELIB_TYPEDESCRIPTION_H_
+// #include "typelib/typedescription.h"
+// #endif
+
+#include <com/sun/star/beans/StringPair.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HXX_
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HXX_
+#include <com/sun/star/uno/RuntimeException.hpp>
+#endif
+
+// #ifndef _RTL_USTRING_H_
+// #include <rtl/ustring.hxx>
+// #endif
+
+#include <list>
+#include <vector>
+
+#include <premac.h>
+#include <Cocoa/Cocoa.h>
+#include <postmac.h>
+
+typedef ::com::sun::star::beans::StringPair UnoFilterEntry;
+typedef ::com::sun::star::uno::Sequence< UnoFilterEntry > UnoFilterList; // can be transported more effectively
+typedef ::std::list<NSString *> NSStringList;
+typedef ::std::list<rtl::OUString> OUStringList;
+
+struct FilterEntry
+{
+protected:
+ rtl::OUString m_sTitle;
+ OUStringList m_sFilterSuffixList;
+ UnoFilterList m_aSubFilters;
+
+public:
+ FilterEntry( const rtl::OUString& _rTitle, const OUStringList _rFilter )
+ : m_sTitle( _rTitle )
+ , m_sFilterSuffixList( _rFilter )
+ {
+ }
+
+ FilterEntry( const rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters );
+
+ rtl::OUString getTitle() const { return m_sTitle; }
+ OUStringList getFilterSuffixList() const { return m_sFilterSuffixList; }
+
+ /// determines if the filter has sub filter (i.e., the filter is a filter group in real)
+ sal_Bool hasSubFilters( ) const;
+
+ /** retrieves the filters belonging to the entry
+ @return
+ the number of sub filters
+ */
+ sal_Int32 getSubFilters( UnoFilterList& _rSubFilterList );
+
+ // helpers for iterating the sub filters
+ const UnoFilterEntry* beginSubFilters() const { return m_aSubFilters.getConstArray(); }
+ const UnoFilterEntry* endSubFilters() const { return m_aSubFilters.getConstArray() + m_aSubFilters.getLength(); }
+};
+
+typedef ::std::vector < FilterEntry > FilterList;
+
+class FilterHelper {
+
+public:
+ FilterHelper();
+ virtual ~FilterHelper();
+
+ //XFilterManager delegates
+ void SAL_CALL appendFilter( const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilter )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ void SAL_CALL setCurrentFilter( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ ::rtl::OUString SAL_CALL getCurrentFilter( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //XFilterGroupManager delegates
+ void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+
+ //accessor
+ FilterList* getFilterList();
+ NSStringList* getFilterNames();
+
+ //misc
+ void SetCurFilter( const rtl::OUString& rFilter );
+ void SetFilterAtIndex(unsigned index);
+ OUStringList getCurrentFilterSuffixList();
+ int getCurrentFilterIndex();
+ void SetFilters();
+ sal_Bool filenameMatchesFilter(NSString * sFilename);
+
+private:
+ FilterList *m_pFilterList;
+ rtl::OUString m_aCurrentFilter;
+ NSStringList *m_pFilterNames;
+
+ int implAddFilter( const rtl::OUString rFilter, const OUStringList rSuffixList);
+ int implAddFilterGroup( const rtl::OUString rFilter,
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair>& _rFilters );
+
+ sal_Bool FilterNameExists( const rtl::OUString rTitle );
+ sal_Bool FilterNameExists( const UnoFilterList& _rGroupedFilters );
+
+ void ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter );
+
+ void fillSuffixList(OUStringList& aSuffixList, const ::rtl::OUString& suffixString);
+
+};
+
+#endif //_FILTERHELPER_HXX_
diff --git a/fpicker/source/aqua/NSString_OOoAdditions.hxx b/fpicker/source/aqua/NSString_OOoAdditions.hxx
new file mode 100644
index 000000000000..e26a8bc25c07
--- /dev/null
+++ b/fpicker/source/aqua/NSString_OOoAdditions.hxx
@@ -0,0 +1,47 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NSString_OOoAdditions.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NSSTRING_OOOADDITIONS_HXX_
+#define _NSSTRING_OOOADDITIONS_HXX_
+
+#include <premac.h>
+#import <Cocoa/Cocoa.h>
+#include <postmac.h>
+#include <rtl/ustring.hxx>
+// #include <sal/types.h>
+
+//for Cocoa types
+@interface NSString (OOoAdditions)
++ (id) stringWithOUString:(const rtl::OUString&)ouString;
+- (id) initWithOUString:(const rtl::OUString&)ouString;
+- (rtl::OUString) OUString;
+@end
+
+#endif // _NSSTRING_OOOADDITIONS_HXX_
diff --git a/fpicker/source/aqua/NSString_OOoAdditions.mm b/fpicker/source/aqua/NSString_OOoAdditions.mm
new file mode 100644
index 000000000000..cc22cbc9c7b1
--- /dev/null
+++ b/fpicker/source/aqua/NSString_OOoAdditions.mm
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NSString_OOoAdditions.mm,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _CFSTRINGUTILITIES_HXX_
+#include "CFStringUtilities.hxx"
+#endif
+
+#include "NSString_OOoAdditions.hxx"
+
+#define CLASS_NAME "NSString"
+
+@implementation NSString (OOoAdditions)
+
++ (id) stringWithOUString:(const rtl::OUString&)ouString
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "ouString", ouString);
+
+ NSString *string = [[NSString alloc] initWithOUString:ouString];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, string);
+ return [string autorelease];
+}
+
+- (id) initWithOUString:(const rtl::OUString&)ouString
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "ouString", ouString);
+ if ((self = [super init])) {
+ self = [self initWithCharacters:ouString.getStr() length:ouString.getLength()];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, self);
+
+ return self;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, self);
+ return nil;
+}
+
+- (rtl::OUString) OUString
+{
+ unsigned int nFileNameLength = [self length];
+
+ UniChar unichars[nFileNameLength+1];
+
+ //'close' the string buffer correctly
+ unichars[nFileNameLength] = '\0';
+
+ [self getCharacters:unichars];
+
+ return rtl::OUString(unichars);
+}
+
+@end
diff --git a/fpicker/source/aqua/NSURL_OOoAdditions.hxx b/fpicker/source/aqua/NSURL_OOoAdditions.hxx
new file mode 100644
index 000000000000..d4af027b3f72
--- /dev/null
+++ b/fpicker/source/aqua/NSURL_OOoAdditions.hxx
@@ -0,0 +1,46 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NSURL_OOoAdditions.hxx,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NSURL_OOOADDITIONS_HXX_
+#define _NSURL_OOOADDITIONS_HXX_
+
+#include <premac.h>
+#include <Foundation/Foundation.h>
+#include <postmac.h>
+#include "CFStringUtilities.hxx"
+#include <rtl/ustring.hxx>
+
+// #include <sal/types.h>
+
+@interface NSURL (OOoAdditions)
+- (rtl::OUString) OUStringForInfo:(InfoType)info;
+@end
+
+#endif \ No newline at end of file
diff --git a/fpicker/source/aqua/NSURL_OOoAdditions.mm b/fpicker/source/aqua/NSURL_OOoAdditions.mm
new file mode 100644
index 000000000000..d9495a5c9a34
--- /dev/null
+++ b/fpicker/source/aqua/NSURL_OOoAdditions.mm
@@ -0,0 +1,85 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: NSURL_OOoAdditions.mm,v $
+ * $Revision: 1.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _NSSTRING_OOOADDITIONS_HXX_
+#include "NSString_OOoAdditions.hxx"
+#endif
+
+#include "NSURL_OOoAdditions.hxx"
+
+@implementation NSURL (OOoAdditions)
+- (rtl::OUString) OUStringForInfo:(InfoType)info
+{
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ NSString *sURLString = nil;
+
+ switch(info) {
+ case FULLPATH:
+ OSL_TRACE("Extracting the full path of an item");
+ sURLString = [self absoluteString];
+ [sURLString retain];
+ break;
+ case FILENAME:
+ OSL_TRACE("Extracting the file name of an item");
+ NSString *path = [self path];
+ if (path == nil) {
+ sURLString = @"";
+ }
+ else {
+ sURLString = [path lastPathComponent];
+ }
+ [sURLString retain];
+ break;
+ case PATHWITHOUTLASTCOMPONENT:
+ OSL_TRACE("Extracting the last but one component of an item's path");
+ path = [self absoluteString];
+ if (path == nil) {
+ sURLString = @"";
+ }
+ else {
+ NSString* lastComponent = [path lastPathComponent];
+ unsigned int lastLength = [lastComponent length];
+ sURLString = [path substringToIndex:([path length] - lastLength)];
+ }
+ [sURLString retain];
+ break;
+ default:
+ break;
+ }
+
+ rtl::OUString sResult = [sURLString OUString];
+ [sURLString release];
+
+ [pool release];
+
+ return sResult;
+}
+@end
diff --git a/fpicker/source/aqua/SalAquaConstants.h b/fpicker/source/aqua/SalAquaConstants.h
new file mode 100644
index 000000000000..d7dc41e78c3c
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaConstants.h
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaConstants.h,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SALAQUACONSTANTS_H_
+#define _SALAQUACONSTANTS_H_
+
+#define kAppFourCharCode 'OOo2'
+#define kControlPropertyTracking 'Trck'
+#define kControlPropertyLastPartCode 'LsPc'
+#define kControlPropertySubType 'SuTy'
+#define kPopupControlPropertyTitleWidth 'PoTW'
+
+#define kAquaSpaceBetweenControls (8)
+#define kAquaSpaceBetweenPopupMenus (10)
+
+#define kAquaSpaceInsideGroupH (16)
+#define kAquaSpaceInsideGroupV (11)
+
+#define kAquaSpaceBoxFrameViewDiffTop (7)
+#define kAquaSpaceBoxFrameViewDiffLeft (7)
+#define kAquaSpaceBoxFrameViewDiffBottom (9)
+#define kAquaSpaceBoxFrameViewDiffRight (7)
+
+#define kAquaSpaceButtonFrameBoundsDiff (6)
+#define kAquaSpaceSwitchButtonFrameBoundsDiff (2)
+
+#define kAquaSpacePopupMenuFrameBoundsDiffTop (2)
+#define kAquaSpacePopupMenuFrameBoundsDiffBottom (4)
+#define kAquaSpacePopupMenuFrameBoundsDiffV (kAquaSpacePopupMenuFrameBoundsDiffTop + kAquaSpacePopupMenuFrameBoundsDiffBottom)
+#define kAquaSpacePopupMenuFrameBoundsDiffLeft (3)
+
+#define kAquaSpaceLabelFrameBoundsDiffH (3)
+#define kAquaSpaceLabelPopupDiffV (6)
+#define kAquaSpaceAfterPopupButtonsV (20)
+
+#define kAquaPopupButtonDefaultHeight (26)
+
+#endif //_SALAQUACONSTANTS_H_
+
diff --git a/fpicker/source/aqua/SalAquaFilePicker.cxx b/fpicker/source/aqua/SalAquaFilePicker.cxx
new file mode 100644
index 000000000000..8f79c5d2201d
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaFilePicker.cxx
@@ -0,0 +1,815 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaFilePicker.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <osl/diagnose.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/ui/dialogs/ControlActions.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+
+#ifndef _TOOLS_URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#include "resourceprovider.hxx"
+
+#ifndef _SV_RC_H
+#include <tools/rc.hxx>
+#endif
+#include <osl/file.hxx>
+#include "CFStringUtilities.hxx"
+#include "NSString_OOoAdditions.hxx"
+#include "NSURL_OOoAdditions.hxx"
+
+#include <iostream>
+
+#include "SalAquaFilePicker.hxx"
+
+
+#pragma mark DEFINES
+
+#define LABEL_TOGGLE( elem ) \
+case elem : \
+aLabel = aResProvider.getResString( CHECKBOX_##elem ); \
+ setLabel( CHECKBOX_##elem, aLabel ); \
+ break
+
+#define CLASS_NAME "SalAquaFilePicker"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::ui::dialogs::TemplateDescription;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------------
+// helper functions
+//------------------------------------------------------------------------
+
+namespace
+{
+ // controling event notifications
+ const bool STARTUP_SUSPENDED = true;
+ const bool STARTUP_ALIVE = false;
+
+ uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames()
+ {
+ uno::Sequence<rtl::OUString> aRet(3);
+ aRet[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.FilePicker" );
+ aRet[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFilePicker" );
+ aRet[2] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.AquaFilePicker" );
+ return aRet;
+ }
+}
+
+#pragma mark Constructor
+//-----------------------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------------------
+
+SalAquaFilePicker::SalAquaFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
+cppu::WeakComponentImplHelper8<XFilterManager, XFilterGroupManager, XFilePickerControlAccess, XFilePickerNotifier,
+ lang::XInitialization, util::XCancellable, lang::XEventListener, lang::XServiceInfo>( m_rbHelperMtx )
+, m_xServiceMgr( xServiceMgr )
+, m_pFilterHelper( NULL )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ m_pDelegate = [[AquaFilePickerDelegate alloc] initWithFilePicker:this];
+ m_pControlHelper->setFilePickerDelegate(m_pDelegate);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+SalAquaFilePicker::~SalAquaFilePicker()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (NULL != m_pFilterHelper)
+ delete m_pFilterHelper;
+
+ [m_pDelegate release];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+
+#pragma mark XFilePickerNotifier
+//------------------------------------------------------------------------------------
+// XFilePickerNotifier
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::addFilePickerListener( const uno::Reference<XFilePickerListener>& xListener )
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ m_xListener = xListener;
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaFilePicker::removeFilePickerListener( const uno::Reference<XFilePickerListener>& )
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ m_xListener.clear();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XAsynchronousExecutableDialog
+//-----------------------------------------------------------------------------------------
+// XExecutableDialog functions
+//-----------------------------------------------------------------------------------------
+void SAL_CALL SalAquaFilePicker::setTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+ implsetTitle(aTitle);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+sal_Int16 SAL_CALL SalAquaFilePicker::execute() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int16 retVal = 0;
+
+ implInitialize();
+
+ // if m_pDialog is nil after initialization, something must have gone wrong before
+ // or there was no initialization (see issue http://www.openoffice.org/issues/show_bug.cgi?id=100214)
+ if (m_pDialog == nil) {
+ //throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog was not properly initialized!"), static_cast< XFilePicker* >( this ));
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ }
+
+ if (m_pFilterHelper) {
+ m_pFilterHelper->SetFilters();
+ }
+
+ if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
+ if (m_sSaveFileName.getLength() == 0) {
+ //if no filename is set, NavigationServices will set the name to "untitled". We don't want this!
+ //So let's try to get the window title to get the real untitled name
+ NSWindow *frontWindow = [NSApp keyWindow];
+ if (NULL != frontWindow) {
+ NSString *windowTitle = [frontWindow title];
+ if (windowTitle != nil) {
+ rtl::OUString ouName = [windowTitle OUString];
+ //a window title will typically be something like "Untitled1 - OpenOffice.org Writer"
+ //but we only want the "Untitled1" part of it
+ sal_Int32 indexOfDash = ouName.indexOf(rtl::OUString::createFromAscii(" - "));
+ if (indexOfDash > -1) {
+ m_sSaveFileName = ouName.copy(0,indexOfDash);
+ if (m_sSaveFileName.getLength() > 0) {
+ setDefaultName(m_sSaveFileName);
+ }
+ } else {
+ OSL_TRACE("no dash present in window title");
+ }
+ } else {
+ OSL_TRACE("couldn't get window title");
+ }
+ } else {
+ OSL_TRACE("no front window found");
+ }
+ }
+ }
+
+ //Set the delegate to be notified of certain events
+ [m_pDialog setDelegate:m_pDelegate];
+
+ int nStatus = runandwaitforresult();
+
+ [m_pDialog setDelegate:nil];
+
+ switch( nStatus )
+ {
+ case NSOKButton:
+ OSL_TRACE("The dialog returned OK");
+ retVal = ExecutableDialogResults::OK;
+ break;
+
+ case NSCancelButton:
+ OSL_TRACE("The dialog was cancelled by the user!");
+ retVal = ExecutableDialogResults::CANCEL;
+ break;
+
+ default:
+ throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog returned with an unknown result!"), static_cast< XFilePicker* >( this ));
+ break;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+
+ return retVal;
+}
+
+
+#pragma mark XFilePicker
+//-----------------------------------------------------------------------------------------
+// XFilePicker functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::setMultiSelectionMode( sal_Bool bMode ) throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "multiSelectable?", bMode);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
+ [(NSOpenPanel*)m_pDialog setAllowsMultipleSelection:YES];
+ OSL_TRACE("dialog allows multi-selection? %d", [(NSOpenPanel*)m_pDialog allowsMultipleSelection]);
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaFilePicker::setDefaultName( const rtl::OUString& aName )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "name", aName);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ m_sSaveFileName = aName;
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaFilePicker::setDisplayDirectory( const rtl::OUString& rDirectory )
+throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", rDirectory);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ implsetDisplayDirectory(rDirectory);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+rtl::OUString SAL_CALL SalAquaFilePicker::getDisplayDirectory() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ rtl::OUString retVal = implgetDisplayDirectory();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+ return retVal;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getFiles() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // OSL_TRACE("starting work");
+ /*
+ * If more than one file is selected in an OpenDialog, then the first result
+ * is the directory and the remaining results contain just the files' names
+ * without the basedir path.
+ */
+ NSArray *files = nil;
+ if (m_nDialogType == NAVIGATIONSERVICES_OPEN) {
+ files = [(NSOpenPanel*)m_pDialog URLs];
+ }
+ else if (m_nDialogType == NAVIGATIONSERVICES_SAVE) {
+ files = [NSArray arrayWithObjects:[m_pDialog URL], nil];
+ }
+
+ long nFiles = [files count];
+ OSL_TRACE("# of items: %d", nFiles);
+
+ uno::Sequence< rtl::OUString > aSelectedFiles(nFiles > 1 ? nFiles + 1 : nFiles);
+
+ for(int nIndex = 0; nIndex < nFiles; nIndex += 1)
+ {
+ NSURL *url = [files objectAtIndex:nIndex];
+ OSL_TRACE("handling %s", [[url description] UTF8String]);
+ InfoType info = FULLPATH;
+ if (nFiles > 1) {
+ //just get the file's name (only in OpenDialog)
+ info = FILENAME;
+ }
+ OUString sFileOrDirURL = [url OUStringForInfo:info];
+
+ //get the directory information, only on the first file processed
+ if (nIndex == 0) {
+ OUString sDirectoryURL = [url OUStringForInfo:PATHWITHOUTLASTCOMPONENT];
+
+ if (nFiles > 1) {
+ aSelectedFiles[0] = OUString(sDirectoryURL);
+ }
+ }
+
+ short nSequenceIndex = nFiles > 1 ? nIndex + 1 : nIndex;
+ aSelectedFiles[nSequenceIndex] = sFileOrDirURL;
+
+ OSL_TRACE("Returned file in getFiles: \"%s\".", OUStringToOString(sFileOrDirURL, RTL_TEXTENCODING_UTF8).getStr());
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return aSelectedFiles;
+}
+
+#pragma mark XFilterManager
+//-----------------------------------------------------------------------------------------
+// XFilterManager functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::appendFilter( const rtl::OUString& aTitle, const rtl::OUString& aFilter )
+throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ensureFilterHelper();
+ m_pFilterHelper->appendFilter( aTitle, aFilter );
+ m_pControlHelper->setFilterControlNeeded(YES);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaFilePicker::setCurrentFilter( const rtl::OUString& aTitle )
+throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ OSL_TRACE( "Setting current filter to %s",
+ OUStringToOString( aTitle, RTL_TEXTENCODING_UTF8 ).getStr() );
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ensureFilterHelper();
+ m_pFilterHelper->setCurrentFilter(aTitle);
+ updateFilterUI();
+
+ updateSaveFileNameExtension();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+rtl::OUString SAL_CALL SalAquaFilePicker::getCurrentFilter() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ensureFilterHelper();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return m_pFilterHelper->getCurrentFilter();
+}
+
+#pragma mark XFilterGroupManager
+//-----------------------------------------------------------------------------------------
+// XFilterGroupManager functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::appendFilterGroup( const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters )
+throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ ensureFilterHelper();
+ m_pFilterHelper->appendFilterGroup(sGroupTitle, aFilters);
+ m_pControlHelper->setFilterControlNeeded(YES);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XFilePickerControlAccess
+//------------------------------------------------------------------------------------
+// XFilePickerControlAccess functions
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const uno::Any& rValue )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ m_pControlHelper->setValue(nControlId, nControlAction, rValue);
+
+ if (nControlId == ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION && m_nDialogType == NAVIGATIONSERVICES_SAVE) {
+ updateSaveFileNameExtension();
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+uno::Any SAL_CALL SalAquaFilePicker::getValue( sal_Int16 nControlId, sal_Int16 nControlAction )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ uno::Any aValue = m_pControlHelper->getValue(nControlId, nControlAction);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return aValue;
+}
+
+void SAL_CALL SalAquaFilePicker::enableControl( sal_Int16 nControlId, sal_Bool bEnable )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ m_pControlHelper->enableControl(nControlId, bEnable);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaFilePicker::setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSString* sLabel = [NSString stringWithOUString:aLabel];
+ m_pControlHelper->setLabel( nControlId, sLabel ) ;
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+rtl::OUString SAL_CALL SalAquaFilePicker::getLabel( sal_Int16 nControlId )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return m_pControlHelper->getLabel(nControlId);
+}
+
+#pragma mark XInitialization
+//------------------------------------------------------------------------------------
+// XInitialization
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::initialize( const uno::Sequence<uno::Any>& aArguments )
+throw( uno::Exception, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "arguments size", aArguments.getLength());
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ // parameter checking
+ uno::Any aAny;
+ if( 0 == aArguments.getLength() )
+ throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "no arguments" ),
+ static_cast<XFilePicker*>( this ), 1 );
+
+ aAny = aArguments[0];
+
+ if( ( aAny.getValueType() != ::getCppuType( ( sal_Int16* )0 ) ) &&
+ (aAny.getValueType() != ::getCppuType( ( sal_Int8* )0 ) ) )
+ throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "invalid argument type" ),
+ static_cast<XFilePicker*>( this ), 1 );
+
+ sal_Int16 templateId = -1;
+ aAny >>= templateId;
+
+ switch( templateId )
+ {
+ case FILEOPEN_SIMPLE:
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ OSL_TRACE( "Template: FILEOPEN_SIMPLE" );
+ break;
+ case FILESAVE_SIMPLE:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_SIMPLE" );
+ break;
+ case FILESAVE_AUTOEXTENSION_PASSWORD:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD" );
+ break;
+ case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS" );
+ break;
+ case FILESAVE_AUTOEXTENSION_SELECTION:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_SELECTION" );
+ break;
+ case FILESAVE_AUTOEXTENSION_TEMPLATE:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION_TEMPLATE" );
+ break;
+ case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE:
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE" );
+ break;
+ case FILEOPEN_PLAY:
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ OSL_TRACE( "Template: FILEOPEN_PLAY" );
+ break;
+ case FILEOPEN_READONLY_VERSION:
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ OSL_TRACE( "Template: FILEOPEN_READONLY_VERSION" );
+ break;
+ case FILEOPEN_LINK_PREVIEW:
+ m_nDialogType = NAVIGATIONSERVICES_OPEN;
+ OSL_TRACE( "Template: FILEOPEN_LINK_PREVIEW" );
+ break;
+ case FILESAVE_AUTOEXTENSION:
+ m_nDialogType = NAVIGATIONSERVICES_SAVE;
+ OSL_TRACE( "Template: FILESAVE_AUTOEXTENSION" );
+ break;
+ default:
+ throw lang::IllegalArgumentException(rtl::OUString::createFromAscii( "Unknown template" ),
+ static_cast< XFilePicker* >( this ),
+ 1 );
+ }
+
+ m_pControlHelper->initialize(templateId);
+
+ implInitialize();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XCancellable
+//------------------------------------------------------------------------------------
+// XCancellable
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::cancel() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (m_pDialog != nil) {
+ [m_pDialog cancel:nil];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XEventListener
+//------------------------------------------------
+// XEventListener
+//------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ uno::Reference<XFilePickerListener> xFilePickerListener( aEvent.Source, ::com::sun::star::uno::UNO_QUERY );
+
+ if( xFilePickerListener.is() )
+ removeFilePickerListener( xFilePickerListener );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+#pragma mark XServiceInfo
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+rtl::OUString SAL_CALL SalAquaFilePicker::getImplementationName()
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ rtl::OUString retVal = rtl::OUString::createFromAscii( FILE_PICKER_IMPL_NAME );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+
+ return retVal;
+}
+
+sal_Bool SAL_CALL SalAquaFilePicker::supportsService( const rtl::OUString& sServiceName )
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "service name", sServiceName);
+
+ sal_Bool retVal = sal_False;
+
+ uno::Sequence <rtl::OUString> supportedServicesNames = FilePicker_getSupportedServiceNames();
+
+ for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) {
+ if( supportedServicesNames[n].compareTo( sServiceName ) == 0) {
+ retVal = sal_True;
+ break;
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return retVal;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL SalAquaFilePicker::getSupportedServiceNames()
+throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return FilePicker_getSupportedServiceNames();
+}
+
+#pragma mark Misc/Private
+//-----------------------------------------------------------------------------------------
+// FilePicker Event functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFilePicker::fileSelectionChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE( "file selection changed");
+ if (m_xListener.is())
+ m_xListener->fileSelectionChanged( aEvent );
+}
+
+void SAL_CALL SalAquaFilePicker::directoryChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE("directory changed");
+ if (m_xListener.is())
+ m_xListener->directoryChanged( aEvent );
+}
+
+void SAL_CALL SalAquaFilePicker::controlStateChanged( FilePickerEvent aEvent )
+{
+ OSL_TRACE("control state changed");
+ if (m_xListener.is())
+ m_xListener->controlStateChanged( aEvent );
+}
+
+void SAL_CALL SalAquaFilePicker::dialogSizeChanged()
+{
+ OSL_TRACE("dialog size changed");
+ if (m_xListener.is())
+ m_xListener->dialogSizeChanged();
+}
+
+//------------------------------------------------------------------------------------
+
+#define MAP_TOGGLE( elem ) \
+case ExtendedFilePickerElementIds::CHECKBOX_##elem: \
+ pWidget = m_pToggles[elem]; \
+ break
+
+#define MAP_BUTTON( elem ) \
+case ExtendedFilePickerElementIds::PUSHBUTTON_##elem: \
+ pWidget = m_pButtons[elem]; \
+ break
+#undef MAP_LIST
+#define MAP_LIST( elem ) \
+case ExtendedFilePickerElementIds::LISTBOX_##elem: \
+ pWidget = m_pListControls[elem]; if (isAList != NULL) *isAList = sal_True; \
+ break
+
+#define MAP_LIST_LABEL( elem ) \
+case ExtendedFilePickerElementIds::LISTBOX_##elem##_LABEL: \
+ pWidget = m_pListControls[elem]; \
+ break
+
+//--------------------------------------------------
+// Misc
+//-------------------------------------------------
+void SalAquaFilePicker::ensureFilterHelper() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (NULL == m_pFilterHelper) {
+ m_pFilterHelper = new FilterHelper;
+ m_pControlHelper->setFilterHelper(m_pFilterHelper);
+ [m_pDelegate setFilterHelper:m_pFilterHelper];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SalAquaFilePicker::implInitialize()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ //call super
+ SalAquaPicker::implInitialize();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SalAquaFilePicker::updateFilterUI() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ m_pControlHelper->updateFilterUI();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SalAquaFilePicker::updateSaveFileNameExtension() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (m_nDialogType != NAVIGATIONSERVICES_SAVE) {
+ return;
+ }
+
+ // we need to set this here again because initial setting does
+ //[m_pDialog setExtensionHidden:YES];
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (m_pControlHelper->isAutoExtensionEnabled() == false) {
+ OSL_TRACE("allowing other file types");
+ [m_pDialog setAllowedFileTypes:nil];
+ [m_pDialog setAllowsOtherFileTypes:YES];
+ } else {
+ ensureFilterHelper();
+
+ OUStringList aStringList = m_pFilterHelper->getCurrentFilterSuffixList();
+ if( aStringList.empty()) // #i9328#
+ return;
+
+ rtl::OUString suffix = (*(aStringList.begin())).copy(1);
+ NSString *requiredFileType = [NSString stringWithOUString:suffix];
+
+ [m_pDialog setRequiredFileType:requiredFileType];
+
+ OSL_TRACE("disallowing other file types");
+ [m_pDialog setAllowsOtherFileTypes:NO];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SalAquaFilePicker::filterControlChanged() {
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ if (m_pDialog == nil) {
+ return;
+ }
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ updateSaveFileNameExtension();
+
+ [m_pDialog validateVisibleColumns];
+
+ FilePickerEvent evt;
+ evt.ElementId = LISTBOX_FILTER;
+ controlStateChanged( evt );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
diff --git a/fpicker/source/aqua/SalAquaFilePicker.hxx b/fpicker/source/aqua/SalAquaFilePicker.hxx
new file mode 100644
index 000000000000..cb6158da6e1e
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaFilePicker.hxx
@@ -0,0 +1,255 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaFilePicker.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SALAQUAFILEPICKER_HXX_
+#define _SALAQUAFILEPICKER_HXX_
+
+//_______________________________________________________________________________________________________________________
+// includes of other projects
+//_______________________________________________________________________________________________________________________
+
+#include <cppuhelper/compbase8.hxx>
+#include <com/sun/star/util/XCancellable.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp>
+#include <com/sun/star/ui/dialogs/XFilterManager.hpp>
+#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp>
+#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp>
+#include <com/sun/star/beans/StringPair.hpp>
+
+#ifndef _SALAQUAPICKER_HXX_
+#include "SalAquaPicker.hxx"
+#endif
+
+#include <memory>
+#include <list>
+
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.hxx>
+#endif
+#include "FilterHelper.hxx"
+#include "AquaFilePickerDelegate.hxx"
+
+//----------------------------------------------------------
+// Implementation class for the XFilePicker Interface
+//----------------------------------------------------------
+
+//----------------------------------------------------------
+// forward declarations
+//----------------------------------------------------------
+
+using namespace rtl;
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalAquaFilePicker :
+ public SalAquaPicker,
+ public cppu::WeakComponentImplHelper8<
+ ::com::sun::star::ui::dialogs::XFilterManager,
+ ::com::sun::star::ui::dialogs::XFilterGroupManager,
+ ::com::sun::star::ui::dialogs::XFilePickerControlAccess,
+ ::com::sun::star::ui::dialogs::XFilePickerNotifier,
+ ::com::sun::star::lang::XInitialization,
+ ::com::sun::star::util::XCancellable,
+ ::com::sun::star::lang::XEventListener,
+ ::com::sun::star::lang::XServiceInfo >
+{
+public:
+
+ // constructor
+ SalAquaFilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceMgr );
+
+ //------------------------------------------------------------------------------------
+ // XFilePickerNotifier
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL addFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener )
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual void SAL_CALL removeFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XExecutableDialog functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL execute( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilePicker functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setMultiSelectionMode( sal_Bool bMode )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDefaultName( const ::rtl::OUString& aName )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDisplayDirectory( const ::rtl::OUString& aDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getDisplayDirectory( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilterManager functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL appendFilter( const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilter )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setCurrentFilter( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
+
+ virtual ::rtl::OUString SAL_CALL getCurrentFilter( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFilterGroupManager functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters )
+ throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------------------------------------------
+ // XFilePickerControlAccess functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setValue( sal_Int16 nControlId, sal_Int16 nControlAction, const ::com::sun::star::uno::Any& aValue )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL enableControl( sal_Int16 nControlId, sal_Bool bEnable )
+ throw(::com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setLabel( sal_Int16 nControlId, const ::rtl::OUString& aLabel )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 nControlId )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XInitialization
+ //------------------------------------------------
+
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XCancellable
+ //------------------------------------------------
+
+ virtual void SAL_CALL cancel( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XEventListener
+ //------------------------------------------------
+
+ using cppu::WeakComponentImplHelperBase::disposing;
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XServiceInfo
+ //------------------------------------------------
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------------------------------------------
+ // FilePicker Event functions
+ //------------------------------------------------------------------------------------
+
+ void SAL_CALL fileSelectionChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+ void SAL_CALL directoryChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+ // rtl::OUString SAL_CALL helpRequested( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ) const;
+ void SAL_CALL controlStateChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent );
+ void SAL_CALL dialogSizeChanged( );
+
+ inline AquaFilePickerDelegate * getDelegate() {
+ return m_pDelegate;
+ }
+
+ inline rtl::OUString getSaveFileName() {
+ return m_sSaveFileName;
+ }
+
+private:
+ // prevent copy and assignment
+ SalAquaFilePicker( const SalAquaFilePicker& );
+ SalAquaFilePicker& operator=( const SalAquaFilePicker& );
+
+ virtual void ensureFilterHelper();
+
+ // to instantiate own services
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >
+ m_xListener;
+
+ FilterHelper *m_pFilterHelper;
+
+ rtl::OUString m_sSaveFileName;
+
+ AquaFilePickerDelegate *m_pDelegate;
+
+ void updateFilterUI();
+ void updateSaveFileNameExtension();
+
+public:
+
+ virtual ~SalAquaFilePicker();
+
+ void filterControlChanged();
+
+ void implInitialize();
+
+};
+
+#endif // _SALAQUAFILEPICKER_HXX_
diff --git a/fpicker/source/aqua/SalAquaFolderPicker.cxx b/fpicker/source/aqua/SalAquaFolderPicker.cxx
new file mode 100644
index 000000000000..7bc31f495050
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaFolderPicker.cxx
@@ -0,0 +1,292 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaFolderPicker.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <osl/diagnose.h>
+#include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include "SalAquaFolderPicker.hxx"
+
+#include <tools/urlobj.hxx>
+#include <iostream>
+
+#include "resourceprovider.hxx"
+
+#ifndef _SV_RC_H
+#include <tools/rc.hxx>
+#endif
+
+#include <osl/file.hxx>
+#include "CFStringUtilities.hxx"
+#include "NSString_OOoAdditions.hxx"
+#include "NSURL_OOoAdditions.hxx"
+
+#pragma mark DEFINES
+#define CLASS_NAME "SalAquaFolderPicker"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::ui::dialogs;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+//------------------------------------------------------------------------
+// helper functions
+//------------------------------------------------------------------------
+
+namespace
+{
+ // controling event notifications
+ uno::Sequence<rtl::OUString> SAL_CALL FolderPicker_getSupportedServiceNames()
+ {
+ uno::Sequence<rtl::OUString> aRet(2);
+ aRet[0] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.SystemFolderPicker" );
+ aRet[1] = rtl::OUString::createFromAscii( "com.sun.star.ui.dialogs.AquaFolderPicker" );
+ return aRet;
+ }
+}
+
+//-----------------------------------------------------------------------------------------
+// constructor
+//-----------------------------------------------------------------------------------------
+SalAquaFolderPicker::SalAquaFolderPicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr ) :
+ m_xServiceMgr( xServiceMgr )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ m_nDialogType = NAVIGATIONSERVICES_DIRECTORY;
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+//-----------------------------------------------------------------------------------------
+// XExecutableDialog functions
+//-----------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFolderPicker::setTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ implsetTitle(aTitle);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+sal_Int16 SAL_CALL SalAquaFolderPicker::execute() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ sal_Int16 retVal = 0;
+
+ int nResult = runandwaitforresult();
+
+ switch( nResult )
+ {
+ case NSOKButton:
+ OSL_TRACE("Dialog returned with OK");
+ retVal = ExecutableDialogResults::OK;
+ break;
+
+ case NSCancelButton:
+ OSL_TRACE("Dialog was cancelled!");
+ retVal = ExecutableDialogResults::CANCEL;
+ break;
+
+ default:
+ throw uno::RuntimeException(rtl::OUString::createFromAscii("The dialog returned with an unknown result!"), static_cast< XFolderPicker* >( this ));
+ break;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return retVal;
+}
+
+//------------------------------------------------------------------------------------
+// XFolderPicker functions
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFolderPicker::setDisplayDirectory( const rtl::OUString& aDirectory )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", aDirectory);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ implsetDisplayDirectory(aDirectory);
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+rtl::OUString SAL_CALL SalAquaFolderPicker::getDisplayDirectory() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ OUString aDirectory = implgetDisplayDirectory();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, aDirectory);
+
+ return aDirectory;
+}
+
+rtl::OUString SAL_CALL SalAquaFolderPicker::getDirectory() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSArray *files = nil;
+ if (m_nDialogType == NAVIGATIONSERVICES_DIRECTORY) {
+ files = [(NSOpenPanel*)m_pDialog URLs];
+ }
+
+ long nFiles = [files count];
+ OSL_TRACE("# of items: %d", nFiles);
+
+ if (nFiles < 1) {
+ throw uno::RuntimeException(rtl::OUString::createFromAscii("no directory selected"), static_cast< XFolderPicker* >( this ));
+ }
+
+ rtl::OUString aDirectory;
+
+ NSURL *url = [files objectAtIndex:0];
+ OSL_TRACE("handling %s", [[url description] UTF8String]);
+
+ aDirectory = [url OUStringForInfo:FULLPATH];
+
+ implsetDisplayDirectory(aDirectory);
+
+ OSL_TRACE("dir url: %s", OUStringToOString(aDirectory, RTL_TEXTENCODING_UTF8).getStr());
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+ return aDirectory;
+}
+
+void SAL_CALL SalAquaFolderPicker::setDescription( const rtl::OUString& rDescription )
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "description", rDescription);
+
+ [m_pDialog setMessage:[NSString stringWithOUString:rDescription]];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+// -------------------------------------------------
+// XServiceInfo
+// -------------------------------------------------
+
+rtl::OUString SAL_CALL SalAquaFolderPicker::getImplementationName()
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ rtl::OUString retVal = rtl::OUString::createFromAscii( FOLDER_PICKER_IMPL_NAME );
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+
+ return retVal;
+}
+
+sal_Bool SAL_CALL SalAquaFolderPicker::supportsService( const rtl::OUString& sServiceName )
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "serviceName", sServiceName);
+
+ sal_Bool retVal = sal_False;
+ uno::Sequence <rtl::OUString> supportedServicesNames = FolderPicker_getSupportedServiceNames();
+
+ for( sal_Int32 n = supportedServicesNames.getLength(); n--; ) {
+ if( supportedServicesNames[n].compareTo( sServiceName ) == 0) {
+ retVal = sal_True;
+ break;
+ }
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+ return retVal;
+}
+
+uno::Sequence<rtl::OUString> SAL_CALL SalAquaFolderPicker::getSupportedServiceNames()
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+
+ return FolderPicker_getSupportedServiceNames();
+}
+
+//------------------------------------------------------------------------------------
+// XCancellable
+//------------------------------------------------------------------------------------
+
+void SAL_CALL SalAquaFolderPicker::cancel() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ [m_pDialog cancel:nil];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+// -------------------------------------------------
+// XEventListener
+// -------------------------------------------------
+
+void SAL_CALL SalAquaFolderPicker::disposing( const lang::EventObject& )
+ throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
diff --git a/fpicker/source/aqua/SalAquaFolderPicker.hxx b/fpicker/source/aqua/SalAquaFolderPicker.hxx
new file mode 100644
index 000000000000..255e455e9a92
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaFolderPicker.hxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaFolderPicker.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SALAQUAFOLDERPICKER_HXX_
+#define _SALAQUAFOLDERPICKER_HXX_
+
+//_______________________________________________________________________________________________________________________
+// includes of other projects
+//_______________________________________________________________________________________________________________________
+
+#ifndef _CPPUHELPER_COMPBASE4_HXX_
+#include <cppuhelper/implbase4.hxx>
+#endif
+#include <com/sun/star/util/XCancellable.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+#ifndef _COM_SUN_STAR_UI_XFOLDERPICKER_HPP_
+#include <com/sun/star/ui/dialogs/XFolderPicker.hpp>
+#endif
+
+#ifndef _SALAQUAPICKER_HXX_
+#include "SalAquaPicker.hxx"
+#endif
+
+#include <memory>
+
+#ifndef _RTL_USTRING_H_
+#include <rtl/ustring.hxx>
+#endif
+
+#include <list>
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalAquaFolderPicker :
+ public SalAquaPicker,
+ public cppu::WeakImplHelper4<
+ ::com::sun::star::ui::dialogs::XFolderPicker,
+ ::com::sun::star::lang::XServiceInfo,
+ ::com::sun::star::lang::XEventListener,
+ ::com::sun::star::util::XCancellable >
+{
+public:
+
+ // constructor
+ SalAquaFolderPicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceMgr );
+
+ //------------------------------------------------------------------------------------
+ // XExecutableDialog functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ virtual sal_Int16 SAL_CALL execute( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------------------------------------------
+ // XFolderPicker functions
+ //------------------------------------------------------------------------------------
+
+ virtual void SAL_CALL setDisplayDirectory( const rtl::OUString& rDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getDisplayDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual rtl::OUString SAL_CALL getDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ virtual void SAL_CALL setDescription( const rtl::OUString& rDescription )
+ throw( com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XServiceInfo
+ //------------------------------------------------
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ //------------------------------------------------
+ // XCancellable
+ //------------------------------------------------
+
+ virtual void SAL_CALL cancel( )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ //------------------------------------------------
+ // XEventListener
+ //------------------------------------------------
+
+ virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent )
+ throw(::com::sun::star::uno::RuntimeException);
+
+private:
+ // prevent copy and assignment
+ SalAquaFolderPicker( const SalAquaFolderPicker& );
+ SalAquaFolderPicker& operator=( const SalAquaFolderPicker& );
+
+ // to instantiate own services
+ ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr;
+
+};
+
+#endif // _SALAQUAFOLDERPICKER_HXX_
diff --git a/fpicker/source/aqua/SalAquaPicker.cxx b/fpicker/source/aqua/SalAquaPicker.cxx
new file mode 100644
index 000000000000..aaf311de020a
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaPicker.cxx
@@ -0,0 +1,267 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaPicker.cxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <cppuhelper/interfacecontainer.h>
+#include <osl/diagnose.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <FPServiceInfo.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#ifndef _SALAQUAPICKER_HXX_
+#include "SalAquaPicker.hxx"
+#endif
+#include <tools/urlobj.hxx>
+#include <osl/file.hxx>
+#include "CFStringUtilities.hxx"
+#include "NSString_OOoAdditions.hxx"
+
+#ifndef _NSURL_OOOADDITIONS_HXX_
+#include "NSURL_OOoAdditions.hxx"
+#endif
+
+#include "SalAquaFilePicker.hxx"
+
+#include <stdio.h>
+
+#pragma mark DEFINES
+#define CLASS_NAME "SalAquaPicker"
+#define kSetHideExtensionStateKey @"NSNavLastUserSetHideExtensionButtonState"
+
+//------------------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------------------
+
+using namespace ::rtl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::uno;
+
+// constructor
+SalAquaPicker::SalAquaPicker()
+: m_pDialog(NULL)
+, m_pControlHelper(new ControlHelper())
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+SalAquaPicker::~SalAquaPicker()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ if (NULL != m_pControlHelper)
+ delete m_pControlHelper;
+
+ if (NULL != m_pDialog)
+ [m_pDialog release];
+
+ [pool release];
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+void SAL_CALL SalAquaPicker::implInitialize()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (m_pDialog != nil) {
+ return;
+ }
+
+ switch (m_nDialogType)
+ {
+ case NAVIGATIONSERVICES_OPEN:
+ OSL_TRACE("NAVIGATIONSERVICES_OPEN");
+ m_pDialog = [NSOpenPanel openPanel];
+ [(NSOpenPanel*)m_pDialog setCanChooseDirectories:NO];
+ [(NSOpenPanel*)m_pDialog setCanChooseFiles:YES];
+ break;
+
+ case NAVIGATIONSERVICES_SAVE:
+ OSL_TRACE("NAVIGATIONSERVICES_SAVE");
+ m_pDialog = [NSSavePanel savePanel];
+ [(NSSavePanel*)m_pDialog setCanSelectHiddenExtension:NO]; //changed for issue #102102
+ /* I would have loved to use
+ * [(NSSavePanel*)m_pDialog setExtensionHidden:YES];
+ * here but unfortunately this
+ * a) only works when the dialog is already displayed because it seems to act on the corresponding checkbox (that we don't show but that doesn't matter)
+ * b) Mac OS X saves this setting on an application-based level which means that the last state is always being restored again when the app runs for the next time
+ *
+ * So the only reliable way seems to be using the NSUserDefaults object because that is where that value is stored and
+ * to just overwrite it if it has the wrong value.
+ */
+ NSUserDefaults *pDefaults = [NSUserDefaults standardUserDefaults];
+ NSNumber *pExtn = [pDefaults objectForKey:kSetHideExtensionStateKey];
+ if(pExtn == nil || [pExtn boolValue] == NO) {
+ OSL_TRACE("Hiding extension");
+ [pDefaults setBool:YES forKey:kSetHideExtensionStateKey];
+ }
+ break;
+
+ case NAVIGATIONSERVICES_DIRECTORY:
+ OSL_TRACE("NAVIGATIONSERVICES_DIRECTORY");
+ m_pDialog = [NSOpenPanel openPanel];
+ [(NSOpenPanel*)m_pDialog setCanChooseDirectories:YES];
+ [(NSOpenPanel*)m_pDialog setCanChooseFiles:NO];
+ break;
+
+ default:
+ OSL_TRACE("m_nDialogType is UNKNOWN: %d", m_nDialogType);
+ break;
+ }
+
+ if (m_pDialog == nil) {
+ OSL_TRACE("An error occurred while creating the dialog!");
+ }
+ else {
+ [(NSOpenPanel*)m_pDialog setCanCreateDirectories:YES];
+ //Retain the dialog instance or it will go away immediately
+ [m_pDialog retain];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+int SalAquaPicker::run()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+
+ if (m_pDialog == NULL) {
+ //this is the case e.g. for the folder picker at this stage
+ implInitialize();
+ }
+
+ NSView *userPane = m_pControlHelper->getUserPane();
+ if (userPane != NULL) {
+ [m_pDialog setAccessoryView:userPane];
+ }
+
+ int retVal = 0;
+
+ NSString *startDirectory;
+ if (m_sDisplayDirectory.getLength() > 0) {
+ NSString *temp = [NSString stringWithOUString:m_sDisplayDirectory];
+ NSURL *url = [NSURL URLWithString:temp];
+ startDirectory = [url path];
+
+ OSL_TRACE("start dir: %s", [startDirectory UTF8String]);
+ // NSLog(@"%@", startDirectory);
+ }
+ else {
+ startDirectory = NSHomeDirectory();
+ }
+
+ switch(m_nDialogType) {
+ case NAVIGATIONSERVICES_DIRECTORY:
+ case NAVIGATIONSERVICES_OPEN:
+ retVal = [(NSOpenPanel*)m_pDialog runModalForDirectory:startDirectory file:nil types:nil];
+ break;
+ case NAVIGATIONSERVICES_SAVE:
+ retVal = [m_pDialog runModalForDirectory:startDirectory file:[NSString stringWithOUString:((SalAquaFilePicker*)this)->getSaveFileName()]/*[m_pDialog saveFilename]*/];
+ break;
+ // [m_pDialog beginSheetForDirectory:startDirectory file:[m_pDialog saveFilename] modalForWindow:[NSApp keyWindow] modalDelegate:((SalAquaFilePicker*)this)->getDelegate() didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:nil];
+ default:
+ break;
+ }
+
+ if (retVal == NSFileHandlingPanelOKButton) {
+ implsetDisplayDirectory([[NSURL fileURLWithPath:[m_pDialog directory]] OUStringForInfo:FULLPATH]);
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, retVal);
+
+ [pool release];
+
+ return retVal;
+}
+
+int SalAquaPicker::runandwaitforresult()
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ int status = this->run();
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, status);
+ return status;
+}
+
+void SAL_CALL SalAquaPicker::implsetDisplayDirectory( const rtl::OUString& aDirectory )
+ throw( lang::IllegalArgumentException, uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "directory", aDirectory);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (aDirectory != m_sDisplayDirectory) {
+ m_sDisplayDirectory = aDirectory;
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
+rtl::OUString SAL_CALL SalAquaPicker::implgetDisplayDirectory() throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__);
+ DBG_PRINT_EXIT(CLASS_NAME, __func__, m_sDisplayDirectory);
+
+ return m_sDisplayDirectory;
+}
+
+void SAL_CALL SalAquaPicker::implsetTitle( const rtl::OUString& aTitle ) throw( uno::RuntimeException )
+{
+ DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle);
+
+ ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ if (m_pDialog != nil) {
+ [m_pDialog setTitle:[NSString stringWithOUString:aTitle]];
+ }
+
+ DBG_PRINT_EXIT(CLASS_NAME, __func__);
+}
+
diff --git a/fpicker/source/aqua/SalAquaPicker.hxx b/fpicker/source/aqua/SalAquaPicker.hxx
new file mode 100644
index 000000000000..79fd6b4dc924
--- /dev/null
+++ b/fpicker/source/aqua/SalAquaPicker.hxx
@@ -0,0 +1,109 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: SalAquaPicker.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _SALAQUAFPICKER_HXX_
+#define _SALAQUAFPICKER_HXX_
+
+//_____________________________________________________________________________
+// includes of other projects
+//_____________________________________________________________________________
+
+#include <osl/mutex.hxx>
+
+#ifndef _RTL_USTRING_HXX
+#include <rtl/ustring.hxx>
+#endif
+
+#ifndef _COM_SUN_STAR_LANG_ILLEGALARGUMENTEXCEPTION_HXX_
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#endif
+
+#ifndef _COM_SUN_STAR_UNO_RUNTIMEEXCEPTION_HXX_
+#include <com/sun/star/uno/RuntimeException.hpp>
+#endif
+#include "ControlHelper.hxx"
+
+#include <premac.h>
+#import <Cocoa/Cocoa.h>
+#include <postmac.h>
+
+//----------------------------------------------------------
+// class declaration
+//----------------------------------------------------------
+
+class SalAquaPicker
+{
+public:
+ // constructor
+ SalAquaPicker();
+ virtual ~SalAquaPicker();
+
+ int run();
+ int runandwaitforresult();
+
+ inline rtl::OUString getDisplayDirectory() { return m_sDisplayDirectory; }
+
+ inline ControlHelper* getControlHelper() const {
+ return m_pControlHelper;
+ }
+
+protected:
+
+ rtl::OUString m_sDisplayDirectory;
+
+ NSSavePanel *m_pDialog;
+
+ ControlHelper *m_pControlHelper;
+
+ osl::Mutex m_rbHelperMtx;
+
+ // The type of dialog
+ enum NavigationServices_DialogType {
+ NAVIGATIONSERVICES_OPEN,
+ NAVIGATIONSERVICES_SAVE,
+ NAVIGATIONSERVICES_DIRECTORY
+ };
+
+ NavigationServices_DialogType m_nDialogType;
+
+ void implsetTitle( const ::rtl::OUString& aTitle )
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ void implsetDisplayDirectory( const rtl::OUString& rDirectory )
+ throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException );
+
+ rtl::OUString implgetDisplayDirectory( )
+ throw( com::sun::star::uno::RuntimeException );
+
+ void implInitialize( );
+
+};
+
+#endif
diff --git a/fpicker/source/aqua/exports.map b/fpicker/source/aqua/exports.map
new file mode 100644
index 000000000000..f4ed78b9e970
--- /dev/null
+++ b/fpicker/source/aqua/exports.map
@@ -0,0 +1,8 @@
+UDK_3_0_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/fpicker/source/aqua/fps-aqua-ucd.txt b/fpicker/source/aqua/fps-aqua-ucd.txt
new file mode 100644
index 000000000000..d71e8f4a574f
--- /dev/null
+++ b/fpicker/source/aqua/fps-aqua-ucd.txt
@@ -0,0 +1,13 @@
+[ComponentDescriptor]
+ImplementationName=com.sun.star.ui.dialogs.SalAquaFilePicker
+ComponentName=fps_aqua.uno.dylib
+LoaderName=com.sun.star.loader.SharedLibrary
+[SupportedServices]
+com.sun.star.ui.dialogs.AquaFilePicker
+
+[ComponentDescriptor]
+ImplementationName=com.sun.star.ui.dialogs.SalAquaFolderPicker
+ComponentName=fps_aqua.uno.dylib
+LoaderName=com.sun.star.loader.SharedLibrary
+[SupportedServices]
+com.sun.star.ui.dialogs.AquaFolderPicker
diff --git a/fpicker/source/aqua/fps_aqua.xml b/fpicker/source/aqua/fps_aqua.xml
new file mode 100644
index 000000000000..955ad4e32886
--- /dev/null
+++ b/fpicker/source/aqua/fps_aqua.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name>fps</module-name>
+ <component-description>
+ <author>Florian Heckl, Pavel Janík</author>
+ <name>com.sun.star.comp.ui.dialogs.FilePicker</name>
+ <description>
+ The native Mac OS X (Aqua) implementation of the FilePicker service.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.ui.dialogs.FilePicker</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.ui.dialogs.XExecutableDialog</type>
+ <type>com.sun.star.ui.dialogs.XFilePicker</type>
+ <type>com.sun.star.ui.dialogs.XFilterManager</type>
+ <type>com.sun.star.ui.dialogs.XFilterGroupManager</type>
+ <type>com.sun.star.ui.dialogs.XFilePickerListener</type>
+ <type>com.sun.star.ui.dialogs.ExecutableDialogException</type>
+ <type>com.sun.star.ui.dialogs.XFilePickerNotifier</type>
+ <type>com.sun.star.ui.dialogs.XFilePickerControlAccess</type>
+ <type>com.sun.star.ui.dialogs.ExtendedFilePickerElementIds</type>
+ <type>com.sun.star.ui.dialogs.ExecutableDialogResults</type>
+ <type>com.sun.star.ui.dialogs.FilePickerEvent</type>
+ <type>com.sun.star.ui.dialogs.CommonFilePickerElementIds</type>
+ <type>com.sun.star.ui.dialogs.ListboxControlActions</type>
+ <type>com.sun.star.ui.dialogs.TemplateDescription</type>
+ <type>com.sun.star.ui.dialogs.FilePreviewImageFormats</type>
+ <type>com.sun.star.util.XCancellable</type>
+ <type>com.sun.star.lang.XComponent</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.uno.TypeClass</type>
+ <type>com.sun.star.uno.XWeak</type>
+ <type>com.sun.star.uno.XAggregation</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.container.XSet</type>
+ </component-description>
+ <component-description>
+ <author>Florian Heckl, Pavel Janík</author>
+ <name>com.sun.star.comp.ui.dialogs.FolderPicker</name>
+ <description>
+ The native Mac OS X (Aqua) implementation of the FolderPicker service.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>c++</language>
+ <status value="beta"/>
+ <supported-service>com.sun.star.ui.dialogs.FolderPicker</supported-service>
+ <service-dependency>...</service-dependency>
+ <type>com.sun.star.ui.dialogs.XExecutableDialog</type>
+ <type>com.sun.star.ui.dialogs.XFolderPicker</type>
+ <type>com.sun.star.ui.dialogs.ExecutableDialogException</type>
+ <type>com.sun.star.ui.dialogs.ExecutableDialogResults</type>
+ <type>com.sun.star.util.XCancellable</type>
+ <type>com.sun.star.lang.XComponent</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.lang.IllegalArgumentException</type>
+ <type>com.sun.star.uno.TypeClass</type>
+ <type>com.sun.star.uno.XWeak</type>
+ <type>com.sun.star.uno.XAggregation</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.container.XSet</type>
+ </component-description>
+ <project-build-dependency>cppuhelper</project-build-dependency>
+ <project-build-dependency>cppu</project-build-dependency>
+ <project-build-dependency>sal</project-build-dependency>
+ <runtime-module-dependency>cppuhelper</runtime-module-dependency>
+ <runtime-module-dependency>cppu2</runtime-module-dependency>
+ <runtime-module-dependency>sal2</runtime-module-dependency>
+</module-description>
diff --git a/fpicker/source/aqua/makefile.mk b/fpicker/source/aqua/makefile.mk
new file mode 100644
index 000000000000..e6a8247480c9
--- /dev/null
+++ b/fpicker/source/aqua/makefile.mk
@@ -0,0 +1,89 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.4 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=fpicker
+TARGET=fps_aqua.uno
+TARGETTYPE=GUI
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+DLLPRE=
+
+# ------------------------------------------------------------------
+
+.IF "$(GUIBASE)" != "aqua"
+
+dummy:
+ @echo "Nothing to build. GUIBASE == $(GUIBASE)"
+
+.ELSE # we build for aqua
+CFLAGSCXX+=$(OBJCXXFLAGS)
+
+# --- Files --------------------------------------------------------
+
+SLOFILES =\
+ $(SLO)$/resourceprovider.obj \
+ $(SLO)$/FPentry.obj \
+ $(SLO)$/SalAquaPicker.obj \
+ $(SLO)$/SalAquaFilePicker.obj \
+ $(SLO)$/SalAquaFolderPicker.obj \
+ $(SLO)$/CFStringUtilities.obj \
+ $(SLO)$/FilterHelper.obj \
+ $(SLO)$/ControlHelper.obj \
+ $(SLO)$/NSString_OOoAdditions.obj \
+ $(SLO)$/NSURL_OOoAdditions.obj \
+ $(SLO)$/AquaFilePickerDelegate.obj
+
+SHL1NOCHECK=TRUE
+SHL1TARGET= $(TARGET)
+SHL1OBJS= $(SLOFILES)
+SHL1STDLIBS=\
+ $(VCLLIB) \
+ $(TOOLSLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP=exports.map
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME=$(SHL1TARGET)
+
+.ENDIF # "$(GUIBASE)" != "aqua"
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/fpicker/source/aqua/resourceprovider.cxx b/fpicker/source/aqua/resourceprovider.cxx
new file mode 100644
index 000000000000..75dfacbf8f2d
--- /dev/null
+++ b/fpicker/source/aqua/resourceprovider.cxx
@@ -0,0 +1,243 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: resourceprovider.cxx,v $
+ * $Revision: 1.5 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <tools/resmgr.hxx>
+#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
+#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
+
+#ifndef _SVTOOLS_SVTOOLS_HRC_
+#include <svtools/svtools.hrc>
+#endif
+
+#ifndef _SVTOOLS_FILEDLG2_HRC_
+#include <svtools/filedlg2.hrc>
+#endif
+#include "NSString_OOoAdditions.hxx"
+
+#include "resourceprovider.hxx"
+
+//------------------------------------------------------------
+// namespace directives
+//------------------------------------------------------------
+
+using rtl::OUString;
+using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
+using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+static const char* RES_NAME = "fps_office";
+static const char* OTHER_RES_NAME = "svt";
+
+//------------------------------------------------------------
+// we have to translate control ids to resource ids
+//------------------------------------------------------------
+
+struct _Entry
+{
+ sal_Int32 ctrlId;
+ sal_Int16 resId;
+};
+
+_Entry CtrlIdToResIdTable[] = {
+ { CHECKBOX_AUTOEXTENSION, STR_SVT_FILEPICKER_AUTO_EXTENSION },
+ { CHECKBOX_PASSWORD, STR_SVT_FILEPICKER_PASSWORD },
+ { CHECKBOX_FILTEROPTIONS, STR_SVT_FILEPICKER_FILTER_OPTIONS },
+ { CHECKBOX_READONLY, STR_SVT_FILEPICKER_READONLY },
+ { CHECKBOX_LINK, STR_SVT_FILEPICKER_INSERT_AS_LINK },
+ { CHECKBOX_PREVIEW, STR_SVT_FILEPICKER_SHOW_PREVIEW },
+ { PUSHBUTTON_PLAY, STR_SVT_FILEPICKER_PLAY },
+ { LISTBOX_VERSION_LABEL, STR_SVT_FILEPICKER_VERSION },
+ { LISTBOX_TEMPLATE_LABEL, STR_SVT_FILEPICKER_TEMPLATES },
+ { LISTBOX_IMAGE_TEMPLATE_LABEL, STR_SVT_FILEPICKER_IMAGE_TEMPLATE },
+ { CHECKBOX_SELECTION, STR_SVT_FILEPICKER_SELECTION },
+ { FOLDERPICKER_TITLE, STR_SVT_FOLDERPICKER_DEFAULT_TITLE },
+ { FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION },
+ { FILE_PICKER_OVERWRITE, STR_SVT_ALREADYEXISTOVERWRITE },
+ { LISTBOX_FILTER_LABEL, STR_SVT_FILEPICKER_FILTER_TITLE}
+};
+
+_Entry OtherCtrlIdToResIdTable[] = {
+ { FILE_PICKER_TITLE_OPEN, STR_FILEDLG_OPEN },
+ { FILE_PICKER_TITLE_SAVE, STR_FILEDLG_SAVE },
+ { FILE_PICKER_FILE_TYPE, STR_FILEDLG_TYPE }
+};
+
+
+const sal_Int32 SIZE_TABLE = sizeof( CtrlIdToResIdTable ) / sizeof( _Entry );
+const sal_Int32 OTHER_SIZE_TABLE = sizeof( OtherCtrlIdToResIdTable ) / sizeof( _Entry );
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+sal_Int16 CtrlIdToResId( sal_Int32 aControlId )
+{
+ sal_Int16 aResId = -1;
+
+ for ( sal_Int32 i = 0; i < SIZE_TABLE; i++ )
+ {
+ if ( CtrlIdToResIdTable[i].ctrlId == aControlId )
+ {
+ aResId = CtrlIdToResIdTable[i].resId;
+ break;
+ }
+ }
+
+ return aResId;
+}
+
+sal_Int16 OtherCtrlIdToResId( sal_Int32 aControlId )
+{
+ sal_Int16 aResId = -1;
+
+ for ( sal_Int32 i = 0; i < OTHER_SIZE_TABLE; i++ )
+ {
+ if ( OtherCtrlIdToResIdTable[i].ctrlId == aControlId )
+ {
+ aResId = OtherCtrlIdToResIdTable[i].resId;
+ break;
+ }
+ }
+
+ return aResId;
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+class CResourceProvider_Impl
+{
+public:
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ CResourceProvider_Impl( )
+ {
+ m_ResMgr = ResMgr::CreateResMgr( RES_NAME );
+ m_OtherResMgr = ResMgr::CreateResMgr( OTHER_RES_NAME );
+ }
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ ~CResourceProvider_Impl( )
+ {
+ delete m_ResMgr;
+ delete m_OtherResMgr;
+ }
+
+ //-------------------------------------
+ //
+ //-------------------------------------
+
+ NSString* getResString( sal_Int16 aId )
+ {
+ String aResString;
+ OUString aResOUString;
+
+ const ::vos::OGuard aGuard( Application::GetSolarMutex() );
+
+ try
+ {
+ OSL_ASSERT( m_ResMgr && m_OtherResMgr );
+
+ // translate the control id to a resource id
+ sal_Int16 aResId = CtrlIdToResId( aId );
+ if ( aResId > -1 )
+ aResString = String( ResId( aResId, *m_ResMgr ) );
+ else
+ {
+ aResId = OtherCtrlIdToResId( aId );
+ if ( aResId > -1 ) {
+ aResString = String( ResId( aResId, *m_OtherResMgr ) );
+ }
+ }
+ if ( aResId > -1 )
+ aResOUString = OUString( aResString );
+ }
+ catch(...)
+ {
+ }
+
+ return [NSString stringWithOUString:aResOUString];
+ }
+
+public:
+ ResMgr* m_ResMgr;
+ ResMgr* m_OtherResMgr;
+};
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+CResourceProvider::CResourceProvider( ) :
+ m_pImpl( new CResourceProvider_Impl() )
+{
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+CResourceProvider::~CResourceProvider( )
+{
+ delete m_pImpl;
+}
+
+//------------------------------------------------------------
+//
+//------------------------------------------------------------
+
+NSString* CResourceProvider::getResString( sal_Int32 aId )
+{
+ NSString* sImmutable = m_pImpl->getResString( aId );
+ NSMutableString *sMutableString = [NSMutableString stringWithString:sImmutable];
+ [sMutableString replaceOccurrencesOfString:@"~" withString:@"" options:0 range:NSMakeRange(0, [sMutableString length])];
+
+ NSString *result = [NSString stringWithString:sMutableString];
+
+ return result;
+}
diff --git a/fpicker/source/aqua/resourceprovider.hxx b/fpicker/source/aqua/resourceprovider.hxx
new file mode 100644
index 000000000000..987a19790423
--- /dev/null
+++ b/fpicker/source/aqua/resourceprovider.hxx
@@ -0,0 +1,70 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: resourceprovider.hxx,v $
+ * $Revision: 1.4 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef _RESOURCEPROVIDER_HXX_
+#define _RESOURCEPROVIDER_HXX_
+
+//------------------------------------------------------------------------
+// includes
+//------------------------------------------------------------------------
+
+#include <sal/types.h>
+
+#include <premac.h>
+#include <Cocoa/Cocoa.h>
+#include <postmac.h>
+
+#define FOLDERPICKER_TITLE 500
+#define FOLDER_PICKER_DEF_DESCRIPTION 501
+#define FILE_PICKER_TITLE_OPEN 502
+#define FILE_PICKER_TITLE_SAVE 503
+#define FILE_PICKER_FILE_TYPE 504
+#define FILE_PICKER_OVERWRITE 505
+
+//------------------------------------------------------------------------
+// declarations
+//------------------------------------------------------------------------
+
+class CResourceProvider_Impl;
+
+class CResourceProvider
+{
+public:
+ CResourceProvider( );
+ ~CResourceProvider( );
+
+ NSString* getResString( sal_Int32 aId );
+
+private:
+ CResourceProvider_Impl* m_pImpl;
+};
+
+#endif