]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/dirdlg.cpp
implemented display mode setting
[wxWidgets.git] / src / mac / dirdlg.cpp
index edfc211caa05465c25cd36acde69e55c778c1d88..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
 
-enum {
-       kSelectItem = 10,                       // select button item number
-       kSFGetFolderDlgID = 250,        // dialog resource number
-       kStrListID = 250,                       // 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
-};
+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
@@ -42,6 +38,8 @@ enum {
 // 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;
@@ -50,6 +48,19 @@ struct UserDataRec {
 typedef struct UserDataRec
        UserDataRec, *UserDataRecPtr;
 
+enum {
+       kSelectItem = 10,                       // select button item number
+       kSFGetFolderDlgID = 250,        // dialog resource number
+       kStrListID = 250,                       // 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);
@@ -171,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)
 
@@ -199,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;
@@ -323,7 +334,7 @@ void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileF
        
        // set initial contents of Select button to a space
        
-       CopyPStr("\p ", theSFR->sfFile.name);
+       memcpy(theSFR->sfFile.name, "\p ", 2);
        
        // point the user data parameter at the reply record so we can get to it later
        
@@ -331,6 +342,8 @@ void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileF
        
        // display the dialog
        
+       #if !TARGET_CARBON
+       
        dlgHookUPP = NewDlgHookYDProc(SFGetFolderDialogHook);
        myModalFilterUPP = NewModalFilterYDProc(SFGetFolderModalDialogFilter);
        
@@ -352,6 +365,8 @@ void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileF
                                        
        DisposeRoutineDescriptor(dlgHookUPP);
        DisposeRoutineDescriptor(myModalFilterUPP);
+       #else
+       #endif
        
        // if cancel wasn't pressed and no fatal error occurred...
        
@@ -407,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)
 
@@ -425,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)
@@ -437,24 +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
 
-               FileFilterYDUPP         invisiblesExcludedCustomFilterUPP;
                StandardFileReply       reply ;
+               FileFilterYDUPP         invisiblesExcludedCustomFilterUPP = 0 ;
                invisiblesExcludedCustomFilterUPP = 
                        NewFileFilterYDProc(OnlyVisibleFoldersCustomFileFilter);
 
+
                StandardGetFolder( prompt , path , invisiblesExcludedCustomFilterUPP, &reply);
        
+
                DisposeRoutineDescriptor(invisiblesExcludedCustomFilterUPP);
+
                if ( reply.sfGood == false )
                {
                        m_path = "" ;
@@ -462,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;
 }