X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ad81651f00edc6f489d9b6a0839d316a964fd521..beb0d04d047966338f95eb2a00ef573d841b1b96:/src/mac/dirdlg.cpp

diff --git a/src/mac/dirdlg.cpp b/src/mac/dirdlg.cpp
index 344b8b32b9..89b3892451 100644
--- a/src/mac/dirdlg.cpp
+++ b/src/mac/dirdlg.cpp
@@ -20,19 +20,17 @@
 
 #include "wx/cmndata.h"
 
+#if defined(__UNIX__)
+  #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
@@ -40,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;
@@ -48,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);
@@ -169,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)
 
@@ -197,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;
@@ -321,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
 	
@@ -329,6 +342,8 @@ void StandardGetFolder( ConstStr255Param message , ConstStr255Param path , FileF
 	
 	// display the dialog
 	
+	#if !TARGET_CARBON
+	
 	dlgHookUPP = NewDlgHookYDProc(SFGetFolderDialogHook);
 	myModalFilterUPP = NewModalFilterYDProc(SFGetFolderModalDialogFilter);
 	
@@ -350,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...
 	
@@ -405,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)
 
@@ -423,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)
@@ -435,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 = "" ;
@@ -463,7 +495,105 @@ int wxDirDialog::ShowModal()
 			m_path = wxMacFSSpec2UnixFilename( &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 = wxMacFSSpec2UnixFilename( &outFileSpec ) ;
+			return wxID_OK ;
+		}
+		return wxID_CANCEL;
+
 	}
-	return wxID_CANCEL;
 }