home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-11 | 34.2 KB | 1,192 lines | [TEXT/KAHL] |
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // //
- // //
- // Copyright PennyWise Software, 1994. //
- // //
- // Part of the PennyWise Software Application Framework //
- // //
- // //
- // TextWindow.c Written by Peter Kaplan //
- // //
- // //
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //
- // This is a template for a PennyWise Software Application Framework window
- //
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- #include "PWFramework.h"
- #include "PWWindowList.h"
- #include "WindowID.h"
- #include "TextWindow.h"
- #include <PWPrintUtils.h>
- #include "ErrorDialog.h"
- #include "HandleMenus.h"
- #include <PWMenuUtils.h>
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // These procedures are static. They will only be called by name from here
- // outside refrences will use our window proc list.
- static void ThisWindowCreate (EventRecord* theEvent, WindowPtr theWindow);
- static short ThisWindowDispose (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowZoomIn (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowZoomOut (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowResize (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowClick (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowUpdate (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowActivate (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowDeactivate(EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowDrag (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowIdle (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowCursor (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowKeyDown (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowPreMenu (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowPostMenu (EventRecord* theEvent, WindowPtr theWindow);
- static short ThisWindowDoMenu (EventRecord* theEvent, WindowPtr theWindow, short theMenu, short theItem, short theWindowID);
- static void ThisWindowGrowRect (EventRecord* theEvent, WindowPtr theWindow, Rect* theRect);
- static void ThisWindowGetScrap (EventRecord* theEvent, WindowPtr theWindow);
- static void ThisWindowPutScrap (EventRecord* theEvent, WindowPtr theWindow);
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static unsigned long GetModTime(FSSpecPtr theSpec);
- static void CalcEditWindowRects(WindowPtr theWindow, Rect* viewRect, Rect *destRect, Rect *scrollRect);
- static void AdjustTEScroll(WindowPtr theWindow, ControlHandle theScrollbar, TEHandle hTE);
- static void SaveTheWindow(WindowPtr theWindow);
- static Boolean GetNewFileSpec(WindowPtr theWindow, FSSpecPtr theSpec);
- static void AsmClikLoop(void);
- static void AdjustViewRect( TEHandle theTE);
- static pascal void VActionProc(ControlHandle control, short part);
- static pascal ProcPtr GetOldClikLoop(void);
- static pascal void PascalClikLoop(void);
- static void PrintNote(WindowPtr theWindow, Boolean withPrompt);
- static void GetNextLine(CharsHandle hChars, short offset,short pageWidth, short *wordLength);
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // This record holds all the information about this window
- // You can add fields to this record.
- // NOTE:ALL WINDOW RECORDS MUST START WITH THIS
- // HEADER OR ELSE THE FRAMEWORK WILL NOT
- // FUNCTION PROPERLY. YOU'VE BEEN WARNED!
- typedef struct OurWinRecord {
- WindowParamHeader theHeader;
- short isDirty;
- ProcPtr theClik;
- TEHandle hTE;
- ControlHandle theScrollbar;
- FSSpec theSpec;
- unsigned long theModTime;
- }OurWinRecord, *OurWinPtr, **OurWinHandle;
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // Macros for accessing the header data
- // you can add your own as you add fields
- // to the OurWinRecord.
- // NOTE:THESE MACROS ASSUME theData HOLDS
- // A VALID COPY OF OurWinHandle.
- #define THE_ID (*theData)->theHeader.theID
- #define IS_DIRTY (*theData)->isDirty
- #define HTE (*theData)->hTE
- #define CLICK (*theData)->theClik
- #define SCROLLBAR (*theData)->theScrollbar
- #define FILESPEC (*theData)->theSpec
- #define MODTIME (*theData)->theModTime
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- #define TEXT_WINDOW_RES_ID 128
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void InitTextWindowHandlers()
- {
- PWInstallWindowType (kWINDOW_ID_TextWindow, kWINDOW_TYPE_APPLICATION);
- PWInstallCreate (kWINDOW_ID_TextWindow, ThisWindowCreate);
- PWInstallDispose (kWINDOW_ID_TextWindow, ThisWindowDispose);
- PWInstallZoomIn (kWINDOW_ID_TextWindow, ThisWindowZoomIn);
- PWInstallZoomOut (kWINDOW_ID_TextWindow, ThisWindowZoomOut);
- PWInstallResize (kWINDOW_ID_TextWindow, ThisWindowResize);
- PWInstallClick (kWINDOW_ID_TextWindow, ThisWindowClick);
- PWInstallUpdate (kWINDOW_ID_TextWindow, ThisWindowUpdate);
- PWInstallActivate (kWINDOW_ID_TextWindow, ThisWindowActivate);
- PWInstallDeactivate (kWINDOW_ID_TextWindow, ThisWindowDeactivate);
- PWInstallIdle (kWINDOW_ID_TextWindow, ThisWindowIdle);
- PWInstallCursor (kWINDOW_ID_TextWindow, ThisWindowCursor);
- PWInstallKeyDown (kWINDOW_ID_TextWindow, ThisWindowKeyDown);
- PWInstallDrag (kWINDOW_ID_TextWindow, ThisWindowDrag);
- PWInstallPreMenu (kWINDOW_ID_TextWindow, ThisWindowPreMenu);
- PWInstallMenu (kWINDOW_ID_TextWindow, ThisWindowDoMenu);
- PWInstallPostMenu (kWINDOW_ID_TextWindow, ThisWindowPostMenu);
- PWInstallGrowRect (kWINDOW_ID_TextWindow, ThisWindowGrowRect);
- PWInstallBackground (kWINDOW_ID_TextWindow, NULL);
- PWInstallScrap2Appl (kWINDOW_ID_TextWindow, ThisWindowGetScrap);
- PWInstallAppl2Scrap (kWINDOW_ID_TextWindow, ThisWindowPutScrap);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowCreate (EventRecord* theEvent, WindowPtr theWindow)
- {
- // This routine will very rarely contain anything worthwhile
- // You will make custom routines for most windows that will be exported
- // via the include file
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // Since we will be exporting this we don't have to conform to any particular input format
- void TextWindowOpen(FSSpecPtr theSpec)
- {
- WindowPtr theWindow; // The window we create
- OurWinHandle theData; // The Data for our window
- TEHandle theTE; // The TE field for our window
- Rect viewRect; // viewRect of TE
- Rect destRect; // destRect of TE
- Rect scrollRect; // Rect for scrollbar
- ControlHandle theScrollbar; // Control for scrollbar
- OSErr theErr; // File System Errors
- short fRefNum; // File Ref Num for this file
- Handle theHandle; // Handle to text in TE Record
- long curEOF; // EOF of file
-
- theWindow = GetNewWindow(TEXT_WINDOW_RES_ID, NULL, (WindowPtr)-1);
- if (theWindow) {
- // We sucessfully got the window
-
- // Now we have to allocate our storage
- theData = (OurWinHandle) NewHandle(sizeof(OurWinRecord));
- if (theData) {
- // We sucessfully allocated storage
-
- // So Lets set the port to our new window
- SetPort(theWindow);
-
- // Figure out the size of the TE & Scroll
- CalcEditWindowRects( theWindow, &viewRect, &destRect, &scrollRect);
-
- theTE = TENew( &destRect, &viewRect);
- if (theTE) {
- TEAutoView(TRUE,theTE);
-
- // Swap the Click routines
- CLICK = (ProcPtr) (*theTE)->clikLoop;
- (*theTE)->clikLoop = (ClikLoopProcPtr) AsmClikLoop;
- TEFeatureFlag(teFOutlineHilite,TEBitSet,theTE);
-
- // Create the scrollbar on the right side of the screen
- theScrollbar = NewControl(theWindow, &scrollRect, theSpec->name ,TRUE,0,0,0,16,0);
- if (theScrollbar) {
-
- // Now lets set the fields
- THE_ID = kWINDOW_ID_TextWindow;
- IS_DIRTY = FALSE;
- HTE = theTE;
- SCROLLBAR = theScrollbar;
-
- // Here we would fill the TE
- if (theSpec) {
-
- // Set the title name
- SetWTitle(theWindow, theSpec->name);
-
- // Store the Spec
- BlockMove(theSpec, &FILESPEC, sizeof(FSSpec));
-
- // Set the last mod date;
- MODTIME = GetModTime(theSpec);
-
- theErr = FSpOpenDF(theSpec,fsRdPerm,&fRefNum);
- if (noErr == theErr) {
-
- // We have a file
- // lets read in the data
-
- // How long is the file?
- GetEOF(fRefNum,&curEOF);
-
- // If it is bigger than 32k TE Cant handle it
- if (curEOF > 32767 )
- curEOF = 32767;
-
- // lets make the handle for the
- // TE field as long as the file
- theHandle = (*theTE)->hText;
- SetHandleSize(theHandle,curEOF);
-
- // We got the handle lets fill it!
- if (theHandle) {
- HLock(theHandle);
-
- if (FSRead(fRefNum,&curEOF,*theHandle) == noErr) {
- (*theTE)->teLength = curEOF;
- }
-
- HUnlock(theHandle);
- TECalText(theTE);
- }
- FSClose(fRefNum);
- }
- else {
- // We could not open the file
- // Open the window blank
- SysBeep(1);
- MODTIME = 0;
- }
- }
- else {
- MODTIME = 0;
- }
-
- AdjustViewRect( theTE);
- AdjustTEScroll( theWindow, theScrollbar, theTE);
-
- // Put our data in the refCon
- SetWRefCon(theWindow, (long) theData);
-
- // Show it & select it before we leave
- ShowWindow(theWindow);
- SelectWindow(theWindow);
- }
- else {
- DisposeWindow(theWindow);
- theWindow = NULL;
- DisposeHandle((Handle)theData);
- TEDispose(theTE);
- }
- }
- else {
- // We could not allocate memory for our window's data
- // So lets get rid of the data
- DisposeWindow(theWindow);
- theWindow = NULL;
- DisposeHandle((Handle)theData);
- }
- }
- else {
- // We could not allocate memory for our window's data
- // So lets get rid of the data
- DisposeWindow(theWindow);
- theWindow = NULL;
- }
- }
-
- if (!theWindow) {
- SysBeep(1);
- // We did not create the window
- // You will probably want to put up a dialog here to explain why
- }
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static short ThisWindowDispose (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- short theResults;
- Str63 theString;
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Want to save it
- theResults = kBTTN_DONT;
-
- if (IS_DIRTY) {
- // Data has been changed we would probably want to put up
- // a “Save Changes to x” dialog here
- // But I'm just going to reset IS_DIRTY
- GetWTitle( theWindow, theString);
-
- theResults = SaveDialog(theString);
- if (theResults == kBTTN_OK) {
- if (GetNewFileSpec( theWindow, &FILESPEC)) {
- SaveTheWindow( theWindow);
- IS_DIRTY = FALSE;
- theResults == kBTTN_DONT;
- }
- else {
- theResults == kBTTN_CANCEL;
- }
- }
- }
-
- if (theResults == kBTTN_DONT) {
- // Now lets break it down
- HideWindow(theWindow);
- DisposeHandle((Handle)theData);
- DisposeWindow(theWindow);
- }
-
- return (theResults==kBTTN_DONT)?TRUE:FALSE; // True if we closed it, false if we did not [ex. pressed cancel in save dialog]
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowZoomIn (EventRecord* theEvent, WindowPtr theWindow)
- { // The defaults will do the right thing
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowZoomOut (EventRecord* theEvent, WindowPtr theWindow)
- { // The defaults will do the right thing
- Rect theRect;
- WStateData *wsdp;
-
- // This makes the window only zoom out to the "Page Setup" size
- // This will change the size depending on the Print, Etc.
-
- GetPageSize(&theRect);
- // De-ref the data--make sure we don't move memory
- wsdp = (WStateData*) *(((WindowPeek)theWindow)->dataHandle);
- // Don't forget the inset 16
- wsdp->stdState.right = wsdp->stdState.left + (theRect.right- theRect.left);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowResize (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
- Rect viewRect;
- Rect destRect;
- Rect scrollRect;
- #define WIDE scrollRect.right - scrollRect.left
- #define HIGH scrollRect.bottom - scrollRect.top
-
- // Do the port swapping
- GetPort(&oldPort);
- SetPort(theWindow);
-
- // Get our data record
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Erase the window completely
- EraseRect(&theWindow->portRect);
-
- // Calculate the TE rects for this window
- CalcEditWindowRects( theWindow, &viewRect, &destRect, &scrollRect);
-
- // Set the dest & view rects
- (*HTE)->destRect = destRect;
- (*HTE)->viewRect = viewRect;
- TECalText(HTE);
-
- // Adjust the view rect for correct height
- AdjustViewRect(HTE);
-
- // Make sure the text is visible
- TESelView(HTE);
-
- // Move & size the control
- (*SCROLLBAR)->contrlVis = FALSE;
- MoveControl(SCROLLBAR,scrollRect.left,scrollRect.top);
- SizeControl(SCROLLBAR,WIDE,HIGH);
-
- // Adjust the scroll values to proper levels
- AdjustTEScroll( theWindow, SCROLLBAR, HTE);
- (*SCROLLBAR)->contrlVis = TRUE;
-
- // make sure the whole window gets redrawn in update
- InvalRect(&theWindow->portRect);
-
- // put the port back the way we found it
- SetPort(oldPort);
-
- #undef WIDE
- #undef HIGH
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowClick (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- Point localPoint;
- GrafPtr oldPort;
- ControlHandle theControl;
- short thePart;
- short theValue;
- short offsetNew;
- short offsetOld;
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- localPoint = theEvent->where;
- GlobalToLocal(&localPoint);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
-
- thePart = FindControl(localPoint, theWindow, &theControl);
- switch ( thePart ) {
- case 0: // It is not in the scroll bar
- if (theEvent->modifiers&shiftKey) {
- // We are shift Clicking extend the selection
-
- // Where is the click occuring
- offsetNew = TEGetOffset(localPoint,HTE);
-
- if ((*HTE)->selStart == (*HTE)->selEnd) {
- // It happend with no current selection
- offsetOld = (*HTE)->selStart;
- }
- else {
- // we have a selection, handle it
- if ((*HTE)->selStart > offsetNew) {
- offsetOld = (*HTE)->selEnd;
- }
- else if ((*HTE)->selEnd < offsetNew) {
- offsetOld = (*HTE)->selStart;
- }
- else {
- offsetOld = (*HTE)->selStart;
- }
- }
- // Now make it the right order
- if (offsetOld<offsetNew)
- TESetSelect(offsetOld,offsetNew,HTE);
- else
- TESetSelect(offsetNew,offsetOld,HTE);
-
- }
- else
- TEClick(localPoint,FALSE,HTE);
- break;
- case inThumb:
- theValue = GetCtlValue(theControl);
- thePart = TrackControl(theControl, localPoint, NULL);
- if (thePart != 0) {
- theValue -= GetCtlValue(theControl);
-
- /* value now has CHANGE in value; if value changed, scroll */
- if ( theValue != 0 )
- TEScroll(0, theValue * (*HTE)->lineHeight, HTE);
- }
- break;
- default: /* they clicked in an arrow, so track & scroll */
- theValue = TrackControl(theControl, localPoint, (ProcPtr) VActionProc);
- break;
- }
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowUpdate (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- DrawGrowIcon(theWindow);
-
- EraseRect(&((*HTE)->viewRect));
- TEUpdate( &theWindow->portRect, HTE);
-
- UpdtControl(theWindow,theWindow->visRgn);
-
- SetPort(oldPort);}
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowActivate (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Call DrawGrowIcon if the window has a grow box
- DrawGrowIcon(theWindow);
-
- TEActivate( HTE);
- HiliteControl(SCROLLBAR,0);
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowDeactivate(EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Deactivate items here
-
- // Call DrawGrowIcon if the window has a grow box
- DrawGrowIcon(theWindow);
-
- TEDeactivate( HTE);
-
- HiliteControl(SCROLLBAR, 255);
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowDrag (EventRecord* theEvent, WindowPtr theWindow)
- { // The default does the right thing
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowIdle (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- TEIdle( HTE);
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowCursor (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
- CursHandle hCurs;
- Rect controlRect;
- Point localPoint;
- RgnHandle theRgn;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- theRgn = NewRgn();
- if (theRgn) {
- // Adjust the cursor here
- if (PtInRgn( theEvent->where, ((WindowPeek)theWindow)->contRgn)) {
-
- // OK the mouse is in the window lets find out where
-
- localPoint = theEvent->where;
- GlobalToLocal(&localPoint);
-
- // Make a box the size of viewRect
- controlRect = theWindow->portRect;
- controlRect.right-=16;
- controlRect.bottom-=16;
-
- if (PtInRect(localPoint,&controlRect)) {
- // OK its in the viewRect area make the cursor an iBeam
- LocalToGlobal(&(((Point*)&(controlRect))[0]));
- LocalToGlobal(&(((Point*)&(controlRect))[1]));
-
- // Set the mouse moved to be the box we are in
- RectRgn(gMouseMovedRgn,&controlRect);
- hCurs = GetCursor(1);
- HLock((Handle)hCurs);
- SetCursor(*hCurs);
- }
- else {
- controlRect = theWindow->portRect;
- controlRect.top = controlRect.bottom -16;
-
- LocalToGlobal(&(((Point*)&(controlRect))[0]));
- LocalToGlobal(&(((Point*)&(controlRect))[1]));
- RectRgn(theRgn,&controlRect);
-
- controlRect = (*SCROLLBAR)->contrlRect;
- LocalToGlobal(&(((Point*)&(controlRect))[0]));
- LocalToGlobal(&(((Point*)&(controlRect))[1]));
- RectRgn(gMouseMovedRgn,&controlRect);
-
- UnionRgn(theRgn,gMouseMovedRgn,gMouseMovedRgn);
- SetCursor(&arrow);
- }
- }
- else {
- SetRectRgn(gMouseMovedRgn,-32768,-32768,32767,32767);
- DiffRgn(gMouseMovedRgn,((WindowPeek)theWindow)->contRgn,gMouseMovedRgn);
- SetCursor(&arrow);
- }
-
- DisposeRgn(theRgn);
- }
-
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowKeyDown (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
- short keyCode;
- short charCode;
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- keyCode = (theEvent->message&keyCodeMask)>>8;
- charCode = theEvent->message&charCodeMask;
-
- if ( keyCode == 8 || (*HTE)->teLength - ((*HTE)->selEnd - (*HTE)->selStart) + 1 < 32767) {
- TEKey(charCode,HTE);
- IS_DIRTY = TRUE;
- AdjustTEScroll( theWindow, SCROLLBAR, HTE);
-
- }
- else
- SysBeep(1);
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowPreMenu (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
- Str63 theString;
- Boolean quotes;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Enable and disable items
- // change item names etc.
-
- // When we inable undo, we can add this
- DisableItem( gMenuEdit, kEDIT_UNDO);
-
- // If we are not selecting any text
- if ((*HTE)->selStart == (*HTE)->selEnd) {
- // Disable Cut, Copy, Clear
- DisableItem( gMenuEdit, kEDIT_CUT);
- DisableItem( gMenuEdit, kEDIT_COPY);
- DisableItem( gMenuEdit, kEDIT_CLEAR);
- }
- else {
- // What test are we selecting
- if (((*HTE)->selEnd - (*HTE)->selStart) > 16) {
- GetIndString( theString, 100, 1);
- quotes = FALSE;
- }
- else {
- BlockMove(&(*((*HTE)->hText))[(*HTE)->selStart], &theString[1], ((*HTE)->selEnd - (*HTE)->selStart));
- theString[0] = ((*HTE)->selEnd - (*HTE)->selStart);
- quotes = TRUE;
- }
-
- AddNameToMenu( gMenuEdit, kEDIT_CUT, theString, FALSE, quotes);
- AddNameToMenu( gMenuEdit, kEDIT_COPY, theString, FALSE, quotes);
- AddNameToMenu( gMenuEdit, kEDIT_CLEAR, theString, FALSE, quotes);
- }
-
- // Lets handle the file name stuff
- GetWTitle(theWindow, theString);
- AddNameToMenu( gMenuFile, kFILE_SAVE, theString, FALSE, TRUE);
- AddNameToMenu( gMenuFile, kFILE_CLOSE, theString, FALSE, TRUE);
- AddNameToMenu( gMenuFile, kFILE_PRINT, theString, TRUE, TRUE);
-
- // If we have no TEXT in the Scrap
- if (TEGetScrapLen()==0) {
- // Disable Paste
- DisableItem( gMenuEdit, kEDIT_PASTE);
- }
-
- if (!IS_DIRTY) {
- DisableItem( gMenuFile, kFILE_SAVE);
- }
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowPostMenu (EventRecord* theEvent, WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // Enable and disable items
- // change item names etc.
- EnableItem( gMenuFile, kFILE_SAVE);
-
-
- EnableItem( gMenuEdit, kEDIT_UNDO);
-
- SetMenuItemToIndString(kMENU_ID_EDIT, kEDIT_CUT, gMenuEdit);
- SetMenuItemToIndString(kMENU_ID_EDIT, kEDIT_COPY, gMenuEdit);
- SetMenuItemToIndString(kMENU_ID_EDIT, kEDIT_CLEAR, gMenuEdit);
-
- SetMenuItemToIndString(kMENU_ID_FILE, kFILE_SAVE, gMenuFile);
- SetMenuItemToIndString(kMENU_ID_FILE, kFILE_CLOSE, gMenuFile);
- SetMenuItemToIndString(kMENU_ID_FILE, kFILE_PRINT, gMenuFile);
-
- EnableItem( gMenuEdit, kEDIT_CUT);
- EnableItem( gMenuEdit, kEDIT_COPY);
- EnableItem( gMenuEdit, kEDIT_CLEAR);
- EnableItem( gMenuEdit, kEDIT_PASTE);
-
-
- SetPort(oldPort);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static short ThisWindowDoMenu (EventRecord* theEvent, WindowPtr theWindow, short theMenu, short theItem, short theWindowID)
- {
- short theResult;
- OurWinHandle theData;
- Str255 theString;
-
- theResult = TRUE;
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- // if we don't handle it return false so the defaults will pick it up
- switch (theMenu) {
- case kMENU_ID_FILE:
- switch (theItem) {
- case kFILE_SAVE:
- {
-
- if (MODTIME != GetModTime(&FILESPEC)) {
- // The file has been changed since we last
- // used it.
- GetWTitle(theWindow, theString);
- ErrorDialog(500, 1, theString);
- }
- else {
- SaveTheWindow( theWindow);
- }
- }
- break;
-
- case kFILE_SAVEAS:
- if (GetNewFileSpec( theWindow, &FILESPEC)) {
- SetWTitle(theWindow, FILESPEC.name);
- SaveTheWindow( theWindow);
- }
- break;
- case kFILE_PRINT:
- PrintNote( theWindow, TRUE);
- break;
- case kFILE_PONE:
- PrintNote( theWindow, FALSE);
- break;
- default:
- theResult = FALSE;
- break;
- }
- break;
- case kMENU_ID_EDIT:
- switch (theItem) {
- //case kEDIT_UNDO:
- // break;
- case kEDIT_CUT:
- ZeroScrap();
- TECut(HTE);
- IS_DIRTY = TRUE;
- break;
- case kEDIT_COPY:
- ZeroScrap();
- TECopy(HTE);
- IS_DIRTY = TRUE;
- break;
- case kEDIT_PASTE:
- TEPaste(HTE);
- IS_DIRTY = TRUE;
- break;
- case kEDIT_CLEAR:
- TEDelete(HTE);
- IS_DIRTY = TRUE;
- break;
- case kEDIT_SEL_ALL:
- TESetSelect(0,32767,HTE);
- break;
- default:
- theResult = FALSE;
- break;
- }
- break;
- default:
- theResult = FALSE;
- }
- AdjustTEScroll( theWindow, SCROLLBAR, HTE);
-
- return theResult;
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowGrowRect (EventRecord* theEvent, WindowPtr theWindow, Rect* theRect)
- {
- // This simply is the size of the rect the window can grow to
- SetRect(theRect, 64, 64, 32767, 32767);
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowGetScrap(EventRecord* theEvent, WindowPtr theWindow)
- {
- // This routine will get called when your application gets a resumeEvent
- // AND the convertClipboardFlag bit is set
- // What must be done is the convertion of the clipboard to a private scrap
- TEFromScrap();
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- static void ThisWindowPutScrap(EventRecord* theEvent, WindowPtr theWindow)
- {
- // This routine will get called when your application gets a suspendEvent
- // What must be done is the convertion of the private scrap to the clipboard
- TEToScrap();
- }
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- //•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- // Utility Routines for this window
- unsigned long GetModTime(FSSpecPtr theSpec)
- {
- HFileParam pb;
-
- pb.ioCompletion = NULL;
- pb.ioVRefNum = theSpec->vRefNum;
- pb.ioFVersNum = 0;
- pb.ioFDirIndex = 0;
- pb.ioNamePtr = theSpec->name;
- pb.ioDirID = theSpec->parID;
-
- PBHGetFInfo((HParmBlkPtr)&pb,FALSE);
-
- return pb.ioFlMdDat;
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- pascal void VActionProc(ControlHandle control, short part)
- {
- OurWinHandle theData;
- short value;
- short max;
- short amount;
- WindowPtr window;
- Rect viewRect;
-
- if ( part != 0 ) { /* if it was actually in the control */
- window = (*control)->contrlOwner;
- theData = (OurWinHandle)GetWRefCon(window);
-
- value = GetCtlValue(control);
- max = GetCtlMax(control);
- amount = 0;
- viewRect = (*HTE)->viewRect;
- switch ( part ) {
- case inUpButton:
- if (value>0) {
- amount = (*HTE)->lineHeight;
- value--;
- }
- break;
- case inDownButton: /* one line */
- if (value<max) {
- amount = -(*HTE)->lineHeight;
- value++;
- }
- break;
- case inPageUp: /* one page */
- amount = (viewRect.bottom - viewRect.top);
- value += -(viewRect.bottom - viewRect.top) / (*HTE)->lineHeight;
- break;
- case inPageDown:
- amount = -(viewRect.bottom - viewRect.top);
- value += (viewRect.bottom - viewRect.top) / (*HTE)->lineHeight;
- break;
- }
- if ( amount != 0) {
- TEPinScroll(0,amount,HTE);
- SetCtlValue(control, value);
- }
- }
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- pascal ProcPtr GetOldClikLoop()
- {
- WindowPtr theWindow;
- OurWinHandle theData;
-
- theWindow = FrontWindow();
- theData = (OurWinHandle) GetWRefCon(theWindow);
- return ((*theData)->theClik);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- pascal void PascalClikLoop()
- {
- WindowPtr window;
- RgnHandle region;
- window = FrontWindow();
- region = NewRgn();
- GetClip(region); /* save clip */
- ClipRect(&window->portRect);
- // AdjustScrollValues(window, true); /* pass true for canRedraw */
- SetClip(region); /* restore clip */
- DisposeRgn(region);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void AsmClikLoop()
- {
- asm {
- MOVEM.L D1-D2/A1,-(SP) ; D0 and A0 need not be saved
- CLR.L -(SP) ; make space for procedure pointer
- JSR GetOldClikLoop ; get the old clikLoop
- MOVEA.L (SP)+,A0 ; into A0
- MOVEM.L (SP)+,D1-D2/A1 ; restore the world as it was
-
- JSR (A0) ; and execute old clikLoop
-
- MOVEM.L D1-D2/A1,-(SP) ; D0 and A0 need not be saved
- JSR PascalClikLoop ; do our clikLoop
- MOVEM.L (SP)+,D1-D2/A1 ; restore the world as it was
- MOVEQ #1,D0 ; clear the zero flag so TextEdit keeps going
- RTS
- }
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void CalcEditWindowRects(WindowPtr theWindow, Rect* viewRect, Rect *destRect, Rect *scrollRect)
- {
- scrollRect->top = theWindow->portRect.top - 1;
- scrollRect->left = theWindow->portRect.right - 15;
- scrollRect->bottom = theWindow->portRect.bottom - 14;
- scrollRect->right = theWindow->portRect.right + 1;
-
- viewRect->top = theWindow->portRect.top + 1;
- viewRect->left = theWindow->portRect.left + 1;
- viewRect->right = theWindow->portRect.right - 16;
- viewRect->bottom = theWindow->portRect.bottom - 16;
- *destRect = *viewRect;
- InsetRect(destRect, 4, 0);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void AdjustViewRect(TEHandle hTE)
- {
- (*hTE)->viewRect.bottom = ((((*hTE)->viewRect.bottom - (*hTE)->viewRect.top) / (*hTE)->lineHeight)
- * (*hTE)->lineHeight) + (*hTE)->viewRect.top;
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void AdjustTEScroll(WindowPtr theWindow, ControlHandle theScrollbar, TEHandle hTE)
- {
- short value, lines, max;
- short oldValue, oldMax;
-
- oldMax = GetCtlMax(theScrollbar);
- oldValue = GetCtlValue(theScrollbar);
-
- lines = (*hTE)->nLines;
-
- // If the last item is a return make adjustment
- if ( *(*(*hTE)->hText + (*hTE)->teLength - 1) == 0x0D )
- lines += 1;
-
- max = lines - (((*hTE)->viewRect.bottom - (*hTE)->viewRect.top) /(*hTE)->lineHeight);
-
- max = (max<0)?0:max;
- value =((*hTE)->viewRect.top - (*hTE)->destRect.top) / (*hTE)->lineHeight;
-
- SetCtlMax(theScrollbar, max);
- SetCtlValue(theScrollbar, value);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void SaveTheWindow(WindowPtr theWindow)
- {
- OurWinHandle theData;
- GrafPtr oldPort;
- short fRefNum;
- OSErr theErr;
- Handle theHandle;
- long curEOF;
-
-
- GetPort(&oldPort);
- SetPort(theWindow);
-
- theData = (OurWinHandle) GetWRefCon(theWindow);
-
- theErr = FSpOpenDF(&FILESPEC,fsRdWrPerm,&fRefNum);
- if (noErr == theErr) {
-
- // Get the handle to the text
- theHandle = (*HTE)->hText;
-
- // We got the handle lets save the file
- if (theHandle) {
-
- // Lock it down
- HLock(theHandle);
-
- // Get the size
- curEOF = GetHandleSize(theHandle);
-
- // Write it
- if (FSWrite(fRefNum,&curEOF,*theHandle) == noErr) {
- // All Is well, make it not dirty
- IS_DIRTY = FALSE;
-
- // And set the EOF
- SetEOF(fRefNum,curEOF);
- }
- else {
- // Who knows what could go wrong here but!
- SysBeep(1);
- }
-
- // Unlock the handle
- HUnlock(theHandle);
- }
- else {
- // Could not get the handle
- SysBeep(1);
- }
-
- FSClose(fRefNum);
- MODTIME = GetModTime(&FILESPEC);
- }
- else {
- // Could not open the file
- SysBeep(1);
- }
-
- SetPort(oldPort);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- Boolean GetNewFileSpec(WindowPtr theWindow, FSSpecPtr theSpec)
- {
- Str63 theString;
- Str32 thePrompt;
- StandardFileReply reply;
-
- GetWTitle(theWindow, theString);
- GetIndString(thePrompt, 100,2);
- StandardPutFile( thePrompt, theString, &reply);
- if (reply.sfGood) {
- BlockMove(&reply.sfFile, theSpec, sizeof(FSSpec));
- FSpDelete(theSpec);
- FSpCreate(theSpec,'PKLP','TEXT',0);
- return TRUE;
- }
- else
- return FALSE;
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void PrintNote(WindowPtr theWindow, Boolean withPrompt)
- {
- OurWinHandle theData;
- Rect printRect;
- GrafPtr oldPort;
- TEHandle hTE;
- Boolean done;
- FontInfo fInfo;
- long pageNumber;
- Rect viewRect;
- Rect destRect;
- short textWidth;
- short pageWidth;
- short offset;
- short count;
- short textTotalLength;
- CharsHandle hChars;
- short wordWidth;
- short wordLength;
- short vert;
- Boolean pageFull;
-
- GetPort(&oldPort);
-
- theData = (OurWinHandle)GetWRefCon(theWindow);
-
- if (withPrompt)
- DoPrintDialog();
-
- StartPrinting();
-
- done = FALSE;
- pageFull = FALSE;
- pageNumber = 1;
-
-
- offset = 0;
- count = 0;
-
- // Set the font and get the info
- TextFont(theWindow->txFont);
- TextSize(theWindow->txSize);
- TextFace(theWindow->txFace);
- GetFontInfo(&fInfo);
-
- hTE = HTE;
-
- hChars = TEGetText(hTE);
- textTotalLength = GetHandleSize(hChars);
- HLock((Handle)hChars);
-
-
- while (!done) {
- GetPageSizeWhileOpen(&printRect);
- pageWidth = printRect.right - printRect.left;
-
- // reset the font
- TextFont(theWindow->txFont);
- TextSize(theWindow->txSize);
- TextFace(theWindow->txFace);
-
- vert = printRect.top + fInfo.ascent + fInfo.leading + fInfo.descent;
-
- while (vert < printRect.bottom - fInfo.descent && offset < textTotalLength) {
- GetNextLine(hChars, offset, pageWidth, &wordLength);
- MoveTo(printRect.left, vert);
-
- // Get rid of invisibles at the begining of line
- while ((*hChars)[offset] < 33 && (*hChars)[offset] != 13) {
- offset++;
- wordLength--;
- }
- if (offset+wordLength > textTotalLength)
- wordLength = textTotalLength - offset;
-
- DrawText(*hChars,offset,wordLength);
- offset+=wordLength;
- if ((*hChars)[offset] == 13)
- offset++;
-
- vert+=fInfo.ascent + fInfo.leading + fInfo.descent;
- }
-
- if (offset >= textTotalLength) {
- done = TRUE;
- }
-
- if (!done) NextPage();
- }
-
- HUnlock((Handle)hChars);
-
- StopPrinting();
-
- SetPort(oldPort);
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
- void GetNextLine(CharsHandle hChars, short offset,short pageWidth, short *wordLength)
- {
- short ourLength;
- short ourWidth;
-
- ourLength = 0;
- ourWidth = 0;
-
- while (ourWidth < pageWidth) {
- *wordLength = ourLength;
-
- if (((*hChars)[offset + ourLength]) == 13) {
- // its a return key so add it to the line and return
- // because it is a natural break
- *wordLength = ourLength;
- return;
- }
- else {
- ourWidth = TextWidth((*hChars),offset,++ourLength);
- }
- }
- // peal off last word
- while ((*hChars)[offset+(*wordLength)] > 32 && *wordLength>0) {
- (*wordLength)--;
- }
- if (*wordLength<=0)
- *wordLength = ourLength;
- }
- //••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••