home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
-
- mac_dialogs.c: Copyright (c) Kevin Hammond 1993. All rights reserved.
-
- This module contains "generic" dialog handling code, plus a few
- common dialogs (e.g. the standard file dialogs).
-
- NB. All dialogs should abort to the main loop if a memory fault occurs.
-
- *****************************************************************************/
-
- #include "mac.h"
-
- #pragma segment Dialogs
-
- char dlgargs[256];
- char *sfbuttontext = dlgargs;
- short KeyModifiers = 0;
-
- static char dlgsearch[256];
- static short dlgsearchsize = 0;
- static Cell dlgsearchfrom;
- ListHandle dlgsearchlist = NIL;
- short dlgOtherButton = 0;
- Boolean dlgcasesens = FALSE;
-
- extern char ftolower();
- extern Boolean ReplyExists;
- extern Boolean cursorkey();
-
- void highlightDefault();
-
- /* Ticks before we give up searching for this item in a list */
- #define KEY_THRESHOLD 60
-
-
- Handle gethandle();
- ControlHandle getctlhandle();
-
- pascal short setbutton(), setSFPbutton();
-
-
- /*
- Simple OK/Cancel dialog with one editable text box
- The EditText item is a numeric value if numeric
- is TRUE.
- */
-
- #define TEXTITEM 3
- #define SCROLLUP 4
- #define SCROLLDOWN 5
- #define SCROLLUPICON 128
- #define SCROLLDOWNICON 129
- #define SCROLLUPPRESSEDICON 130
- #define SCROLLDOWNPRESSEDICON 131
-
-
- int numdialog(dialogrno,itemno,init,min,max)
- short dialogrno;
- int itemno;
- int init, min, max;
- {
- DialogPtr etdlg;
- short itemhit;
- char valuestr[20];
- int value = init, newval, time;
-
- sprintf(valuestr,"%d",init);
-
- SetCursor(&(qd.arrow));
- etdlg = GetNewDialog(dialogrno,nil,(WindowPtr) -1);
-
- /* Initialise Parameter */
- SetDlgItemText(etdlg,itemno,valuestr);
-
- /* Now show dialog window */
- ShowWindow(etdlg);
-
- /* Highlight the default (OK) button */
- highlightDefault(etdlg);
-
- for(;;)
- {
- ModalDialog((ModalFilterProcPtr) nil,&itemhit);
- switch(itemhit)
- {
- case OK:
- getitext(gethandle(itemno,etdlg),valuestr);
- value = atoi(valuestr);
-
- case CANCEL:
- DisposDialog(etdlg);
- return(itemhit == OK?value:0);
-
- case SCROLLUP:
- case SCROLLDOWN:
- SetDItemPic(etdlg,itemhit,itemhit==SCROLLUP?SCROLLUPPRESSEDICON:
- SCROLLDOWNPRESSEDICON);
- do {
- if(itemhit == SCROLLUP)
- {
- if(++value > max)
- value = max;
- }
- else
- {
- if(--value < min)
- value = min;
- }
-
- sprintf(valuestr,"%d",value);
- setitext(gethandle(itemno,etdlg),valuestr);
- SelIText(etdlg,TEXTITEM,0,32767);
- Delay(8,&time); /* Slow things down a little */
- } while(StillDown());
-
- SetDItemPic(etdlg,itemhit,
- itemhit==SCROLLUP?SCROLLUPICON:SCROLLDOWNICON);
- break;
-
-
- case TEXTITEM:
- getitext(gethandle(itemno,etdlg),valuestr);
- newval = atoi(valuestr);
- if(newval <=0)
- {
- SysBeep(1);
- SelIText(etdlg,TEXTITEM,0,32767);
- }
- else
- value = newval;
- }
- }
- }
-
-
- /*
- Simple Yes/No/Cancel dialog.
-
- button defines the default button.
- */
-
- int yesnodialog(dialogrno,s1,s2,button)
- short dialogrno;
- char *s1, *s2;
- short button;
- {
- DialogPtr yndlg;
- short itemhit;
-
- SetCursor(&(qd.arrow));
- paramtext(s1,s2,"","");
-
- yndlg = GetNewDialog(dialogrno,nil,(WindowPtr) -1);
- ShowWindow(yndlg);
-
- ((DialogPeek)yndlg)->aDefItem = button;
-
- highlightDefault(yndlg);
-
- for(;;)
- {
- ModalDialog((ModalFilterProcPtr) nil,&itemhit);
-
- switch(itemhit)
- {
- case YES:
- case NO:
- case CANCEL:
- DisposDialog(yndlg);
- return(itemhit);
- }
- }
- }
-
- /*
- Packaged SFGetFile dialog.
- Return the string chosen or "" if cancelled.
- */
-
- char *getfile(nitems,typelist,msg,buttonstring)
- short nitems;
- SFTypeList typelist;
- char *msg, *buttonstring;
- {
- Point where;
- char *filename = "";
- Boolean getOK;
- StandardFileReply SFReply;
-
- SetCursor(&(qd.arrow));
-
- SetPt(&where,75,35);
- strcpy(sfbuttontext,buttonstring);
-
- if(systemVersion >= 0x0700)
- {
- #if 1
- StandardGetFile(NIL,nitems,typelist,&SFReply);
- #else
- CustomGetFile(NIL,nitems,typelist,&SFReply,sfGetDialogID,
- where,setbutton,NIL,NIL,NIL,NIL);
- #endif
-
- ReplySpec = SFReply.sfFile;
- getOK = SFReply.sfGood;
- }
- else
- {
- sfgetfile(&where,msg,NIL,nitems,typelist,setbutton,&Reply);
-
- SFReplyToFSSpec(Reply, &ReplySpec);
- getOK = Reply.good;
- }
-
- if(getOK)
- {
- *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
- filename = (char *)ReplySpec.name+1;
- }
-
- savedir(ReplySpec.vRefNum,ReplySpec.parID,TRUE);
- return(filename);
- }
-
-
- /*
- Packaged SFGetFile dialog.
- Return the string chosen or "" if cancelled.
- Use the named dialog rather than the standard SF dialog.
- */
-
- char *askgetfile(nitems,typelist,prompt,buttonstring,dlg6,dlg7)
- short nitems;
- SFTypeList typelist;
- char *prompt, *buttonstring;
- short dlg6, dlg7;
- {
- Point where;
- FInfo dummyFInfo;
-
-
- SetCursor(&(qd.arrow));
- SetPt(&where,75,35);
- strcpy(sfbuttontext,buttonstring);
-
- if(systemVersion >= 0x0700)
- {
- StandardFileReply Reply;
-
- CustomGetFile(NIL,nitems,typelist,&Reply,dlg7,where,NIL,
- NIL,NIL,NIL,NIL);
-
- if(Reply.sfGood)
- {
- ReplySpec = Reply.sfFile;
- ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
- *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
- return((char *)ReplySpec.name+1);
- }
- else
- return("");
- }
- else
- {
- if(dlg6 == 0)
- sfgetfile(&where,"",NIL,nitems,typelist,setbutton,&Reply);
- else
- sfpgetfile(&where,"",NIL,nitems,typelist,setSFPbutton,&Reply,dlg6,NIL);
-
- if(Reply.good)
- {
- SFReplyToFSSpec(Reply, &ReplySpec);
- ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
-
- *((char *)Reply.fName + (int) *((char *)Reply.fName)+1) = '\0';
- return((char *)Reply.fName+1);
- }
- else
- return("");
- }
- }
-
-
- /*
- Packaged SFPutFile dialog.
-
- Return the name of the file chosen or "" if cancelled.
- */
-
- char *putfile(title,defaultfile,buttonstring)
- char *title, *defaultfile, *buttonstring;
- {
- Point where;
- FInfo dummyFInfo;
- char *filename = "";
- Boolean putOK;
- StandardFileReply SFReply;
-
- SetCursor(&(qd.arrow));
- SetPt(&where,75,35);
- strcpy(sfbuttontext,buttonstring);
-
-
- if(systemVersion >= 0x0700)
- {
- #if 1
- StandardPutFile(c2pstr(title),c2pstr(defaultfile),&SFReply);
- #else
- CustomPutFile(c2pstr(title),c2pstr(defaultfile),&SFReply,
- sfPutDialogID,where,setbutton,NIL,NIL,NIL,NIL);
- #endif
- (void)p2cstr(title);
- (void)p2cstr(defaultfile);
-
- ReplySpec = SFReply.sfFile;
- putOK = SFReply.sfGood;
- }
- else
- {
- sfputfile(&where,title,defaultfile,setbutton,&Reply);
- SFReplyToFSSpec(Reply, &ReplySpec);
- putOK = Reply.good;
- }
-
- if(putOK)
- {
- *((char *)ReplySpec.name + (int) *((char *)ReplySpec.name)+1) = '\0';
- filename = (char *)ReplySpec.name+1;
- }
-
- if(*filename != '\0')
- ReplyExists = HGetFInfo(ReplySpec.vRefNum,ReplySpec.parID,ReplySpec.name,&dummyFInfo) == noErr;
-
- savedir(ReplySpec.vRefNum,ReplySpec.parID,TRUE);
- return(filename);
- }
-
-
-
- /*
- Set the text of a button.
- Used as a dialog hook in an SF dialog.
- */
-
- pascal short setbutton(item,dlg)
- short item;
- DialogPtr dlg;
- {
- static Boolean dohighlight = FALSE;
- if(dohighlight)
- {
- highlightDefault(dlg);
- dohighlight = FALSE;
- }
-
- if(*sfbuttontext != '\0')
- {
- SetButtonTitle(dlg,OK,sfbuttontext);
- dohighlight = TRUE;
- *sfbuttontext = '\0';
- }
- return(item);
- }
-
-
- /*
- Set the text of a button.
- Used as a dialog hook in an SFP dialog.
-
- We don't highlight the default, since with SFP calls, we can't highlight
- until after first event.
-
- -- MS
- */
-
- pascal short setSFPbutton(item,dlg)
- short item;
- DialogPtr dlg;
- {
- if(*sfbuttontext != '\0')
- {
- SetButtonTitle(dlg,OK,sfbuttontext);
- *sfbuttontext = '\0';
- }
- return(item);
- }
-
-
- /*
- Set the title of a button.
- */
-
- SetButtonTitle(dlg,item,text)
- DialogPtr dlg;
- short item;
- char *text;
- {
- setctitle(getctlhandle(item,dlg),text);
- }
-
-
- /*
- Disable/Enable a button.
- */
-
- DisableButton(dlg,item)
- DialogPtr dlg;
- short item;
- {
- HiliteControl(getctlhandle(item,dlg),255);
- }
-
-
- EnableButton(dlg,item)
- DialogPtr dlg;
- short item;
- {
- HiliteControl(getctlhandle(item,dlg),0);
- }
-
-
-
- /*
- Get a handle for a dialog item
- */
-
- Handle gethandle(item,dialogptr)
- short item;
- DialogPtr dialogptr;
- {
- short itemtype;
- Rect itemrect;
- Handle itemhandle;
-
- GetDItem(dialogptr,item,&itemtype,&itemhandle,&itemrect);
- return(itemhandle);
- }
-
-
- /*
- Get the type of a dialog item
- */
-
- short getitemtype(item,dialogptr)
- short item;
- DialogPtr dialogptr;
- {
- short itemtype;
- Rect itemrect;
- Handle itemhandle;
-
- GetDItem(dialogptr,item,&itemtype,&itemhandle,&itemrect);
- return(itemtype);
- }
-
- GetDlgItemRect(dialogptr, item, itemrect)
- DialogPtr dialogptr;
- short item;
- Rect *itemrect;
- {
- short itemtype;
- Handle itemhandle;
-
- GetDItem(dialogptr,item,&itemtype,&itemhandle,itemrect);
- }
-
-
-
- ControlHandle getctlhandle(item,dialogptr)
- short item;
- DialogPtr dialogptr;
- {
- return((ControlHandle) gethandle(item,dialogptr));
- }
-
-
-
- /*
- Highlight the Default button in a dialog
- */
-
- void highlightDefault(dlgarg)
- DialogPtr dlgarg;
- {
- DialogPeek dlg = (DialogPeek) dlgarg;
- short button = (dlg)->aDefItem;
- Rect displayRect;
- short itemType;
- Handle itemHandle;
- WindowPtr SavePort;
-
- GetDItem((DialogPtr)dlg,button,&itemType,&itemHandle,&displayRect);
- GetPort(&SavePort);
- SetPort((WindowPtr)dlg);
- PenSize(3,3);
- InsetRect(&displayRect,-4,-4);
- FrameRoundRect(&displayRect,16,16);
- SetPort(SavePort);
- }
-
-
-
- /*
- Draw the frame around a dialog item.
- */
-
- DrawFrame(dlg,item)
- DialogPtr dlg;
- short item;
- {
- Rect displayRect;
- short itemType;
- Handle itemHandle;
-
- GetDItem(dlg,item,&itemType,&itemHandle,&displayRect);
- FrameDlgRect(dlg,displayRect);
- }
-
-
- /*
- Draw the frame around a Rect.
- */
-
- FrameDlgRect(dlg,rect)
- DialogPtr dlg;
- Rect rect;
- {
- WindowPtr SavePort;
-
- GetPort(&SavePort);
- SetPort((WindowPtr)dlg);
- PenNormal();
- OffsetRect(&rect,2,2);
- FrameRect(&rect);
- SetPort(SavePort);
- }
-
-
- /*
- Frame a dialog list item.
- */
-
- FrameDlgList(dlg,rect)
- DialogPtr dlg;
- Rect rect;
- {
- WindowPtr SavePort;
-
- GetPort(&SavePort);
- SetPort((WindowPtr)dlg);
- PenNormal();
- OffsetRect(&rect,2,2);
- SetRect(&rect,rect.left-4,rect.top-3,rect.right-1,rect.bottom-1);
- FrameRect(&rect);
- SetPort(SavePort);
- }
-
-
- /*
- Set the text of an edittext or static text item.
- */
-
- SetDlgItemText(dlg,item,text)
- DialogPtr dlg;
- short item;
- char *text;
- {
- Handle itemhandle = gethandle(item,dlg);
- setitext(itemhandle,text);
-
- if (getitemtype(item, dlg) == editText) /* Only select if it's editable */
- SelIText(dlg,item,0,32767);
- }
-
-
- /*
- Set Dialog item text from an Int value.
- */
-
-
- SetDlgItemETVal(dlg,item,value)
- DialogPtr dlg;
- short item;
- int value;
- {
- char sval[20];
- sprintf(sval,"%d",value);
- SetDlgItemText(dlg,item,sval);
- }
-
-
- /*
- Get Dialog item value from its text.
- */
-
- Boolean GetDlgItemETVal(dlg,item,value)
- DialogPtr dlg;
- short item;
- int *value;
- {
- char sval[256];
- int temp;
-
- getitext(gethandle(item,dlg),sval);
-
- if((temp = atoi(sval)) > 0)
- {
- *value = temp;
- return(TRUE);
- }
-
- return(FALSE);
- }
-
-
- /*
- Set the value of a dialog control.
- */
-
- SetDlgItemValue(dlg,item,value)
- DialogPtr dlg;
- short item, value;
- {
- SetCtlValue(getctlhandle(item,dlg),value);
- }
-
-
-
- /*
- Invert the value of a dialog control.
- Used for check-boxes and radio-controls.
- */
-
- InvertDlgItemValue(dlg,item)
- DialogPtr dlg;
- short item;
- {
- ControlHandle ctlhandle = getctlhandle(item,dlg);
- short itemvalue = GetCtlValue(ctlhandle);
- SetCtlValue(ctlhandle,!itemvalue);
- }
-
-
- /*
- Set the picture for a dialog item to PICT #pic
- */
-
- SetDItemPic(dialog,item,pic)
- DialogPtr dialog;
- short item, pic;
- {
- Handle OldPicHandle;
- PicHandle NewPicHandle;
- Rect box;
- short itype;
-
- GetDItem(dialog,item,&itype,&OldPicHandle,&box);
- NewPicHandle = GetPicture(pic);
- if(NewPicHandle != NIL)
- SetDItem(dialog,item,itype,(Handle)NewPicHandle,&box);
- }
-
-
- /*
- Enable standard buttons.
- */
-
- EnableButtons(dlg)
- DialogPtr dlg;
- {
- EnableButton(dlg,((DialogPeek)dlg)->aDefItem);
- if(dlgOtherButton != 0)
- EnableButton(dlg,dlgOtherButton);
- }
-
-
- /*
- Dialog FIlter Procedure for List items.
- */
-
-
- pascal Boolean ListDlgFilter(dlg,event,itemhit)
- DialogPtr dlg;
- EventRecord *event;
- short *itemhit;
- {
- static long lastkey = 0;
- KeyModifiers = event->modifiers;
-
- switch (event->what)
- {
- case keyDown:
- case autoKey:
- {
- char ch = (char) (event->message & charCodeMask); /* Convert to ASCII */
-
- if(ch == '\n' || ch == '\r' || ch == ENTERkey)
- {
- *itemhit = ((DialogPeek)dlg)->aDefItem;
- return(TRUE);
- }
-
- else if ((event->modifiers & cmdKey) != 0)
- {
- if(ch == '.' )
- {
- *itemhit = CANCEL;
- return(TRUE);
- }
- }
-
- else if (ch == ESC)
- {
- *itemhit = CANCEL;
- return(TRUE);
- }
-
- else if (cursorkey(ch))
- {
- dlgarrowkey(dlgsearchlist,(Boolean)(ch==UARROWkey||ch==LARROWkey));
- EnableButtons(dlg);
- lastkey = 0;
- }
-
- else
- {
- /* Reset the search string after a certain interval */
- if (event->when - lastkey > KEY_THRESHOLD)
- {
- dlgsearchsize = 0;
- SetPt(&dlgsearchfrom,0,0);
- }
-
- /* extend the search string and record the time */
- lastkey = event->when;
- dlgsearch[dlgsearchsize++] = ch;
-
- /* Try to find the next matching cell */
- if(findcellmatching(dlgsearch,dlgsearchsize,
- dlgsearchlist,&dlgsearchfrom,dlgcasesens))
- EnableButtons(dlg);
- else
- dlgsearchsize--;
- }
- }
- break;
-
- /* mouseDown outside any item should reset the selection */
- case mouseDown:
- lastkey = 0;
- if(*itemhit == 0)
- {
- UnsetListSelection(dlgsearchlist);
- return(TRUE);
- }
- break;
- }
-
- return(FALSE);
- }
-
-
- /*
- Handle arrow keys in a list dialog.
- */
-
- dlgarrowkey(list,up)
- ListHandle list;
- Boolean up;
- {
- Cell sel;
- Boolean newsel;
-
- SetPt(&sel,0,0);
- newsel = !LGetSelect(TRUE,&sel,list);
-
- if(up || !up && (newsel || LNextCell(TRUE,TRUE,&sel,list)))
- {
- UnsetListSelection(list);
- if(sel.v > 0 && up)
- --sel.v;
-
- /* Force scrolling for the last item in the list */
- if(!up && !newsel)
- {
- /* LDoDraw(FALSE,list);*/
- ++sel.v;
- LSetSelect(TRUE,sel,list);
- LAutoScroll(list);
- LSetSelect(FALSE,sel,list);
- --sel.v;
- /* LDoDraw(TRUE,list);*/
- }
-
- /* Highlight the new item and scroll to it */
- LSetSelect(TRUE,sel,list);
- LAutoScroll(list);
- }
- }
-
- /*
- Reset Dialog search parameters.
- */
-
- resetDlgSearch(list,casesens)
- ListHandle list;
- Boolean casesens;
- {
- SetPt(&dlgsearchfrom,0,0);
- dlgsearchsize = 0;
- dlgsearchlist = list;
- dlgcasesens = casesens;
- }
-
-
- /*
- Find the first matching cell from the location given.
- */
-
-
- findcellmatching(match,size,list,from,casesens)
- char match[];
- short size;
- ListHandle list;
- Cell *from;
- Boolean casesens;
- {
- char buff[256];
- short len;
- Cell next;
- SetPt(&next,from->h,from->v);
-
- if(list != NIL)
- {
- while(TRUE)
- {
- len = 255;
- LGetCell(buff,&len,next,list);
- buff[len] = '\0';
- if(len >= size && equalitems(buff,match,size,casesens))
- {
- UnsetListSelection(list);
- LSetSelect(TRUE,next,list);
- HLock((Handle)list);
- SetPt(&((*list)->clikLoc),next.h,next.v);
- HUnlock((Handle)list);
- LAutoScroll(list);
- from->v = next.v;
- return(TRUE);
- }
-
- if(!LNextCell(TRUE,TRUE,&next,list))
- return(FALSE);
- }
- }
- }
-
-
- int equalitems(i1,i2,len,casesens)
- char *i1, *i2;
- int len;
- Boolean casesens;
- {
- int count;
-
- for(count=0; count < len; ++count,++i1,++i2)
- if(casesens)
- {
- if(*i1!=*i2)
- return(FALSE);
- }
- else if(ftolower(*i1)!=ftolower(*i2))
- return(FALSE);
-
- return(TRUE);
- }
-
-
-
- UnsetListSelection(list)
- ListHandle list;
- {
- Cell sel;
-
- SetPt(&sel,0,0);
- while(LGetSelect(TRUE,&sel,list))
- LSetSelect(FALSE,sel,list);
- }
-
-
-
- /*************************************************************************
-
- Error and debug Alerts.
-
- *************************************************************************/
-
-
-
- /*
- Complain to the user about something.
- */
-
- void Complain(file,theStringIndex)
- char *file;
- short theStringIndex;
- {
- char complaint[256];
- getindstring(complaint, Res_Complaint_Strings, theStringIndex);
- paramtext(file,complaint,"","");
- SetCursor(&qd.arrow);
- (void) Alert(Res_Complaint_Alert, NIL);
- }
-
-
- /*
- Show an error dialog.
- */
-
- Error(e,s)
- char *e, *s;
- {
- SetCursor(&(qd.arrow));
- paramtext(e,s,"","");
- StopAlert(Res_Error_Alert,NIL);
- }
-
-
- /*
- Show an error dialog, and abort to the main program.
- */
-
- AbortError(e,s)
- char *e, *s;
- {
- extern jmp_buf catch_error;
- Error(e,s);
- longjmp(catch_error,1);
- }
-
-
- /*
- Show an error dialog with an integer argument,
- and abort to the main program.
- */
-
-
- AbortErrorN(fmt,n)
- char *fmt;
- int n;
- {
- char s[256];
- sprintf(s,fmt,n);
- AbortError("",s);
- }
-
- /*
- Show an error dialog, and quit MacGofer.
- */
-
- FatalError(s)
- char *s;
- {
- quit = TRUE;
- AbortError("Fatal ",s);
- }
-
-
-
- /*
- Various dialogs used when debugging.
- */
-
-
-
- Debug(s)
- char *s;
- {
- SetCursor(&(qd.arrow));
- paramtext(s,"","","");
- NoteAlert(Res_Debug_Alert,NIL);
- }
-
-
- Debug2(fmt,a1)
- char *fmt, *a1;
- {
- char str[256];
-
- sprintf(str,fmt,a1);
- Debug(str);
- }
-
- Debug3(fmt,a1,a2)
- char *fmt, *a1, *a2;
- {
- char str[256];
-
- sprintf(str,fmt,a1,a2);
- Debug(str);
- }
-
- Debug4(fmt,a1,a2,a3)
- char *fmt, *a1, *a2, *a3;
- {
- char str[256];
-
- sprintf(str,fmt,a1,a2,a3);
- Debug(str);
- }
-
-