]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/filedlg.cpp
MoreFilesX 1.0.1: A collection of useful high-level File Manager routines which
[wxWidgets.git] / src / mac / filedlg.cpp
index f9502a3883ea348739a89210e12621b4ef4cd585..b417d0fd9f371c1c4aa59bf395441d39dbbc5ccf 100644 (file)
@@ -31,6 +31,8 @@ IMPLEMENT_CLASS(wxFileDialog, wxDialog)
 
 // begin wxmac
 
+#include "wx/mac/private.h"
+
 #include <Navigation.h>
 
 #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