diff options
Diffstat (limited to 'fpicker/source/aqua')
26 files changed, 5299 insertions, 0 deletions
diff --git a/fpicker/source/aqua/AquaFilePickerDelegate.hxx b/fpicker/source/aqua/AquaFilePickerDelegate.hxx new file mode 100644 index 000000000000..9515cdb59aa9 --- /dev/null +++ b/fpicker/source/aqua/AquaFilePickerDelegate.hxx @@ -0,0 +1,57 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..4266453a7102 --- /dev/null +++ b/fpicker/source/aqua/AquaFilePickerDelegate.mm @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..14b87b0d8759 --- /dev/null +++ b/fpicker/source/aqua/CFStringUtilities.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..f742dde67081 --- /dev/null +++ b/fpicker/source/aqua/CFStringUtilities.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..470c22e09b10 --- /dev/null +++ b/fpicker/source/aqua/ControlHelper.cxx @@ -0,0 +1,1019 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..c9a146c7532f --- /dev/null +++ b/fpicker/source/aqua/ControlHelper.hxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..66cff666db45 --- /dev/null +++ b/fpicker/source/aqua/FPServiceInfo.hxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..5d5dc16c5d32 --- /dev/null +++ b/fpicker/source/aqua/FPentry.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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; +} + +//------------------------------------------------ +// +//------------------------------------------------ + +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..9c644326005e --- /dev/null +++ b/fpicker/source/aqua/FilterHelper.cxx @@ -0,0 +1,545 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 "NSURL_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__); + + if (m_aCurrentFilter == NULL) { + OSL_TRACE("filter name is null"); + return sal_True; + } + + NSFileManager *manager = [NSFileManager defaultManager]; + NSDictionary* pAttribs = [manager fileAttributesAtPath: sFilename traverseLink: NO]; + if( pAttribs ) + { + NSObject* pType = [pAttribs objectForKey: NSFileType]; + if( pType && [pType isKindOfClass: [NSString class]] ) + { + NSString* pT = (NSString*)pType; + if( [pT isEqualToString: NSFileTypeDirectory] || + [pT isEqualToString: NSFileTypeSymbolicLink] ) + return sal_True; + } + } + + 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(); + + { + 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; + } + } + } + + // might be an alias + NSString* pResolved = resolveAlias( sFilename ); + if( pResolved ) + { + sal_Bool bResult = filenameMatchesFilter( pResolved ); + [pResolved autorelease]; + if( bResult ) + 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..0c4e7562389d --- /dev/null +++ b/fpicker/source/aqua/FilterHelper.hxx @@ -0,0 +1,160 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..09c6029de126 --- /dev/null +++ b/fpicker/source/aqua/NSString_OOoAdditions.hxx @@ -0,0 +1,44 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..6707cff4c847 --- /dev/null +++ b/fpicker/source/aqua/NSString_OOoAdditions.mm @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..31b55385e155 --- /dev/null +++ b/fpicker/source/aqua/NSURL_OOoAdditions.hxx @@ -0,0 +1,48 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 <CoreFoundation/CoreFoundation.h> +#include <postmac.h> +#include "CFStringUtilities.hxx" +#include <rtl/ustring.hxx> + +@interface NSURL (OOoAdditions) +- (rtl::OUString) OUStringForInfo:(InfoType)info; +@end + +/* + returns the resolved string if there was an alias + if there was no alias, nil is returned +*/ + +NSString* resolveAlias( NSString* i_pSystemPath ); + +#endif diff --git a/fpicker/source/aqua/NSURL_OOoAdditions.mm b/fpicker/source/aqua/NSURL_OOoAdditions.mm new file mode 100644 index 000000000000..ecc38b7e232b --- /dev/null +++ b/fpicker/source/aqua/NSURL_OOoAdditions.mm @@ -0,0 +1,112 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 + +NSString* resolveAlias( NSString* i_pSystemPath ) +{ + NSString* pResolvedPath = nil; + CFURLRef rUrl = CFURLCreateWithFileSystemPath( kCFAllocatorDefault, + (CFStringRef)i_pSystemPath, + kCFURLPOSIXPathStyle, false); + if( rUrl != NULL ) + { + FSRef rFS; + if( CFURLGetFSRef( rUrl, &rFS ) ) + { + MacOSBoolean bIsFolder = false; + MacOSBoolean bAlias = false; + OSErr err = FSResolveAliasFile( &rFS, true, &bIsFolder, &bAlias); + if( (err == noErr) && bAlias ) + { + CFURLRef rResolvedUrl = CFURLCreateFromFSRef( kCFAllocatorDefault, &rFS ); + if( rResolvedUrl != NULL ) + { + pResolvedPath = (NSString*)CFURLCopyFileSystemPath( rResolvedUrl, kCFURLPOSIXPathStyle ); + CFRelease( rResolvedUrl ); + } + } + } + CFRelease( rUrl ); + } + + return pResolvedPath; +} diff --git a/fpicker/source/aqua/SalAquaConstants.h b/fpicker/source/aqua/SalAquaConstants.h new file mode 100644 index 000000000000..83d74c63fc09 --- /dev/null +++ b/fpicker/source/aqua/SalAquaConstants.h @@ -0,0 +1,63 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..699997bd2dbe --- /dev/null +++ b/fpicker/source/aqua/SalAquaFilePicker.cxx @@ -0,0 +1,812 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..60795d87dec9 --- /dev/null +++ b/fpicker/source/aqua/SalAquaFilePicker.hxx @@ -0,0 +1,252 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..60857e47c6c3 --- /dev/null +++ b/fpicker/source/aqua/SalAquaFolderPicker.cxx @@ -0,0 +1,289 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..b7529a11e34f --- /dev/null +++ b/fpicker/source/aqua/SalAquaFolderPicker.hxx @@ -0,0 +1,138 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..1a4132f23ea5 --- /dev/null +++ b/fpicker/source/aqua/SalAquaPicker.cxx @@ -0,0 +1,267 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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) { + NSString* pDir = [m_pDialog directory]; + if (pDir) { + implsetDisplayDirectory([[NSURL fileURLWithPath:pDir] 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..be22ffddf063 --- /dev/null +++ b/fpicker/source/aqua/SalAquaPicker.hxx @@ -0,0 +1,106 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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/fps_aqua.component b/fpicker/source/aqua/fps_aqua.component new file mode 100644 index 000000000000..a04443e37ffd --- /dev/null +++ b/fpicker/source/aqua/fps_aqua.component @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!--********************************************************************** +* +* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +* +* Copyright 2000, 2010 Oracle and/or its affiliates. +* +* OpenOffice.org - a multi-platform office productivity suite +* +* 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. +* +**********************************************************************--> + +<component loader="com.sun.star.loader.SharedLibrary" + xmlns="http://openoffice.org/2010/uno-components"> + <implementation name="com.sun.star.ui.dialogs.SalAquaFilePicker"> + <service name="com.sun.star.ui.dialogs.AquaFilePicker"/> + </implementation> + <implementation name="com.sun.star.ui.dialogs.SalAquaFolderPicker"> + <service name="com.sun.star.ui.dialogs.AquaFolderPicker"/> + </implementation> +</component> 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..ff0473c8a71e --- /dev/null +++ b/fpicker/source/aqua/makefile.mk @@ -0,0 +1,93 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# 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=$(SOLARENV)/src/component.map +SHL1DEF= $(MISC)$/$(SHL1TARGET).def +DEF1NAME=$(SHL1TARGET) + +.ENDIF # "$(GUIBASE)" != "aqua" + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + +ALLTAR : $(MISC)/fps_aqua.component + +$(MISC)/fps_aqua.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \ + fps_aqua.component + $(XSLTPROC) --nonet --stringparam uri \ + '$(COMPONENTPREFIX_BASIS_NATIVE)$(SHL1TARGETN:f)' -o $@ \ + $(SOLARENV)/bin/createcomponent.xslt fps_aqua.component diff --git a/fpicker/source/aqua/resourceprovider.cxx b/fpicker/source/aqua/resourceprovider.cxx new file mode 100644 index 000000000000..51985208c7ed --- /dev/null +++ b/fpicker/source/aqua/resourceprovider.cxx @@ -0,0 +1,240 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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..66323e9a08e5 --- /dev/null +++ b/fpicker/source/aqua/resourceprovider.hxx @@ -0,0 +1,67 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * 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 |