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.
Sources/MSUtils.c
// MSUtils.c |
// |
// Original version by Jon Lansdell and Nigel Humphreys. |
// 4.0 and 3.1 updates by Greg Sutton. |
// ©Apple Computer Inc 1996, all rights reserved. |
/* |
Changes for 3.1: |
12-Oct-95 : CW : Simplified FeatureIsImplemented routine. |
Added init of gHasDragManager flag in CheckEnvironment. |
Changes for 4.0: |
17-Apr-96 : GS : Changed pascal calling conventions to C where possible. |
Changed behavior of outlining Up, Down and Other in Size menu. |
*/ |
#ifdef THINK_C |
#include "PLStrs.h" |
#else |
#include <PLStringFuncs.h> |
#endif |
#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 "MSUtils.h" |
// Name: LesserOf |
// Purpose: Returns the Lesser of two longints. |
#pragma segment Utils |
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 |
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 |
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 |
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 |
void SetShortMenus( void ) |
{ |
DeleteMenu(mfontID); |
DeleteMenu(sizeID); |
DeleteMenu(styleID); |
DeleteMenu(mscriptID); |
DeleteMenu(subroutineID); |
SetMenuItemState ( false, myMenus[fileM], fmClose); |
SetMenuItemState ( false, myMenus[fileM], fmSave); |
SetMenuItemState ( false, myMenus[fileM], fmSaveAs); |
SetMenuItemState ( false, myMenus[fileM], fmRevert); |
SetMenuItemState ( false, myMenus[fileM], fmPageSetUp); |
if (gGXIsPresent) |
{ |
SetMenuItemState ( false, myMenus[fileM], fmPrint); |
SetMenuItemState ( false, myMenus[fileM], fmPrintOne ); |
} |
else |
SetMenuItemState ( false, myMenus[fileM], fmNoGXPrint); |
// now the unnecessary items on the edit menu |
SetMenuItemState ( false, myMenus[editM], undoCommand); |
SetMenuItemState ( false, myMenus[editM], cutCommand); |
SetMenuItemState ( false, myMenus[editM], copyCommand); |
SetMenuItemState ( false, myMenus[editM], clearCommand); |
SetMenuItemState ( false, myMenus[editM], pasteCommand); |
SetMenuItemState ( false, myMenus[editM], selectAllCommand); |
DrawMenuBar(); |
} // SetShortMenus |
// Name: SetLongMenus |
// Purpose: Reinstates the full menu bar - called when first document |
// opened. |
#pragma segment Utils |
void SetLongMenus( void ) |
{ |
InsertMenu(myMenus[fontM], 0); |
InsertMenu(myMenus[sizeM], 0); |
InsertMenu(myMenus[styleM], 0); |
InsertMenu(myMenus[scriptM], 0); |
InsertMenu(myMenus[subroutineM], 0); |
SetMenuItemState ( true, myMenus[fileM], fmClose); |
SetMenuItemState ( true, myMenus[fileM], fmSave); |
SetMenuItemState ( true, myMenus[fileM], fmSaveAs); |
SetMenuItemState ( true, myMenus[fileM], fmRevert); |
SetMenuItemState ( true, myMenus[fileM], fmPageSetUp); |
if (gGXIsPresent) |
{ |
SetMenuItemState ( true, myMenus[fileM], fmPrint ); |
SetMenuItemState ( true, myMenus[fileM], fmPrintOne ); |
} |
else |
SetMenuItemState ( true, 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 |
SetMenuItemState ( true, 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 |
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 |
void SetSizeMenu( DPtr theDoc ) |
{ |
short i; |
short aSize; |
short max; |
long theSize; |
Str255 name; |
Boolean sizeinMenu; |
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++) |
{ |
GetItem(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); |
if ( RealFont(theStyle.tsFont, theStyle.tsSize ) && (contMode & doFont) != 0 ) |
SetItemStyle(myMenus[sizeM], max, outline); |
else |
SetItemStyle(myMenus[sizeM], max, 0); |
} |
else |
{ |
CheckItem(myMenus[sizeM], max, false); |
SetItemStyle(myMenus[sizeM], max, 0); |
} |
// Outline Up if next size up is available |
if ( RealFont(theStyle.tsFont, theStyle.tsSize + 1 ) && (contMode & doFont) != 0 ) |
SetItemStyle(myMenus[sizeM], max - 3, outline); |
else |
SetItemStyle(myMenus[sizeM], max - 3, 0); |
// Outline Down if next size up is available |
if ( RealFont(theStyle.tsFont, theStyle.tsSize - 1 ) && (contMode & doFont) != 0 ) |
SetItemStyle(myMenus[sizeM], max - 2, outline); |
else |
SetItemStyle(myMenus[sizeM], max - 2, 0); |
} |
// Name: SetFontMenu |
// Purpose: Set the font menu according to the state of |
// current selection of the supplied document. |
#pragma segment Utils |
void SetFontMenu( DPtr theDoc ) |
{ |
MenuHandle theMHandle; |
short theNumber; |
short i; |
short max; |
Str255 name; |
TextStyle theStyle; |
short contMode; |
theMHandle = GetMHandle(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++) |
{ |
GetItem(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 |
void GetTempFileName( DPtr aDoc, Str255 newString ) |
{ |
Str255 s; |
Str255 fileName; |
if (aDoc->everSaved == false) |
PLstrcpy(fileName, (unsigned char *)"\pTEXTra"); |
else |
PLstrcpy(fileName, aDoc->theFileName); |
// generate a unique(ish) temporary filename |
if (fileName[0] > 21) |
fileName[0] = 21; |
NumToString(TickCount(), s); |
PLstrcat(fileName, s); |
PLstrcpy(newString,fileName); |
} |
// Name: SetText |
// Purpose: Sets the text of the supplied itemNo in aDialog to |
// theString and select it. |
#pragma segment Utils |
void SetText( DialogPtr aDialog, short itemNo, Str255 theString ) |
{ |
Handle itemHandle; |
Rect box; |
short kind; |
TEHandle theTEHandle; |
GetDItem(aDialog, itemNo, &kind, &itemHandle, &box); |
SetIText(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 |
void RetrieveText( DialogPtr aDialog, short anItem, Str255 aString ) |
{ |
short kind; |
Rect box; |
Handle itemHandle; |
GetDItem(aDialog, anItem, &kind, &itemHandle, &box); |
GetIText(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; |
GetDItem(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 |
void AdornDefaultButton(DialogPtr theDialog,short theItem) |
{ |
short kind; |
Handle itemHandle; |
Rect box; |
GetDItem(theDialog, theItem, &kind, &itemHandle, &box); |
SetDItem(theDialog, theItem, kind, (Handle)gDefaultButtonUPP, &box); |
} |
void GetRectOfDialogItem( DialogPtr theDialog, short theItem, Rect *theRect ) |
{ |
short kind; |
Handle itemHandle; |
GetDItem(theDialog, theItem, &kind, &itemHandle, theRect); |
} |
// ------- 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 |
#pragma segment Utils |
short NumToolboxTraps(void) |
{ |
if (NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap)) |
return(0x200); |
else |
return(0x400); |
} |
#pragma segment Utils |
#define TrapMask 0x0800 |
TrapType GetTrapType(short theTrap) |
{ |
if ((theTrap & TrapMask) > 0) |
return(ToolTrap); |
else |
return(OSTrap); |
} |
#pragma segment Utils |
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 |
Boolean GestaltAvailable( void ) |
{ |
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 |
Boolean FeatureIsImplemented( OSType theFeature, short theTestBit ) |
{ |
OSErr err; |
long result; |
err = Gestalt ( theFeature, &result ); |
return (err == noErr && (result & (1L << theTestBit))); |
} |
#pragma segment Utils |
Boolean CheckEnvironment( void ) |
{ |
long response; |
// 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); |
// 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*) kUnresolvedSymbolAddress); |
#endif |
// Want the process manager |
gHasProcessManager = ( noErr == Gestalt( gestaltOSAttr, &response ) ); |
return (gEditionManagerImplemented |
&& gAliasManagerImplemented |
&& gAppleEventsImplemented |
&& gOutlineFontsImplemented |
&& gHasProcessManager ); |
} // CheckEnvironment |
// DoPageSetup returns true if the page setup of the document is altered |
Boolean DoPageSetup(DPtr theDoc) |
{ |
Boolean result = false; |
if ( ! gGXIsPresent ) |
if ( theDoc ) |
{ |
PrOpen(); |
result = PrStlDialog(theDoc->thePrintSetup); |
PrClose(); |
} |
return(result); |
} // DoPageSetup |
// Name: CtrlKeyPressed |
// Purpose: Returns true if control key pressed during event |
Boolean CtrlKeyPressed( const EventRecord *theEvent ) |
{ |
return((theEvent->modifiers & controlKey) != 0); |
} |
// Name: OptionKeyPressed |
// Purpose: Returns true if option key pressed during event |
Boolean OptionKeyPressed( const EventRecord *theEvent ) |
{ |
return((theEvent->modifiers & optionKey) != 0); |
} |
Boolean SetMenuItemState ( Boolean theState, |
MenuHandle theMenu, |
short item ) |
{ |
Boolean reDrawMenuBar = false; |
Boolean isSet; |
if (item == kMenuTitle) |
{ |
isSet = ((*theMenu)->enableFlags & 0x00000001); |
reDrawMenuBar = (isSet != theState); |
} |
if (theState) |
EnableItem ( theMenu, item ); |
else |
DisableItem ( theMenu, item ); |
return ( reDrawMenuBar ); |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14