X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/9854b6eddf82c31af6753452bb3c2d0b7cb7d2a8..2078e2f129c323dd1b01aeef5061f787f8475386:/src/mac/carbon/filedlg.cpp diff --git a/src/mac/carbon/filedlg.cpp b/src/mac/carbon/filedlg.cpp index 15771305be..81845d173e 100644 --- a/src/mac/carbon/filedlg.cpp +++ b/src/mac/carbon/filedlg.cpp @@ -1,44 +1,38 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: filedlg.cpp -// Purpose: wxFileDialog -// Author: AUTHOR +// Name: src/mac/carbon/filedlg.cpp +// Purpose: wxFileDialog +// Author: Stefan Csomor // Modified by: -// Created: ??/??/98 +// Created: 1998-01-01 // RCS-ID: $Id$ -// Copyright: (c) AUTHOR +// Copyright: (c) Stefan Csomor // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "filedlg.h" -#endif +#include "wx/wxprec.h" -#include "wx/defs.h" -#include "wx/app.h" -#include "wx/utils.h" -#include "wx/dialog.h" -#include "wx/filedlg.h" -#include "wx/intl.h" -#include "wx/tokenzr.h" +#if wxUSE_FILEDLG -#ifndef __DARWIN__ - #include "PLStringFuncs.h" -#endif +#include "wx/filedlg.h" -#if !USE_SHARED_LIBRARY -IMPLEMENT_CLASS(wxFileDialog, wxDialog) +#ifndef WX_PRECOMP + #include "wx/intl.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/dialog.h" #endif -// begin wxmac +#include "wx/tokenzr.h" +#include "wx/filename.h" #include "wx/mac/private.h" -#include - -#include "MoreFiles.h" -#include "MoreFilesExtras.h" +#ifndef __DARWIN__ + #include + #include "PLStringFuncs.h" +#endif -extern bool gUseNavServices ; +IMPLEMENT_CLASS(wxFileDialog, wxFileDialogBase) // the data we need to pass to our standard file hook routine // includes a pointer to the dialog, a pointer to the standard @@ -46,521 +40,397 @@ extern bool gUseNavServices ; // and a copy of the "previous" file spec of the reply record // so we can see if the selection has changed -const int kwxMacFileTypes = 10 ; - -struct OpenUserDataRec { - int currentfilter ; - wxString name [kwxMacFileTypes] ; - wxString extensions[kwxMacFileTypes] ; - OSType filtermactypes[kwxMacFileTypes] ; - int numfilters ; -}; -typedef struct OpenUserDataRec - OpenUserDataRec, *OpenUserDataRecPtr; - -static pascal void NavEventProc( - NavEventCallbackMessage inSelector, - NavCBRecPtr ioParams, - NavCallBackUserData ioUserData); - -#if TARGET_CARBON - static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc); -#else - static NavEventUPP sStandardNavEventFilter = NewNavEventProc(NavEventProc); -#endif - -static pascal void -NavEventProc( - NavEventCallbackMessage inSelector, - NavCBRecPtr ioParams, - NavCallBackUserData ioUserData ) +struct OpenUserDataRec { - OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ; - if (inSelector == kNavCBEvent) { - // In Universal Headers 3.2, Apple changed the definition of - /* - #if UNIVERSAL_INTERFACES_VERSION >= 0x0320 // Universal Headers 3.2 - UModalAlerts::ProcessModalEvent(*(ioParams->eventData.eventDataParms.event)); - - #else - UModalAlerts::ProcessModalEvent(*(ioParams->eventData.event)); - #endif - */ - - wxTheApp->MacHandleOneEvent(ioParams->eventData.eventDataParms.event); - } else if ( inSelector == kNavCBPopupMenuSelect ) - { - NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; - data->currentfilter = menu->menuType ; - } -} + int currentfilter ; + bool saveMode ; + wxArrayString name ; + wxArrayString extensions ; + wxArrayLong filtermactypes ; + wxString defaultLocation; + CFArrayRef menuitems ; +}; -const char * gfilters[] = -{ - "*.TXT" , - "*.TIF" , - "*.JPG" , - - NULL -} ; - -OSType gfiltersmac[] = -{ - 'TEXT' , - 'TIFF' , - 'JPEG' , - - '****' -} ; +typedef struct OpenUserDataRec +OpenUserDataRec, *OpenUserDataRecPtr; +static pascal void NavEventProc( + NavEventCallbackMessage inSelector, + NavCBRecPtr ioParams, + NavCallBackUserData ioUserData ); +static NavEventUPP sStandardNavEventFilter = NewNavEventUPP(NavEventProc); -void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) +static pascal void NavEventProc( + NavEventCallbackMessage inSelector, + NavCBRecPtr ioParams, + NavCallBackUserData ioUserData ) { - myData->currentfilter = 0 ; - - if ( filter && filter[0] ) - { - wxString filter2(filter) ; - int filterIndex = 0; - bool isName = true ; - wxString current ; - for( unsigned int i = 0; i < filter2.Len(); i++ ) + OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ; + if (inSelector == kNavCBEvent) + { + } + else if ( inSelector == kNavCBStart ) { - if( filter2.GetChar(i) == wxT('|') ) - { - if( isName ) { - myData->name[filterIndex] = current ; + if (data && !(data->defaultLocation).empty()) + { + // Set default location for the modern Navigation APIs + // Apple Technical Q&A 1151 + FSRef theFile; + wxMacPathToFSRef(data->defaultLocation, &theFile); + AEDesc theLocation = { typeNull, NULL }; + if (noErr == ::AECreateDesc(typeFSRef, &theFile, sizeof(FSRef), &theLocation)) + ::NavCustomControl(ioParams->context, kNavCtlSetLocation, (void *) &theLocation); } - else { - myData->extensions[filterIndex] = current.MakeUpper() ; - ++filterIndex ; + + if( data->extensions.GetCount() > 0 ) + { + NavMenuItemSpec menuItem; + memset( &menuItem, 0, sizeof(menuItem) ); + menuItem.version = kNavMenuItemSpecVersion; + menuItem.menuType = data->currentfilter; + ::NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &menuItem); } - isName = !isName ; - current = "" ; - } - else - { - current += filter2.GetChar(i) ; - } } -// if ( filterIndex > 0 ) + else if ( inSelector == kNavCBPopupMenuSelect ) { - wxASSERT_MSG( !isName , "incorrect format of format string" ) ; - myData->extensions[filterIndex] = current.MakeUpper() ; - ++filterIndex ; - } - - myData->numfilters = filterIndex ; - for ( int i = 0 ; i < myData->numfilters ; i++ ) - { - int j ; - for ( j = 0 ; gfilters[j] ; j++ ) - { - if ( strcmp( myData->extensions[i] , gfilters[j] ) == 0 ) - { - myData->filtermactypes[i] = gfiltersmac[j] ; - break ; - } - } - if( gfilters[j] == NULL ) - { - myData->filtermactypes[i] = '****' ; - } - } - } - else - { - myData->numfilters = 0 ; - } + NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; + const size_t numFilters = data->extensions.GetCount(); + if ( menu->menuType < numFilters ) + { + data->currentfilter = menu->menuType ; + if ( data->saveMode ) + { + int i = menu->menuType ; + + // isolate the first extension string + wxString firstExtension = data->extensions[i].BeforeFirst('|').BeforeFirst(';'); + + wxString extension = firstExtension.AfterLast('.') ; + wxString sfilename ; + + wxMacCFStringHolder cfString( NavDialogGetSaveFileName( ioParams->context ) , false ); + sfilename = cfString.AsString() ; + + int pos = sfilename.Find('.', true) ; + if ( pos != wxNOT_FOUND && extension != wxT("*") ) + { + sfilename = sfilename.Left(pos+1)+extension ; + cfString.Assign( sfilename , wxFONTENCODING_DEFAULT ) ; + NavDialogSetSaveFileName( ioParams->context , cfString ) ; + } + } + } + } } -static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecPtr data) +void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) { - Str255 filename ; - -#if TARGET_CARBON - p2cstrcpy((char *)filename, name) ; -#else - PLstrcpy( filename , name ) ; - p2cstr( filename ) ; -#endif - wxString file(filename) ; - file.MakeUpper() ; - - if ( data->numfilters > 0 ) + myData->menuitems = NULL ; + myData->currentfilter = 0 ; + myData->saveMode = false ; + + if ( !filter.empty() ) { - //for ( int i = 0 ; i < data->numfilters ; ++i ) - int i = data->currentfilter ; - if ( data->extensions[i].Right(2) == ".*" ) - return true ; - - { - if ( type == data->filtermactypes[i] ) - return true ; - - wxStringTokenizer tokenizer( data->extensions[i] , ";" ) ; - while( tokenizer.HasMoreTokens() ) - { - wxString extension = tokenizer.GetNextToken() ; - if ( extension.GetChar(0) == '*' ) - extension = extension.Mid(1) ; - - if ( file.Len() >= extension.Len() && extension == file.Right(extension.Len() ) ) - return true ; - } - } - return false ; - } - return true ; -} + wxString filter2(filter) ; + int filterIndex = 0; + bool isName = true ; + wxString current ; -#ifndef __DARWIN__ -static pascal Boolean CrossPlatformFileFilter(CInfoPBPtr myCInfoPBPtr, void *dataPtr) -{ - OpenUserDataRecPtr data = (OpenUserDataRecPtr) dataPtr ; - // return true if this item is invisible or a file - - Boolean visibleFlag; - Boolean folderFlag; - - visibleFlag = ! (myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdFlags & kIsInvisible); - folderFlag = (myCInfoPBPtr->hFileInfo.ioFlAttrib & 0x10); - - // because the semantics of the filter proc are "true means don't show - // it" we need to invert the result that we return - - if ( !visibleFlag ) - return true ; - - if ( !folderFlag ) - { - return !CheckFile( myCInfoPBPtr->hFileInfo.ioNamePtr , myCInfoPBPtr->hFileInfo.ioFlFndrInfo.fdType , data ) ; - } - - return false ; -} -#endif + for ( unsigned int i = 0; i < filter2.length() ; i++ ) + { + if ( filter2.GetChar(i) == wxT('|') ) + { + if ( isName ) + { + myData->name.Add( current ) ; + } + else + { + myData->extensions.Add( current ) ; + ++filterIndex ; + } + + isName = !isName ; + current = wxEmptyString ; + } + else + { + current += filter2.GetChar(i) ; + } + } + // we allow for compatibility reason to have a single filter expression (like *.*) without + // an explanatory text, in that case the first part is name and extension at the same time -// end wxmac + wxASSERT_MSG( filterIndex == 0 || !isName , wxT("incorrect format of format string") ) ; + if ( current.empty() ) + myData->extensions.Add( myData->name[filterIndex] ) ; + else + myData->extensions.Add( current ) ; + if ( filterIndex == 0 || isName ) + myData->name.Add( current ) ; -wxString wxFileSelector(const char *title, - const char *defaultDir, const char *defaultFileName, - const char *defaultExtension, const char *filter, int flags, - wxWindow *parent, int x, int y) -{ - // If there's a default extension specified but no filter, we create a suitable - // filter. - - wxString filter2(""); - if ( defaultExtension && !filter ) - filter2 = wxString("*.") + wxString(defaultExtension) ; - else if ( filter ) - filter2 = filter; - - wxString defaultDirString; - if (defaultDir) - defaultDirString = defaultDir; - else - defaultDirString = ""; + ++filterIndex ; - wxString defaultFilenameString; - if (defaultFileName) - defaultFilenameString = defaultFileName; - else - defaultFilenameString = ""; + const size_t extCount = myData->extensions.GetCount(); + for ( size_t i = 0 ; i < extCount; i++ ) + { + wxUint32 fileType, creator; + wxString extension = myData->extensions[i]; - wxFileDialog fileDialog(parent, title, defaultDirString, defaultFilenameString, filter2, flags, wxPoint(x, y)); + // Remove leading '*' + if (extension.length() && (extension.GetChar(0) == '*')) + extension = extension.Mid( 1 ); - if ( fileDialog.ShowModal() == wxID_OK ) - { - strcpy(wxBuffer, (const char *)fileDialog.GetPath()); - return wxBuffer; + // Remove leading '.' + if (extension.length() && (extension.GetChar(0) == '.')) + extension = extension.Mid( 1 ); + + if (wxFileName::MacFindDefaultTypeAndCreator( extension, &fileType, &creator )) + myData->filtermactypes.Add( (OSType)fileType ); + else + myData->filtermactypes.Add( '****' ); // We'll fail safe if it's not recognized + } } - else - return wxGetEmptyString(); } -WXDLLEXPORT wxString wxFileSelectorEx(const char *title, - const char *defaultDir, - const char *defaultFileName, - int* defaultFilterIndex, - const char *filter, - int flags, - wxWindow* parent, - int x, - int y) - +static Boolean CheckFile( const wxString &filename , OSType type , OpenUserDataRecPtr data) { - wxFileDialog fileDialog(parent, title ? title : "", defaultDir ? defaultDir : "", - defaultFileName ? defaultFileName : "", filter ? filter : "", flags, wxPoint(x, y)); + wxString file(filename) ; + file.MakeUpper() ; - if ( fileDialog.ShowModal() == wxID_OK ) + if ( data->extensions.GetCount() > 0 ) { - *defaultFilterIndex = fileDialog.GetFilterIndex(); - strcpy(wxBuffer, (const char *)fileDialog.GetPath()); - return wxBuffer; + //for ( int i = 0 ; i < data->numfilters ; ++i ) + int i = data->currentfilter ; + if ( data->extensions[i].Right(2) == wxT(".*") ) + return true ; + + { + if ( type == (OSType)data->filtermactypes[i] ) + return true ; + + wxStringTokenizer tokenizer( data->extensions[i] , wxT(";") ) ; + while ( tokenizer.HasMoreTokens() ) + { + wxString extension = tokenizer.GetNextToken() ; + if ( extension.GetChar(0) == '*' ) + extension = extension.Mid(1) ; + extension.MakeUpper(); + + if ( file.length() >= extension.length() && extension == file.Right(extension.length() ) ) + return true ; + } + } + + return false ; } - else - return wxGetEmptyString(); -} -wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message, - const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard, - long style, const wxPoint& pos) -{ - wxASSERT_MSG( NavServicesAvailable() , "Navigation Services are not running" ) ; - m_message = message; - m_dialogStyle = style; - m_parent = parent; - m_path = ""; - m_fileName = defaultFileName; - m_dir = defaultDir; - m_wildCard = wildCard; - m_filterIndex = 1; + return true ; } +// end wxmac -pascal Boolean CrossPlatformFilterCallback ( - AEDesc *theItem, - void *info, - void *callBackUD, - NavFilterModes filterMode -) +wxFileDialog::wxFileDialog( + wxWindow *parent, const wxString& message, + const wxString& defaultDir, const wxString& defaultFileName, const wxString& wildCard, + long style, const wxPoint& pos, const wxSize& sz, const wxString& name) + : wxFileDialogBase(parent, message, defaultDir, defaultFileName, wildCard, style, pos, sz, name) { - bool display = true; - OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ; - - if (filterMode == kNavFilteringBrowserList) - { - NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ; - if (theItem->descriptorType == typeFSS && !theInfo->isFolder) - { - FSSpec spec; - memcpy( &spec , *theItem->dataHandle , sizeof(FSSpec) ) ; - display = CheckFile( spec.name , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; - } - } - - return display; + wxASSERT_MSG( NavServicesAvailable() , wxT("Navigation Services are not running") ) ; } -int wxFileDialog::ShowModal() +pascal Boolean CrossPlatformFilterCallback( + AEDesc *theItem, + void *info, + void *callBackUD, + NavFilterModes filterMode ) { - NavDialogOptions mNavOptions; - NavObjectFilterUPP mNavFilterUPP = NULL; - NavPreviewUPP mNavPreviewUPP = NULL ; - NavReplyRecord mNavReply; - AEDesc mDefaultLocation ; - bool mSelectDefault = false ; - - ::NavGetDefaultDialogOptions(&mNavOptions); - - mNavFilterUPP = nil; - mNavPreviewUPP = nil; - mSelectDefault = false; - mNavReply.validRecord = false; - mNavReply.replacing = false; - mNavReply.isStationery = false; - mNavReply.translationNeeded = false; - mNavReply.selection.descriptorType = typeNull; - mNavReply.selection.dataHandle = nil; - mNavReply.keyScript = smSystemScript; - mNavReply.fileTranslation = nil; - - // Set default location, the location - // that's displayed when the dialog - // first appears - - FSSpec location ; - wxMacFilename2FSSpec( m_dir , &location ) ; - OSErr err = noErr ; - - mDefaultLocation.descriptorType = typeNull; - mDefaultLocation.dataHandle = nil; - - err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation ); - - if ( mDefaultLocation.dataHandle ) { - - if (mSelectDefault) { - mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation; - } else { - mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation; - } - } - -#if TARGET_CARBON - c2pstrcpy((StringPtr)mNavOptions.message, m_message) ; -#else - strcpy((char *)mNavOptions.message, m_message) ; - c2pstr((char *)mNavOptions.message ) ; -#endif -#if TARGET_CARBON - c2pstrcpy((StringPtr)mNavOptions.savedFileName, m_fileName) ; -#else - strcpy((char *)mNavOptions.savedFileName, m_fileName) ; - c2pstr((char *)mNavOptions.savedFileName ) ; -#endif + OpenUserDataRecPtr data = (OpenUserDataRecPtr) callBackUD ; - if ( m_dialogStyle & wxSAVE ) - { - - mNavOptions.dialogOptionFlags |= kNavNoTypePopup ; - mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ; - mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ; - - err = ::NavPutFile( - &mDefaultLocation, - &mNavReply, - &mNavOptions, - sStandardNavEventFilter , - 'TEXT', - 'TEXT', - 0L); // User Data - } - else - { - OpenUserDataRec myData; - MakeUserDataRec( &myData , m_wildCard ) ; - NavTypeListHandle typelist = NULL ; - - if ( myData.numfilters > 0 ) - { - mNavOptions.popupExtension = (NavMenuItemSpecArrayHandle) NewHandle( sizeof( NavMenuItemSpec ) * myData.numfilters ) ; - for ( int i = 0 ; i < myData.numfilters ; ++i ) { - (*mNavOptions.popupExtension)[i].version = kNavMenuItemSpecVersion ; - (*mNavOptions.popupExtension)[i].menuCreator = 'WXNG' ; - (*mNavOptions.popupExtension)[i].menuType = i ; - #if TARGET_CARBON - c2pstrcpy((StringPtr)(*mNavOptions.popupExtension)[i].menuItemName, myData.name[i]) ; - #else - strcpy((char *)(*mNavOptions.popupExtension)[i].menuItemName, myData.name[i]) ; - c2pstr((char *)(*mNavOptions.popupExtension)[i].menuItemName ) ; - #endif - } - } - - mNavFilterUPP = NewNavObjectFilterUPP( CrossPlatformFilterCallback ) ; - if ( m_dialogStyle & wxMULTIPLE ) - mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ; - else - mNavOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles ; - - err = ::NavGetFile( - &mDefaultLocation, - &mNavReply, - &mNavOptions, - sStandardNavEventFilter , - mNavPreviewUPP, - mNavFilterUPP, - typelist /*inFileTypes.TypeListHandle() */, - &myData); // User Data - if ( typelist ) - DisposeHandle( (Handle) typelist ) ; - } - - DisposeNavObjectFilterUPP(mNavFilterUPP); - if ( mDefaultLocation.dataHandle != nil ) - { - ::AEDisposeDesc(&mDefaultLocation); - } - - if ( (err != noErr) && (err != userCanceledErr) ) { - m_path = "" ; - return wxID_CANCEL ; - } - - if (mNavReply.validRecord) { - - FSSpec outFileSpec ; - AEDesc specDesc ; - AEKeyword keyWord ; - - long count ; - ::AECountItems( &mNavReply.selection , &count ) ; - for ( long i = 1 ; i <= count ; ++i ) - { - OSErr err = ::AEGetNthDesc( &mNavReply.selection , i , typeFSS, &keyWord , &specDesc); - if ( err != noErr ) { - m_path = "" ; - return wxID_CANCEL ; - } - outFileSpec = **(FSSpec**) specDesc.dataHandle; - if (specDesc.dataHandle != nil) { - ::AEDisposeDesc(&specDesc); - } -#ifdef __DARWIN__ - FSRef fsr ; - err = FSpMakeFSRef( &outFileSpec , &fsr ) ; - if ( err == fnfErr ) + if (filterMode == kNavFilteringBrowserList) + { + // We allow navigation to all folders. For files, we check against the current + // filter string. + // However, packages should be dealt with like files and not like folders. So + // check if a folder is a package before deciding what to do. + NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*) info ; + FSRef fsref; + + if ( theInfo->isFolder ) { - FSSpec fss ; - err = FSMakeFSSpec( outFileSpec.vRefNum , outFileSpec.parID, "\p" , &fss ) ; - err = FSpMakeFSRef( &fss , &fsr ) ; - char path[256] ; - err = FSRefMakePath( &fsr , (unsigned char*) path , sizeof(path) ) ; - strcat( path , "/" ) ; - p2cstr( outFileSpec.name ) ; - strcat( path , (char*) outFileSpec.name ) ; - m_path = path ; + // check bundle bit (using Finder Services - used by OS9 on some bundles) + FSCatalogInfo catalogInfo; + if (FSGetCatalogInfo (&fsref, kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL) != noErr) + return true; + + // Check bundle item (using Launch Services - used by OS-X through info.plist or APP) + LSItemInfoRecord lsInfo; + if (LSCopyItemInfoForRef(&fsref, kLSRequestBasicFlagsOnly, &lsInfo ) != noErr) + return true; + + // If it's not a bundle, then it's a normal folder and it passes our filter + FileInfo *fileInfo = (FileInfo *) catalogInfo.finderInfo; + if ( !(fileInfo->finderFlags & kHasBundle) && + !(lsInfo.flags & (kLSItemInfoIsApplication | kLSItemInfoIsPackage)) ) + return true; } else { - m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ; + AECoerceDesc (theItem, typeFSRef, theItem); + if ( AEGetDescData (theItem, &fsref, sizeof (FSRef)) == noErr) + { + wxString file = wxMacFSRefToPath( &fsref ) ; + return CheckFile( file , theInfo->fileAndFolder.fileInfo.finderInfo.fdType , data ) ; + } } -#else - m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ; -#endif - m_paths.Add( m_path ) ; - m_fileName = wxFileNameFromPath(m_path); - m_fileNames.Add(m_fileName); - } - // set these to the first hit - m_path = m_paths[ 0 ] ; - m_fileName = wxFileNameFromPath(m_path); - m_dir = wxPathOnly(m_path); - NavDisposeReply( &mNavReply ) ; - return wxID_OK ; - } - return wxID_CANCEL; -} + } -// Generic file load/save dialog -static wxString -wxDefaultFileSelector(bool load, const char *what, const char *extension, const char *default_name, wxWindow *parent) -{ - char *ext = (char *)extension; - - char prompt[50]; - wxString str; - if (load) - str = "Load %s file"; - else - str = "Save %s file"; - sprintf(prompt, wxGetTranslation(str), what); - - if (*ext == '.') ext++; - char wild[60]; - sprintf(wild, "*.%s", ext); - - return wxFileSelector (prompt, NULL, default_name, ext, wild, 0, parent); + return true; } -// Generic file load dialog -wxString -wxLoadFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent) +int wxFileDialog::ShowModal() { - return wxDefaultFileSelector(TRUE, what, extension, default_name, parent); -} + OSErr err; + NavDialogCreationOptions dialogCreateOptions; + // set default options + ::NavGetDefaultDialogCreationOptions(&dialogCreateOptions); -// Generic file save dialog -wxString -wxSaveFileSelector(const char *what, const char *extension, const char *default_name, wxWindow *parent) -{ - return wxDefaultFileSelector(FALSE, what, extension, default_name, parent); + // this was always unset in the old code + dialogCreateOptions.optionFlags &= ~kNavSelectDefaultLocation; + + wxMacCFStringHolder message(m_message, m_font.GetEncoding()); + dialogCreateOptions.windowTitle = message; + + wxMacCFStringHolder defaultFileName(m_fileName, m_font.GetEncoding()); + dialogCreateOptions.saveFileName = defaultFileName; + + + NavDialogRef dialog; + NavObjectFilterUPP navFilterUPP = NULL; + OpenUserDataRec myData; + myData.defaultLocation = m_dir; + + MakeUserDataRec(&myData , m_wildCard); + myData.currentfilter = m_filterIndex; + size_t numFilters = myData.extensions.GetCount(); + if (numFilters) + { + CFMutableArrayRef popup = CFArrayCreateMutable( kCFAllocatorDefault , + numFilters , &kCFTypeArrayCallBacks ) ; + dialogCreateOptions.popupExtension = popup ; + myData.menuitems = dialogCreateOptions.popupExtension ; + for ( size_t i = 0 ; i < numFilters ; ++i ) + { + CFArrayAppendValue( popup , (CFStringRef) wxMacCFStringHolder( myData.name[i] , m_font.GetEncoding() ) ) ; + } + } + + if (HasFdFlag(wxFD_SAVE)) + { + myData.saveMode = true; + + dialogCreateOptions.optionFlags |= kNavDontAutoTranslate; + dialogCreateOptions.optionFlags |= kNavDontAddTranslateItems; + if (!numFilters) + dialogCreateOptions.optionFlags |= kNavNoTypePopup; + + // The extension is important + if (numFilters < 2) + dialogCreateOptions.optionFlags |= kNavPreserveSaveFileExtension; + + if (!(m_windowStyle & wxFD_OVERWRITE_PROMPT)) + dialogCreateOptions.optionFlags |= kNavDontConfirmReplacement; + + err = ::NavCreatePutFileDialog( + &dialogCreateOptions, + kNavGenericSignature, // Suppresses the 'Default' (top) menu item + kNavGenericSignature, + sStandardNavEventFilter, + &myData, // for defaultLocation + &dialog ); + } + else + { + // let the user select bundles/programs in dialogs + dialogCreateOptions.optionFlags |= kNavSupportPackages; + + navFilterUPP = NewNavObjectFilterUPP(CrossPlatformFilterCallback); + err = ::NavCreateGetFileDialog( + &dialogCreateOptions, + NULL, // NavTypeListHandle + sStandardNavEventFilter, + NULL, // NavPreviewUPP + navFilterUPP, + (void *) &myData, // inClientData + &dialog ); + } + + if (err == noErr) + err = ::NavDialogRun(dialog); + + // clean up filter related data, etc. + if (navFilterUPP) + ::DisposeNavObjectFilterUPP(navFilterUPP); + + if (err != noErr) + { + ::NavDialogDispose(dialog); + return wxID_CANCEL; + } + + NavReplyRecord navReply; + err = ::NavDialogGetReply(dialog, &navReply); + if (err == noErr && navReply.validRecord) + { + AEKeyword theKeyword; + DescType actualType; + Size actualSize; + FSRef theFSRef; + wxString thePath ; + long count; + + m_filterIndex = myData.currentfilter; + ::AECountItems( &navReply.selection, &count ); + for (long i = 1; i <= count; ++i) + { + err = ::AEGetNthPtr( + &(navReply.selection), i, typeFSRef, &theKeyword, &actualType, + &theFSRef, sizeof(theFSRef), &actualSize ); + if (err != noErr) + break; + + if (HasFdFlag(wxFD_SAVE)) + thePath = wxMacFSRefToPath( &theFSRef, navReply.saveFileName ); + else + thePath = wxMacFSRefToPath( &theFSRef ); + + if (!thePath) + { + ::NavDisposeReply(&navReply); + ::NavDialogDispose(dialog); + return wxID_CANCEL; + } + + m_path = thePath; + m_paths.Add(m_path); + m_fileName = wxFileNameFromPath(m_path); + m_fileNames.Add(m_fileName); + } + + // set these to the first hit + m_path = m_paths[0]; + m_fileName = wxFileNameFromPath(m_path); + m_dir = wxPathOnly(m_path); + } + + ::NavDisposeReply(&navReply); + ::NavDialogDispose(dialog); + + return (err == noErr) ? wxID_OK : wxID_CANCEL; } +#endif // wxUSE_FILEDLG