X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/76a5e5d21ee1a6230d777ce0209b2df4c6075f0f..2ad50cc75b44bdb79c3c1a031e1a548d0fa5bfb9:/src/mac/filedlg.cpp diff --git a/src/mac/filedlg.cpp b/src/mac/filedlg.cpp index 87e7846177..66a0c2fc79 100644 --- a/src/mac/filedlg.cpp +++ b/src/mac/filedlg.cpp @@ -35,9 +35,13 @@ IMPLEMENT_CLASS(wxFileDialog, wxDialog) #include -#include "MoreFiles.h" -#include "MoreFilesExtras.h" - +#ifdef __DARWIN__ +# include "MoreFilesX.h" +#else +# include "MoreFiles.h" +# include "MoreFilesExtras.h" +#endif + extern bool gUseNavServices ; // the data we need to pass to our standard file hook routine @@ -46,15 +50,15 @@ 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 ; + bool saveMode ; + wxArrayString name ; + wxArrayString extensions ; + wxArrayLong filtermactypes ; + NavMenuItemSpecArrayHandle menuitems ; }; + typedef struct OpenUserDataRec OpenUserDataRec, *OpenUserDataRecPtr; @@ -75,23 +79,42 @@ NavEventProc( NavCBRecPtr ioParams, NavCallBackUserData ioUserData ) { - OpenUserDataRec * data = ( OpenUserDataRec *) ioUserData ; + 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 - */ - +#if !TARGET_CARBON wxTheApp->MacHandleOneEvent(ioParams->eventData.eventDataParms.event); - } else if ( inSelector == kNavCBPopupMenuSelect ) +#endif + } + else if ( inSelector == kNavCBStart ) { - NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; - data->currentfilter = menu->menuType ; + if ( data->menuitems ) + NavCustomControl(ioParams->context, kNavCtlSelectCustomType, &(*data->menuitems)[data->currentfilter]); + } + else if ( inSelector == kNavCBPopupMenuSelect ) + { + NavMenuItemSpec * menu = (NavMenuItemSpec *) ioParams->eventData.eventDataParms.param ; + if ( menu->menuCreator == 'WXNG' ) + { + data->currentfilter = menu->menuType ; + if ( data->saveMode ) + { + int i = menu->menuType ; + wxString extension = data->extensions[i].AfterLast('.') ; + extension.MakeLower() ; + Str255 filename ; + // get the current filename + NavCustomControl(ioParams->context, kNavCtlGetEditFileName, &filename); + CopyPascalStringToC( filename , (char*) filename ) ; + wxString sfilename( filename ) ; + int pos = sfilename.Find('.',TRUE) ; + if ( pos != wxNOT_FOUND ) + { + sfilename = sfilename.Left(pos+1)+extension ; + CopyCStringToPascal( sfilename.c_str() , filename ) ; + NavCustomControl(ioParams->context, kNavCtlSetEditFileName, &filename); + } + } + } } } @@ -117,23 +140,25 @@ OSType gfiltersmac[] = void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) { - myData->currentfilter = 0 ; - + myData->menuitems = NULL ; + myData->currentfilter = 0 ; + myData->saveMode = FALSE ; + if ( filter && filter[0] ) { wxString filter2(filter) ; int filterIndex = 0; bool isName = true ; wxString current ; - for( unsigned int i = 0; i < filter2.Len(); i++ ) + for( unsigned int i = 0; i < filter2.Len() ; i++ ) { if( filter2.GetChar(i) == wxT('|') ) { if( isName ) { - myData->name[filterIndex] = current ; + myData->name.Add( current ) ; } else { - myData->extensions[filterIndex] = current.MakeUpper() ; + myData->extensions.Add( current.MakeUpper() ) ; ++filterIndex ; } isName = !isName ; @@ -144,36 +169,38 @@ void MakeUserDataRec(OpenUserDataRec *myData , const wxString& filter ) current += filter2.GetChar(i) ; } } -// if ( filterIndex > 0 ) - { - wxASSERT_MSG( !isName , "incorrect format of format string" ) ; - myData->extensions[filterIndex] = current.MakeUpper() ; - ++filterIndex ; - } + // 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 + + wxASSERT_MSG( filterIndex == 0 || !isName , "incorrect format of format string" ) ; + if ( current.IsEmpty() ) + myData->extensions.Add( myData->name[filterIndex] ) ; + else + myData->extensions.Add( current.MakeUpper() ) ; + if ( filterIndex == 0 || isName ) + myData->name.Add( current.MakeUpper() ) ; + + ++filterIndex ; + - myData->numfilters = filterIndex ; - for ( int i = 0 ; i < myData->numfilters ; i++ ) + const size_t extCount = myData->extensions.GetCount(); + for ( size_t i = 0 ; i < extCount; i++ ) { int j ; for ( j = 0 ; gfilters[j] ; j++ ) { if ( strcmp( myData->extensions[i] , gfilters[j] ) == 0 ) { - myData->filtermactypes[i] = gfiltersmac[j] ; + myData->filtermactypes.Add( gfiltersmac[j] ) ; break ; } } if( gfilters[j] == NULL ) { - myData->filtermactypes[i] = '****' ; + myData->filtermactypes.Add( '****' ) ; } } } - else - { - myData->numfilters = 0 ; - } - } static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecPtr data) @@ -189,7 +216,7 @@ static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecP wxString file(filename) ; file.MakeUpper() ; - if ( data->numfilters > 0 ) + if ( data->extensions.GetCount() > 0 ) { //for ( int i = 0 ; i < data->numfilters ; ++i ) int i = data->currentfilter ; @@ -197,7 +224,7 @@ static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecP return true ; { - if ( type == data->filtermactypes[i] ) + if ( type == (OSType)data->filtermactypes[i] ) return true ; wxStringTokenizer tokenizer( data->extensions[i] , ";" ) ; @@ -275,8 +302,7 @@ wxString wxFileSelector(const char *title, if ( fileDialog.ShowModal() == wxID_OK ) { - strcpy(wxBuffer, (const char *)fileDialog.GetPath()); - return wxBuffer; + return fileDialog.GetPath(); } else return wxGetEmptyString(); @@ -299,8 +325,7 @@ WXDLLEXPORT wxString wxFileSelectorEx(const char *title, if ( fileDialog.ShowModal() == wxID_OK ) { *defaultFilterIndex = fileDialog.GetFilterIndex(); - strcpy(wxBuffer, (const char *)fileDialog.GetPath()); - return wxBuffer; + return fileDialog.GetPath(); } else return wxGetEmptyString(); @@ -310,7 +335,7 @@ 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" ) ; + wxASSERT_MSG( NavServicesAvailable() , "Navigation Services are not running" ) ; m_message = message; m_dialogStyle = style; m_parent = parent; @@ -318,7 +343,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message, m_fileName = defaultFileName; m_dir = defaultDir; m_wildCard = wildCard; - m_filterIndex = 1; + m_filterIndex = 0; } @@ -329,204 +354,212 @@ pascal Boolean CrossPlatformFilterCallback ( NavFilterModes filterMode ) { - 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; + 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; } int wxFileDialog::ShowModal() { - NavDialogOptions mNavOptions; - NavObjectFilterUPP mNavFilterUPP = NULL; - NavPreviewUPP mNavPreviewUPP = NULL ; - NavReplyRecord mNavReply; - AEDesc mDefaultLocation ; - bool mSelectDefault = false ; + NavDialogOptions mNavOptions; + NavObjectFilterUPP mNavFilterUPP = NULL; + NavPreviewUPP mNavPreviewUPP = NULL ; + NavReplyRecord mNavReply; + AEDesc mDefaultLocation ; + bool mSelectDefault = false ; + + // zero all data + + m_path = wxEmptyString ; + m_fileName = wxEmptyString ; + m_paths.Empty(); + m_fileNames.Empty(); + + // setup dialog - ::NavGetDefaultDialogOptions(&mNavOptions); + ::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; + 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 + // Set default location, the location + // that's displayed when the dialog + // first appears - FSSpec location ; - wxMacFilename2FSSpec( m_dir , &location ) ; - OSErr err = noErr ; + FSSpec location ; + wxMacFilename2FSSpec( m_dir , &location ) ; + OSErr err = noErr ; - mDefaultLocation.descriptorType = typeNull; - mDefaultLocation.dataHandle = nil; + mDefaultLocation.descriptorType = typeNull; + mDefaultLocation.dataHandle = nil; - err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation ); + err = ::AECreateDesc(typeFSS, &location, sizeof(FSSpec), &mDefaultLocation ); - if ( mDefaultLocation.dataHandle ) { + if ( mDefaultLocation.dataHandle ) { - if (mSelectDefault) { - mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation; - } else { - mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation; - } - } + if (mSelectDefault) { + mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation; + } else { + mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation; + } + } #if TARGET_CARBON - c2pstrcpy((StringPtr)mNavOptions.message, m_message) ; + c2pstrcpy((StringPtr)mNavOptions.message, m_message) ; #else - strcpy((char *)mNavOptions.message, m_message) ; - c2pstr((char *)mNavOptions.message ) ; + strcpy((char *)mNavOptions.message, m_message) ; + c2pstr((char *)mNavOptions.message ) ; #endif #if TARGET_CARBON - c2pstrcpy((StringPtr)mNavOptions.savedFileName, m_fileName) ; + c2pstrcpy((StringPtr)mNavOptions.savedFileName, m_fileName) ; #else - strcpy((char *)mNavOptions.savedFileName, m_fileName) ; - c2pstr((char *)mNavOptions.savedFileName ) ; + strcpy((char *)mNavOptions.savedFileName, m_fileName) ; + c2pstr((char *)mNavOptions.savedFileName ) ; #endif - if ( m_dialogStyle & wxSAVE ) - { - - mNavOptions.dialogOptionFlags |= kNavNoTypePopup ; - mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ; - mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ; + OpenUserDataRec myData; + MakeUserDataRec( &myData , m_wildCard ) ; + myData.currentfilter = m_filterIndex ; + if ( myData.extensions.GetCount() > 0 ) + { + mNavOptions.popupExtension = (NavMenuItemSpecArrayHandle) NewHandle( sizeof( NavMenuItemSpec ) * myData.extensions.GetCount() ) ; + myData.menuitems = mNavOptions.popupExtension ; + for ( size_t i = 0 ; i < myData.extensions.GetCount() ; ++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 + } + } + if ( m_dialogStyle & wxSAVE ) + { + myData.saveMode = true ; + + 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 - } - } + err = ::NavPutFile( + &mDefaultLocation, + &mNavReply, + &mNavOptions, + sStandardNavEventFilter , + NULL, + kNavGenericSignature, + &myData); // User Data + m_filterIndex = myData.currentfilter ; + } + else + { + myData.saveMode = false ; - mNavFilterUPP = NewNavObjectFilterUPP( CrossPlatformFilterCallback ) ; - if ( m_dialogStyle & wxMULTIPLE ) - mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ; - else - mNavOptions.dialogOptionFlags &= ~kNavAllowMultipleFiles ; + 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 ) ; - } + err = ::NavGetFile( + &mDefaultLocation, + &mNavReply, + &mNavOptions, + sStandardNavEventFilter , + mNavPreviewUPP, + mNavFilterUPP, + NULL , + &myData); + m_filterIndex = myData.currentfilter ; + } - DisposeNavObjectFilterUPP(mNavFilterUPP); - if ( mDefaultLocation.dataHandle != nil ) - { - ::AEDisposeDesc(&mDefaultLocation); - } + DisposeNavObjectFilterUPP(mNavFilterUPP); + if ( mDefaultLocation.dataHandle != nil ) + { + ::AEDisposeDesc(&mDefaultLocation); + } - if ( (err != noErr) && (err != userCanceledErr) ) { - m_path = "" ; - return wxID_CANCEL ; - } + if ( (err != noErr) && (err != userCanceledErr) ) { + return wxID_CANCEL ; + } - if (mNavReply.validRecord) { + if (mNavReply.validRecord) { - FSSpec outFileSpec ; - AEDesc specDesc ; - AEKeyword keyWord ; + 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); - } - - - // outFolderDirID = thePB.dirInfo.ioDrDirID; - m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ; - m_paths.Add( 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; + 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); + } + m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ; + 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); + 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); } // Generic file load dialog