Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
Source/SVEditWindow.c
/* |
File: SVEditWindow.c |
Contains: |
Written by: Original version by Jon Lansdell and Nigel Humphreys. |
3.1 updates by Greg Sutton. |
Copyright: Copyright © 1995-1999 by Apple Computer, Inc., All Rights Reserved. |
You may incorporate this Apple sample source code into your program(s) without |
restriction. This Apple sample source code has been provided "AS IS" and the |
responsibility for its operation is yours. You are not permitted to redistribute |
this Apple sample source code as "Apple sample source code" after having made |
changes. If you're going to re-distribute the source, we require that you make |
it clear in the source that the code was descended from Apple sample source |
code, but that you've made changes. |
Change History (most recent first): |
7/19/1999 Karl Groethe Updated for Metrowerks Codewarror Pro 2.1 and removed GX printing(now obsolete |
11/1/95 DS Made Changes for GX Printing. |
10/12/95 CW Cleaned up DoContent and added call to DoWindowContentDrag |
Clean up CloseMyWindow and added call to RemoveDragHandlers |
Added InstallDragHandlers call to NewDocument |
Use HiliteControl on suspend/resume instead of Show/HideControl |
*/ |
#include <Scrap.h> |
#include <Packages.h> |
#include <DriverServices.h> |
#include <TextUtils.h> |
#include "SVEditWindow.h" |
#include "SVDrag.h" |
#include "SVAERecording.h" |
#include "SVEditPrinting.h" |
#define kControlInvisible 0 |
#define kControlVisible 0xFF |
#define kScrollbarWidth 16 |
#define kScrollbarAdjust (kScrollbarWidth - 1) |
#define kScrollTweek 2 |
#define kTextOffset 5 |
#define kButtonScroll 10 |
#define kHOffset 20 // Stagger window offsets |
#define kVOffset 20 |
#define kTBarHeight 20 |
#define kMBarHeight 20 |
#pragma segment Window |
DPtr DPtrFromWindowPtr(WindowPtr theWindow) |
{ |
if (theWindow) |
return((DPtr)GetWRefCon(theWindow)); |
else |
return(NULL); |
} // DPtrFromWindowPtr |
#pragma segment main |
/* |
Scroll the TERec around to match up to the potentially updated scrollbar |
values. This is really useful when the window resizes such that the |
scrollbars become inactive and the TERec had been previously scrolled. |
*/ |
pascal void AdjustTE(DPtr theDoc) |
{ |
short h; |
short v; |
TEHandle myText; |
myText = theDoc->theText; |
h = ((*myText)->viewRect.left - (*myText)->destRect.left) - |
GetControlValue(theDoc->hScrollBar) + kTextOffset; |
v = ((*myText)->viewRect.top - (*myText)->destRect.top) - |
GetControlValue(theDoc->vScrollBar) + kTextOffset; |
if (h || v) |
{ |
TEScroll(h, v, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} /* AdjustTE */ |
/*Calculate the new control maximum value and current value, whether it is the horizontal or |
vertical scrollbar. The vertical max is calculated by comparing the number of lines to the |
vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document |
width to the width of the viewRect. The current values are set by comparing the offset between |
the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by |
calling ShowControl.*/ |
/*TEStyleSample-vertical max originally used line by line calculations-lineheight was a |
constant value so it was easy to figure out what the range should be and pin the value |
within range. Now we need to use max and min values in pixels rather than in nlines*/ |
#pragma segment main |
pascal void AdjustHV(Boolean isVert, ControlHandle control, DPtr theDoc, Boolean canRedraw) |
{ |
TEHandle docTE; |
short value; |
short max; |
short oldValue; |
short oldMax; |
Rect sizeRect; |
GetRectOfPage( theDoc, &sizeRect ); |
docTE = theDoc->theText; |
oldValue = GetControlValue(control); |
oldMax = GetControlMaximum(control); |
if (isVert) |
{ |
/* new for TEStyleSample */ |
max = TEGetHeight((*docTE)->nLines, 0, docTE) - |
((*docTE)->viewRect.bottom - (*docTE)->viewRect.top); |
} |
else |
max = sizeRect.right - ((*docTE)->viewRect.right - (*docTE)->viewRect.left); |
max += kTextOffset + kTextOffset; /* Allow over scroll by kTextOffset */ |
if (max < 0) |
max = 0; /* check for negative values */ |
SetControlMaximum(control, max); |
if (isVert) |
value = (*docTE)->viewRect.top - (*docTE)->destRect.top; |
else |
value = (*docTE)->viewRect.left - (*docTE)->destRect.left; |
value += kTextOffset; |
if (value < 0) |
value = 0; |
else |
if (value > max) |
value = max; /* pin the value to within range */ |
SetControlValue(control, value); |
if (canRedraw && ((max != oldMax) || (value != oldValue))) |
ShowControl(control); /* check to see if the control can be re-drawn */ |
} /* AdjustHV */ |
#pragma segment Main |
pascal void AdjustScrollValues(DPtr theDoc, Boolean canRedraw) |
/* Simply call the common adjust routine for the vertical and horizontal scrollbars. */ |
{ |
AdjustHV(true, theDoc->vScrollBar, theDoc, canRedraw); |
AdjustHV(false, theDoc->hScrollBar, theDoc, canRedraw); |
} /* AdjustScrollValues */ |
pascal void GetTERect(WindowPtr window, Rect *teRect) |
/* return a rectangle that is inset from the portRect by the size of |
the scrollbars and a little extra margin. */ |
{ |
*teRect = window->portRect; |
(*teRect).bottom -= kScrollbarAdjust; /* and for the scrollbars */ |
(*teRect).right -= kScrollbarAdjust; |
} /* GetTERect */ |
pascal void AdjustScrollSizes(DPtr theDoc) |
/* Re-calculate the position and size of the viewRect and the scrollbars. |
kScrollTweek compensates for off-by-one requirements of the scrollbars |
to have borders coincide with the growbox. */ |
{ |
Rect teRect; |
Rect myPortRect; |
GetTERect(theDoc->theWindow, &teRect); /*start with teRect*/ |
myPortRect = theDoc->theWindow->portRect; |
(*(theDoc->theText))->viewRect = teRect; |
MoveControl(theDoc->vScrollBar, myPortRect.right - kScrollbarAdjust, - 1); |
SizeControl(theDoc->vScrollBar, |
kScrollbarWidth, |
(myPortRect.bottom - myPortRect.top) - (kScrollbarAdjust - kScrollTweek)); |
MoveControl(theDoc->hScrollBar, - 1, myPortRect.bottom - kScrollbarAdjust); |
SizeControl(theDoc->hScrollBar, |
(myPortRect.right - myPortRect.left) - (kScrollbarAdjust - kScrollTweek), |
kScrollbarWidth); |
} /* AdjustScrollSizes */ |
#pragma segment Window |
pascal void AdjustScrollbars(DPtr theDoc, Boolean needsResize) |
/* Turn off the controls by jamming a zero into their contrlVis fields |
(HideControl erases them and we don't want that). If the controls are to |
be resized as well, call the procedure to do that, then call the procedure |
to adjust the maximum and current values. Finally reset the controls |
to be visible if not in background. */ |
{ |
(*(theDoc->vScrollBar))->contrlVis = kControlInvisible; /* turn them off */ |
(*(theDoc->hScrollBar))->contrlVis = kControlInvisible; |
if (needsResize) /* move and size if needed */ |
AdjustScrollSizes(theDoc); |
AdjustScrollValues(theDoc, !needsResize); /* fool with max and current value */ |
/* Now, restore visibility in case we never had to ShowControl during adjustment */ |
if (!gInBackground) |
{ |
(*(theDoc->vScrollBar))->contrlVis = kControlVisible; /* turn them on */ |
(*(theDoc->hScrollBar))->contrlVis = kControlVisible; |
} |
else |
{ /* make sure they stay invisible */ |
if ((*(theDoc->vScrollBar))->contrlVis) |
HideControl(theDoc->vScrollBar); |
if ((*(theDoc->vScrollBar))->contrlVis) |
HideControl(theDoc->hScrollBar); |
} |
} /* AdjustScrollbars */ |
#pragma segment Window |
pascal void GetWinContentRect(WindowPtr theWindow, Rect *r) |
{ |
*r = theWindow->portRect; |
r->right -= kScrollbarAdjust; |
r->bottom -= kScrollbarAdjust; |
} /* GetWinContentRect */ |
#pragma segment Window |
pascal void InvalidateDocument(DPtr theDoc) |
{ |
GrafPtr oldPort; |
GetPort(&oldPort); |
SetPort(theDoc->theWindow); |
InvalRect(&theDoc->theWindow->portRect); |
SetPort(oldPort); |
} |
pascal void DoResizeWindow(DPtr theDoc) |
/* Called when the window has been resized to fix up the controls and content */ |
{ |
AdjustScrollbars(theDoc, true); |
AdjustTE(theDoc); |
InvalidateDocument(theDoc); |
} /* ResizeWindow */ |
pascal void ResizePageSetupForDocument(DPtr theDoc) |
/* Called when the window has been resized to fix up the controls and content */ |
{ |
Rect pageRect; |
GetRectOfPage( theDoc, &pageRect ); |
(*(theDoc->theText))->destRect.right = (*(theDoc->theText))->destRect.left |
+ pageRect.right; |
TECalText(theDoc->theText); |
DoResizeWindow(theDoc); |
} /* ResizePageSetupForDocument */ |
#pragma segment Main |
pascal void CommonAction(ControlHandle control, short *amount) |
/* Common algorithm for setting the new value of a control. It returns the actual amount |
the value of the control changed. Note the pinning is done for the sake of returning |
the amount the control value changed. */ |
{ |
short value; |
short max; |
value = GetControlValue(control); /* get current value */ |
max = GetControlMaximum(control); /* and max value */ |
*amount = value - *amount; |
if (*amount < 0) |
*amount = 0; |
else |
if (*amount > max) |
*amount = max; |
SetControlValue(control, *amount); |
*amount = value - *amount; /* calculate true change */ |
} /* CommonAction */ |
#pragma segment Main |
pascal void VActionProc(ControlHandle control, short part) |
/* Determines how much to change the value of the vertical scrollbar by and how |
much to scroll the TE record. */ |
{ |
short amount; |
WindowPtr window; |
DPtr theDoc; |
if (part) |
{ |
window = (*control)->contrlOwner; |
theDoc = DPtrFromWindowPtr(window); |
switch (part) { |
case kControlUpButtonPart: |
case kControlDownButtonPart : amount = 24; |
break; |
case kControlPageUpPart: |
case kControlPageDownPart : amount = (*(theDoc->theText))->viewRect.bottom - |
(*(theDoc->theText))->viewRect.top; |
break; |
} /* case */ |
if (part == kControlDownButtonPart || part == kControlPageDownPart) |
amount = -amount; /* reverse direction */ |
CommonAction(control, &amount); |
if (amount) |
{ |
TEScroll(0, amount, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} /* if */ |
} /* VActionProc */ |
#pragma segment Main |
pascal void HActionProc(ControlHandle control, short part) |
/* Determines how much to change the value of the horizontal scrollbar by and how |
much to scroll the TE record. */ |
{ |
short amount; |
WindowPtr window; |
DPtr theDoc; |
if (part) |
{ |
window = (*control)->contrlOwner; |
theDoc = DPtrFromWindowPtr(window); |
switch (part) { |
case kControlUpButtonPart : |
case kControlDownButtonPart : amount = kButtonScroll; /* a few pixels */ |
break; |
case kControlPageUpPart : |
case kControlPageDownPart : amount = (*(theDoc->theText))->viewRect.right - |
(*(theDoc->theText))->viewRect.left; /* a page */ |
break; |
} /* switch */ |
if (part == kControlDownButtonPart || part == kControlPageDownPart) |
amount = - amount; /* reverse direction */ |
CommonAction(control, &amount); |
if (amount) |
{ |
TEScroll(amount, 0, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} /* if */ |
} /* HActionProc */ |
/**----------------------------------------------------------------------- |
Name: ShowSelect |
Purpose: Scrolls the text selection into view. |
-----------------------------------------------------------------------**/ |
#pragma segment Window |
pascal void ShowSelect(DPtr theDoc) |
{ |
AdjustScrollbars(theDoc, false); |
/* |
Let TextEdit do the hard work of keeping the selection visibleÉ |
*/ |
TEAutoView(true, theDoc->theText); |
TESelView(theDoc->theText); |
TEAutoView(false, theDoc->theText); |
/* |
Now rematch the text and the scrollbarsÉ |
*/ |
SetControlValue(theDoc->hScrollBar, |
(*(theDoc->theText))->viewRect.left - |
(*(theDoc->theText))->destRect.left + kTextOffset); |
SetControlValue(theDoc->vScrollBar, |
(*(theDoc->theText))->viewRect.top - |
(*(theDoc->theText))->destRect.top + kTextOffset); |
} /* ShowSelect */ |
#pragma segment Window |
pascal void OffsetWindow(WindowPtr aWindow) |
{ |
short theWidth; |
short theHeight; |
short theHScreen; |
short theVScreen; |
short xWidth; |
short xHeight; |
short hMax; |
short vMax; |
short wLeft; |
short wTop; |
theWidth = aWindow->portRect.right - aWindow->portRect.left; |
theHeight = aWindow->portRect.bottom - aWindow->portRect.top + kTBarHeight; |
theHScreen = qd.screenBits.bounds.right - qd.screenBits.bounds.left; |
theVScreen = qd.screenBits.bounds.bottom - qd.screenBits.bounds.top; |
xWidth = theHScreen - theWidth; |
xHeight = theVScreen - (theHeight + kMBarHeight); |
hMax = (xWidth / kVOffset) + 1; |
vMax = (xHeight / kVOffset) + 1; |
gWCount++; |
wLeft = (gWCount % hMax) * kVOffset; |
wTop = ((gWCount % vMax) * kVOffset) + kTBarHeight + kMBarHeight; |
MoveWindow(aWindow, wLeft, wTop, false); |
} |
pascal void GetLocalUpdateRgn(WindowPtr window, RgnHandle localRgn) |
/* Returns the update region in local coordinates */ |
{ |
CopyRgn(((WindowPeek)window)->updateRgn, localRgn); /* save old update region */ |
OffsetRgn(localRgn, |
window->portBits.bounds.left, |
window->portBits.bounds.top); /* convert to local coords */ |
} /* GetLocalUpdateRgn */ |
#pragma segment Window |
pascal void MyGrowWindow(WindowPtr w, Point p) |
{ |
GrafPtr savePort; |
long theResult; |
Rect r; |
GetPort(&savePort); |
SetPort(w); |
SetRect(&r, 80, 80, qd.screenBits.bounds.right, qd.screenBits.bounds.bottom); |
theResult = GrowWindow(w, p, &r); |
if (theResult) |
IssueSizeWindow(w, LoWord(theResult), HiWord(theResult)); |
SetPort(savePort); |
} |
#pragma segment Window |
pascal void DoZoom(WindowPtr w, |
short c, |
Point p) |
{ |
GrafPtr savePort; |
GetPort(&savePort); |
SetPort(w); |
if (TrackBox(w, p, c)) |
{ |
EraseRect(&w->portRect); |
IssueZoomCommand(w, c); |
} |
} |
#pragma segment Window |
pascal void DoContent ( WindowPtr theWindow, EventRecord theEvent ) |
{ |
short cntlCode; |
short part; |
short value; |
ControlHandle theControl; |
GrafPtr savePort; |
Boolean extend; |
DPtr theDoc; |
Point localPt; |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
theDoc = DPtrFromWindowPtr ( theWindow ); |
localPt = theEvent.where; |
GlobalToLocal ( &localPt ); |
cntlCode = FindControl ( localPt, theWindow, &theControl ); |
if ( cntlCode == 0 ) |
{ |
if ( UserWantsToDrag ( theWindow, theEvent.where ) ) |
{ |
if ( DoWindowContentDrag ( theWindow, &theEvent ) ) |
TEClick ( localPt, false, theDoc->theText ); |
} |
else |
{ |
/*only extend the selection if the shiftkey is down*/ |
extend = (theEvent.modifiers & shiftKey); |
if ( PtInDocument ( localPt, theDoc ) ) |
TEClick ( localPt, extend, theDoc->theText ); |
} |
} |
else if ( cntlCode == kControlIndicatorPart ) |
{ |
value = GetControlValue(theControl); |
part = TrackControl(theControl, localPt, nil); |
if (part) |
{ |
value -= GetControlValue(theControl); |
if (value) |
{ |
if (theControl == theDoc->vScrollBar) |
TEScroll(0, value, theDoc->theText); |
else |
TEScroll(value, 0, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} |
} |
else |
{ |
if (theControl == theDoc->vScrollBar) |
part = TrackControl(theControl, localPt, (ControlActionUPP) gVScrollActionUPP); |
else |
part = TrackControl(theControl, localPt, (ControlActionUPP) gHScrollActionUPP); |
} |
SetPort(savePort); |
} |
void DoBackgroundContent ( WindowPtr theWindow, EventRecord theEvent) |
{ |
Point thePoint; |
GrafPtr savePort; |
RgnHandle dragRgn; |
DPtr theDoc; |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
theDoc = DPtrFromWindowPtr ( theWindow ); |
thePoint = theEvent.where; |
GlobalToLocal ( &thePoint ); |
dragRgn = NewRgn ( ); |
GetSelectedTextRgn ( theDoc, dragRgn ); |
if ( PtInRgn ( thePoint, dragRgn ) ) |
{ |
if ( DoWindowContentDrag ( theWindow, &theEvent ) ) |
SelectWindow (theWindow ); |
} |
else |
SelectWindow ( theWindow ); |
SetPort ( savePort ); |
return; |
} |
/* |
pascal void DoContent(WindowPtr theWindow, |
EventRecord theEvent) |
{ |
short cntlCode; |
short part; |
ControlHandle theControl; |
GrafPtr savePort; |
Boolean extend; |
DPtr theDoc; |
short value; |
GetPort(&savePort); |
SetPort(theWindow); |
theDoc = DPtrFromWindowPtr(theWindow); |
GlobalToLocal(&theEvent.where); |
cntlCode = FindControl(theEvent.where, theWindow, &theControl); |
if (cntlCode == 0) |
{ |
//only extend the selection if the shiftkey is down |
extend = (theEvent.modifiers & shiftKey); |
if (PtInRect(theEvent.where, &(*(theDoc->theText))->viewRect)) |
TEClick(theEvent.where, extend, theDoc->theText); |
} |
else |
if (cntlCode == kControlIndicatorPart) |
{ |
value = GetCtlValue(theControl); |
part = TrackControl(theControl, theEvent.where, nil); |
if (part) |
{ |
value -= GetCtlValue(theControl); |
if (value) |
{ |
if (theControl == theDoc->vScrollBar) |
TEScroll(0, value, theDoc->theText); |
else |
TEScroll(value, 0, theDoc->theText); |
DrawPageExtras(theDoc); |
} |
} |
} |
else |
if (theControl == theDoc->vScrollBar) |
part = TrackControl(theControl, theEvent.where, gVScrollActionUPP); |
else |
part = TrackControl(theControl, theEvent.where, gHScrollActionUPP); |
SetPort(savePort); |
} |
*/ |
#pragma segment Window |
pascal OSErr DoActivate(WindowPtr theWindow, Boolean activate) |
{ |
OSErr err; |
Rect r; |
DPtr theDoc; |
err = noErr; |
if (theWindow) |
if (Ours(theWindow)) |
{ |
theDoc = DPtrFromWindowPtr(theWindow); |
SetPort(theWindow); |
DrawGrowIcon(theWindow); |
GetWinContentRect(theWindow, &r); |
InvalRect(&r); |
if (activate) |
{ |
TEActivate(theDoc->theText); |
HiliteControl ( theDoc->vScrollBar, 0 ); |
HiliteControl ( theDoc->hScrollBar, 0 ); |
DisableItem(myMenus[editM], undoCommand); |
err = TEFromScrap(); |
if (gWCount == 0) |
SetShortMenus(); |
} |
else |
{ |
TEDeactivate(theDoc->theText); |
HiliteControl ( theDoc->vScrollBar, 255 ); |
HiliteControl ( theDoc->hScrollBar, 255 ); |
err = ZeroScrap(); |
err = TEToScrap(); |
} |
} |
return(err); |
} |
#pragma segment Window |
pascal void GetPageEnds(short pageHeight, |
TEHandle theText, |
PageEndsArray pageBounds, |
short *nPages) |
{ |
short pageBase; /* total pixel offset of pages so far */ |
short thisLine; |
short lastLine; |
short pageSoFar; |
short thisPage; /* Current page being calced */ |
short thisLineH; /* Height of text line */ |
short pageFirstLine; /* Line # of top of page */ |
pageBase = 0; |
thisLine = 1; |
lastLine = (*theText)->nLines; |
thisPage = 0; |
pageSoFar = 0; |
while ((thisLine <= lastLine) || (pageSoFar!=0)) |
{ |
pageFirstLine = thisLine; |
thisLineH = TEGetHeight(thisLine, thisLine, theText); |
while ((thisLineH+pageSoFar<pageHeight) && (thisLine <= lastLine)) |
{ |
pageSoFar += thisLineH; |
thisLine++; |
thisLineH = TEGetHeight(thisLine, thisLine, theText); |
} |
if (pageSoFar) |
{ |
pageBounds[thisPage] = pageSoFar+pageBase; |
pageBase = pageBounds[thisPage]; |
thisPage++; |
pageSoFar = 0; |
} |
/* |
Special case text line taller than page |
*/ |
if ((thisLine == pageFirstLine) && |
(thisLineH > pageHeight)) |
{ |
do { |
pageBounds[thisPage] = pageBase+pageHeight; |
pageBase = pageBounds[thisPage]; |
thisPage += 1; |
thisLineH -= pageHeight; |
} while (thisLineH >= pageHeight); |
pageSoFar = thisLineH; /* Carry bottom of large line to next page */ |
thisLine += 1; /* carry xs on as pageSoFar and start measuring next line */ |
} |
} |
*nPages = thisPage; |
} /* GetPageEnds */ |
pascal void DrawPageBreaks(DPtr theDoc) |
{ |
PageEndsArray pageEnds; |
short nPages; |
short ctr; |
short lineBase; |
short pageHeight; |
Rect viewRect; |
Rect pageRect; |
GetRectOfPage( theDoc, &pageRect ); |
pageHeight = pageRect.bottom - pageRect.top; |
GetPageEnds(pageHeight, |
theDoc->theText, |
pageEnds, |
&nPages); |
lineBase = (*(theDoc->theText))->destRect.top; |
viewRect = (*(theDoc->theText))->viewRect; |
PenPat(&qd.gray); |
for (ctr = 0; ctr<nPages-1; ctr++) |
{ |
MoveTo(viewRect.left, lineBase+pageEnds[ctr]); |
LineTo(viewRect.right,lineBase+pageEnds[ctr]); |
} |
PenNormal(); |
} /* DrawPageBreaks */ |
pascal void DrawPageExtras(DPtr theDoc) |
{ |
GrafPtr oldPort; |
RgnHandle oldClip; |
Rect rectToClip; |
GetPort(&oldPort); |
SetPort(theDoc->theWindow); |
oldClip = NewRgn(); |
GetClip(oldClip); |
GetWinContentRect(theDoc->theWindow,&rectToClip); |
ClipRect(&rectToClip); |
/* and then the page breaks */ |
DrawPageBreaks(theDoc); |
SetClip(oldClip); |
DisposeRgn(oldClip); |
SetPort(oldPort); |
} /* DrawPageExtras */ |
pascal void DoUpdate ( WindowPtr theWindow ) |
{ |
GrafPtr savePort; |
Rect rectClip; |
DPtr theDocument; |
theDocument = DPtrFromWindowPtr ( theWindow ); |
if ( Ours ( theWindow ) ) |
{ |
GetPort ( &savePort ); |
SetPort ( theWindow ); |
BeginUpdate ( theWindow ); |
ClipRect(&theWindow->portRect); |
EraseRect(&theWindow->portRect); |
DrawControls(theWindow); |
DrawGrowIcon(theWindow); |
GetWinContentRect(theWindow, &rectClip); |
ClipRect(&rectClip); |
TEUpdate(&theWindow->portRect, theDocument->theText); |
DrawPageExtras(theDocument); |
EndUpdate(theWindow); |
ClipRect(&theWindow->portRect); |
SetPort ( savePort ); |
} |
return; |
} /* DoUpdate */ |
#pragma segment Window |
DPtr NewDocument(Boolean isForOldDoc, WindowPtr behindWindow) |
{ |
Rect destRect; |
Rect viewRect; |
Rect vScrollRect; |
Rect hScrollRect; |
DPtr myDoc; |
WindowPtr myWindow; |
ControlHandle vScroll; |
ControlHandle hScroll; |
Str255 theName; |
Str255 newNumber; |
Rect pageRect; |
if (!gWCount) |
SetLongMenus(); |
myDoc = nil; |
myWindow = GetNewWindow(WindowID, nil, behindWindow); |
if (myWindow) |
{ |
if (isForOldDoc==false) |
{ |
GetWTitle(myWindow, theName); |
NumToString(++gNewDocCount, newNumber); |
if (gNewDocCount>1) |
{ |
PStrCat(theName, (unsigned char *)"\p #"); |
PStrCat(theName, newNumber); |
SetWTitle(myWindow, theName); |
} |
} |
OffsetWindow(myWindow); |
SetPort(myWindow); |
myDoc = (DPtr)NewPtr(sizeof(DocRec)); |
SetWRefCon(myWindow, (long)myDoc); |
myDoc->theWindow = myWindow; |
vScrollRect = myWindow->portRect; |
vScrollRect.left = vScrollRect.right - kScrollbarAdjust; |
vScrollRect.right = vScrollRect.left + kScrollbarWidth; |
vScrollRect.bottom = vScrollRect.bottom - 14; |
vScrollRect.top = vScrollRect.top - 1; |
vScroll = NewControl(myWindow, &vScrollRect, (unsigned char *)"\pScrollBar", true, 0, 0, 0, scrollBarProc, 0); |
hScrollRect = myWindow->portRect; |
hScrollRect.top = hScrollRect.bottom - kScrollbarAdjust; |
hScrollRect.bottom = hScrollRect.top + kScrollbarWidth; |
hScrollRect.right = hScrollRect.right - 14; |
hScrollRect.left = hScrollRect.left - 1; |
hScroll = NewControl(myWindow, &hScrollRect, (unsigned char *)"\pScrollBar", true, 0, 0, 0, scrollBarProc, 0); |
myDoc->vScrollBar = vScroll; |
myDoc->hScrollBar = hScroll; |
myDoc->lastID = 0; |
myDoc->dirty = false; |
GetTERect(myWindow, &viewRect); |
destRect = viewRect; |
myDoc->theFont = kFontIDTimes; |
myDoc->theStyle = 0; |
myDoc->theSize = 12; |
myDoc->documentJob = nil; |
myDoc->thePrintSetup = nil; |
myDoc->thePrintSetup = (THPrint)NewHandle(sizeof(TPrint)); |
PrOpen(); |
PrintDefault(myDoc->thePrintSetup); |
PrClose(); |
GetRectOfPage( myDoc, &pageRect ); |
destRect.right = destRect.left + pageRect.right; |
OffsetRect(&destRect, kTextOffset, kTextOffset); |
TextFont(kFontIDTimes); |
TextSize(12); |
TextFace(0); |
myDoc->theText = TEStyleNew(&destRect, &viewRect); |
/* |
SetClikLoop(@AutoScroll, myDoc->theText); |
*/ |
myDoc->theFileName[0] = 0; |
myDoc->everSaved = false; |
myDoc->theWindow = myWindow; |
DoResizeWindow(myDoc); |
InstallDragHandlers ( myWindow ); |
} |
return(myDoc); |
} |
#pragma segment Window |
pascal void CloseMyWindow(WindowPtr aWindow) |
{ |
DPtr aDocument; |
TEHandle theText; |
HideWindow(aWindow); |
aDocument = DPtrFromWindowPtr(aWindow); |
theText = aDocument->theText; |
TEDispose(theText); |
if (aDocument->thePrintSetup) |
DisposeHandle((Handle)aDocument->thePrintSetup); |
if (aDocument->documentJob) |
//GXDisposeJob(aDocument->documentJob); |
RemoveDragHandlers ( aWindow ); |
DisposePtr((Ptr)aDocument); |
DisposeWindow(aWindow); |
gWCount--; |
/*if there are no more windows open, set up the short menus*/ |
if (gWCount == 0) |
SetShortMenus(); |
} |
/* |
Name : PrintWindow |
Function : Prints the document supplied in theDoc. askUser controls interaction |
with the user. |
Uses extra memory equal to the size of the textedit use in the |
printed document. |
*/ |
pascal void PrintWindow(DPtr theDoc, Boolean askUser) |
{ |
GrafPtr oldPort; |
TEHandle printerTE; |
TPPrPort printerPort; |
Rect printView; |
PageEndsArray pageBounds; |
short nPages; |
short pageCtr; |
Boolean abort; |
Rect rectToClip; |
TPrStatus thePrinterStatus; |
DialogPtr progressDialog; |
WindowPtr tempWind; // Temp window to create TERec in |
Rect tempWindRect = {0,0,0,0}; // Bounds for temp window |
abort = false; |
/* |
Preserve the current port |
*/ |
GetPort(&oldPort); |
PrOpen(); |
if (askUser) |
abort = !PrJobDialog(theDoc->thePrintSetup); |
if (abort) |
{ |
PrClose(); |
return; |
} |
progressDialog = GetNewDialog(1005, nil, (WindowPtr)-1); |
DrawDialog(progressDialog); |
printerPort = PrOpenDoc(theDoc->thePrintSetup, nil, nil); |
SetPort((GrafPtr)printerPort); |
// Create a temporary window(which is not shown) |
tempWind = NewWindow( nil, &tempWindRect, "\p", |
false, documentProc, (WindowPtr)-1, |
false, 0); |
// Duplicate the text edit rec |
printView = (*(theDoc->thePrintSetup))->prInfo.rPage; |
DuplicateStyleTERec ( theDoc->theText, |
&printerTE, |
&printView, |
(GrafPtr)tempWind ); |
// Work out the offsets |
(*printerTE)->destRect = printView; // GetPageEnds calls TECalText |
GetPageEnds(printView.bottom-printView.top, |
printerTE, |
pageBounds, |
&nPages); |
TEDeactivate(printerTE); |
// Set the TERec to the printer port |
(*printerTE)->inPort = (GrafPtr)printerPort; |
for (pageCtr = 0; pageCtr <= nPages-1; pageCtr++) |
if (!abort) |
{ |
PrOpenPage(printerPort, nil); |
rectToClip = printView; |
if (pageCtr > 0) |
rectToClip.bottom = rectToClip.top + (pageBounds[pageCtr]-pageBounds[pageCtr-1]); |
else |
rectToClip.bottom = rectToClip.top + pageBounds[pageCtr]; |
ClipRect(&rectToClip); |
if (PrError() == iPrAbort) |
abort = true; |
if (! abort) |
TEUpdate(&printView, printerTE); |
if (PrError() == iPrAbort) |
abort = true; |
PrClosePage(printerPort); |
TEScroll(0,rectToClip.top-rectToClip.bottom, printerTE); |
} |
TEDispose(printerTE); |
DisposeWindow ( tempWind ); |
PrCloseDoc(printerPort); |
if (( (*(theDoc->thePrintSetup))->prJob.bJDocLoop == bSpoolLoop ) && |
( PrError() == noErr ) && |
(! abort)) |
PrPicFile( theDoc->thePrintSetup, nil, nil, nil, &thePrinterStatus); |
PrClose(); |
DisposeDialog(progressDialog); |
SetPort(oldPort); |
InvalRect(&oldPort->portRect); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22