home *** CD-ROM | disk | FTP | other *** search
- /* PDDialogs.c: Utility dialogs routines for ProjectDrag
- *
- * A set of applets for drag and drop source control by Tim Maroney.
- * See develop, issue 23 for details.
- *
- * Built on DropShell by Leonard Rosenthol, Stephan Somogyi, and Marshall Clow,
- * and using the MoreFiles utilities by Jim Luther.
- *
- * This software is free, but don't modify and redistribute it without
- * changing the status window to indicate your name and your changes!
- */
-
- #include <Dialogs.h>
- #include <Errors.h>
- #include <Fonts.h>
- #include <Packages.h>
- #include <string.h>
-
- #include "PDDialogs.h"
- #include "PDUtilities.h"
- #include "DSUtils.h"
- #include "TasksAndErrors.h"
-
-
- #define k3StateConfirmAlert 202
- #define k3ConfirmYesItem 1
- #define k3ConfirmCancelItem 2
- #define k3ConfirmNoItem 5
-
- #define kUserSettingsDialog 203
- #define kUserNameItem 7
- #define kNicknameItem 8
-
- #define kTextDisplayDialog 205
- #define kMessageItem 2
- #define kEditTextItem 4
- #define kScrollerItem 5
-
- #define k2StateConfirmAlert 206
- #define k2ConfirmYesItem 1
- #define k2ConfirmNoItem 2
-
- #define kMargin 4
- #define kPageLines 16
- #define kScrollToTop 0
- #define kScrollToBottom 1
- #define kCheckOneItem 5
- #define kCheckTwoItem 6
-
- static Boolean pUserSettingsInitialized = false;
- static Str63 pUserName;
- static Str15 pNickname;
-
-
- static TEHandle pTextHandle;
- static Boolean pPersistentFlag;
-
-
- pascal Boolean MyFilterProc(DialogPtr theDialog,EventRecord *ev,short *itemHit)
- {
- return StdFilterProc(theDialog, ev, itemHit);
- }
-
-
- OSErr GetUserSettings(Str63 userName, Str15 userNickname, Boolean alwaysAsk)
- {
- OSErr err = noErr;
- FSSpec userSettingsFile;
-
- userName[0] = userNickname[0] = 0;
-
- if (!alwaysAsk && pUserSettingsInitialized)
- {
- /* just return the stashed copy */
- BlockMove(pUserName, userName, pUserName[0] + 1);
- BlockMove(pNickname, userNickname, pNickname[0] + 1);
- return noErr;
- }
-
- TaskStart(kProjectDragStrings, kGettingUserName, NULL, NULL, NULL, NULL);
-
- /* find the user settings file */
- err = FindPreferencesFolder(&userSettingsFile.vRefNum, &userSettingsFile.parID);
- if (err != noErr) return RaiseErrorNumber(err);
- GetIndString(userSettingsFile.name, kProjectDragStrings, kPrefsFileName);
-
- {
- /* try to get it from the preferences file */
- short refNum;
- long eof;
-
- err = FSpOpenDF(&userSettingsFile, fsRdPerm, &refNum);
- if (err == noErr)
- {
- char buffer[72];
- err = GetEOF(refNum, &eof);
- if (err == noErr)
- {
- if (eof > 72)
- {
- FSpDelete(&userSettingsFile); /* bad prefs file */
- err = paramErr; /* aargh */
- }
- else
- {
- err = FSRead(refNum, &eof, buffer);
- if (err == noErr)
- {
- /* now parse it; CR-separated */
- StringPtr src = buffer;
- StringPtr dst = userName + 1;
- short len = 0;
- userName[0] = 0;
- while ((len < eof) && (len <= 63) && (*src != '\n'))
- {
- *dst++ = *src++;
- userName[0]++;
- len++;
- }
- eof -= (len + 1);
- userNickname[0] = 0;
- len = 0;
- src++;
- dst = userNickname + 1;
- while ((len < eof) && (len <= 7) && (*src != '\n'))
- {
- *dst++ = *src++;
- userNickname[0]++;
- }
-
- BlockMove(userName, pUserName, userName[0] + 1);
- BlockMove(userNickname, pNickname, userNickname[0] + 1);
- pUserSettingsInitialized = true;
- }
- FSClose(refNum);
- if (err != noErr)
- FSpDelete(&userSettingsFile); /* bad prefs file */
- else if (!alwaysAsk)
- {
- TaskDone();
- return noErr;
- }
- }
- }
- }
- err = noErr; /* ready to try the next approach */
- }
-
- {
- DialogPtr dialog;
- Boolean done = false;
- Rect r;
- Handle h;
- short type;
-
- dialog = GetNewDialog(kUserSettingsDialog, NULL, (WindowPtr)-1);
- if (dialog == NULL) return RaiseErrorNumber(resNotFound);
- SetDialogDefaultItem(dialog, ok);
- SetDialogCancelItem(dialog, cancel);
- SetDialogTracksCursor(dialog, true);
- if (pUserSettingsInitialized)
- {
- GetDItem(dialog, kUserNameItem, &type, &h, &r);
- SetIText(h, pUserName);
- GetDItem(dialog, kNicknameItem, &type, &h, &r);
- SetIText(h, pNickname);
- }
- SelectDialogItemText(dialog, kUserNameItem, 0, 32767);
- while (!done)
- {
- short itemHit;
- Str255 s;
- Boolean enableOK = false;
- ControlHandle ch;
-
- /* fix the OK button */
- GetDItem(dialog, kUserNameItem, &type, &h, &r);
- GetIText(h, s);
- if (s[0] > 0)
- {
- enableOK = true;
- }
- else
- {
- GetDItem(dialog, kNicknameItem, &type, &h, &r);
- GetIText(h, s);
- if (s[0] > 0) enableOK = true;
- }
- GetDItem(dialog, ok, &type, &h, &r);
- ch = (ControlHandle)h;
- HiliteControl(ch, enableOK ? 0 : 255);
-
- ShowWindow(dialog);
- ModalDialog(MyFilterProc, &itemHit);
- switch (itemHit)
- {
- case ok:
- GetDItem(dialog, kUserNameItem, &type, &h, &r);
- GetIText(h, s);
- if (s[0] > 63) s[0] = 63;
- BlockMove(s, userName, s[0] + 1);
-
- GetDItem(dialog, kNicknameItem, &type, &h, &r);
- GetIText(h, s);
- if (s[0] > 7) s[0] = 7;
- BlockMove(s, userNickname, s[0] + 1);
-
- BlockMove(userName, pUserName, userName[0] + 1);
- BlockMove(userNickname, pNickname, userNickname[0] + 1);
-
- /* write the preferences file */
- err = FSpCreate(&userSettingsFile, 'ttxt', 'TEXT', smSystemScript);
- if (err == noErr || err == dupFNErr)
- {
- short refNum;
- err = FSpOpenDF(&userSettingsFile, fsWrPerm, &refNum);
- if (err == noErr)
- {
- char buffer[72];
- long count = userName[0] + userNickname[0] + 2;
-
- BlockMove(userName + 1, buffer, userName[0] + 1);
- buffer[userName[0]] = '\n';
- BlockMove(userNickname + 1, buffer + userName[0] + 1, userNickname[0] + 1);
- buffer[count - 1] = '\n';
- err = FSWrite(refNum, &count, buffer);
- FSClose(refNum);
- if (err != noErr)
- FSpDelete(&userSettingsFile);
- }
- }
- if (err != noErr)
- {
- /* alert the user that prefs couldn't be written; but continue! */
- ErrorAlert(kProjectDragStrings, kCantWritePrefs, err);
- err = noErr;
- }
-
- pUserSettingsInitialized = true;
- done = true;
- TaskDone();
- break;
-
- case cancel:
- err = RaiseErrorNumber(userCanceledErr);
- done = true;
- break;
- }
- }
- DisposeDialog(dialog);
- }
-
- return err;
- }
-
-
- static pascal Boolean ConfirmAlertFilter(DialogPtr theDialog, EventRecord *theEvent,
- short *itemHit)
- {
- #pragma unused (itemHit)
-
- SetDialogDefaultItem(theDialog, ok);
- SetDialogCancelItem(theDialog, cancel);
-
- /* is it a mouse click in the persistent answer checkbox? */
- if (theEvent->what == mouseDown)
- {
- GrafPtr save;
- Point pt = theEvent->where;
- short theItem;
-
- GetPort(&save);
- SetPort(theDialog);
-
- GlobalToLocal(&pt);
- theItem = FindDialogItem(theDialog, pt);
- if (theItem >= 0)
- {
- Handle h;
- Rect r;
- short type;
-
- GetDialogItem(theDialog, ++theItem, &type, &h, &r);
- if (type == ctrlItem + chkCtrl)
- {
- ControlHandle ch = (ControlHandle)h;
- if (TrackControl(ch, pt, NULL) != 0)
- {
- Boolean value = !GetControlValue(ch);
- SetControlValue(ch, value);
- pPersistentFlag = value;
- theEvent->what = nullEvent; /* handled it */
- SetPort(save);
- return false;
- }
- }
-
- }
- SetPort(save);
- }
-
- return StdFilterProc(theDialog, theEvent, itemHit);
- }
-
-
- ConfirmResponse ResTextYesNoCancel(short strListID, short strIndex,
- StringPtr param1, StringPtr param2,
- StringPtr param3, StringPtr param4)
- {
- Str255 message;
- ConfirmResponse answer;
-
- if (GetPersistentAnswer(strListID, strIndex, &answer))
- return answer;
-
- ReplaceInIndString(message, strListID, strIndex, param1, param2, param3, param4);
- ParamText(message, NULL, NULL, NULL);
- pPersistentFlag = false;
- switch (Alert(k3StateConfirmAlert, ConfirmAlertFilter))
- {
- case k3ConfirmYesItem:
- answer = kConfirmYes;
- break;
- case k3ConfirmCancelItem:
- answer = kConfirmCancel;
- break;
- case k3ConfirmNoItem:
- default:
- answer = kConfirmNo;
- break;
- }
- if (pPersistentFlag)
- PersistentAnswer(strListID, strIndex, answer);
- return answer;
- }
-
-
- Boolean ResTextYesNo(short strListID, short strIndex,
- StringPtr param1, StringPtr param2,
- StringPtr param3, StringPtr param4)
- {
- Str255 message;
- Boolean answer;
- ConfirmResponse persistent;
-
- if (GetPersistentAnswer(strListID, strIndex, &persistent))
- return (persistent == kConfirmYes);
-
- ReplaceInIndString(message, strListID, strIndex, param1, param2, param3, param4);
- ParamText(message, NULL, NULL, NULL);
- pPersistentFlag = false;
- switch (Alert(k2StateConfirmAlert, ConfirmAlertFilter))
- {
- case k2ConfirmYesItem:
- answer = true;
- break;
- case k2ConfirmNoItem:
- default:
- answer = false;
- break;
- }
- if (pPersistentFlag)
- PersistentAnswer(strListID, strIndex, answer ? kConfirmYes : kConfirmNo);
- return answer;
- }
-
-
- /*
- Modal Dialog TextEdit useritem snippet
- Steve Falkenburg -- MacDTS
-
- This snippet shows the steps necessary to implement a scrolling, editable text field
- in a dialog.
-
- Modified to implement an output/diagnostic dialog for ProjectDrag by Tim Maroney;
- */
-
-
- // prototypes
-
- void SetupTextDisplayDialog(DialogPtr theDialog, ConstStr255Param message, CStringHandle theText);
-
- pascal void EditTextDrawProc(DialogPtr theDialog,short theItem);
- pascal Boolean MyDialogFilter(DialogPtr theDialog,EventRecord *ev,short *itemHit);
- Boolean HandleMouse(DialogPtr theDialog,Point pt,short modifiers);
-
- void HandleScroller(DialogPtr theDialog,Point pt);
- pascal void ScrollBarAction(ControlHandle theControl,short part);
- void ScrollText(DialogPtr theDialog, short lines);
- void ReAlignTextToScrollbar(DialogPtr theDialog);
- void ReAlignScrollbarToText(DialogPtr theDialog);
-
- ControlHandle GetScrollBar(DialogPtr theDialog);
-
-
-
- /* display dialog, and handle pretty standard ModalDialog loop. The modal dialog loop doesn't
- handle item hits to the scroll bar or text items. These are handled through the filter
- procedure
- */
-
-
- void ResTextDisplayDialog(short strListID, short index, CStringHandle theText)
- {
- Str255 message;
- GetIndString(message, strListID, index);
- TextDisplayDialog(message, theText);
- }
-
-
- void TextDisplayDialog(ConstStr255Param message, CStringHandle theText)
- {
- DialogPtr theDialog;
- short item;
-
- theDialog = GetNewDialog(kTextDisplayDialog, NULL, (WindowPtr)-1L);
- SetupTextDisplayDialog(theDialog, message, theText);
-
- ShowWindow(theDialog);
- do {
- ModalDialog(MyDialogFilter,&item);
- } while (item != ok);
-
- TEDispose(pTextHandle);
- DisposeDialog(theDialog);
- }
-
-
- /* Creates the necessary data structures necessary to use the textedit item in our dialog.
- */
-
- void SetupTextDisplayDialog(DialogPtr theDialog, ConstStr255Param message, CStringHandle theText)
- {
- short iType;
- Handle iHndl;
- Rect iRect;
- ControlHandle theControl;
- Byte state;
-
- SetPort(theDialog);
-
- GetDItem(theDialog,kScrollerItem,&iType,&iHndl,&iRect); // set up the scroll bar
- theControl = (ControlHandle)iHndl;
- SetCtlMin(theControl,0); // (it's stored in a CNTL)
- SetCtlMax(theControl,0);
-
- GetDItem(theDialog,kMessageItem,&iType,&iHndl,&iRect);
- SetIText(iHndl, message);
-
- GetDItem(theDialog,kEditTextItem,&iType,&iHndl,&iRect);
- SetDItem(theDialog,kEditTextItem,iType,(Handle)EditTextDrawProc,&iRect);
-
- InsetRect(&iRect,kMargin,kMargin);
-
- TextFont(applFont);
- TextSize(9);
- pTextHandle = TENew(&iRect,&iRect); // create our textedit item
- state = HGetState((Handle)theText);
- HLock((Handle)theText);
- TESetText(*theText, GetHandleSize((Handle)theText) - 1, pTextHandle);
- HSetState((Handle)theText, state);
- SetCtlMax(theControl, (*pTextHandle)->nLines);
- TextFont(0);
- TextSize(0);
-
- SetDialogDefaultItem(theDialog, ok);
- SetDialogTracksCursor(theDialog, true);
- }
-
-
- /* dialog user item draw procedure for text box. It just calls FrameRect
- */
-
- pascal void EditTextDrawProc(DialogPtr theDialog,short theItem)
- {
- short iType;
- Handle iHndl;
- Rect iRect;
- GrafPtr savePort;
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- GetDItem(theDialog,theItem,&iType,&iHndl,&iRect);
- FrameRect(&iRect);
-
- TEUpdate(&iRect, pTextHandle);
-
- SetPort(savePort);
- }
-
-
- /* this is the main dispatcher for events to be passed off to the scroll bar or textedit box.
- looks sort of like a WaitNextEvent event handler.
- */
-
- pascal Boolean MyDialogFilter(DialogPtr theDialog,EventRecord *ev,short *itemHit)
- {
- Boolean handledIt = StdFilterProc(theDialog, ev, itemHit);
- if (handledIt)
- return true;
-
- switch (ev->what) {
- case mouseDown:
- return HandleMouse(theDialog,ev->where,ev->modifiers);
- default:
- return false;
- }
- }
-
-
- /* mouse-down hander. here, we see if the mousedown was in the scrollbar or in the textedit
- record. if in the textedit item, we call teclick. If in the scrollbar, we call handlescroller
- to do further processing
- */
-
- Boolean HandleMouse(DialogPtr theDialog,Point pt,short modifiers)
- {
- short iType;
- Handle iHndl;
- Rect textRect,scrollerRect;
- GrafPtr savePort;
- Boolean shiftDown,result;
-
- GetPort(&savePort);
- SetPort(theDialog);
-
- shiftDown = modifiers & shiftKey;
- GlobalToLocal(&pt);
-
- GetDItem(theDialog,kEditTextItem,&iType,&iHndl,&textRect);
- GetDItem(theDialog,kScrollerItem,&iType,&iHndl,&scrollerRect);
-
- if (PtInRect(pt,&scrollerRect)) {
- HandleScroller(theDialog,pt);
- result = true;
- }
- else
- {
- result = false;
- }
-
- SetPort(savePort);
-
- return result;
- }
-
-
- /* here, we see which part of the scrollbar was clicked in by calling findcontrol. trackcontrol
- is then called with the appropriate action proc if in one of the buttons or page areas. if
- in the thumb, the text is simply re-aligned to the new scrollbar position
- */
-
- void HandleScroller(DialogPtr theDialog,Point pt)
- {
- short part;
- ControlHandle theControl;
-
- part = FindControl(pt,theDialog,&theControl);
- switch (part) {
- case inUpButton:
- case inDownButton:
- case inPageUp:
- case inPageDown:
- TrackControl(theControl,pt,ScrollBarAction);
- break;
- case inThumb:
- TrackControl(theControl,pt,nil);
- ReAlignTextToScrollbar(theDialog);
- break;
- }
- }
-
-
- /* trackcontrol callback used to determine which direction to scroll the text, and by how much.
- once this is known, the text is scrolled, and the scrollbar adjusted.
- */
-
- pascal void ScrollBarAction(ControlHandle theControl,short part)
- {
- DialogPtr theDialog;
- short lines;
- short ctlValue,ctlMax,ctlMin;
-
- ctlMax = GetCtlMax(theControl);
- ctlMin = GetCtlMin(theControl);
- ctlValue = GetCtlValue(theControl);
-
- theDialog = (*theControl)->contrlOwner;
-
- switch (part) {
- case inUpButton:
- lines = -1;
- break;
- case inDownButton:
- lines = 1;
- break;
- case inPageUp:
- lines = -kPageLines;
- break;
- case inPageDown:
- lines = kPageLines;
- break;
- default:
- return;
- }
-
- if ((ctlValue+lines)>ctlMax)
- lines = ctlMax-ctlValue;
- if ((ctlValue+lines)<ctlMin)
- lines = ctlMin-ctlValue;
-
- if (lines!=0) {
- ScrollText(theDialog, lines);
- SetCtlValue(theControl,ctlValue+lines);
- }
- }
-
-
- /* sets the text top line to be the same as the current scrollbar position. this is called after
- a thumb movement in the scrollbar.
- */
-
- void ReAlignTextToScrollbar(DialogPtr theDialog)
- {
- ControlHandle scrollBar;
- short controlScrollPosition,textScrollPosition,scrollDelta,scrollPix;
-
- scrollBar = GetScrollBar(theDialog);
-
- controlScrollPosition = GetCtlValue(scrollBar);
- textScrollPosition = ((**pTextHandle).viewRect.top - (**pTextHandle).destRect.top) / (**pTextHandle).lineHeight;
- scrollDelta = textScrollPosition - controlScrollPosition;
- scrollPix = scrollDelta * (*pTextHandle)->lineHeight;
- TEScroll(0,scrollPix,pTextHandle);
- }
-
-
- /* sets the scrollbar thumb to the current text position. this is called after autoscrolling,
- which may occur after a call to TEKey, or during a drag-scroll
- */
-
- void ReAlignScrollbarToText(DialogPtr theDialog)
- {
- ControlHandle scrollBar;
- short textScrollPosition;
-
- scrollBar = GetScrollBar(theDialog);
-
- textScrollPosition = ((**pTextHandle).viewRect.top - (**pTextHandle).destRect.top) / (**pTextHandle).lineHeight;
- SetCtlValue(scrollBar,textScrollPosition);
- }
-
-
- /* scrolls the text by the delta passed in to the function. called in response to clicking the
- arrows or page areas of the scrollbar to move the text
- */
-
- void ScrollText(DialogPtr theDialog, short lines)
- {
- short scrollPix;
- short textScrollPosition;
- short theMax = GetCtlMax(GetScrollBar(theDialog));
-
- textScrollPosition = ((**pTextHandle).viewRect.top - (**pTextHandle).destRect.top) / (**pTextHandle).lineHeight;
- if ((textScrollPosition+lines)<0)
- lines = -textScrollPosition;
- if ((textScrollPosition+lines)>theMax)
- lines = theMax-textScrollPosition;
-
- scrollPix = lines * (*pTextHandle)->lineHeight;
-
- TEScroll(0,-scrollPix,pTextHandle);
- }
-
-
- /* utility procedure to return a handle to the scrollbar control
- */
-
- ControlHandle GetScrollBar(DialogPtr theDialog)
- {
- Handle theScroller;
- short iType;
- Rect iRect;
-
- GetDItem(theDialog,kScrollerItem,&iType,&theScroller,&iRect);
- return (ControlHandle)theScroller;
- }
-