home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
macintosh-c
/
macc-carbon-demos-nonbinhex.sit
/
macc-carbon-demos-nonbinhex
/
chap26-demo
/
MLTEMenus.c
< prev
next >
Wrap
C/C++ Source or Header
|
2001-05-31
|
43KB
|
1,530 lines
// *******************************************************************************************
// MTLETextEditor.h CLASSIC EVENT MODEL
// *******************************************************************************************
//
// This program demonstrates the use of the Multilingual Text Engine API to create a basic
// multi-styled text editor. New documents created by the program are created and saved as
// Textension ('txtn') documents. Existing 'TEXT' documents and Unicode ('utxt') documents
// are saved in the original format. In the case of 'TEXT' documents, style information is
// saved in a 'styl' resource.
//
// The program utilises the following resources:
//
// • A 'plst' resource.
//
// • An 'MBAR' resource, and 'MENU' resources for Apple, File, Edit, Size, Style, Colour,
// and Justification (preload, non-purgeable).
//
// • A 'WIND' resource (purgeable) (initially not visible).
//
// • A 'STR ' resource (purgeable) containing the "missing application name" string, which is
// copied to all document files created by the program.
//
// • 'STR#' resources (purgeable) containing error strings, the application's name (for
// certain Navigation Services functions), and strings for the Edit menu Undo and Redo
// items.
//
// • A 'kind' resource (purgeable) describing file types, which is used by Navigation
// Services to build the native file types section of the Show pop-up menu in the Open
// dialog box.
//
// • An 'open' resource (purgeable) containing the file type list for the Open dialog box.
//
// • The 'BNDL' resource (non-purgeable), 'FREF' resources (non-purgeable), signature
// resource (non-purgeable), and icon family resources (purgeable), required to support the
// built application.
//
// • A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground,
// doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
//
// *******************************************************************************************
// ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
#include <Carbon.h>
// …………………………………………………………………………………………………………………………………………………………………………………………………………………………… defines
#define rMenubar 128
#define mAppleApplication 128
#define iAbout 1
#define mFile 129
#define iNew 1
#define iOpen 2
#define iClose 4
#define iSave 5
#define iSaveAs 6
#define iRevert 7
#define iPageSetup 9
#define iPrint 10
#define iQuit 12
#define mEdit 130
#define iUndo 1
#define iRedo 2
#define iCut 4
#define iCopy 5
#define iPaste 6
#define iClear 7
#define iSelectAll 8
#define mFont 131
#define mSize 132
#define iTwelve 4
#define mStyle 133
#define iPlain 1
#define iBold 3
#define iUnderline 5
#define mColour 134
#define iBlack 4
#define iColourPicker 6
#define mJustification 135
#define iDefault 1
#define iLeft 2
#define iForceFull 6
#define mWindow 136
#define mFirstHierarchical 160
#define rNewWindow 128
#define rAboutDialog 128
#define rErrorStrings 128
#define eInstallHandler 1000
#define eMaxWindows 1001
#define eCantFindFinderProcess 1002
#define rMiscellaneousStrings 129
#define sApplicationName 1
#define rOpenResource 128
#define kMaxWindows 8
#define kOpen 0
#define kPrint 1
#define kFileCreator 'bbJk'
#define MAX_UINT32 0xFFFFFFFF
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#define topLeft(r) (((Point *) &(r))[0])
#define kATSUCGContextTag 32767L
// …………………………………………………………………………………………………………………………………………………………………………………………… function prototypes
void main (void);
void doPreliminaries (void);
void doInitialiseMTLE (void);
void doInstallAEHandlers (void);
void eventLoop (void);
UInt32 doGetSleepTime (void);
void doIdle (void);
void doEvents (EventRecord *);
void doMouseDown (EventRecord *);
void doBringFinderToFront (void);
OSStatus doFindProcess (OSType,OSType,ProcessSerialNumber *);
void doActivate (EventRecord *);
void doUpdate (EventRecord *);
Boolean isApplicationWindow (WindowRef,TXNObject *);
void doAboutDialog (void);
void doSynchroniseFiles (void);
OSStatus openAppEventHandler (AppleEvent *,AppleEvent *,SInt32);
OSStatus reopenAppEventHandler (AppleEvent *,AppleEvent *,SInt32);
OSStatus openAndPrintDocsEventHandler (AppleEvent *,AppleEvent *,SInt32);
OSStatus quitAppEventHandler (AppleEvent *,AppleEvent *,SInt32);
OSStatus doHasGotRequiredParams (AppleEvent *);
void doErrorAlert (SInt16);
void doCopyPString (Str255,Str255);
void doConcatPStrings (Str255,Str255);
void doEnableDisableMenus (Boolean);
void doAdjustAndPrepareMenus (void);
void doAdjustFileMenu (MenuRef,WindowRef);
void doAdjustEditMenu (MenuRef,WindowRef);
void doPrepareFontMenu (WindowRef);
void doPrepareSizeMenu (MenuRef,WindowRef);
void doPrepareStyleMenu (MenuRef,WindowRef);
void doPrepareColourMenu (MenuRef,WindowRef);
Boolean isEqualRGB (RGBColor *,RGBColor *);
void doPrepareJustificationMenu (MenuRef,WindowRef);
void doMenuChoice (SInt32);
void doFileMenuChoice (MenuItemIndex,WindowRef);
void doEditMenuChoice (MenuItemIndex,WindowRef);
void doFontMenuChoice (MenuID,MenuItemIndex,WindowRef);
void doSizeMenuChoice (MenuItemIndex,WindowRef);
void doStyleMenuChoice (MenuItemIndex,WindowRef);
void doColourMenuChoice (MenuItemIndex,WindowRef);
void doJustificationMenuChoice (MenuItemIndex,WindowRef);
OSStatus doNewCommand (void);
OSStatus doOpenCommand (void);
OSStatus doCloseCommand (NavAskSaveChangesAction);
OSStatus doSaveCommand (void);
OSStatus doSaveAsCommand (void);
OSStatus doRevertCommand (void);
OSStatus doQuitCommand (NavAskSaveChangesAction);
OSStatus doNewDocWindow (WindowRef *,FSSpec *,TXNFileType);
OSStatus doOpenFile (FSSpec,OSType);
void doCloseWindow (WindowRef,TXNObject);
OSStatus doWriteFile (WindowRef,Boolean);
OSStatus doCopyResources (FSSpec,TXNFileType,Boolean);
OSStatus doCopyAResource (ResType,SInt16,SInt16,SInt16);
void navEventFunction (NavEventCallbackMessage,NavCBRecPtr,
NavCallBackUserData);
// *******************************************************************************************
// MLTETextEditor.c
// *******************************************************************************************
// ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
#include "MLTETextEditor.h"
// …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
SInt16 gAppResFileRefNum;
Boolean gRunningOnX = false;
Boolean gDone;
TXNFontMenuObject gTXNFontMenuObject;
RgnHandle gCursorRgnHdl;
extern SInt16 gCurrentNumberOfWindows;
// ************************************************************************************** main
void main(void)
{
MenuBarHandle menubarHdl;
SInt32 response;
MenuRef menuRef;
OSStatus osStatus = noErr;
// ……………………………………………………………………………………………………………………………………………………………………………………………… do preliminaries
doPreliminaries();
// ………………………………………………………………………………………… save application's resource file file reference number
gAppResFileRefNum = CurResFile();
// ……………………………………………………………………………………………………………………………………………………………………… set up menu bar and menus
menubarHdl = GetNewMBar(rMenubar);
if(menubarHdl == NULL)
doErrorAlert(MemError());
SetMenuBar(menubarHdl);
CreateStandardWindowMenu(0,&menuRef);
SetMenuID(menuRef,mWindow);
InsertMenu(menuRef,0);
DeleteMenuItem(menuRef,1);
Gestalt(gestaltMenuMgrAttr,&response);
if(response & gestaltMenuMgrAquaLayoutMask)
{
menuRef = GetMenuRef(mFile);
if(menuRef != NULL)
{
DeleteMenuItem(menuRef,iQuit);
DeleteMenuItem(menuRef,iQuit - 1);
}
gRunningOnX = true;
}
// ……………………………………………………………………………………………………………… build hierarchical font menu and draw menu bar
menuRef = GetMenuRef(mFont);
osStatus = TXNNewFontMenuObject(menuRef,mFont,mFirstHierarchical,&gTXNFontMenuObject);
if(osStatus != noErr)
doErrorAlert(osStatus);
DrawMenuBar();
// ……………………………………………………………………………………………………………………………………… install required Apple event handlers
doInstallAEHandlers();
// ……………………………………………………………………………………………………………………………………………………………………………………………… enter event loop
eventLoop();
}
// *************************************************************************** doPreliminaries
void doPreliminaries(void)
{
MoreMasterPointers(960);
InitCursor();
FlushEvents(everyEvent,0);
doInitialiseMTLE();
}
// ************************************************************************** doInitializeMTLE
void doInitialiseMTLE(void)
{
TXNMacOSPreferredFontDescription defaultFont[1];
OSStatus osStatus = noErr;
SInt16 fontID;
GetFNum("\pNew York",&fontID);
defaultFont[0].fontID = fontID;
defaultFont[0].pointSize = 0x000C0000;
defaultFont[0].fontStyle = kTXNDefaultFontStyle;
defaultFont[0].encoding = kTXNSystemDefaultEncoding;
osStatus = TXNInitTextension(&defaultFont[0],1,kTXNWantMoviesMask);
if(osStatus != noErr)
doErrorAlert(osStatus);
}
// *********************************************************************** doInstallAEHandlers
void doInstallAEHandlers(void)
{
OSStatus osStatus = noErr;
osStatus = AEInstallEventHandler(kCoreEventClass,kAEOpenApplication,
NewAEEventHandlerUPP((AEEventHandlerProcPtr) openAppEventHandler),
0L,false);
if(osStatus != noErr) doErrorAlert(eInstallHandler);
osStatus = AEInstallEventHandler(kCoreEventClass,kAEReopenApplication,
NewAEEventHandlerUPP((AEEventHandlerProcPtr) reopenAppEventHandler),
0L,false);
if(osStatus != noErr) doErrorAlert(eInstallHandler);
osStatus = AEInstallEventHandler(kCoreEventClass,kAEOpenDocuments,
NewAEEventHandlerUPP((AEEventHandlerProcPtr) openAndPrintDocsEventHandler),
kOpen,false);
if(osStatus != noErr) doErrorAlert(eInstallHandler);
osStatus = AEInstallEventHandler(kCoreEventClass,kAEPrintDocuments,
NewAEEventHandlerUPP((AEEventHandlerProcPtr) openAndPrintDocsEventHandler),
kPrint,false);
if(osStatus != noErr) doErrorAlert(eInstallHandler);
osStatus = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
0L,false);
if(osStatus != noErr) doErrorAlert(eInstallHandler);
}
// ********************************************************************************* eventLoop
void eventLoop(void)
{
EventRecord eventStructure;
gDone = false;
gCursorRgnHdl = NewRgn();
while(!gDone)
{
if(WaitNextEvent(everyEvent,&eventStructure,doGetSleepTime(),gCursorRgnHdl))
doEvents(&eventStructure);
else
{
if(eventStructure.what == nullEvent)
{
doIdle();
doSynchroniseFiles();
}
}
}
}
// **************************************************************************** doGetSleepTime
UInt32 doGetSleepTime(void)
{
WindowRef windowRef;
UInt32 sleepTime;
TXNObject txnObject = NULL;
windowRef = FrontWindow();
if(isApplicationWindow(windowRef,&txnObject))
sleepTime = TXNGetSleepTicks(txnObject);
else
sleepTime = GetCaretTime();
return sleepTime;
}
// ************************************************************************************ doIdle
void doIdle(void)
{
WindowRef windowRef;
TXNObject txnObject = NULL;
windowRef = FrontWindow();
if(isApplicationWindow(windowRef,&txnObject))
{
if(TXNGetChangeCount(txnObject))
SetWindowModified(windowRef,true);
}
}
// ********************************************************************************** doEvents
void doEvents(EventRecord *eventStrucPtr)
{
WindowRef windowRef;
TXNObject txnObject = NULL;
switch(eventStrucPtr->what)
{
case kHighLevelEvent:
AEProcessAppleEvent(eventStrucPtr);
break;
case mouseDown:
doMouseDown(eventStrucPtr);
break;
case keyDown:
if(eventStrucPtr->modifiers & cmdKey)
{
doAdjustAndPrepareMenus();
doMenuChoice(MenuEvent(eventStrucPtr));
}
break;
case updateEvt:
doUpdate(eventStrucPtr);
break;
case activateEvt:
doActivate(eventStrucPtr);
break;
case osEvt:
switch((eventStrucPtr->message >> 24) & 0x000000FF)
{
case suspendResumeMessage:
if(eventStrucPtr->message & resumeFlag)
SetThemeCursor(kThemeArrowCursor);
break;
case mouseMovedMessage:
windowRef = FrontWindow();
if(isApplicationWindow(windowRef,&txnObject))
TXNAdjustCursor(txnObject,gCursorRgnHdl);
}
break;
}
}
// ******************************************************************************* doMouseDown
void doMouseDown(EventRecord *eventStrucPtr)
{
WindowRef windowRef;
WindowPartCode partCode;
OSStatus osStatus = noErr;
TXNObject txnObject = NULL;
Boolean handled = false;
SInt32 itemSelected;
partCode = FindWindow(eventStrucPtr->where,&windowRef);
switch(partCode)
{
case inMenuBar:
doAdjustAndPrepareMenus();
doMenuChoice(MenuSelect(eventStrucPtr->where));
break;
case inContent:
if(windowRef != FrontWindow())
SelectWindow(windowRef);
else
{
if(isApplicationWindow(windowRef,&txnObject))
TXNClick(txnObject,eventStrucPtr);
}
break;
case inGoAway:
if(TrackGoAway(windowRef,eventStrucPtr->where))
doCloseCommand(kNavSaveChangesClosingDocument);
break;
case inProxyIcon:
osStatus = TrackWindowProxyDrag(windowRef,eventStrucPtr->where);
if(osStatus == errUserWantsToDragWindow)
handled = false;
else if(osStatus == noErr)
handled = true;
case inDrag:
if(!handled)
{
if(IsWindowPathSelectClick(windowRef,eventStrucPtr))
{
if(WindowPathSelect(windowRef,NULL,&itemSelected) == noErr)
{
if(LoWord(itemSelected) > 1)
doBringFinderToFront();
}
handled = true;
}
}
if(!handled)
DragWindow(windowRef,eventStrucPtr->where,NULL);
if(isApplicationWindow(windowRef,&txnObject))
TXNAdjustCursor(txnObject,gCursorRgnHdl);
break;
case inGrow:
if(isApplicationWindow(windowRef,&txnObject))
{
TXNGrowWindow(txnObject,eventStrucPtr);
TXNAdjustCursor(txnObject,gCursorRgnHdl);
}
break;
case inZoomIn:
case inZoomOut:
if(TrackBox(windowRef,eventStrucPtr->where,partCode))
{
if(isApplicationWindow(windowRef,&txnObject))
{
TXNZoomWindow(txnObject,partCode);
TXNAdjustCursor(txnObject,gCursorRgnHdl);
}
}
break;
}
}
// ********************************************************************** doBringFinderToFront
void doBringFinderToFront(void)
{
ProcessSerialNumber finderProcess;
if(doFindProcess('MACS','FNDR',&finderProcess) == noErr)
SetFrontProcess(&finderProcess);
else
doErrorAlert(eCantFindFinderProcess);
}
// ***************************************************************************** doFindProcess
OSStatus doFindProcess(OSType creator,OSType type,ProcessSerialNumber *outProcSerNo)
{
ProcessSerialNumber procSerialNo;
ProcessInfoRec procInfoStruc;
OSStatus osStatus = noErr;
procSerialNo.highLongOfPSN = 0;
procSerialNo.lowLongOfPSN = kNoProcess;
procInfoStruc.processInfoLength = sizeof(ProcessInfoRec);
procInfoStruc.processName = NULL;
procInfoStruc.processAppSpec = NULL;
procInfoStruc.processLocation = NULL;
while(true)
{
osStatus = GetNextProcess(&procSerialNo);
if(osStatus != noErr)
break;
osStatus = GetProcessInformation(&procSerialNo,&procInfoStruc);
if(osStatus != noErr)
break;
if((procInfoStruc.processSignature == creator) && (procInfoStruc.processType == type))
break;
}
*outProcSerNo = procSerialNo;
return osStatus;
}
// ******************************************************************************** doActivate
void doActivate(EventRecord *eventStrucPtr)
{
WindowRef windowRef;
TXNObject txnObject = NULL;
Boolean becomingActive;
TXNFrameID txnFrameID = 0;
windowRef = (WindowRef) eventStrucPtr->message;
if(isApplicationWindow(windowRef,&txnObject))
{
becomingActive = ((eventStrucPtr->modifiers & activeFlag) == activeFlag);
GetWindowProperty(windowRef,kFileCreator,'tFRM',sizeof(TXNFrameID),NULL,&txnFrameID);
if(becomingActive)
TXNActivate(txnObject,txnFrameID,becomingActive);
else
TXNActivate(txnObject,txnFrameID,becomingActive);
TXNFocus(txnObject,becomingActive);
}
}
// ********************************************************************************** doUpdate
void doUpdate(EventRecord *eventStrucPtr)
{
WindowRef windowRef;
GrafPtr oldPort;
TXNObject txnObject = NULL;
windowRef = (WindowRef) eventStrucPtr->message;
GetPort(&oldPort);
SetPortWindowPort(windowRef);
if(isApplicationWindow(windowRef,&txnObject))
TXNUpdate(txnObject);
SetPort(oldPort);
}
// *********************************************************************** isApplicationWindow
Boolean isApplicationWindow(WindowRef windowRef,TXNObject *txnObject)
{
OSStatus osStatus = noErr;
osStatus = GetWindowProperty(windowRef,kFileCreator,'tOBJ',sizeof(TXNObject),NULL,
txnObject);
return (windowRef != NULL) && (GetWindowKind(windowRef) == kApplicationWindowKind);
}
// ***************************************************************************** doAboutDialog
void doAboutDialog(void)
{
DialogRef dialogRef;
SInt16 itemHit;
dialogRef = GetNewDialog(rAboutDialog,NULL,(WindowRef) -1);
ModalDialog(NULL,&itemHit);
DisposeDialog(dialogRef);
}
// ************************************************************************ doSynchroniseFiles
void doSynchroniseFiles(void)
{
UInt32 currentTicks;
WindowRef windowRef;
static UInt32 nextSynchTicks = 0;
OSStatus hasNoAliasHdl = noErr;
Boolean aliasChanged;
AliasHandle aliasHdl = NULL;
FSSpec newFSSpec;
OSStatus osStatus = noErr;
SInt16 trashVRefNum;
SInt32 trashDirID;
TXNObject txnObject = NULL;
currentTicks = TickCount();
windowRef = FrontWindow();
if(currentTicks > nextSynchTicks)
{
while(windowRef != NULL)
{
hasNoAliasHdl = GetWindowProperty(windowRef,kFileCreator,'tALH',sizeof(AliasHandle),
NULL,&aliasHdl);
if(hasNoAliasHdl)
break;
aliasChanged = false;
ResolveAlias(NULL,aliasHdl,&newFSSpec,&aliasChanged);
if(aliasChanged)
{
SetWindowProperty(windowRef,kFileCreator,'FiSp',sizeof(FSSpec),&newFSSpec);
SetWTitle(windowRef,newFSSpec.name);
}
osStatus = FindFolder(kUserDomain,kTrashFolderType,kDontCreateFolder,
&trashVRefNum,&trashDirID);
if(osStatus == noErr)
{
do
{
if(newFSSpec.parID == fsRtParID)
break;
if((newFSSpec.vRefNum == trashVRefNum) && (newFSSpec.parID == trashDirID))
{
GetWindowProperty(windowRef,kFileCreator,'tOBJ',sizeof(TXNObject),NULL,
&txnObject);
TXNDeleteObject(txnObject);
DisposeWindow(windowRef);
gCurrentNumberOfWindows --;
break;
}
} while(FSMakeFSSpec(newFSSpec.vRefNum,newFSSpec.parID,"\p",&newFSSpec) == noErr);
}
windowRef = GetNextWindow(windowRef);
}
nextSynchTicks = currentTicks + 15;
}
}
// *********************************************************************** openAppEventHandler
OSStatus openAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefCon)
{
OSStatus osStatus = noErr;
osStatus = doHasGotRequiredParams(appEvent);
if(osStatus == noErr)
osStatus = doNewCommand();
return osStatus;
}
// ********************************************************************* reopenAppEventHandler
OSStatus reopenAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,
SInt32 handlerRefCon)
{
OSStatus osStatus = noErr;
osStatus = doHasGotRequiredParams(appEvent);
if(osStatus == noErr)
if(!FrontWindow())
osStatus = doNewCommand();
return osStatus;
}
// ************************************************************** openAndPrintDocsEventHandler
OSStatus openAndPrintDocsEventHandler(AppleEvent *appEvent,AppleEvent *reply,
SInt32 handlerRefcon)
{
FSSpec fileSpec;
AEDescList docList;
OSStatus osStatus, ignoreErr;
SInt32 index, numberOfItems;
Size actualSize;
AEKeyword keyWord;
DescType returnedType;
FInfo fileInfo;
TXNObject txnObject;
osStatus = AEGetParamDesc(appEvent,keyDirectObject,typeAEList,&docList);
if(osStatus == noErr)
{
osStatus = doHasGotRequiredParams(appEvent);
if(osStatus == noErr)
{
osStatus = AECountItems(&docList,&numberOfItems);
if(osStatus == noErr)
{
for(index=1;index<=numberOfItems;index++)
{
osStatus = AEGetNthPtr(&docList,index,typeFSS,&keyWord,&returnedType,
&fileSpec,sizeof(fileSpec),&actualSize);
if(osStatus == noErr)
{
osStatus = FSpGetFInfo(&fileSpec,&fileInfo);
if(osStatus == noErr)
{
if(osStatus = doOpenFile(fileSpec,fileInfo.fdType))
doErrorAlert(osStatus);
if(osStatus == noErr && handlerRefcon == kPrint)
{
if(isApplicationWindow(FrontWindow(),&txnObject))
{
if(osStatus = TXNPrint(txnObject))
doErrorAlert(osStatus);
if(osStatus = doCloseCommand(kNavSaveChangesOther))
doErrorAlert(osStatus);
}
}
}
}
else
doErrorAlert(osStatus);
}
}
}
else
doErrorAlert(osStatus);
ignoreErr = AEDisposeDesc(&docList);
}
else
doErrorAlert(osStatus);
return osStatus;
}
// *********************************************************************** quitAppEventHandler
OSStatus quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
{
OSStatus osStatus = noErr;
osStatus = doHasGotRequiredParams(appEvent);
if(osStatus == noErr)
{
while(FrontWindow())
{
osStatus = doCloseCommand(kNavSaveChangesQuittingApplication);
if(osStatus != noErr && osStatus != kNavAskSaveChangesCancel)
doErrorAlert(osStatus);
if(osStatus == kNavAskSaveChangesCancel)
return noErr;
}
}
gDone = true;
return osStatus;
}
// ******************************************************************** doHasGotRequiredParams
OSStatus doHasGotRequiredParams(AppleEvent *appEvent)
{
DescType returnedType;
Size actualSize;
OSStatus osStatus = noErr;
osStatus = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,
NULL,0,&actualSize);
if(osStatus == errAEDescNotFound)
osStatus = noErr;
else if(osStatus == noErr)
osStatus = errAEParamMissed;
return osStatus;
}
// ****************************************************************************** doErrorAlert
void doErrorAlert(SInt16 errorCode)
{
Str255 errorString, theString;
SInt16 itemHit;
if(errorCode == kATSUFontsMatched)
return;
if(errorCode == eInstallHandler)
GetIndString(errorString,rErrorStrings,1);
else if(errorCode == eMaxWindows)
GetIndString(errorString,rErrorStrings,2);
else if(errorCode == eCantFindFinderProcess)
GetIndString(errorString,rErrorStrings,3);
else
{
GetIndString(errorString,rErrorStrings,4);
NumToString((SInt32) errorCode,theString);
doConcatPStrings(errorString,theString);
}
if(errorCode != memFullErr)
StandardAlert(kAlertCautionAlert,errorString,NULL,NULL,&itemHit);
else
{
StandardAlert(kAlertStopAlert,errorString,NULL,NULL,&itemHit);
ExitToShell();
}
}
// ***************************************************************************** doCopyPString
void doCopyPString(Str255 sourceString,Str255 destinationString)
{
SInt16 stringLength;
stringLength = sourceString[0];
BlockMove(sourceString + 1,destinationString + 1,stringLength);
destinationString[0] = stringLength;
}
// ************************************************************************** doConcatPStrings
void doConcatPStrings(Str255 targetString,Str255 appendString)
{
SInt16 appendLength;
appendLength = MIN(appendString[0],255 - targetString[0]);
if(appendLength > 0)
{
BlockMoveData(appendString+1,targetString+targetString[0]+1,(SInt32) appendLength);
targetString[0] += appendLength;
}
}
// *******************************************************************************************
// MLTEMenus.c
// *******************************************************************************************
// ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
#include "MLTETextEditor.h"
// …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
RGBColor gCurrentColourPickerColour = { 0x0000,0x0000,0x0000 };
extern SInt16 gCurrentNumberOfWindows;
extern TXNFontMenuObject gTXNFontMenuObject;
extern Boolean gDone;
// ********************************************************************** doEnableDisableMenus
void doEnableDisableMenus(Boolean enableMenus)
{
if(enableMenus)
{
EnableMenuItem(GetMenuRef(mEdit),0);
EnableMenuItem(GetMenuRef(mFont),0);
EnableMenuItem(GetMenuRef(mSize),0);
EnableMenuItem(GetMenuRef(mStyle),0);
EnableMenuItem(GetMenuRef(mColour),0);
EnableMenuItem(GetMenuRef(mJustification),0);
EnableMenuItem(GetMenuRef(mWindow),0);
}
else
{
DisableMenuItem(GetMenuRef(mEdit),0);
DisableMenuItem(GetMenuRef(mFont),0);
DisableMenuItem(GetMenuRef(mSize),0);
DisableMenuItem(GetMenuRef(mStyle),0);
DisableMenuItem(GetMenuRef(mColour),0);
DisableMenuItem(GetMenuRef(mJustification),0);
DisableMenuItem(GetMenuRef(mWindow),0);
}
}
// ******************************************************************* doAdjustAndPrepareMenus
void doAdjustAndPrepareMenus(void)
{
WindowRef windowRef;
windowRef = FrontWindow();
doAdjustFileMenu(GetMenuRef(mFile),windowRef);
doAdjustEditMenu(GetMenuRef(mEdit),windowRef);
doPrepareFontMenu(windowRef);
doPrepareSizeMenu(GetMenuRef(mSize),windowRef);
doPrepareStyleMenu(GetMenuRef(mStyle),windowRef);
doPrepareColourMenu(GetMenuRef(mColour),windowRef);
doPrepareJustificationMenu(GetMenuRef(mJustification),windowRef);
DrawMenuBar();
}
// ************************************************************************** doAdjustFileMenu
void doAdjustFileMenu(MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
if(gCurrentNumberOfWindows <= kMaxWindows)
{
EnableMenuItem(menuRef,iNew);
EnableMenuItem(menuRef,iOpen);
}
else
{
DisableMenuItem(menuRef,iNew);
DisableMenuItem(menuRef,iOpen);
}
if(isApplicationWindow(windowRef,&txnObject))
{
EnableMenuItem(menuRef,iClose);
if(TXNGetChangeCount(txnObject))
{
EnableMenuItem(menuRef,iSave);
EnableMenuItem(menuRef,iRevert);
}
else
{
DisableMenuItem(menuRef,iSave);
DisableMenuItem(menuRef,iRevert);
}
if(TXNDataSize(txnObject))
{
EnableMenuItem(menuRef,iSaveAs);
EnableMenuItem(menuRef,iPageSetup);
EnableMenuItem(menuRef,iPrint);
}
else
{
DisableMenuItem(menuRef,iSaveAs);
DisableMenuItem(menuRef,iPageSetup);
DisableMenuItem(menuRef,iPrint);
}
}
else
{
DisableMenuItem(menuRef,iClose);
DisableMenuItem(menuRef,iSave);
DisableMenuItem(menuRef,iSaveAs);
DisableMenuItem(menuRef,iRevert);
DisableMenuItem(menuRef,iPageSetup);
DisableMenuItem(menuRef,iPrint);
}
}
// ************************************************************************** doAdjustEditMenu
void doAdjustEditMenu(MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
SInt16 menuItem;
Str255 itemText;
TXNActionKey actionKey;
if(isApplicationWindow(windowRef,&txnObject))
{
// ……………………………………………………………………………………………………………………………………………………………………………………… disable all items
for(menuItem = iUndo;menuItem <= iSelectAll;menuItem ++)
DisableMenuItem(menuRef,menuItem);
// ………………………………………………………………………………………………………… undo and redo default - can't undo, can't redo
GetIndString(itemText,130,1);
SetMenuItemText(menuRef,iUndo,itemText);
GetIndString(itemText,130,2);
SetMenuItemText(menuRef,iRedo,itemText);
// ……………………………………………………………………………………………………… if undoable, enable undo item and set item text
if(TXNCanUndo(txnObject,&actionKey))
{
EnableMenuItem(menuRef,iUndo);
if((actionKey < kTXNTypingAction) || (actionKey > kTXNMoveAction))
actionKey = -1;
GetIndString(itemText,130,2 * actionKey + 5);
SetMenuItemText(menuRef,iUndo,itemText);
}
// ……………………………………………………………………………………………………… if redoable, enable redo item and set item text
if(TXNCanRedo(txnObject,&actionKey))
{
EnableMenuItem(menuRef,iRedo);
if((actionKey < kTXNTypingAction) || (actionKey > kTXNMoveAction))
actionKey = -1;
GetIndString(itemText,130,2 * actionKey + 6);
SetMenuItemText(menuRef,iRedo,itemText);
}
// ………………………………………………………………………………………… if there is a selection, enable cut, copy, and clear
if(!TXNIsSelectionEmpty(txnObject))
{
EnableMenuItem(menuRef,iCut);
EnableMenuItem(menuRef,iCopy);
EnableMenuItem(menuRef,iClear);
}
// ………………………………………………………………………………………………………………………………………… if scrap is pastable, enable paste
if(TXNIsScrapPastable())
EnableMenuItem(menuRef,iPaste);
// ………………………………………………………………………………………………… if any characters in TXNObject, enable select all
if(TXNDataSize(txnObject))
EnableMenuItem(menuRef,iSelectAll);
}
}
// ************************************************************************* doPrepareFontMenu
void doPrepareFontMenu(WindowRef windowRef)
{
TXNObject txnObject = NULL;
if(isApplicationWindow(windowRef,&txnObject))
TXNPrepareFontMenu(txnObject,gTXNFontMenuObject);
}
// ************************************************************************* doPrepareSizeMenu
void doPrepareSizeMenu(MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
static Fixed itemSizes[8] = { 0x00090000,0x000A0000,0x000B0000,0x000C0000,
0x000E0000,0x00120000,0x00180000,0x00240000 };
TXNContinuousFlags txnContinuousFlags = 0;
TXNTypeAttributes txnTypeAttributes;
OSStatus osStatus = noErr;
SInt16 menuItem;
if(isApplicationWindow(windowRef,&txnObject))
{
txnTypeAttributes.tag = kTXNQDFontSizeAttribute;
txnTypeAttributes.size = kTXNFontSizeAttributeSize;
txnTypeAttributes.data.dataValue = 0;
osStatus = TXNGetContinuousTypeAttributes(txnObject,&txnContinuousFlags,1,
&txnTypeAttributes);
if(osStatus == noErr)
{
for(menuItem = 1;menuItem < 8;menuItem ++)
{
CheckMenuItem(menuRef,menuItem,(txnContinuousFlags & kTXNSizeContinuousMask) &&
(txnTypeAttributes.data.dataValue == itemSizes[menuItem - 1]));
}
}
}
}
// ************************************************************************ doPrepareStyleMenu
void doPrepareStyleMenu(MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
TXNContinuousFlags txnContinuousFlags = 0;
TXNTypeAttributes txnTypeAttributes;
OSStatus osStatus = noErr;
SInt16 menuItem;
if(isApplicationWindow(windowRef,&txnObject))
{
txnTypeAttributes.tag = kTXNQDFontStyleAttribute;
txnTypeAttributes.size = kTXNQDFontStyleAttributeSize;
txnTypeAttributes.data.dataValue = 0;
osStatus = TXNGetContinuousTypeAttributes(txnObject,&txnContinuousFlags,1,
&txnTypeAttributes);
if(osStatus == noErr)
{
CheckMenuItem(menuRef,iPlain,(txnContinuousFlags & kTXNStyleContinuousMask) &&
(txnTypeAttributes.data.dataValue == normal));
for(menuItem = iBold;menuItem <= iUnderline;menuItem ++)
{
CheckMenuItem(menuRef,menuItem,(txnContinuousFlags & kTXNStyleContinuousMask) &&
(txnTypeAttributes.data.dataValue & (1 << (menuItem - iBold))));
}
}
}
}
// *********************************************************************** doPrepareColourMenu
void doPrepareColourMenu(MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
TXNContinuousFlags txnContinuousFlags = 0;
TXNTypeAttributes txnTypeAttributes;
RGBColor attributesColour;
OSStatus osStatus = noErr;
SInt16 menuItem;
RGBColor itemColours[4] = { { 0xFFFF,0x0000,0x0000 },{ 0x0000,0x8888,0x0000 },
{ 0x0000,0x0000,0xFFFF },{ 0x0000,0x0000,0x0000 } };
if(isApplicationWindow(windowRef,&txnObject))
{
txnTypeAttributes.tag = kTXNQDFontColorAttribute;
txnTypeAttributes.size = kTXNQDFontColorAttributeSize;
txnTypeAttributes.data.dataPtr = &attributesColour;
osStatus = TXNGetContinuousTypeAttributes(txnObject,&txnContinuousFlags,1,
&txnTypeAttributes);
if(osStatus == noErr)
{
for(menuItem = 1;menuItem < 5;menuItem ++)
{
CheckMenuItem(menuRef,menuItem,(txnContinuousFlags & kTXNColorContinuousMask) &&
(isEqualRGB(&attributesColour,&itemColours[menuItem - 1])));
}
}
}
}
// ******************************************************************************** isEqualRGB
Boolean isEqualRGB(RGBColor *attributesColour,RGBColor *itemColour)
{
return (attributesColour->red == itemColour->red &&
attributesColour->green == itemColour->green &&
attributesColour->blue == itemColour->blue);
}
// **************************************************************** doPrepareJustificationMenu
void doPrepareJustificationMenu (MenuRef menuRef,WindowRef windowRef)
{
TXNObject txnObject = NULL;
static UInt32 itemJustifications[6] = { kTXNFlushDefault,kTXNFlushLeft,kTXNFlushRight,
kTXNCenter,kTXNFullJust,kTXNForceFullJust};
TXNControlTag txnControlTag[1];
TXNControlData txnControlData[1];
SInt16 menuItem;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
txnControlTag[0] = kTXNJustificationTag ;
txnControlData[0].uValue = 0;
osStatus = TXNGetTXNObjectControls(txnObject,1,txnControlTag,txnControlData);
if(osStatus == noErr)
{
for(menuItem = iDefault;menuItem <= iForceFull;menuItem ++ )
CheckMenuItem(menuRef,menuItem,(txnControlData[0].uValue ==
itemJustifications[menuItem - 1]));
}
}
}
// ****************************************************************************** doMenuChoice
void doMenuChoice(SInt32 menuChoice)
{
MenuID menuID;
MenuItemIndex menuItem;
OSStatus osStatus = noErr;
WindowRef windowRef;
TXNObject txnObject = NULL;
windowRef = FrontWindow();
menuID = HiWord(menuChoice);
menuItem = LoWord(menuChoice);
if(menuID == 0)
return;
switch(menuID)
{
case mAppleApplication:
if(menuItem == iAbout)
doAboutDialog();
break;
case mFile:
doFileMenuChoice(menuItem,windowRef);
break;
case mEdit:
doEditMenuChoice(menuItem,windowRef);
break;
case mFont:
doFontMenuChoice(menuID,menuItem,windowRef);
break;
case mSize:
doSizeMenuChoice(menuItem,windowRef);
break;
case mStyle:
doStyleMenuChoice(menuItem,windowRef);
break;
case mColour:
doColourMenuChoice(menuItem,windowRef);
break;
case mJustification:
doJustificationMenuChoice(menuItem,windowRef);
break;
default:
if(menuID >= mFirstHierarchical)
doFontMenuChoice(menuID,menuItem,windowRef);
break;
}
HiliteMenu(0);
}
// ************************************************************************** doFileMenuChoice
void doFileMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
OSStatus osStatus = noErr;
switch(menuItem)
{
case iNew:
if(osStatus = doNewCommand())
doErrorAlert(osStatus);
break;
case iOpen:
if(osStatus = doOpenCommand())
doErrorAlert(osStatus);
break;
case iClose:
if((osStatus = doCloseCommand(kNavSaveChangesClosingDocument)) &&
osStatus != kNavAskSaveChangesCancel)
doErrorAlert(osStatus);
break;
case iSave:
if(osStatus = doSaveCommand())
doErrorAlert(osStatus);
break;
case iSaveAs:
if(osStatus = doSaveAsCommand())
doErrorAlert(osStatus);
break;
case iRevert:
if(osStatus = doRevertCommand())
doErrorAlert(osStatus);
break;
case iPageSetup:
if(isApplicationWindow(windowRef,&txnObject))
{
osStatus = TXNPageSetup(txnObject);
if(osStatus != userCanceledErr && osStatus != noErr)
doErrorAlert(osStatus);
}
break;
case iPrint:
if(isApplicationWindow(windowRef,&txnObject))
{
osStatus = TXNPrint(txnObject);
if(osStatus != userCanceledErr && osStatus != noErr)
doErrorAlert(osStatus);
}
break;
case iQuit:
if((osStatus = doQuitCommand(kNavSaveChangesQuittingApplication)) &&
osStatus != kNavAskSaveChangesCancel)
doErrorAlert(osStatus);
if(osStatus != kNavAskSaveChangesCancel)
{
if(gTXNFontMenuObject != NULL)
{
if(osStatus = TXNDisposeFontMenuObject(gTXNFontMenuObject))
doErrorAlert(osStatus);
}
gTXNFontMenuObject = NULL;
TXNTerminateTextension();
gDone = true;
}
break;
}
}
// ************************************************************************** doEditMenuChoice
void doEditMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
switch(menuItem)
{
case iUndo:
TXNUndo(txnObject);
break;
case iRedo:
TXNRedo(txnObject);
break;
case iCut:
if((osStatus = TXNCut(txnObject)) == noErr)
TXNConvertToPublicScrap();
else
doErrorAlert(osStatus);
break;
case iCopy:
if((osStatus = TXNCopy(txnObject)) == noErr)
TXNConvertToPublicScrap();
else
doErrorAlert(osStatus);
break;
case iPaste:
if(osStatus = TXNPaste(txnObject))
doErrorAlert(osStatus);
break;
case iClear:
if(osStatus = TXNClear(txnObject))
doErrorAlert(osStatus);
break;
case iSelectAll:
TXNSelectAll(txnObject);
break;
}
}
}
// ************************************************************************** doFontMenuChoice
void doFontMenuChoice(MenuID menuID,MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
if(gTXNFontMenuObject != NULL)
{
if(osStatus = TXNDoFontMenuSelection(txnObject,gTXNFontMenuObject,menuID,menuItem))
doErrorAlert(osStatus);
}
}
}
// ************************************************************************** doSizeMenuChoice
void doSizeMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
static Fixed itemSizes[8] = { 0x00090000,0x000A0000,0x000B0000,0x000C0000,
0x000E0000,0x00120000,0x00180000,0x00240000 };
Fixed sizeToSet;
TXNTypeAttributes txnTypeAttributes;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
sizeToSet = itemSizes[menuItem - 1];
txnTypeAttributes.tag = kTXNQDFontSizeAttribute;
txnTypeAttributes.size = kTXNFontSizeAttributeSize;
txnTypeAttributes.data.dataValue = sizeToSet;
if(TXNSetTypeAttributes(txnObject,1,&txnTypeAttributes,kTXNUseCurrentSelection,
kTXNUseCurrentSelection))
doErrorAlert(osStatus);
}
}
// ************************************************************************* doStyleMenuChoice
void doStyleMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
static Style itemStyles[5] = { normal,0,bold,italic,underline };
Style styleToSet;
TXNTypeAttributes txnTypeAttributes;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
styleToSet = itemStyles[menuItem - 1];
txnTypeAttributes.tag = kTXNQDFontStyleAttribute;
txnTypeAttributes.size = kTXNQDFontStyleAttributeSize;
txnTypeAttributes.data.dataValue = styleToSet;
if(TXNSetTypeAttributes(txnObject,1,&txnTypeAttributes,kTXNUseCurrentSelection,
kTXNUseCurrentSelection))
doErrorAlert(osStatus);
}
}
// ************************************************************************ doColourMenuChoice
void doColourMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
Point where;
Boolean colorPickerButton;
Str255 prompt = "\pPick a text colour";
RGBColor colourToSet;
RGBColor itemColours[4] = { { 0xFFFF,0x0000,0x0000 },{ 0x0000,0x8888,0x0000 },
{ 0x0000,0x0000,0xFFFF },{ 0x0000,0x0000,0x0000 } };
TXNTypeAttributes txnTypeAttributes;
OSStatus osStatus = noErr;
if(isApplicationWindow(windowRef,&txnObject))
{
if(menuItem == iColourPicker)
{
where.v = where.h = 0;
colorPickerButton = GetColor(where,prompt,&gCurrentColourPickerColour,&colourToSet);
if(colorPickerButton)
gCurrentColourPickerColour = colourToSet;
else
return;
}
else
colourToSet = itemColours[menuItem - 1];
txnTypeAttributes.tag = kTXNQDFontColorAttribute;
txnTypeAttributes.size = kTXNQDFontColorAttributeSize;
txnTypeAttributes.data.dataPtr = &colourToSet;
if(TXNSetTypeAttributes(txnObject,1,&txnTypeAttributes,kTXNUseCurrentSelection,
kTXNUseCurrentSelection))
doErrorAlert(osStatus);
}
}
// ***************************************************************** doJustificationMenuChoice
void doJustificationMenuChoice(MenuItemIndex menuItem,WindowRef windowRef)
{
TXNObject txnObject = NULL;
static UInt32 itemJustifications[6] = { kTXNFlushDefault,kTXNFlushLeft,kTXNFlushRight,
kTXNCenter,kTXNFullJust,kTXNForceFullJust };
OSStatus osStatus = noErr;
UInt32 justificationToSet;
TXNControlTag txnControlTag[1];
TXNControlData txnControlData[1];
if(isApplicationWindow(windowRef,&txnObject))
{
justificationToSet = itemJustifications[menuItem - 1];
txnControlTag[0] = kTXNJustificationTag;
osStatus = TXNGetTXNObjectControls(txnObject,1,txnControlTag,txnControlData);
if(txnControlData[0].uValue != justificationToSet)
{
txnControlData[0].uValue = justificationToSet;
osStatus = TXNSetTXNObjectControls(txnObject,false,1,txnControlTag,txnControlData);
if(osStatus != noErr)
doErrorAlert(osStatus);
}
}
}
// *******************************************************************************************