]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/dirdlg.cpp
toplevel fixes
[wxWidgets.git] / src / mac / carbon / dirdlg.cpp
index 02bbef6a204bad2100a085c8786858f9820e07b6..83533f1236711365c82828ecadfabb3b500e8d2c 100644 (file)
 
 #include "wx/cmndata.h"
 
+#ifdef __DARWIN__
+  #include <Carbon/Carbon.h>
+#else
+  #include <Navigation.h>
+#endif
+
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_CLASS(wxDirDialog, wxDialog)
 #endif
 
+bool gUseNavServices = NavServicesAvailable() ;
+
 // the data we need to pass to our standard file hook routine
 // includes a pointer to the dialog, a pointer to the standard
 // file reply record (so we can inspect the current selection)
 // and a copy of the "previous" file spec of the reply record
 // so we can see if the selection has changed
 
+#if !TARGET_CARBON
+
 struct UserDataRec {
        StandardFileReply       *sfrPtr;
        FSSpec                          oldSelectionFSSpec;
@@ -38,8 +48,6 @@ struct UserDataRec {
 typedef struct UserDataRec
        UserDataRec, *UserDataRecPtr;
 
-#if !TARGET_CARBON
-
 enum {
        kSelectItem = 10,                       // select button item number
        kSFGetFolderDlgID = 250,        // dialog resource number
@@ -174,7 +182,7 @@ static Boolean SameFSSpec(FSSpecPtr spec1, FSSpecPtr spec2)
 // flashing of the button when the key is hit
 
 static pascal Boolean SFGetFolderModalDialogFilter(DialogPtr theDlgPtr, EventRecord *eventRec,
-                                                                                       short *item, Ptr dataPtr)
+                                                                                       short *item, void *dataPtr)
 {
 #pragma unused (dataPtr)
 
@@ -202,7 +210,7 @@ static pascal Boolean SFGetFolderModalDialogFilter(DialogPtr theDlgPtr, EventRec
 // MyDlgHook is a hook routine that maps the select button to Open
 // and sets the Select button name
 
-static pascal short SFGetFolderDialogHook(short item, DialogPtr theDlgPtr, Ptr dataPtr)
+static pascal short SFGetFolderDialogHook(short item, DialogPtr theDlgPtr, void *dataPtr)
 {
        UserDataRecPtr  theUserDataRecPtr;
        long                    desktopDirID;
@@ -307,7 +315,6 @@ static pascal short SFGetFolderDialogHook(short item, DialogPtr theDlgPtr, Ptr d
        
        return item;
 }
-#endif
 
 void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileFilterYDUPP fileFilter, StandardFileReply *theSFR)
 {
@@ -415,7 +422,7 @@ void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileF
        }
 }
 
-static pascal Boolean OnlyVisibleFoldersCustomFileFilter(CInfoPBPtr myCInfoPBPtr, Ptr dataPtr)
+static pascal Boolean OnlyVisibleFoldersCustomFileFilter(CInfoPBPtr myCInfoPBPtr, void *dataPtr)
 {
 #pragma unused (dataPtr)
 
@@ -433,6 +440,9 @@ static pascal Boolean OnlyVisibleFoldersCustomFileFilter(CInfoPBPtr myCInfoPBPtr
        return !(visibleFlag && folderFlag);
 }
 
+#endif
+
+
 wxDirDialog::wxDirDialog(wxWindow *parent, const wxString& message,
         const wxString& defaultPath,
         long style, const wxPoint& pos)
@@ -445,28 +455,36 @@ wxDirDialog::wxDirDialog(wxWindow *parent, const wxString& message,
 
 int wxDirDialog::ShowModal()
 {
+       #if !TARGET_CARBON
+       if ( !gUseNavServices )
        {
                Str255                          prompt ;
                Str255                          path ;
 
+#if TARGET_CARBON
+               c2pstrcpy((StringPtr)prompt, m_message) ;
+#else
                strcpy((char *)prompt, m_message) ;
                c2pstr((char *)prompt ) ;
-       
+#endif
+#if TARGET_CARBON
+               c2pstrcpy((StringPtr)path, m_path ) ;
+#else
                strcpy((char *)path, m_path ) ;
                c2pstr((char *)path ) ;
+#endif
 
                StandardFileReply       reply ;
                FileFilterYDUPP         invisiblesExcludedCustomFilterUPP = 0 ;
-               #if !TARGET_CARBON
                invisiblesExcludedCustomFilterUPP = 
                        NewFileFilterYDProc(OnlyVisibleFoldersCustomFileFilter);
-               #endif
+
 
                StandardGetFolder( prompt , path , invisiblesExcludedCustomFilterUPP, &reply);
        
-               #if !TARGET_CARBON
+
                DisposeRoutineDescriptor(invisiblesExcludedCustomFilterUPP);
-               #endif
+
                if ( reply.sfGood == false )
                {
                        m_path = "" ;
@@ -474,10 +492,108 @@ int wxDirDialog::ShowModal()
                }
                else
                {
-                       m_path = wxMacFSSpec2UnixFilename( &reply.sfFile ) ;
+                       m_path = wxMacFSSpec2MacFilename( &reply.sfFile ) ;
+                       return wxID_OK ;
+               }
+               return wxID_CANCEL;
+       }
+       else
+       #endif
+       {
+               NavDialogOptions                mNavOptions;
+               NavObjectFilterUPP              mNavFilterUPP = NULL;
+               NavPreviewUPP                   mNavPreviewUPP = NULL ;
+               NavReplyRecord                  mNavReply;
+               AEDesc*                                 mDefaultLocation = NULL ;
+               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
+               
+               if ( mDefaultLocation ) {
+                       
+                       if (mSelectDefault) {
+                               mNavOptions.dialogOptionFlags |= kNavSelectDefaultLocation;
+                       } else {
+                               mNavOptions.dialogOptionFlags &= ~kNavSelectDefaultLocation;
+                       }
+               }
+               
+               OSErr err = ::NavChooseFolder(
+                                                       mDefaultLocation,
+                                                       &mNavReply,
+                                                       &mNavOptions,
+                                                       NULL,
+                                                       mNavFilterUPP,
+                                                       0L);                                                    // User Data
+               
+               if ( (err != noErr) && (err != userCanceledErr) ) {
+                       m_path = "" ;
+                       return wxID_CANCEL ;
+               }
+
+               if (mNavReply.validRecord) {            // User chose a folder
+               
+                       FSSpec  folderInfo;
+                       FSSpec  outFileSpec ;
+                       AEDesc specDesc ;
+                       
+                       OSErr err = ::AECoerceDesc( &mNavReply.selection , typeFSS, &specDesc);
+                       if ( err != noErr ) {
+                               m_path = "" ;
+                               return wxID_CANCEL ;
+                       }                       
+                       folderInfo = **(FSSpec**) specDesc.dataHandle;
+                       if (specDesc.dataHandle != nil) {
+                               ::AEDisposeDesc(&specDesc);
+                       }
+
+//                     mNavReply.GetFileSpec(folderInfo);
+                       
+                               // The FSSpec from NavChooseFolder is NOT the file spec
+                               // for the folder. The parID field is actually the DirID
+                               // of the folder itself, not the folder's parent, and
+                               // the name field is empty. We must call PBGetCatInfo
+                               // to get the parent DirID and folder name
+                       
+                       Str255          name;
+                       CInfoPBRec      thePB;                  // Directory Info Parameter Block
+                       thePB.dirInfo.ioCompletion      = nil;
+                       thePB.dirInfo.ioVRefNum         = folderInfo.vRefNum;   // Volume is right
+                       thePB.dirInfo.ioDrDirID         = folderInfo.parID;             // Folder's DirID
+                       thePB.dirInfo.ioNamePtr         = name;
+                       thePB.dirInfo.ioFDirIndex       = -1;   // Lookup using Volume and DirID
+                       
+                       err = ::PBGetCatInfoSync(&thePB);
+                       if ( err != noErr ) {
+                               m_path = "" ;
+                               return wxID_CANCEL ;
+                       }                       
+                                                                                               // Create cannonical FSSpec
+                       ::FSMakeFSSpec(thePB.dirInfo.ioVRefNum, thePB.dirInfo.ioDrParID,
+                                                  name, &outFileSpec);
+                                                       
+                       // outFolderDirID = thePB.dirInfo.ioDrDirID;
+                       m_path = wxMacFSSpec2MacFilename( &outFileSpec ) ;
                        return wxID_OK ;
                }
+               return wxID_CANCEL;
+
        }
-       return wxID_CANCEL;
 }