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/SVEditUtils.c
/* |
File: SVEditUtils.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 |
10/12/95 CW Simplified FeatureIsImplemented routine. |
Added init of gHasDragManager flag in CheckEnvironment. |
*/ |
#include <DriverServices.h> |
#include <Events.h> |
#include <Traps.h> |
#include <Dialogs.h> |
#include <Fonts.h> |
#include <Packages.h> |
#include <ToolUtils.h> |
#include <AppleEvents.h> |
#include <CodeFragments.h> |
#include "SVEditUtils.h" |
#include <TextUtils.h> |
/**----------------------------------------------------------------------- |
Name: LesserOf |
Purpose: Returns the Lesser of two longints. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal long LesserOf(long A, long B) |
{ |
if (A<B) |
return(A); |
else |
return(B); |
} /*LesserOf*/ |
/**----------------------------------------------------------------------- |
Name: GreaterOf |
Purpose: Returns the Greater of two longints. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal long GreaterOf(long A, long B) |
{ |
if (A>B) |
return(A); |
else |
return(B); |
} /*GreaterOf*/ |
/**----------------------------------------------------------------------- |
Name: ShowError |
Purpose: Reports an error to the user as both string and number. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void ShowError(Str255 theError, |
long theErrorCode) |
{ |
short alertResult; |
Str255 theString; |
OSErr myErr; |
myErr = AEInteractWithUser(kAEDefaultTimeout, nil,nil); |
if (myErr == noErr) |
{ |
SetCursor(&qd.arrow); |
NumToString(theErrorCode, theString); |
ParamText(theError, theString, (unsigned char *)"", (unsigned char *)""); |
alertResult = Alert(300, nil); |
} |
} /* ShowError */ |
/**----------------------------------------------------------------------- |
Name: Ours |
Purpose: Checks the frontmost window belongs to the app. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal Boolean Ours(WindowPtr aWindow) |
{ |
if (aWindow) |
if (((WindowPeek)aWindow)->windowKind == zoomDocProc) |
return(true); |
return(false); |
} /* Ours */ |
/**----------------------------------------------------------------------- |
Name: SetShortMenus |
Purpose: Cuts the menus down to a minimum - Apple File Edit. |
Greys out the unavailable options - used when no docs open |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetShortMenus() |
{ |
DeleteMenu(mfontID); |
DeleteMenu(sizeID); |
DeleteMenu(styleID); |
DisableItem(myMenus[fileM], fmClose); |
DisableItem(myMenus[fileM], fmSave); |
DisableItem(myMenus[fileM], fmSaveAs); |
DisableItem(myMenus[fileM], fmRevert); |
DisableItem(myMenus[fileM], fmPageSetUp); |
DisableItem(myMenus[fileM], fmNoGXPrint); |
/* now the unnecessary items on the edit menu */ |
DisableItem(myMenus[editM], undoCommand); |
DisableItem(myMenus[editM], cutCommand); |
DisableItem(myMenus[editM], copyCommand); |
DisableItem(myMenus[editM], clearCommand); |
DisableItem(myMenus[editM], pasteCommand); |
DisableItem(myMenus[editM], selectAllCommand); |
DrawMenuBar(); |
} /* SetShortMenus */ |
/**----------------------------------------------------------------------- |
Name: SetLongMenus |
Purpose: Reinstates the full menu bar - called when first document |
opened. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetLongMenus() |
{ |
InsertMenu(myMenus[fontM], 0); |
InsertMenu(myMenus[sizeM], 0); |
InsertMenu(myMenus[styleM], 0); |
EnableItem(myMenus[fileM], fmClose); |
EnableItem(myMenus[fileM], fmSave); |
EnableItem(myMenus[fileM], fmSaveAs); |
EnableItem(myMenus[fileM], fmRevert); |
EnableItem(myMenus[fileM], fmPageSetUp); |
EnableItem(myMenus[fileM], fmNoGXPrint ); |
/* now the necessary items on the edit menu - |
many other items fixed on each pass thru the main event |
loop or before the window pulled down |
*/ |
EnableItem(myMenus[editM], selectAllCommand); |
DrawMenuBar(); |
} /* SetLongMenus */ |
/**----------------------------------------------------------------------- |
Name: SetStyleMenu |
Purpose: Sets the style menu checking to reflect the style of the |
first character of the current selection in the given |
document. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetStyleMenu(DPtr theDoc) |
{ |
TextStyle theTStyle; |
short contMode; |
short i; |
contMode = doFace; |
TEContinuousStyle(&contMode,&theTStyle,theDoc->theText); |
if ((contMode & doFace) != 0) |
{ |
CheckItem(myMenus[styleM], cPlain, (theTStyle.tsFace == 0)); |
CheckItem(myMenus[styleM], cBold, (bold & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cItalic, (italic & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cUnderline, (underline & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cOutline, (outline & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cShadow, (shadow & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cCondense, (condense & theTStyle.tsFace)); |
CheckItem(myMenus[styleM], cExtend, (extend & theTStyle.tsFace)); |
} |
else |
for (i=cPlain; i<= cExtend; i++) |
CheckItem(myMenus[styleM], i, false); |
} |
/**----------------------------------------------------------------------- |
Name: SetSizeMenu |
Purpose: Outline all the items if the current font is an |
outline font. Check the size of the current selection |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetSizeMenu(DPtr theDoc) |
{ |
short i; |
short aSize; |
short max; |
long theSize; |
Str255 name; |
Boolean sizeinMenu; |
Boolean oldState; |
Point numer; |
TextStyle theStyle; |
TEHandle myText; |
short contMode; |
numer.h = 1; |
numer.v = 1; |
myText = theDoc->theText; |
contMode = doSize+doFont; |
TEContinuousStyle(&contMode,&theStyle,theDoc->theText); |
sizeinMenu = false; |
max = CountMItems(myMenus[sizeM]); |
for (i = 1; i <= max - 5; i++) |
{ |
GetMenuItemText(myMenus[sizeM], i, name); |
StringToNum(name, &theSize); |
aSize = (short)theSize; |
if (RealFont(theStyle.tsFont, aSize) && (contMode & doFont) != 0) // there is only one font and this size exists |
SetItemStyle(myMenus[sizeM], i, outline); |
else |
SetItemStyle(myMenus[sizeM], i, 0); |
if ((aSize == theStyle.tsSize) && (contMode & doSize) != 0) |
{ |
sizeinMenu = true; |
CheckItem(myMenus[sizeM], i, true); |
} |
else |
CheckItem(myMenus[sizeM], i, false); |
} |
/* |
if it's not a size in the menu,and there is only one size in the |
selection range check the other item |
*/ |
if (!sizeinMenu && (contMode & doSize) != 0) |
CheckItem(myMenus[sizeM], max, true); |
else |
CheckItem(myMenus[sizeM], max, false); |
/*if this is an outline font, set the rest of the items to outline style*/ |
/*RealFont will ensure that the sizes are outlined*/ |
oldState = GetOutlinePreferred(); |
SetOutlinePreferred(true); |
for (i = max-4; i <= max; i++) |
{ |
if (IsOutline(numer, numer) && (contMode & doFont)!= 0) |
SetItemStyle(myMenus[sizeM], i, outline); |
else |
SetItemStyle(myMenus[sizeM], i, 0); |
} |
SetOutlinePreferred(oldState); |
} |
/**----------------------------------------------------------------------- |
Name: SetFontMenu |
Purpose: Set the font menu according to the state of |
current selection of the supplied document. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetFontMenu(DPtr theDoc) |
{ |
MenuHandle theMHandle; |
short theNumber; |
short i; |
short max; |
Str255 name; |
TextStyle theStyle; |
short contMode; |
theMHandle = GetMenuHandle(mfontID); |
if (gFontMItem) |
CheckItem(theMHandle, gFontMItem, false); |
max = CountMItems(theMHandle); |
contMode = doFont; |
TEContinuousStyle(&contMode,&theStyle,theDoc->theText); |
gFontMItem = 0; |
if (contMode & doFont) |
for (i=1; i<=max; i++) |
{ |
GetMenuItemText(theMHandle, i, name); |
GetFNum(name, &theNumber); |
if (theNumber == theStyle.tsFont) |
gFontMItem = i; |
} |
if (gFontMItem) |
CheckItem(theMHandle, gFontMItem, true); |
SetSizeMenu(theDoc); |
SetStyleMenu(theDoc); |
} |
/**----------------------------------------------------------------------- |
Name: GetTempFileName |
Purpose: Fills newstring with a temporary file name. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void GetTempFileName(DPtr aDoc, |
Str255 newString) |
{ |
Str255 s; |
Str255 fileName; |
if (aDoc->everSaved == false) |
PStrCopy(fileName, (unsigned char *)"\pTEXTra"); |
else |
PStrCopy(fileName, aDoc->theFileName); |
/*generate a unique(ish) temporary filename*/ |
if (fileName[0] > 21) |
fileName[0] = 21; |
NumToString(TickCount(), s); |
PStrCat(fileName, s); |
PStrCopy(newString,fileName); |
} |
/**----------------------------------------------------------------------- |
Name: SetText |
Purpose: Sets the text of the supplied itemNo in aDialog to |
theString and select it. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void SetText(DialogPtr aDialog, |
short itemNo, |
Str255 theString) |
{ |
Handle itemHandle; |
Rect box; |
short kind; |
TEHandle theTEHandle; |
GetDialogItem(aDialog, itemNo, &kind, &itemHandle, &box); |
SetDialogItemText(itemHandle, theString); |
theTEHandle = ((DialogPeek)aDialog)->textH; |
/*set all the text to be selected*/ |
if (theTEHandle) |
TESetSelect(0, 255, theTEHandle); |
} |
/**----------------------------------------------------------------------- |
Name: RetrieveText |
Purpose: Returns the text of anItem in aDialog in aString. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void RetrieveText(DialogPtr aDialog, |
short anItem, |
Str255 aString) |
{ |
short kind; |
Rect box; |
Handle itemHandle; |
GetDialogItem(aDialog, anItem, &kind, &itemHandle, &box); |
GetDialogItemText(itemHandle, aString); |
} |
/**----------------------------------------------------------------------- |
Name: DrawDefaultOutline |
Purpose: Draws an outline around theItem. |
Called as a useritem Proc by the dialog manager. |
To use place a useritem over the default item in the |
dialog and install the address of this proc as the item |
handle. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void DrawDefaultOutline(DialogPtr theDialog, short theItem) |
{ |
short kind; |
Handle itemHandle; |
Rect box; |
GetDialogItem(theDialog, theItem, &kind, &itemHandle, &box); |
PenSize(3, 3); |
InsetRect(&box, - 4, - 4); |
FrameRoundRect(&box, 16, 16); |
PenNormal(); |
} /* DrawDefaultOutline */ |
/**----------------------------------------------------------------------- |
Name: AdornDefaultButton |
Purpose: Installs DrawDefaultOutline as the useritem proc |
for the given item. |
-----------------------------------------------------------------------**/ |
#pragma segment Utils |
pascal void AdornDefaultButton(DialogPtr theDialog,short theItem) |
{ |
short kind; |
Handle itemHandle; |
Rect box; |
GetDialogItem(theDialog, theItem, &kind, &itemHandle, &box); |
SetDialogItem(theDialog, theItem, kind, (Handle)gDefaultButtonUPP, &box); |
} |
/*------- Determining of Gestalt is available ---------------*/ |
/*The following routines come from the Inside Mac VI recommendations*/ |
/*about how to find if a trap is available*/ |
/* |
The glue for Gestalt will be in MPW 3.2, so if it is available we will also |
need to check the system version |
*/ |
pascal void GetRectOfDialogItem(DialogPtr theDialog, short theItem, Rect *theRect) |
{ |
short kind; |
Handle itemHandle; |
GetDialogItem(theDialog, theItem, &kind, &itemHandle, theRect); |
} |
#pragma segment Utils |
pascal short NumToolboxTraps(void) |
{ |
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap)) |
return(0x200); |
else |
return(0x400); |
} |
#pragma segment Utils |
#define TrapMask 0x0800 |
pascal TrapType GetTrapType(short theTrap) |
{ |
if ((theTrap & TrapMask) > 0) |
return(ToolTrap); |
else |
return(OSTrap); |
} |
#pragma segment Utils |
pascal Boolean TrapAvailable(short theTrap) |
{ |
TrapType tType; |
tType = GetTrapType(theTrap); |
if (tType == ToolTrap) |
{ |
theTrap = theTrap & 0x07FF; |
if (theTrap >= NumToolboxTraps()) |
theTrap = _Unimplemented; |
} |
return(NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented,ToolTrap)); |
} |
#pragma segment Utils |
#define _Gestalt 0xA1AD |
pascal Boolean GestaltAvailable() |
{ |
return(TrapAvailable(_Gestalt)); |
} |
/**------ FeatureIsImplemented ------------**/ |
/*This is called to use Gestalt to determine if a feature is implemented. |
This applies to only those referenced by OSType*/ |
#pragma segment Utils |
pascal Boolean FeatureIsImplemented ( OSType theFeature, short theTestBit ) |
{ |
OSErr err; |
long result; |
err = Gestalt ( theFeature, &result ); |
return (err == noErr && (result & (1L << theTestBit))); |
} |
#pragma segment Utils |
pascal Boolean CheckEnvironment() |
{ |
/* |
first determine of Gestalt is available- if it isn't exit |
as we only run under 7.0. It could it present in 6.04 - so we need |
to do some further checks for important features |
*/ |
gGestaltAvailable = GestaltAvailable(); |
if (!gGestaltAvailable) |
return(false); |
/*first check if the Edition Manager is present*/ |
gEditionManagerImplemented = FeatureIsImplemented(gestaltEditionMgrAttr, |
gestaltEditionMgrPresent); |
/*and for good measure- the Alias manager*/ |
gAliasManagerImplemented = FeatureIsImplemented(gestaltAliasMgrAttr, |
gestaltAliasMgrPresent); |
/*check for the AppleEvents manager - we certainly can't work without it*/ |
gAppleEventsImplemented = FeatureIsImplemented(gestaltAppleEventsAttr, |
gestaltAppleEventsPresent); |
/*check if recording is implemented*/ |
gRecordingImplemented = FeatureIsImplemented(gestaltAppleEventsAttr,1); |
/*check for the Outline fonts*/ |
gOutlineFontsImplemented = FeatureIsImplemented(gestaltFontMgrAttr, |
gestaltOutlineFonts); |
// We would also like the Drag Manager |
gHasDragManager = FeatureIsImplemented ( gestaltDragMgrAttr, gestaltDragMgrPresent ); |
// It isn't enough to use Gestalt because we may not have sucessfully linked |
// to the DragLib shared library. So, we also need to test one of the symbols |
// against kUnresolvedSymbol to make sure we have a valid connection to it. |
#if GENERATINGCFM |
if ( gHasDragManager ) |
gHasDragManager = (InstallTrackingHandler != (void*) kUnresolvedCFragSymbolAddress); |
#endif |
return (gEditionManagerImplemented && |
gAliasManagerImplemented && |
gAppleEventsImplemented && |
gOutlineFontsImplemented); |
} /* CheckEnvironment */ |
/* |
DoPageSetup returns true if the page setup of the document is altered |
*/ |
pascal Boolean DoPageSetup(DPtr theDoc) |
{ |
Boolean result = false; |
if (theDoc) |
{ |
PrOpen(); |
result = PrStlDialog(theDoc->thePrintSetup); |
PrClose(); |
} |
return(result); |
} /* DoPageSetup */ |
/* |
Name: CtrlKeyPressed |
Purpose: Returns true if control key pressed during event |
*/ |
pascal Boolean CtrlKeyPressed(const EventRecord *theEvent) |
{ |
return((theEvent->modifiers & controlKey) != 0); |
} |
/* |
Name: OptionKeyPressed |
Purpose: Returns true if option key pressed during event |
*/ |
pascal Boolean OptionKeyPressed(const EventRecord *theEvent) |
{ |
return((theEvent->modifiers & optionKey) != 0); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-07-22