X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bb378910f731c7065efda0f873b353170e4610bc..15126fa8c239f279ca2501c0b52afcc1c3e5d4cc:/src/mac/filedlg.cpp diff --git a/src/mac/filedlg.cpp b/src/mac/filedlg.cpp index f9502a3883..b417d0fd9f 100644 --- a/src/mac/filedlg.cpp +++ b/src/mac/filedlg.cpp @@ -31,6 +31,8 @@ IMPLEMENT_CLASS(wxFileDialog, wxDialog) // begin wxmac +#include "wx/mac/private.h" + #include #include "MoreFiles.h" @@ -44,15 +46,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; @@ -73,27 +75,44 @@ 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 - */ - wxTheApp->MacHandleOneEvent(ioParams->eventData.eventDataParms.event); - } else if ( inSelector == kNavCBPopupMenuSelect ) + } + 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); + } + } + } } } -char * gfilters[] = +const char * gfilters[] = { "*.TXT" , "*.TIF" , @@ -112,152 +131,28 @@ OSType gfiltersmac[] = } ; -#if !TARGET_CARBON - -static void wxMacSetupStandardFile(short newVRefNum, long newDirID) -{ - enum - { SFSaveDisk = 0x214, CurDirStore = 0x398 }; - *(short *) SFSaveDisk = -1 * newVRefNum; - *(long *) CurDirStore = newDirID; -} - -static void wxMacSetupStandardFileFromPath( const char* s ) -{ - Str255 volume ; - Str255 path ; - short vRefNum ; - long dirRef ; - short i,j ; - Boolean isDirectory ; - - for (i=0 ; (s[i]!=0) && (s[i]!=':') ;i++) - { - volume[i]=s[i] ; - } - volume[i]=':' ; - volume[i+1]=0 ; - - // then copy the rest of the filename - - for (j=0;(s[i]!=0);i++,j++) - { - path[j]=s[i] ; - } - path[j]=0 ; - - c2pstr((Ptr) volume) ; - c2pstr((Ptr) path) ; - - SetVol(volume, 0) ; - GetVol( NULL, &vRefNum ) ; - - GetDirectoryID( vRefNum , fsRtDirID , path , &dirRef , &isDirectory ) ; - wxMacSetupStandardFile(vRefNum, dirRef) ; -} - -enum { - kSelectItem = 10, // select button item number - kSFGetFileDlgID = 251, // dialog resource number - kStrListID = 251, // our strings - kSelectStrNum = 1, // word 'Select: ' for button - kDesktopStrNum = 2, // word 'Desktop' for button - kSelectNoQuoteStrNum = 3, // word 'Select: ' for button - - kUseQuotes = true, // parameter for SetButtonName - kDontUseQuotes = false -}; - -static void GetLabelString(StringPtr theStr, short stringNum) -{ - GetIndString(theStr, kStrListID, stringNum); -} - -static void CopyPStr(StringPtr src, StringPtr dest) -{ - BlockMoveData(src, dest, 1 + src[0]); -} - -static char GetSelectKey(void) -{ - // this is the key used to trigger the select button - - // NOT INTERNATIONAL SAVVY; should at least grab it from resources - - return 's'; -} - -// FlashButton briefly highlights the dialog button -// as feedback for key equivalents - -static void FlashButton(DialogPtr theDlgPtr, short buttonID) -{ - short buttonType; - Handle buttonHandle; - Rect buttonRect; - unsigned long finalTicks; - - GetDialogItem(theDlgPtr, buttonID, &buttonType, &buttonHandle, &buttonRect); - HiliteControl((ControlHandle) buttonHandle, kControlButtonPart); - Delay(10, &finalTicks); - HiliteControl((ControlHandle) buttonHandle, 0); -} - -static Boolean SameFSSpec(FSSpecPtr spec1, FSSpecPtr spec2) -{ - return (spec1->vRefNum == spec2->vRefNum - && spec1->parID == spec2->parID - && EqualString(spec1->name, spec2->name, false, false)); -} -// MyModalDialogFilter maps a key to the Select button, and handles -// flashing of the button when the key is hit - -static pascal Boolean SFGetFolderModalDialogFilter(DialogPtr theDlgPtr, EventRecord *eventRec, - short *item, void *dataPtr) -{ -#pragma unused (dataPtr) - - // make certain the proper dialog is showing, 'cause standard file - // can nest dialogs but calls the same filter for each - - if (((WindowPeek) theDlgPtr)->refCon == sfMainDialogRefCon) - { - // check if the select button was hit - /* - if ((eventRec->what == keyDown) - && (eventRec->modifiers & cmdKey) - && ((eventRec->message & charCodeMask) == GetSelectKey())) - { - *item = kSelectItem; - FlashButton(theDlgPtr, kSelectItem); - return true; - } - */ - } - - return false; -} -#endif !TARGET_CARBON 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 ; @@ -268,144 +163,39 @@ 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] = '****' ; - } - } - } - else - { - myData->numfilters = 0 ; - } - -} - -#ifndef __DARWIN__ -void ExtendedOpenFile( ConstStr255Param message , ConstStr255Param path , const char *filter , FileFilterYDUPP fileFilter, StandardFileReply *theSFR ) -{ - Point thePt; - OpenUserDataRec myData; - FSSpec tempSpec; - Boolean folderFlag; - Boolean wasAliasedFlag; - DlgHookYDUPP dlgHookUPP; - ModalFilterYDUPP myModalFilterUPP; - OSErr err; - SFTypeList types ; - - - // presumably we're running System 7 or later so CustomGetFile is - // available - - // set initial contents of Select button to a space - - memcpy( theSFR->sfFile.name , "\p " , 2 ) ; - - // point the user data parameter at the reply record so we can get to it later - - MakeUserDataRec( &myData , filter ) ; - // display the dialog - -#if !TARGET_CARBON - - dlgHookUPP = NULL ; -// dlgHookUPP = NewDlgHookYDProc(SFGetFolderDialogHook); - myModalFilterUPP = NewModalFilterYDProc(SFGetFolderModalDialogFilter); - - thePt.h = thePt.v = -1; // center dialog - - ParamText( message , NULL , NULL , NULL ) ; - - CustomGetFile( fileFilter, - -1, // show all types - NULL, - theSFR, - kSFGetFileDlgID, - thePt, // top left point - dlgHookUPP, - myModalFilterUPP, - nil, // activate list - nil, // activate proc - &myData); - - DisposeRoutineDescriptor(dlgHookUPP); - DisposeRoutineDescriptor(myModalFilterUPP); -#else -#endif - // if cancel wasn't pressed and no fatal error occurred... - - if (theSFR->sfGood) - { - // if no name is in the reply record file spec, - // use the file spec of the parent folder - - if (theSFR->sfFile.name[0] == '\0') - { - err = FSMakeFSSpec(theSFR->sfFile.vRefNum, theSFR->sfFile.parID, - "\p", &tempSpec); - if (err == noErr) - { - theSFR->sfFile = tempSpec; - } - else - { - // no name to return, forget it - - theSFR->sfGood = false; - } - } - - // if there is now a name in the file spec, check if it's - // for a folder or a volume - - if (theSFR->sfFile.name[0] != '\0') - { - // the parID of the root of a disk is always fsRtParID == 1 - - if (theSFR->sfFile.parID == fsRtParID) - { - theSFR->sfIsVolume = true; - theSFR->sfIsFolder = false; // it would be reasonable for this to be true, too - } - - // we have a valid FSSpec, now let's make sure it's not for an alias file - - err = ResolveAliasFile(&theSFR->sfFile, true, &folderFlag, &wasAliasedFlag); - if (err != noErr) - { - theSFR->sfGood = false; - } - - // did the alias resolve to a folder? - - if (folderFlag && ! theSFR->sfIsVolume) - { - theSFR->sfIsFolder = true; + myData->filtermactypes.Add( '****' ) ; } } } } -#endif static Boolean CheckFile( ConstStr255Param name , OSType type , OpenUserDataRecPtr data) { @@ -420,7 +210,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 ; @@ -428,7 +218,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] , ";" ) ; @@ -541,6 +331,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" ) ; m_message = message; m_dialogStyle = style; m_parent = parent; @@ -548,7 +339,7 @@ wxFileDialog::wxFileDialog(wxWindow *parent, const wxString& message, m_fileName = defaultFileName; m_dir = defaultDir; m_wildCard = wildCard; - m_filterIndex = 1; + m_filterIndex = 0; } @@ -578,70 +369,6 @@ pascal Boolean CrossPlatformFilterCallback ( int wxFileDialog::ShowModal() { -#if !TARGET_CARBON - if ( !gUseNavServices ) - { - if ( m_dialogStyle & wxSAVE ) - { - StandardFileReply reply ; - Str255 prompt ; - Str255 filename ; - - strcpy((char *)prompt, m_message) ; - c2pstr((char *)prompt ) ; - strcpy((char *)filename, m_fileName) ; - c2pstr((char *)filename ) ; - - StandardPutFile( prompt , filename , &reply ) ; - if ( reply.sfGood == false ) - { - m_path = "" ; - return wxID_CANCEL ; - } - else - { - m_path = wxMacFSSpec2MacFilename( &reply.sfFile ) ; - return wxID_OK ; - } - } - else - { - OSType types = '????' ; - Str255 prompt ; - Str255 path ; - - strcpy((char *)prompt, m_message) ; - c2pstr((char *)prompt ) ; - strcpy((char *)path, m_dir ) ; - c2pstr((char *)path ) ; - - StandardFileReply reply ; - FileFilterYDUPP crossPlatformFileFilterUPP = 0 ; - #if !TARGET_CARBON - crossPlatformFileFilterUPP = - NewFileFilterYDProc(CrossPlatformFileFilter); - #endif - - ExtendedOpenFile( prompt , path , m_wildCard , crossPlatformFileFilterUPP, &reply); - #if !TARGET_CARBON - DisposeFileFilterYDUPP(crossPlatformFileFilterUPP); - #endif - if ( reply.sfGood == false ) - { - m_path = "" ; - return wxID_CANCEL ; - } - else - { - m_path = wxMacFSSpec2UnixFilename( &reply.sfFile ) ; - return wxID_OK ; - } - } - return wxID_CANCEL; -} - else -#endif - { NavDialogOptions mNavOptions; NavObjectFilterUPP mNavFilterUPP = NULL; NavPreviewUPP mNavPreviewUPP = NULL ; @@ -698,10 +425,30 @@ int wxFileDialog::ShowModal() c2pstr((char *)mNavOptions.savedFileName ) ; #endif + 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 ) { - - mNavOptions.dialogOptionFlags |= kNavNoTypePopup ; + myData.saveMode = true ; + mNavOptions.dialogOptionFlags |= kNavDontAutoTranslate ; mNavOptions.dialogOptionFlags |= kNavDontAddTranslateItems ; @@ -710,33 +457,16 @@ int wxFileDialog::ShowModal() &mNavReply, &mNavOptions, sStandardNavEventFilter , - 'TEXT', - 'TEXT', - 0L); // User Data + NULL, + kNavGenericSignature, + &myData); // User Data + m_filterIndex = myData.currentfilter ; } else { - OpenUserDataRec myData; - MakeUserDataRec( &myData , m_wildCard ) ; - NavTypeListHandle typelist = NULL ; + myData.saveMode = false ; - 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 ) ; + mNavFilterUPP = NewNavObjectFilterUPP( CrossPlatformFilterCallback ) ; if ( m_dialogStyle & wxMULTIPLE ) mNavOptions.dialogOptionFlags |= kNavAllowMultipleFiles ; else @@ -749,10 +479,9 @@ int wxFileDialog::ShowModal() sStandardNavEventFilter , mNavPreviewUPP, mNavFilterUPP, - typelist /*inFileTypes.TypeListHandle() */, - &myData); // User Data - if ( typelist ) - DisposeHandle( (Handle) typelist ) ; + NULL , + &myData); + m_filterIndex = myData.currentfilter ; } DisposeNavObjectFilterUPP(mNavFilterUPP); @@ -785,22 +514,19 @@ int wxFileDialog::ShowModal() if (specDesc.dataHandle != nil) { ::AEDisposeDesc(&specDesc); } - - - // outFolderDirID = thePB.dirInfo.ioDrDirID; 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 ; + } + // 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