summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjingham <jingham>2000-04-17 02:16:50 (GMT)
committerjingham <jingham>2000-04-17 02:16:50 (GMT)
commit6f987a6c0e78f61f4725eaea8d5af917ae0e512f (patch)
tree1a59843ce7c822315b06ab28e8408ea558bbff17
parent819f7a916c062ecac5004dcb6fc66e842baddc59 (diff)
downloadtk-6f987a6c0e78f61f4725eaea8d5af917ae0e512f.zip
tk-6f987a6c0e78f61f4725eaea8d5af917ae0e512f.tar.gz
tk-6f987a6c0e78f61f4725eaea8d5af917ae0e512f.tar.bz2
Add Navigation Services support.
-rw-r--r--mac/tkMacDialog.c851
1 files changed, 716 insertions, 135 deletions
diff --git a/mac/tkMacDialog.c b/mac/tkMacDialog.c
index cfd1863..51c250c 100644
--- a/mac/tkMacDialog.c
+++ b/mac/tkMacDialog.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkMacDialog.c,v 1.4 1999/05/22 06:32:42 jingham Exp $
+ * RCS: @(#) $Id: tkMacDialog.c,v 1.5 2000/04/17 02:16:50 jingham Exp $
*/
#include <Gestalt.h>
@@ -20,6 +20,7 @@
#include <StandardFile.h>
#include <ColorPicker.h>
#include <Lowmem.h>
+#include <Navigation.h>
#include "tkPort.h"
#include "tkInt.h"
#include "tclMacInt.h"
@@ -43,6 +44,7 @@
#define SAVE_FILE 0
#define OPEN_FILE 1
+#define CHOOSE_FOLDER 2
#define MATCHED 0
#define UNMATCHED 1
@@ -62,24 +64,46 @@ typedef struct _OpenFileData {
* -filetypes option is set). */
} OpenFileData;
+
static pascal Boolean FileFilterProc _ANSI_ARGS_((CInfoPBPtr pb,
void *myData));
static int GetFileName _ANSI_ARGS_ ((ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *CONST objv[], int isOpen));
-static Boolean MatchOneType _ANSI_ARGS_((CInfoPBPtr pb,
+static int NavGetFileName _ANSI_ARGS_ ((ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], int isOpen));
+static Boolean MatchOneType _ANSI_ARGS_((StringPtr fileNamePtr, OSType fileType,
OpenFileData *myofdPtr, FileFilter *filterPtr));
static pascal short OpenHookProc _ANSI_ARGS_((short item,
DialogPtr theDialog, OpenFileData * myofdPtr));
static int ParseFileDlgArgs _ANSI_ARGS_ ((Tcl_Interp * interp,
OpenFileData * myofdPtr, int argc, char ** argv,
int isOpen));
-
+static pascal Boolean OpenFileFilterProc(AEDesc* theItem, void* info,
+ NavCallBackUserData callBackUD,
+ NavFilterModes filterMode );
+pascal void OpenEventProc(NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParms,
+ NavCallBackUserData callBackUD );
+static void InitFileDialogs();
+static int StdGetFile(Tcl_Interp *interp, OpenFileData *ofd,
+ unsigned char *initialFile, int isOpen);
+static int NavServicesGetFile(Tcl_Interp *interp, OpenFileData *ofd,
+ AEDesc *initialDesc, unsigned char *initialFile,
+ StringPtr title, StringPtr message, int multiple, int isOpen);
+static int HandleInitialDirectory (Tcl_Interp *interp, char *initialDir, FSSpec *dirSpec,
+ AEDesc *dirDescPtr);
/*
* Filter and hook functions used by the tk_getOpenFile and tk_getSaveFile
* commands.
*/
+int fileDlgInited = 0;
+int useNavServices = 0;
+NavObjectFilterUPP openFileFilterUPP;
+NavEventUPP openFileEventUPP;
+
static FileFilterYDUPP openFilter = NULL;
static DlgHookYDUPP openHook = NULL;
static DlgHookYDUPP saveHook = NULL;
@@ -274,7 +298,121 @@ Tk_GetOpenFileObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return GetFileName(clientData, interp, objc, objv, OPEN_FILE);
+ int i, result, multiple;
+ OpenFileData ofd;
+ Tk_Window parent;
+ Str255 message, title;
+ AEDesc initialDesc = {typeNull, NULL};
+ FSSpec dirSpec;
+ static char *openOptionStrings[] = {
+ "-filetypes", "-initialdir", "-message", "-multiple",
+ "-parent", "-title", NULL
+ };
+ enum openOptions {
+ OPEN_TYPES, OPEN_INITDIR, OPEN_MESSAGE, OPEN_MULTIPLE,
+ OPEN_PARENT, OPEN_TITLE
+ };
+
+ if (!fileDlgInited) {
+ InitFileDialogs();
+ }
+
+ result = TCL_ERROR;
+ parent = (Tk_Window) clientData;
+ multiple = false;
+ title[0] = 0;
+ message[0] = 0;
+
+ TkInitFileFilters(&ofd.fl);
+
+ ofd.curType = 0;
+ ofd.popupItem = OPEN_POPUP_ITEM;
+ ofd.usePopup = 1;
+
+ for (i = 1; i < objc; i += 2) {
+ char *choice;
+ int index, choiceLen;
+ char *string;
+ int srcRead, dstWrote;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], openOptionStrings, "option",
+ TCL_EXACT, &index) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetStringFromObj(objv[i], NULL);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ result = TCL_ERROR;
+ goto end;
+ }
+
+ switch (index) {
+ case OPEN_TYPES:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (TkGetFileFilters(interp, &ofd.fl, choice, 0)
+ != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case OPEN_INITDIR:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (HandleInitialDirectory(interp, choice, &dirSpec,
+ &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case OPEN_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ message[0] = dstWrote;
+ break;
+ case OPEN_MULTIPLE:
+ if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &multiple) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case OPEN_PARENT:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ parent = Tk_NameToWindow(interp, choice, parent);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case OPEN_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ title[0] = dstWrote;
+ break;
+ }
+ }
+
+ if (useNavServices) {
+ AEDesc *initialPtr = NULL;
+
+ if (initialDesc.descriptorType == typeFSS) {
+ initialPtr = &initialDesc;
+ }
+ result = NavServicesGetFile(interp, &ofd, initialPtr, NULL,
+ title, message, multiple, OPEN_FILE);
+ } else {
+ result = StdGetFile(interp, &ofd, NULL, OPEN_FILE);
+ }
+
+ end:
+ TkFreeFileFilters(&ofd.fl);
+ AEDisposeDesc(&initialDesc);
+
+ return result;
}
/*
@@ -300,69 +438,180 @@ Tk_GetSaveFileObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *CONST objv[]) /* Argument objects. */
{
- return GetFileName(clientData, interp, objc, objv, SAVE_FILE);
+ int i, result;
+ Str255 initialFile;
+ Tk_Window parent;
+ AEDesc initialDesc = {typeNull, NULL};
+ FSSpec dirSpec;
+ Str255 title, message;
+ OpenFileData ofd;
+ static char *saveOptionStrings[] = {
+ "-defaultextension", "-initialdir", "-initialfile",
+ "-message", "-parent", "-title", NULL
+ };
+ enum saveOptions {
+ SAVE_DEFAULT, SAVE_INITDIR, SAVE_INITFILE,
+ SAVE_MESSAGE, SAVE_PARENT, SAVE_TITLE
+ };
+
+ if (!fileDlgInited) {
+ InitFileDialogs();
+ }
+
+ result = TCL_ERROR;
+ parent = (Tk_Window) clientData;
+ StrLength(initialFile) = 0;
+ title[0] = 0;
+ message[0] = 0;
+
+
+ for (i = 1; i < objc; i += 2) {
+ char *choice;
+ int index, choiceLen;
+ char *string;
+ Tcl_DString ds;
+ int srcRead, dstWrote;
+
+ if (Tcl_GetIndexFromObj(interp, objv[i], saveOptionStrings, "option",
+ TCL_EXACT, &index) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if (i + 1 == objc) {
+ string = Tcl_GetStringFromObj(objv[i], NULL);
+ Tcl_AppendResult(interp, "value for \"", string, "\" missing",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+ switch (index) {
+ case SAVE_DEFAULT:
+ break;
+ case SAVE_INITDIR:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (HandleInitialDirectory(interp, choice, &dirSpec,
+ &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case SAVE_INITFILE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ if (Tcl_TranslateFileName(interp, choice, &ds) == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
+ Tcl_DStringLength(&ds), 0, NULL,
+ StrBody(initialFile), 255, &srcRead, &dstWrote, NULL);
+ StrLength(initialFile) = (unsigned char) dstWrote;
+ Tcl_DStringFree(&ds);
+ break;
+ case SAVE_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(message) = (unsigned char) dstWrote;
+ break;
+ case SAVE_PARENT:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ parent = Tk_NameToWindow(interp, choice, parent);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case SAVE_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(title) = (unsigned char) dstWrote;
+ break;
+ }
+ }
+
+ TkInitFileFilters(&ofd.fl);
+ ofd.usePopup = 0;
+
+ if (useNavServices) {
+ AEDesc *initialPtr = NULL;
+
+ if (initialDesc.descriptorType == typeFSS) {
+ initialPtr = &initialDesc;
+ }
+ result = NavServicesGetFile(interp, &ofd, initialPtr, initialFile,
+ title, message, false, SAVE_FILE);
+ } else {
+ result = StdGetFile(interp, NULL, initialFile, SAVE_FILE);
+ }
+
+ end:
+
+ AEDisposeDesc(&initialDesc);
+
+ return result;
}
/*
*----------------------------------------------------------------------
*
- * GetFileName --
+ * Tk_ChooseDirectoryObjCmd --
*
- * Calls the Mac file dialog functions for the user to choose a
- * file to or save.
+ * This procedure implements the "tk_chooseDirectory" dialog box
+ * for the Windows platform. See the user documentation for details
+ * on what it does.
*
* Results:
- * A standard Tcl result.
+ * See user documentation.
*
* Side effects:
- * If the user selects a file, the native pathname of the file
- * is returned in the interp's result. Otherwise an empty string
- * is returned in the interp's result.
+ * A modal dialog window is created. Tcl_SetServiceMode() is
+ * called to allow background events to be processed
*
*----------------------------------------------------------------------
*/
-static int
-GetFileName(
- ClientData clientData, /* Main window associated with interpreter. */
- Tcl_Interp *interp, /* Current interpreter. */
- int objc, /* Number of arguments. */
- Tcl_Obj *CONST objv[], /* Argument objects. */
- int isOpen) /* true if we should call GetOpenFileName(),
- * false if we should call GetSaveFileName() */
+int
+Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
+ ClientData clientData; /* Main window associated with interpreter. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int objc; /* Number of arguments. */
+ Tcl_Obj *CONST objv[]; /* Argument objects. */
{
int i, result;
- OpenFileData ofd;
- StandardFileReply reply;
- Point mypoint;
- MenuHandle menu;
- Str255 initialFile;
- char *choice[6];
Tk_Window parent;
- static char *optionStrings[] = {
- "-defaultextension", "-filetypes", "-initialdir", "-initialfile",
- "-parent", "-title", NULL
+ AEDesc initialDesc = {typeNull, NULL};
+ FSSpec dirSpec;
+ Str255 message, title;
+ int srcRead, dstWrote;
+ OpenFileData ofd;
+ static char *chooseOptionStrings[] = {
+ "-initialdir", "-message", "-mustexist", "-parent", "-title", NULL
};
- enum options {
- FILE_DEFAULT, FILE_TYPES, FILE_INITDIR, FILE_INITFILE,
- FILE_PARENT, FILE_TITLE
+ enum chooseOptions {
+ CHOOSE_INITDIR, CHOOSE_MESSAGE, CHOOSE_MUSTEXIST,
+ CHOOSE_PARENT, CHOOSE_TITLE
};
+
+
+ if (!NavServicesAvailable()) {
+ return TCL_ERROR;
+ }
- if (openFilter == NULL) {
- openFilter = NewFileFilterYDProc(FileFilterProc);
- openHook = NewDlgHookYDProc(OpenHookProc);
- saveHook = NewDlgHookYDProc(OpenHookProc);
+ if (!fileDlgInited) {
+ InitFileDialogs();
}
-
result = TCL_ERROR;
parent = (Tk_Window) clientData;
- memset(choice, 0, sizeof(choice));
+ title[0] = 0;
+ message[0] = 0;
for (i = 1; i < objc; i += 2) {
- int index;
+ char *choice;
+ int index, choiceLen;
char *string;
- if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option",
+ if (Tcl_GetIndexFromObj(interp, objv[i], chooseOptionStrings, "option",
TCL_EXACT, &index) != TCL_OK) {
return TCL_ERROR;
}
@@ -372,35 +621,77 @@ GetFileName(
(char *) NULL);
return TCL_ERROR;
}
- choice[index] = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ switch (index) {
+ case CHOOSE_INITDIR:
+ choice = Tcl_GetStringFromObj(objv[i + 1], NULL);
+ if (HandleInitialDirectory(interp, choice, &dirSpec,
+ &initialDesc) != TCL_OK) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case CHOOSE_MESSAGE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(message), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(message) = (unsigned char) dstWrote;
+ break;
+ case CHOOSE_PARENT:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ parent = Tk_NameToWindow(interp, choice, parent);
+ if (parent == NULL) {
+ result = TCL_ERROR;
+ goto end;
+ }
+ break;
+ case CHOOSE_TITLE:
+ choice = Tcl_GetStringFromObj(objv[i + 1], &choiceLen);
+ Tcl_UtfToExternal(NULL, NULL, choice, choiceLen,
+ 0, NULL, StrBody(title), 255,
+ &srcRead, &dstWrote, NULL);
+ StrLength(title) = (unsigned char) dstWrote;
+ break;
+ }
}
-
- StrLength(initialFile) = 0;
- menu = NULL;
-
+
TkInitFileFilters(&ofd.fl);
- ofd.curType = 0;
- ofd.popupItem = OPEN_POPUP_ITEM;
- ofd.usePopup = isOpen;
-
- if (choice[FILE_TYPES] != NULL) {
- if (TkGetFileFilters(interp, &ofd.fl, choice[FILE_TYPES], 0) != TCL_OK) {
- goto end;
+ ofd.usePopup = 0;
+
+ if (useNavServices) {
+ AEDesc *initialPtr = NULL;
+
+ if (initialDesc.descriptorType == typeFSS) {
+ initialPtr = &initialDesc;
}
+ result = NavServicesGetFile(interp, &ofd, initialPtr, NULL,
+ title, message, false, CHOOSE_FOLDER);
+ } else {
+ result = TCL_ERROR;
}
- if (choice[FILE_INITDIR] != NULL) {
- FSSpec dirSpec;
+
+ end:
+ AEDisposeDesc(&initialDesc);
+
+ return result;
+}
+
+int
+HandleInitialDirectory (
+ Tcl_Interp *interp,
+ char *initialDir,
+ FSSpec *dirSpec,
+ AEDesc *dirDescPtr)
+{
Tcl_DString ds;
long dirID;
OSErr err;
Boolean isDirectory;
- char *string;
Str255 dir;
int srcRead, dstWrote;
- string = choice[FILE_INITDIR];
- if (Tcl_TranslateFileName(interp, string, &ds) == NULL) {
- goto end;
+ if (Tcl_TranslateFileName(interp, initialDir, &ds) == NULL) {
+ return TCL_ERROR;
}
Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds), 0, NULL, StrBody(dir), 255,
@@ -408,46 +699,360 @@ GetFileName(
StrLength(dir) = (unsigned char) dstWrote;
Tcl_DStringFree(&ds);
- err = FSpLocationFromPath(StrLength(dir), StrBody(dir), &dirSpec);
+ err = FSpLocationFromPath(StrLength(dir), StrBody(dir), dirSpec);
if (err != noErr) {
- Tcl_AppendResult(interp, "bad directory \"", string, "\"", NULL);
- goto end;
+ Tcl_AppendResult(interp, "bad directory \"", initialDir, "\"", NULL);
+ return TCL_ERROR;
}
- err = FSpGetDirectoryID(&dirSpec, &dirID, &isDirectory);
+ err = FSpGetDirectoryID(dirSpec, &dirID, &isDirectory);
if ((err != noErr) || !isDirectory) {
- Tcl_AppendResult(interp, "bad directory \"", string, "\"", NULL);
- goto end;
+ Tcl_AppendResult(interp, "bad directory \"", initialDir, "\"", NULL);
+ return TCL_ERROR;
}
- /*
- * Make sure you negate -dirSpec.vRefNum because the
- * standard file package wants it that way !
- */
+
+ if (useNavServices) {
+ AECreateDesc( typeFSS, dirSpec, sizeof(*dirSpec), dirDescPtr);
+ } else {
+ /*
+ * Make sure you negate -dirSpec.vRefNum because the
+ * standard file package wants it that way !
+ */
- LMSetSFSaveDisk(-dirSpec.vRefNum);
- LMSetCurDirStore(dirID);
+ LMSetSFSaveDisk(-dirSpec->vRefNum);
+ LMSetCurDirStore(dirID);
+ }
+ return TCL_OK;
+}
+
+static void
+InitFileDialogs()
+{
+ fileDlgInited = 1;
+
+ if (NavServicesAvailable()) {
+ openFileFilterUPP = NewNavObjectFilterProc(OpenFileFilterProc);
+ openFileEventUPP = NewNavEventProc(OpenEventProc);
+ useNavServices = 1;
+ } else {
+ openFilter = NewFileFilterYDProc(FileFilterProc);
+ openHook = NewDlgHookYDProc(OpenHookProc);
+ saveHook = NewDlgHookYDProc(OpenHookProc);
+ useNavServices = 0;
}
- if (choice[FILE_INITFILE] != NULL) {
- Tcl_DString ds;
- int srcRead, dstWrote;
+
- if (Tcl_TranslateFileName(interp, choice[FILE_INITFILE], &ds) == NULL) {
- goto end;
- }
- Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds), 0, NULL,
- StrBody(initialFile), 255, &srcRead, &dstWrote, NULL);
- StrLength(initialFile) = (unsigned char) dstWrote;
- Tcl_DStringFree(&ds);
- }
- if (choice[FILE_PARENT] != NULL) {
- parent = Tk_NameToWindow(interp, choice[FILE_PARENT], parent);
- if (parent == NULL) {
- return TCL_ERROR;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetFileName --
+ *
+ * Calls the Mac file dialog functions for the user to choose a
+ * file to or save.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * If the user selects a file, the native pathname of the file
+ * is returned in the interp's result. Otherwise an empty string
+ * is returned in the interp's result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetFileName(
+ ClientData clientData, /* Main window associated with interpreter. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ int isOpen) /* true if we should call GetOpenFileName(),
+ * false if we should call GetSaveFileName() */
+{
+ return TCL_OK;
+}
+
+static int
+NavServicesGetFile(
+ Tcl_Interp *interp,
+ OpenFileData *ofdPtr,
+ AEDesc *initialDesc,
+ unsigned char *initialFile,
+ StringPtr title,
+ StringPtr message,
+ int multiple,
+ int isOpen)
+{
+ NavReplyRecord theReply;
+ NavDialogOptions diagOptions;
+ OSErr err;
+ Tcl_Obj *theResult;
+ int result;
+
+
+ diagOptions.location.h = -1;
+ diagOptions.location.v = -1;
+ diagOptions.dialogOptionFlags = kNavDontAutoTranslate
+ + kNavDontAddTranslateItems;
+
+ if (multiple) {
+ diagOptions.dialogOptionFlags += kNavAllowMultipleFiles;
+ }
+
+ if (ofdPtr != NULL && ofdPtr->usePopup) {
+ FileFilter *filterPtr;
+
+ filterPtr = ofdPtr->fl.filters;
+ if (filterPtr == NULL) {
+ ofdPtr->usePopup = 0;
}
}
+
+ if (ofdPtr != NULL && ofdPtr->usePopup) {
+ NavMenuItemSpecHandle popupExtensionHandle = NULL;
+ NavMenuItemSpec *popupItems;
+ FileFilter *filterPtr;
+ short index = 0;
+
+ ofdPtr->curType = 0;
+
+ popupExtensionHandle = (NavMenuItemSpecHandle) NewHandle(ofdPtr->fl.numFilters
+ * sizeof(NavMenuItemSpec));
+ HLock((Handle) popupExtensionHandle);
+ popupItems = *popupExtensionHandle;
+
+ for (filterPtr = ofdPtr->fl.filters; filterPtr != NULL;
+ filterPtr = filterPtr->next, popupItems++, index++) {
+ int len;
+
+ len = strlen(filterPtr->name);
+ BlockMove(filterPtr->name, popupItems->menuItemName + 1, len);
+ popupItems->menuItemName[0] = len;
+ popupItems->menuCreator = 'WIsH';
+ popupItems->menuType = index;
+ }
+ HUnlock((Handle) popupExtensionHandle);
+ diagOptions.popupExtension = popupExtensionHandle;
+ } else {
+ diagOptions.dialogOptionFlags += kNavNoTypePopup;
+ diagOptions.popupExtension = NULL;
+ }
+
+ if ((initialFile != NULL) && (initialFile[0] != 0)) {
+ char *lastColon;
+ int len;
+
+ len = initialFile[0];
+
+ p2cstr(initialFile);
+ lastColon = strrchr((char *)initialFile, ':');
+ if (lastColon != NULL) {
+ len -= lastColon - ((char *) (initialFile + 1));
+ BlockMove(lastColon + 1, diagOptions.savedFileName + 1, len);
+ diagOptions.savedFileName[0] = len;
+ } else {
+ BlockMove(initialFile, diagOptions.savedFileName + 1, len);
+ diagOptions.savedFileName[0] = len;
+ }
+ } else {
+ diagOptions.savedFileName[0] = 0;
+ }
+
+ strcpy((char *) (diagOptions.clientName + 1),"Wish");
+ diagOptions.clientName[0] = strlen("Wish");
+
+ if (title == NULL) {
+ diagOptions.windowTitle[0] = 0;
+ } else {
+ BlockMove(title, diagOptions.windowTitle, title[0] + 1);
+ diagOptions.windowTitle[0] = title[0];
+ }
+
+ if (message == NULL) {
+ diagOptions.message[0] = 0;
+ } else {
+ BlockMove(message, diagOptions.message, message[0] + 1);
+ diagOptions.message[0] = message[0];
+ }
+
+ diagOptions.actionButtonLabel[0] = 0;
+ diagOptions.cancelButtonLabel[0] = 0;
+ diagOptions.preferenceKey = 0;
+
+ /* Now process the selection list. We have to use the popupExtension
+ * to fill the menu.
+ */
+
+
+ if (isOpen == OPEN_FILE) {
+ err = NavGetFile(initialDesc, &theReply, &diagOptions, openFileEventUPP,
+ NULL, openFileFilterUPP, NULL, ofdPtr);
+ } else if (isOpen == SAVE_FILE) {
+ err = NavPutFile (initialDesc, &theReply, &diagOptions, openFileEventUPP,
+ 'TEXT', 'WIsH', NULL);
+ } else if (isOpen == CHOOSE_FOLDER) {
+ err = NavChooseFolder (initialDesc, &theReply, &diagOptions,
+ openFileEventUPP, NULL, NULL);
+ }
+
+ theResult = Tcl_NewListObj(0, NULL);
+
+ if ( theReply.validRecord && err == noErr ) {
+ AEDesc resultDesc;
+ long count;
+ Tcl_DString fileName;
+ Handle pathHandle;
+ int length;
+
+ if ( err == noErr ) {
+ err = AECountItems(&(theReply.selection), &count);
+ if (err == noErr) {
+ long i;
+ for (i = 1; i <= count; i++ ) {
+ err = AEGetNthDesc(&(theReply.selection),
+ i, typeFSS, NULL, &resultDesc);
+ if (err == noErr) {
+ HLock(resultDesc.dataHandle);
+ pathHandle = NULL;
+ FSpPathFromLocation((FSSpec *) *resultDesc.dataHandle,
+ &length, &pathHandle);
+ HLock(pathHandle);
+ Tcl_ExternalToUtfDString(NULL, (char *) *pathHandle, -1, &fileName);
+ Tcl_ListObjAppendElement(interp, theResult,
+ Tcl_NewStringObj(Tcl_DStringValue(&fileName),
+ Tcl_DStringLength(&fileName)));
+ Tcl_DStringFree(&fileName);
+ HUnlock(pathHandle);
+ DisposeHandle(pathHandle);
+ HUnlock(resultDesc.dataHandle);
+ AEDisposeDesc( &resultDesc );
+ }
+ }
+ }
+ }
+ err = NavDisposeReply( &theReply );
+ Tcl_SetObjResult(interp, theResult);
+ result = TCL_OK;
+ } else if (err == userCanceledErr) {
+ result = TCL_OK;
+ } else {
+ result = TCL_ERROR;
+ }
+
+ if (diagOptions.popupExtension != NULL) {
+ DisposeHandle((Handle) diagOptions.popupExtension);
+ }
+
+ return result;
+}
+
+static pascal Boolean
+OpenFileFilterProc(
+ AEDesc* theItem, void* info,
+ NavCallBackUserData callBackUD,
+ NavFilterModes filterMode )
+{
+ OpenFileData *ofdPtr = (OpenFileData *) callBackUD;
+ if (!ofdPtr->usePopup) {
+ return true;
+ } else {
+ if (ofdPtr->fl.numFilters == 0) {
+ return true;
+ } else {
+
+ if ( theItem->descriptorType == typeFSS ) {
+ NavFileOrFolderInfo* theInfo = (NavFileOrFolderInfo*)info;
+ int result;
+
+ if ( !theInfo->isFolder ) {
+ OSType fileType;
+ StringPtr fileNamePtr;
+ int i;
+ FileFilter *filterPtr;
+
+ fileType = theInfo->fileAndFolder.fileInfo.finderInfo.fdType;
+ HLock(theItem->dataHandle);
+ fileNamePtr = (((FSSpec *) *theItem->dataHandle)->name);
+
+ if (ofdPtr->usePopup) {
+ i = ofdPtr->curType;
+ for (filterPtr=ofdPtr->fl.filters; filterPtr && i>0; i--) {
+ filterPtr = filterPtr->next;
+ }
+ if (filterPtr) {
+ result = MatchOneType(fileNamePtr, fileType,
+ ofdPtr, filterPtr);
+ } else {
+ result = false;
+ }
+ } else {
+ /*
+ * We are not using the popup menu. In this case, the file is
+ * considered matched if it matches any of the file filters.
+ */
+ result = UNMATCHED;
+ for (filterPtr=ofdPtr->fl.filters; filterPtr;
+ filterPtr=filterPtr->next) {
+ if (MatchOneType(fileNamePtr, fileType,
+ ofdPtr, filterPtr) == MATCHED) {
+ result = MATCHED;
+ break;
+ }
+ }
+ }
+
+ HUnlock(theItem->dataHandle);
+ return (result == MATCHED);
+ } else {
+ return true;
+ }
+ }
+ }
+
+ return true;
+ }
+}
+
+pascal void
+OpenEventProc(
+ NavEventCallbackMessage callBackSelector,
+ NavCBRecPtr callBackParams,
+ NavCallBackUserData callBackUD )
+{
+ NavMenuItemSpec *chosenItem;
+ OpenFileData *ofd = (OpenFileData *) callBackUD;
+ static SInt32 otherEvent = ~(kNavCBCustomize|kNavCBStart|kNavCBTerminate
+ |kNavCBNewLocation|kNavCBShowDesktop|kNavCBSelectEntry|kNavCBAccept
+ |kNavCBCancel|kNavCBAdjustPreview);
+
+ if (callBackSelector == kNavCBPopupMenuSelect) {
+ chosenItem = (NavMenuItemSpec *) callBackParams->eventData.eventDataParms.param;
+ ofd->curType = chosenItem->menuType;
+ } else if (callBackSelector == kNavCBAdjustRect || callBackSelector & otherEvent != 0) {
+ while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT|TCL_WINDOW_EVENTS)) {
+ /* Empty Body */
+ }
+ }
+}
+
+static int
+StdGetFile(
+ Tcl_Interp *interp,
+ OpenFileData *ofd,
+ unsigned char *initialFile,
+ int isOpen)
+{
+ int i;
+ StandardFileReply reply;
+ Point mypoint;
+ MenuHandle menu = NULL;
+
/*
- * 2. Set the items in the file types popup.
+ * Set the items in the file types popup.
*/
/*
@@ -455,7 +1060,7 @@ GetFileName(
* left overs from previous invocation of this command
*/
- if (ofd.usePopup) {
+ if (ofd != NULL && ofd->usePopup) {
FileFilter *filterPtr;
menu = GetMenu(OPEN_MENU);
@@ -469,9 +1074,9 @@ GetFileName(
DeleteMenuItem(menu, i);
}
- filterPtr = ofd.fl.filters;
+ filterPtr = ofd->fl.filters;
if (filterPtr == NULL) {
- ofd.usePopup = 0;
+ ofd->usePopup = 0;
} else {
for ( ; filterPtr != NULL; filterPtr = filterPtr->next) {
Str255 str;
@@ -484,33 +1089,37 @@ GetFileName(
}
/*
- * 3. Call the toolbox file dialog function.
+ * Call the toolbox file dialog function.
*/
SetPt(&mypoint, -1, -1);
TkpSetCursor(NULL);
- if (isOpen) {
- if (ofd.usePopup) {
+ if (isOpen == OPEN_FILE) {
+ if (ofd != NULL && ofd->usePopup) {
CustomGetFile(openFilter, (short) -1, NULL, &reply, OPEN_BOX,
mypoint, openHook, NULL, NULL, NULL, (void*) &ofd);
} else {
StandardGetFile(NULL, -1, NULL, &reply);
}
- } else {
+ } else if (isOpen == SAVE_FILE) {
static Str255 prompt = "\pSave as";
- if (ofd.usePopup) {
+ if (ofd != NULL && ofd->usePopup) {
/*
* Currently this never gets called because we don't use
* popup for the save dialog.
*/
CustomPutFile(prompt, initialFile, &reply, OPEN_BOX,
- mypoint, saveHook, NULL, NULL, NULL, (void *) &ofd);
+ mypoint, saveHook, NULL, NULL, NULL, (void *) ofd);
} else {
StandardPutFile(prompt, initialFile, &reply);
}
}
+ /*
+ * Now parse the reply, and populate the Tcl result.
+ */
+
if (reply.sfGood) {
int length;
Handle pathHandle;
@@ -529,14 +1138,11 @@ GetFileName(
}
}
- result = TCL_OK;
-
- end:
- TkFreeFileFilters(&ofd.fl);
if (menu != NULL) {
DisposeMenu(menu);
}
- return result;
+
+ return TCL_OK;
}
/*
*----------------------------------------------------------------------
@@ -649,7 +1255,8 @@ FileFilterProc(
filterPtr = filterPtr->next;
}
if (filterPtr) {
- return MatchOneType(pb, ofdPtr, filterPtr);
+ return MatchOneType(pb->hFileInfo.ioNamePtr, pb->hFileInfo.ioFlFndrInfo.fdType,
+ ofdPtr, filterPtr);
} else {
return UNMATCHED;
}
@@ -661,7 +1268,8 @@ FileFilterProc(
for (filterPtr=ofdPtr->fl.filters; filterPtr;
filterPtr=filterPtr->next) {
- if (MatchOneType(pb, ofdPtr, filterPtr) == MATCHED) {
+ if (MatchOneType(pb->hFileInfo.ioNamePtr, pb->hFileInfo.ioFlFndrInfo.fdType,
+ ofdPtr, filterPtr) == MATCHED) {
return MATCHED;
}
}
@@ -688,7 +1296,8 @@ FileFilterProc(
static Boolean
MatchOneType(
- CInfoPBPtr pb, /* Information about the file */
+ StringPtr fileNamePtr, /* Name of the file */
+ OSType fileType, /* Type of the file */
OpenFileData * ofdPtr, /* Information about this file dialog */
FileFilter * filterPtr) /* Match the file described by pb against
* this filter */
@@ -730,10 +1339,10 @@ MatchOneType(
int len;
char * p, *q, *ext;
- if (pb->hFileInfo.ioNamePtr == NULL) {
+ if (fileNamePtr == NULL) {
continue;
}
- p = (char*)(pb->hFileInfo.ioNamePtr);
+ p = (char*)(fileNamePtr);
len = p[0];
strncpy(filename, p+1, len);
filename[len] = '\0';
@@ -767,7 +1376,7 @@ MatchOneType(
}
for (mfPtr=clausePtr->macTypes; mfPtr; mfPtr=mfPtr->next) {
- if (pb->hFileInfo.ioFlFndrInfo.fdType == mfPtr->type) {
+ if (fileType == mfPtr->type) {
macMatched = 1;
break;
}
@@ -780,33 +1389,5 @@ MatchOneType(
return UNMATCHED;
}
-/*
- *----------------------------------------------------------------------
- *
- * Tk_ChooseDirectoryObjCmd --
- *
- * This procedure implements the "tk_chooseDirectory" dialog box
- * for the Windows platform. See the user documentation for details
- * on what it does.
- *
- * Results:
- * See user documentation.
- *
- * Side effects:
- * A modal dialog window is created. Tcl_SetServiceMode() is
- * called to allow background events to be processed
- *
- *----------------------------------------------------------------------
- */
-
-int
-Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv)
- ClientData clientData; /* Main window associated with interpreter. */
- Tcl_Interp *interp; /* Current interpreter. */
- int objc; /* Number of arguments. */
- Tcl_Obj *CONST objv[]; /* Argument objects. */
-{
- return TCL_ERROR;
-}