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.
Publish.c
/*------------------------------------------------------------------------------ |
* |
* Apple Developer Technical Support |
* |
* Edition publishing routines |
* |
* Program: AEObject-Edition Sample |
* File: Publish.c - C Source |
* |
* by: C.K. Haun <TR> |
* |
* Copyright © 1990-1992 Apple Computer, Inc. |
* All rights reserved. |
* |
*------------------------------------------------------------------------------ |
* Publish handles most of the publishing housekeeping. There is (are,am,be,whatever) |
* some routines that are common to both publishing and subscribing, they |
* are located in Subscribe.c |
*----------------------------------------------------------------------------*/ |
#define __PUBLISH__ |
#pragma segment Publish |
#include "Sampdefines.h" |
/* CreatePublisher takes the currently selected area in the current window |
* and creates an edition. It starts by setting up some default data |
* structures and creating a preview picture. |
* Then the user is prompted for a location and name for the publisher |
* with the NewPublisherDialog. If the user clicks OK, then the edition |
* is created and the section handle and rectangle for this edition is |
* stored in my data structure for this window, and the first edition |
* is written out. |
*/ |
OSErr CreatePublisher(OSType typeToMake,Boolean fromEvent,FSSpecPtr theSpec) |
{ |
NewPublisherReply myreply; |
Handle theData; |
Rect currentRect; |
mySectionDataHandle pubText; |
Str31 addPub; |
static pubCounter; |
OSErr myErr; |
FSSpecPtr theOwningDoc = nil; |
FSSpec tempSpec; |
windowCHandle shortName; |
extern Point expPoint; |
extern Boolean gExpanded; |
Boolean myWasChanged; |
/* we're publishing from the current, topmost window */ |
shortName = (windowCHandle)GetWRefCon(FrontWindow()); |
HLock((Handle)shortName); |
switch (typeToMake) { |
case kGenericPICTWord: |
currentRect = (*shortName)->selectionRect; |
/* take the rectangle we currently have selected, and make it a picture */ |
theData = (Handle)MyMakePicture(¤tRect); /* my function to make a PICT */ |
/* Set up the reply record for the publisher dialog. */ |
myreply.usePart = false; /* must be false */ |
myreply.previewFormat = kGenericPICTWord; /* type of data we're publishing */ |
myreply.preview = theData; /* handle to the pict data */ |
break; |
case kGenericTEXTWord: |
/* make text preview */ |
myreply.usePart = false; /* must be false */ |
myreply.previewFormat = kGenericTEXTWord; /* type of data we're publishing */ |
pubText = GetTextSection(shortName, stPublisher); |
HLock((Handle)pubText); |
theData = (*pubText)->additionalData; /* duplicate the text for our preview */ |
HandToHand(&theData); |
if (GetHandleSize(theData) > kMaxTextPreview) |
SetHandleSize(theData, kMaxTextPreview); |
myreply.preview = theData; |
break; |
case kCustomType: |
break; |
} |
GetLastEditionContainerUsed(&gEdSpec); /* get a new edition containter. */ |
/* this call gives us a duplicate of the last used, or if none used last, gives */ |
/* us a default container */ |
/* BY THE WAY - the 'last used' means the last used by the Edition Manager, not */ |
/* by your application, so if you don't specify a default name then the */ |
/* name that comes up as the default for the edition may be the last */ |
/* name used by another application, or from the last time your */ |
/* application was run. So if you are concerned about this (like you */ |
/* think it may confuse the user) set your own default */ |
/* As a sidelight (and not guarenteed) an alias to the last edition container used */ |
/* is stored in the 'Preferences' folder in the system folder */ |
myreply.container = gEdSpec; /* put our file spec in the container to be filled */ |
/* now set the default name to be the same as the window plus a count */ |
GetWTitle(FrontWindow(), &myreply.container.theFile.name); |
GetIndString(addPub, kGeneralStrings, kDotPub); |
AppendString(myreply.container.theFile.name, addPub); |
NumToString((long)((*shortName)->numPubs) + 1, addPub); |
AppendString(myreply.container.theFile.name, addPub); |
if(!fromEvent){ |
if (!gExpanded) |
myErr = NewPublisherDialog(&myreply); /* run the dialog */ |
else |
{ |
ExpDlgHookUPP dhUPP = NewExpDlgHookProc(ExpOptHook); |
ExpModalFilterUPP mfUPP = NewExpModalFilterProc(ExpOptFilter); |
myErr = NewPublisherExpDialog(&myreply, expPoint, kExpandedDITL, dhUPP, mfUPP, nil); |
DisposeRoutineDescriptor(dhUPP); |
DisposeRoutineDescriptor(mfUPP); |
} |
if (myErr) { |
ShowMe("\pPubisher dialog", myErr,__LINE__); |
return(myErr); |
} |
if (myreply.canceled) { /* they canceled. release memory, reset our */ |
/* menus and cursors, and go away */ |
switch (typeToMake) { |
case kGenericPICTWord: |
KillPicture((PicHandle)theData); |
InvalRect(&(*shortName)->selectionRect); |
gShowPub = false; |
(*shortName)->hasSelection = false; |
SetMyCursor(0); |
SwitchChecks(kSelectStuff); |
break; |
case kGenericTEXTWord: |
DisposeHandle((*pubText)->additionalData); |
DisposeHandle((Handle)pubText); |
DisposeHandle(theData); |
break; |
case kCustomType: |
break; |
} |
return(userCanceledErr); |
}} |
/* They clicked Publish. First create the container (file) to hold the data */ |
/* See if thye are replacing a file */ |
if (!myreply.replacing) { |
/* If we were given a spec by the event, the put that file in */ |
if(theSpec)myreply.container.theFile=*theSpec; |
if (myErr = CreateEditionContainerFile(&myreply.container.theFile, kMySignature, myreply.container.theFileScript)) { |
ShowMe("\pCreateEditionContainerFIle", myErr,__LINE__); |
return(myErr); |
} |
} else { |
/* they agreed to delete an existing file. Kill it. */ |
FSpDelete(&myreply.container.theFile); |
if (myErr = CreateEditionContainerFile(&myreply.container.theFile, kMySignature, myreply.container.theFileScript)) { |
ShowMe("\pCreateEditionContainerFIle", myErr,__LINE__); |
return(myErr); |
} |
} |
/* now create the section record to describe this data to the edition manager */ |
/* The section handle that is returned by this function will be the */ |
/* way that you will reference this edition for as long as the edition is */ |
/* active. */ |
/* The main way you'll keep track is through the section ID number. */ |
/* In this case, I have a base ID number for the window, and I just increment */ |
/* my general ID (gSectionID) every time I create an edition, and add it to the window ID. */ |
if (GetHandleSize((Handle)(*shortName)->fileAliasHandle) == 0) { |
myErr = NewSection(&myreply.container, nil, stPublisher, (*shortName)->windowID + gSectionID, pumOnSave, &gSecHandle); |
/* nil for sectionDocument if it's never been saved */ |
} else { |
/* if the file has been saved once, then we can store a reference to the 'parent' file */ |
/* in the edition */ |
myErr = ResolveAlias(nil, ((*shortName)->fileAliasHandle), &tempSpec, &myWasChanged); |
myErr = NewSection(&myreply.container, &tempSpec, stPublisher, (*shortName)->windowID + gSectionID, pumOnSave, |
&gSecHandle); |
theOwningDoc=&tempSpec; |
} |
if (!myErr) { |
/* put the section handle into our window structure */ |
(*gSecHandle)->refCon = kNeverSaved; /* meaning that this _document_ has not been saved */ |
/* put what type of thing this is in the refcon of the section handle */ |
switch (typeToMake) { |
/* This is a little kludgy because I want to */ |
case kGenericPICTWord: |
(*gSecHandle)->refCon = kPictType; |
break; |
case kGenericTEXTWord: |
(*gSecHandle)->refCon = kTextType; |
break; |
} |
StorePublisher(shortName, gSecHandle, &(*shortName)->selectionRect, pubText, typeToMake); |
/* now write the data to the container */ |
/* first make a spec from the saved alias, if there is one */ |
MyWriteSection(gSecHandle, theData, typeToMake,theOwningDoc); |
} else { |
/* error creating the section */ |
ShowMe("\p Couldn't create section", myErr,__LINE__); |
} |
HUnlock(theData); |
switch (typeToMake) { |
case kGenericPICTWord: |
KillPicture((PicHandle)theData); |
break; |
case kGenericTEXTWord: |
break; |
case kCustomType: |
break; |
} |
(*shortName)->hasSelection = false; |
InvalRect(&(*shortName)->selectionRect); /* get rid of border once publish has happened */ |
gShowPub = false; |
(*shortName)->hasSelection = false; |
SetMyCursor(0); |
SwitchChecks(kSelectStuff); |
HUnlock((Handle)shortName); |
} |
/* end CreatePublisher */ |
/* MyUpdateEdition publishes the latest data for this edition. This will |
* be called when the user selects 'Send Edition Now' from the options |
* dialog, or when the document is saved (if automatic saving is |
* enabled), or if a section write AppleEvent happens |
*/ |
OSErr MyUpdateEdition(SectionHandle theSection) |
{ |
WindowPtr tempWindow; |
Boolean tempSub, tempPub; |
Boolean wasChanged; |
windowCHandle shortName; |
SectionHandle *tempPtr; |
FSSpecPtr theOwningDoc=nil; |
FSSpec owner; |
register qq; |
Rect *tempRectPtr; |
extern Rect gShowPubRect; |
extern Rect gShowSubRect; |
WindowPtr owningWindow = FindSection(theSection); |
GetPort(&tempWindow); |
shortName = (windowCHandle)GetWRefCon(owningWindow); |
HLock((Handle)shortName); |
if(GetHandleSize((Handle)(*shortName)->fileAliasHandle)){ |
ResolveAlias(nil,(*shortName)->fileAliasHandle,&owner,&wasChanged); |
theOwningDoc=&owner; |
} |
if (((*theSection)->refCon & 0xf) == kPictType) { |
HLock((Handle)theSection); |
/* kill the borders, if any are showing right now */ |
tempSub = gShowSub; |
tempPub = gShowPub; |
if (gShowSub) |
InvalRect(&gShowSubRect); |
if (gShowPub) |
InvalRect(&gShowPubRect); |
gShowSub = gShowPub = false; |
SetPort(owningWindow); |
(ProcPtr)((*shortName)->drawMe)(shortName, owningWindow); /* draw without borders */ |
/* |
/* search this window for the section asked for */ |
HLock((*shortName)->pubs); |
tempPtr = (SectionHandle *)*(*shortName)->pubs; |
for (qq = 0; qq < (*shortName)->numPubs; qq++) { |
HLock((Handle)*tempPtr); |
if ((*theSection)->sectionID == (*(*tempPtr))->sectionID) { |
PicHandle tempPic; |
/* it's this one, grab the rect, pic it, publish it, and go away */ |
HLock((*shortName)->pubRects); |
tempRectPtr = (Rect *)*(*shortName)->pubRects; |
tempRectPtr += qq; |
tempPic = MyMakePicture(tempRectPtr); |
HUnlock((*shortName)->pubRects); |
MyWriteSection(*tempPtr, (Handle)tempPic, kGenericPICTWord,theOwningDoc); |
KillPicture(tempPic); |
HUnlock((Handle)*tempPtr); |
break; |
} |
} |
HUnlock((Handle)theSection); |
HUnlock((Handle)shortName); |
} else { |
mySectionDataHandle theTS = TextSectionFromSecHandle(theSection); |
/* it's a text pub */ |
MyWriteSection(theSection, (*theTS)->additionalData, kGenericTEXTWord,theOwningDoc); |
} |
InvalRect(&owningWindow->portRect); |
SetPort(tempWindow); |
return(noErr); |
} |
/* end MyUpdateEdition */ |
/* MyMakePicture is a handy place to create our PICT demo data item. |
* It's called to create the actual edition data as well as the 'preview' |
* picture. |
*/ |
PicHandle MyMakePicture(Rect *thisRect) |
{ |
PicHandle thepic; |
windowCHandle drawers; |
Boolean tempPub, tempSub; |
RgnHandle tempClip; |
/* make sure borders aren't included in the picture */ |
tempPub = gShowPub; |
tempSub = gShowSub; |
gShowPub = false; |
gShowSub = false; |
tempClip = NewRgn(); |
GetClip(tempClip); |
ClipRect(thisRect); |
thepic = OpenPicture(thisRect); |
drawers = (windowCHandle)GetWRefCon(FrontWindow() ); |
HLock((Handle)drawers); |
(ProcPtr)((*drawers)->drawMe)(drawers, FrontWindow() ); |
HUnlock((Handle)drawers); |
ClosePicture(); |
SetClip(tempClip); |
DisposeRgn(tempClip); |
/* restore old border states */ |
gShowPub = tempPub; |
gShowSub = tempSub; |
return(thepic); |
} |
/* end MyMakePicture */ |
/* AEWriteSectionHandler is the AppleEvent handler for section write |
* events. It first pulls the SectionHandle out of the AppleEvent record, |
* then verifies that this is a registered section (still active, not canceled) |
* and then calls MyUpdateEdition to write the edition |
*/ |
pascal OSErr AEWriteSectionHandler(AppleEvent *messagein, AppleEvent *reply, long refIn) |
{ |
#pragma unused (reply,refIn) |
SectionHandle theSection; |
OSErr myErr; |
myErr = GetSectionHandleFromEvent(messagein, &theSection); |
if (myErr = IsRegisteredSection((SectionHandle)theSection)) { |
ShowMe("\p Write IsRegisteredSection", myErr,__LINE__); |
return(myErr); |
} |
MyUpdateEdition(theSection); |
} |
/* end AEWriteSectionHandler */ |
/* ¥¥¥¥¥ REVISED! This event has been revised since it's initial release */ |
/* to reflect the final definition of this event, and the object that it accepts */ |
/* as a parameter */ |
/* ¥¥¥¥ NEW EVENT ¥¥¥¥ */ |
/* ¥¥ Please read the description and code in the Inside Mac vol VI chapters on */ |
/* the Edition Manager and APpleEvents for a full description */ |
/* AECreatePubHandler handles the new create publisher event */ |
pascal OSErr AECreatePubHandler(AppleEvent *messagein, AppleEvent *reply, long refIn) |
{ |
#pragma unused (reply,refIn) |
windowCHandle tempWC; |
OSErr myErr = noErr; |
Size returnedSize; |
long savedStart,savedEnd; |
Rect savedRect; |
DescType returnedType = typeNull; |
OSType theType; |
AEDesc returnedToken; |
AEDesc theObject; |
FSSpec theFSSpec; |
FSSpecPtr theFSS = nil; |
CTextObjHandle cTextBack; |
CWordObjHandle cWordBack; |
CShapeObjHandle cShapeback; |
WindowPtr containingWindow; |
WindowPtr oldFront=nil; |
theObject.descriptorType = typeNull; |
returnedToken.descriptorType = typeNull; |
oldFront = FrontWindow(); |
/* this event has two parameters, a object specifier and an alias handle. */ |
/* Both parameters are optional. */ |
/* if the object doesn't exsist, then we publish the current selection */ |
/* if the alias doesn't exsist, then we put up the options dialog */ |
AEGetParamDesc(messagein,keyDirectObject,typeObjectSpecifier,&theObject); |
/* the AEM has a built-in coercion from alias to FSSpec */ |
AEGetParamPtr(messagein,keyAEEditionFileLoc,typeAlias,&returnedType,(Ptr)&theFSSpec,sizeof(FSSpec),&returnedSize); |
if(typeFSS == returnedType) |
theFSS = &theFSSpec; |
/* checking for null instead of for an error |
because I don't care if either of these error out, I just care if they return a descriptor |
or not. Which I could do with two error variables, but you know.... */ |
/* Now resolve the object I got (if I got one) */ |
if(theObject.descriptorType != typeNull) |
myErr = AEResolve(&theObject, kAEIDoMinimum, &returnedToken); |
if(!myErr){ |
/* so the action, will be something like this, since I am but a lowly */ |
/* example program */ |
/* if the value returned from AEResolve is a graphic-type thing, I will put it's */ |
/* rectangle into the current selection, and call CreatePub. */ |
/* if it's a text thing, I will save the current selection, reset the selction, and */ |
/* call CreatePub. I'm typing this in as a comment because I don't know if I'll */ |
/* get it implemented within my release timeframe, but that is the idea. */ |
/* Also, because of the way I initially designed this program, the publisher must */ |
/* be the front window. Not a good idea, I will re-write that in a future release, */ |
/* but for now we live with it. */ |
switch(returnedToken.descriptorType){ |
/* get the owning window */ |
case cText: |
theType = kGenericTEXTWord; |
cTextBack = (CTextObjHandle)returnedToken.dataHandle; |
containingWindow=(*cTextBack)->theOwningWindow; |
tempWC = (windowCHandle)GetWRefCon(containingWindow); |
/* save off current */ |
savedStart = (*(*tempWC)->boxHandle)->selStart; |
savedEnd=(*(*tempWC)->boxHandle)->selEnd; |
/* and since they asked for the whole text, make the end equal the beginning */ |
(*(*tempWC)->boxHandle)->selEnd = (*(*tempWC)->boxHandle)->teLength; |
(*(*tempWC)->boxHandle)->selStart=0; |
/* and do the thing */ |
SelectWindow(containingWindow); |
myErr = CreatePublisher(theType,true,theFSS); |
/* restore */ |
(*(*tempWC)->boxHandle)->selStart = savedStart; |
(*(*tempWC)->boxHandle)->selEnd = savedEnd; |
break; |
case cWord: |
theType = kGenericTEXTWord; |
cWordBack = (CWordObjHandle)returnedToken.dataHandle; |
containingWindow=(*cWordBack)->theOwningWindow; |
tempWC = (windowCHandle)GetWRefCon(containingWindow); |
savedStart = (*(*tempWC)->boxHandle)->selStart; |
savedEnd=(*(*tempWC)->boxHandle)->selEnd; |
(*(*tempWC)->boxHandle)->selStart = (*cWordBack)->startPos; |
(*(*tempWC)->boxHandle)->selEnd = (*cWordBack)->endPos; |
/* do the thing */ |
SelectWindow(containingWindow); |
myErr = CreatePublisher(theType,true,theFSS); |
(*(*tempWC)->boxHandle)->selStart = savedStart; |
(*(*tempWC)->boxHandle)->selEnd = savedEnd; |
break; |
case cGraphicLine: |
case cRectangle: |
case cOval: |
theType = kGenericPICTWord; |
/* save the current selection rect if any */ |
cShapeback = (CShapeObjHandle)returnedToken.dataHandle; |
containingWindow=(*cShapeback)->theOwningWindow; |
tempWC = (windowCHandle)GetWRefCon(containingWindow); |
savedRect=(*tempWC)->selectionRect; |
(*tempWC)->selectionRect = (*(*cShapeback)->theShape)->theRect; |
SelectWindow(containingWindow); |
myErr = CreatePublisher(theType,true,theFSS); |
(*tempWC)->selectionRect = savedRect; |
break; |
default: |
myErr = errAEEventNotHandled; /* I don't know how to publish this object */ |
break; |
} |
} else { |
/* Here, there was an object, but I couldn't understand it. That is an _error_ */ |
/* condition, which is different from no object being available */ |
myErr= errAENoSuchObject; |
} |
/* if there was an old front window, make it frontmost agin */ |
if(oldFront)ChangePlane(oldFront); |
return(myErr); |
} |
/* end AECreatePubHandler */ |
/* AEScrollSectionHandler handles the scroll section event. You'll get this |
* event when the user clicks 'Open Publisher' either from the |
* Subcriber Options dialog, or from the Finder window. |
* This may also have happened after an ODOC AppleEvent, so |
* don't assume anything about your state that wouldn't be true |
* after an initial application launch |
*/ |
pascal OSErr AEScrollSectionHandler(AppleEvent *messagein, AppleEvent *reply, long refIn) |
{ |
#pragma unused (reply,refIn) |
WindowPtr tempWindow; |
SectionHandle theSection; |
OSErr myErr; |
myErr = GetSectionHandleFromEvent(messagein, &theSection); |
tempWindow = FindSection(theSection); |
/* First bring our application to the front, then */ |
/* treat this the same way you would a click in a back window */ |
myErr=AEInteractWithUser(kAEDefaultTimeout,nil, gCommonIdleFunctionUPP); |
if(!myErr)SetFrontProcess(&gOurSN); |
else ShowMe("\ptheEr",myErr,__LINE__); |
if (tempWindow != nil) |
ChangePlane(tempWindow); |
return(noErr); |
} |
/* end AEScrollSectionHandler */ |
/* AECancelSectionHandler cancels a current section, either a publisher |
* or subscriber. This function pulls the section handle out of the |
* AppleEvent, then dispatches to the proper cancel routine for a |
* pub or sub. |
*/ |
pascal OSErr AECancelSectionHandler(AppleEvent *messagein, AppleEvent *reply, long refIn) |
{ |
#pragma unused (reply,refIn) |
SectionHandle theSection; |
OSErr myErr; |
myErr = GetSectionHandleFromEvent(messagein, &theSection); |
myErr = IsRegisteredSection(theSection); |
if (myErr != noErr) |
return(myErr); /* already killed by someone */ |
MyCancelSection(theSection, FindSection(theSection)); |
} |
/* end AECancelSectionHandler */ |
/* MyWriteSection actually opens and writes the section data. This will |
* be called in response to a click in 'Send Edition Now' in the pub options |
* box, from the section event 'write section', or when the file is being saved |
* and 'pumAuto' is enabled |
*/ |
OSErr MyWriteSection(SectionHandle secHandle, Handle theData, OSType theType,FSSpecPtr inSpec) |
{ |
OSErr myErr; |
/* update the time in the section handle please */ |
/* this tells the Edition Manager that the eidtion has changed, and */ |
/* to alert all the subscribers to the change */ |
SpinCursor(); |
HLock((Handle)secHandle); |
GetDateTime(&(*secHandle)->mdDate); /* ¥¥¥ Please see NOTE in main.c about mdDate (find mdDate) */ |
HUnlock((Handle)secHandle); |
/* OpenNewEdition, _NOT_ OpenEdition. You need to use OpenNewEdition */ |
/* to get write access and to let the Edition Manager determine if you */ |
/* are allowed to write to this section */ |
myErr = OpenNewEdition(secHandle, kMySignature,inSpec, &gEdRefNum); |
if (myErr) |
ShowMe("\pOpenNewEdition", myErr,__LINE__); |
HLock(theData); |
/* And actually write the data (finally) */ |
SpinCursor(); |
myErr = WriteEdition(gEdRefNum, theType, *theData, GetHandleSize(theData)); |
if (myErr) |
ShowMe("\pWriteEdition", myErr,__LINE__); |
if (myErr) |
myErr = 0; |
else |
myErr = -1; |
/* The Boolean tells the Edition Manager if you were successful in */ |
/* writing the data. */ |
myErr = CloseEdition(gEdRefNum, (Boolean)myErr); |
if(myErr)ShowMe("\pCloseEdition", myErr,__LINE__); |
return(myErr); |
} |
/* end MyWriteSection */ |
/* StorePublisher moves the window data struct storing function to here */ |
/* shortName is locked on entry */ |
void StorePublisher(windowCHandle shortName, SectionHandle storeSection, Rect *inRect, mySectionDataHandle textIn, OSType typeIn) |
{ |
Rect *tempRectPtr; |
SectionHandle *tempPtr; |
OSErr myErr; |
switch (typeIn) { |
case kGenericPICTWord: |
HUnlock((*shortName)->pubs); |
MySetHandleSize((*shortName)->pubs, GetHandleSize((*shortName)->pubs) + sizeof(Handle)); |
myErr = MemError(); |
if (myErr) |
ShowMe("\pMemory", myErr,__LINE__); |
HLock((*shortName)->pubs); |
tempPtr = (SectionHandle *)((*(*shortName)->pubs) + (sizeof(Handle) * ((*shortName)->numPubs))); |
*tempPtr = (SectionHandle)storeSection; |
/* ¥¥¥¥ NOTE, please look at the note in the Subscribe.c file concerning the dirty flag and */ |
/* editions. Open Subscribe.c and find the string 'Human Interface' */ |
/* (*shortName)->windowDirty = true; */ |
/* save the rectangle to show the published rectangle if the user wants to see it. */ |
HUnlock((*shortName)->pubRects); |
MySetHandleSize((*shortName)->pubRects, (GetHandleSize((*shortName)->pubRects) + sizeof(Rect))); |
myErr = MemError(); |
if (myErr) |
ShowMe("\pMemory", myErr,__LINE__); |
HLock((*shortName)->pubRects); |
tempRectPtr = (Rect *)*(*shortName)->pubRects; |
tempRectPtr += (*shortName)->numPubs; |
*tempRectPtr = *inRect; |
(*shortName)->numPubs++; |
HUnlock((*shortName)->pubRects); |
HUnlock((*shortName)->pubs); |
break; |
case kGenericTEXTWord: |
/* set my text section ID to the same as the actual section ID, again, it keeps */ |
/* dereferencing down */ |
(*textIn)->theID = (*storeSection)->sectionID; |
/* tell myself that this is a publisher */ |
(*textIn)->publishing = true; |
if ((*shortName)->textSections == nil) { |
(*shortName)->textSections = textIn; |
} else { |
mySectionDataHandle tempTS = (*shortName)->textSections; |
while ((*tempTS)->nextSection != nil) { |
tempTS = (*tempTS)->nextSection; |
} |
(*tempTS)->nextSection = textIn; |
} |
(*textIn)->theSection = storeSection; |
break; |
} |
gSectionID++; |
} |
/* Find Section returns the window that this section is included in */ |
/* Need to look in both the PICT and TEXT lists */ |
WindowPtr FindSection(SectionHandle inSection) |
{ |
long subIDtofind; |
Boolean secFound = false; |
SectionHandle *tempPtr; |
SectionRecord *tempRecord; |
Handle tempHandle; |
WindowPtr tempNextWindow; |
register jj; |
subIDtofind = (*inSection)->sectionID; |
tempNextWindow = (WindowPtr)LMGetWindowList(); /* start at the beginning of the chain */ |
while(tempNextWindow){ |
if (((WindowPeek)tempNextWindow)->windowKind == kDocumentWindow){ /* the clipboard is not publishing */ |
windowCHandle tempWC; |
/* do housekeeping to get to the section handle list */ |
tempWC = (windowCHandle)GetWRefCon(tempNextWindow); |
HLock((Handle)tempWC); |
if (((*inSection)->refCon & 0xf) == kPictType) { |
tempHandle = (*tempWC)->pubs; /* handle containing SectionHandles */ |
HLock(tempHandle); |
tempPtr = (SectionHandle *)*tempHandle; |
/* Loop through all our sections until we find this edition */ |
for (jj = 0; jj < (*tempWC)->numPubs; jj++) { |
HLock((Handle)*tempPtr); |
tempRecord = *(*tempPtr); |
if (tempRecord->sectionID == subIDtofind) { |
HUnlock((Handle)*tempPtr); |
HUnlock((Handle)tempWC); |
return(tempNextWindow); |
} else { |
HUnlock((Handle)tempWC); |
HUnlock((Handle)*tempPtr); |
tempPtr += 1; |
} |
} |
HUnlock(tempHandle); |
/* same thing for subscribers */ |
tempHandle = (*tempWC)->subs; /* handle containing SectionHandles */ |
HLock(tempHandle); |
tempPtr = (SectionHandle *)*tempHandle; |
/* Loop through all our sections until we find this edition */ |
for (jj = 0; jj < (*tempWC)->numSubs; jj++) { |
HLock((Handle)*tempPtr); |
tempRecord = *(*tempPtr); |
if (tempRecord->sectionID == subIDtofind) { |
HUnlock((Handle)*tempPtr); |
HUnlock((Handle)tempWC); |
return(tempNextWindow); |
} else { |
HUnlock((Handle)tempWC); |
HUnlock((Handle)*tempPtr); |
tempPtr += 1; |
} |
} |
HUnlock(tempHandle); |
} else { |
/* Look in the TEXT lists */ |
if ((*tempWC)->textSections) { |
mySectionDataHandle tempTS = (*tempWC)->textSections; |
do { |
if ((*((*tempTS)->theSection))->sectionID == subIDtofind) { |
HUnlock((Handle)tempWC); |
return(tempNextWindow); |
} |
tempTS = (*tempTS)->nextSection; |
} while (tempTS); |
} |
} |
tempNextWindow = (WindowPtr)((WindowPeek)tempNextWindow)->nextWindow; |
HUnlock((Handle)tempWC); |
} /* if document */ |
tempNextWindow = (WindowPtr) ((WindowPeek)tempNextWindow)->nextWindow; |
} /* while windows */ |
return(nil); |
} |
pascal short ExpOptHook(short itemOffset, short itemHit, DialogPtr theDialog, Ptr yourDataPtr) |
{ |
#pragma unused (yourDataPtr) |
short myHit; |
short itemType; |
ControlHandle theButton; |
Rect theRect; |
/* first make sure that a sub-dialog is not frontmost */ |
/* so we don't filter keys or hits to a sub-dialog */ |
if (GetWRefCon((WindowPtr)theDialog) == sfMainDialogRefCon || GetWRefCon((WindowPtr)theDialog) == emOptionsDialogRefCon) { |
/* only have one item in this expansion, but we'll check the range anyway */ |
myHit = itemHit - itemOffset; /* since our item numbers are relative to the total number */ |
/* of items in the dialog, and the system may change. Always do your item numbering based */ |
/* on the offset, this will prevent incompatability when the system dialog grows or shrinks */ |
if (myHit == 1) { /* I only added one item, so this be the one */ |
/* Pass itemHit here, not myHit, since the dialog manager has no idea that this is an */ |
/* additive dialog. It is counting from the actual start of the DITL, not the start of */ |
/* your custom items */ |
GetDialogItem(theDialog, itemHit, &itemType, (Handle *)&theButton, &theRect); |
if (GetControlValue(theButton)) |
SetControlValue(theButton, false); |
else |
SetControlValue(theButton, true); |
} |
} |
return(itemHit); /* the return value must be absolute */ |
} |
pascal Boolean ExpOptFilter(DialogPtr theDialog, EventRecord *theEvent, short itemOffset, short *itemHit, Ptr yourDataPtr) |
{ |
#pragma unused (itemHit,yourDataPtr) |
short itemType; |
ControlHandle theButton; |
Rect theRect; |
/* first make sure that a sub-dialog is not frontmost */ |
/* so we don't filter keys or hits to a sub-dialog */ |
if (GetWRefCon((WindowPtr)theDialog) == sfMainDialogRefCon || GetWRefCon((WindowPtr)theDialog) == emOptionsDialogRefCon) { |
/* standard filter proc kinda stuff here */ |
if ((theEvent->what) == keyDown) { |
char tempChar; |
tempChar = theEvent->message & charCodeMask; |
if (((tempChar == 'A') || (tempChar == 'a')) && (theEvent->modifiers & cmdKey)) { |
/* they pressed an A with the command key down, we get to handle it. */ |
GetDialogItem(theDialog, itemOffset + 1, &itemType, (Handle *)&theButton, &theRect); |
if (GetControlValue(theButton)) |
SetControlValue(theButton, false); |
else |
SetControlValue(theButton, true); |
return(true); /* tell folks we handled it */ |
} |
} |
} |
return(false); /* was not a keystroke we wanted */ |
} |
/* shortName is locked on entry */ |
mySectionDataHandle GetTextSection(windowCHandle shortName, SectionType what) |
{ |
CharsHandle theRawText; |
TEHandle tempTE; |
mySectionDataHandle theTextSection; |
Handle theSelection; |
theTextSection = (mySectionDataHandle)NewHandle(sizeof(mySectionData)); |
HLock((Handle)theTextSection); |
(*theTextSection)->bordered = gShowingAll; /* create section reflecting current */ |
/* global border state */ |
tempTE = (*shortName)->boxHandle; |
(*theTextSection)->startChar = (*tempTE)->selStart; |
if (what == stPublisher) { |
/* initialize it if it's a publisher */ |
(*theTextSection)->endChar = (*tempTE)->selEnd; |
theRawText = TEGetText(tempTE); |
theSelection = NewHandle(((*tempTE)->selEnd) - ((*tempTE)->selStart)); |
HLock(theSelection); |
HLock((Handle)theRawText); |
BlockMove((Ptr)*theRawText + (*tempTE)->selStart, (Ptr)*theSelection, (*tempTE)->selEnd - (*tempTE)->selStart); |
HUnlock(theSelection); |
HUnlock((Handle)theRawText); |
(*theTextSection)->additionalData = theSelection; |
} else { |
/* set start same as end for subscribers */ |
(*theTextSection)->endChar = (*tempTE)->selStart; |
(*theTextSection)->additionalData = NewHandle(0); |
} |
(*theTextSection)->nextSection = nil; |
return(theTextSection); |
} |
mySectionDataHandle TextSectionFromSecHandle(SectionHandle theSection) |
{ |
windowCHandle tempWC = (windowCHandle)GetWRefCon(FindSection(theSection)); /* gets the window it's in */ |
mySectionDataHandle tempTS = (*tempWC)->textSections; |
unsigned long idToFind; |
idToFind = (*theSection)->sectionID; |
/* find the ID that matches this thang */ |
do { |
if ((*tempTS)->theID == idToFind) |
return(tempTS); |
tempTS = (*tempTS)->nextSection; |
} while (tempTS); |
return(nil); /* failed */ |
} |
/* In SearchPubs we'll search the publishers in this window for a publisher */ |
/* that was clicked in. If we find one, hilite it and outline it. */ |
/* Point is already in local coordinates */ |
Boolean SearchPubs(Point thePoint) |
{ |
register qq; |
Rect rectToCheck; |
Rect cornerRect; |
Rect *theRects; |
Str63 pubString; |
Boolean gotIt = false; |
windowCHandle shortname = (windowCHandle)GetWRefCon(FrontWindow()); |
HLock((Handle)shortname); |
if ((*shortname)->numPubs) { /* does this window have any publishers? */ |
/* yes, see if one was clicked in */ |
HLock((*shortname)->pubRects); /* lock the rect handle down */ |
theRects = (Rect *)*(*shortname)->pubRects; |
/* dereference it and cast it to a rect pointer so checking will be |
* conceptually easier (i.e. you can read it) |
*/ |
for (qq = 0; qq < (*shortname)->numPubs; qq++) { /* step through 'em */ |
SectionHandle *tempPtr; |
rectToCheck = *theRects; |
if (PtInRect(thePoint, &rectToCheck)) { /* thePoint is coming from your */ |
/* last event record */ |
/* We've found a section that has been clicked in */ |
if (gShowPub && (rectToCheck != gShowPubRect)) |
InvalRect(&gShowPubRect); /* clear previous, if there was one */ |
gShowPub = true; |
if (gShowSub) {/* clear previous, if there was one */ |
InsetRect(&gShowSubRect, -4, -4); |
InvalRect(&gShowSubRect); |
InsetRect(&gShowSubRect, 4, 4); |
gShowSub = false; |
} |
/* make sure the border gets draw next update */ |
InsetRect(&rectToCheck,-4,-4); |
InvalRect(&rectToCheck); |
InsetRect(&rectToCheck,4,4); |
/* we've found it with it's rectangle, so now dig out the */ |
/* section handle */ |
HLock((*shortname)->pubs); |
tempPtr = (SectionHandle *)*(*shortname)->pubs; |
tempPtr += qq; |
/* and move the section handle into our global variable that */ |
/* contains the currently highlighted section, so we can */ |
/* access it from the Options function and dialog */ |
gShowingSecHandle = *tempPtr; |
/* done with the pointer handle */ |
HUnlock((*shortname)->pubs); |
/* change the menu item name now */ |
GetIndString(pubString, kGeneralStrings, kPubOptString); |
SetMenuItemText(gEditMenuHandle, kSoptionsItem,pubString); |
gShowPubRect = rectToCheck; |
gotIt = true; |
/* Now we need to stretch the thing if the user wants too */ |
/* See if it was in the corner rect first */ |
cornerRect = gShowPubRect; |
cornerRect.top = cornerRect.bottom - 7; |
cornerRect.left = cornerRect.right - 7; |
if (PtInRect(thePoint, &cornerRect)) { |
PullRect(shortname, &gShowPubRect, false, true,true); |
if (*theRects != gShowPubRect) { |
*theRects = gShowPubRect; |
InvalRect(theRects); |
} |
} |
} |
if (gotIt) |
break; |
theRects++; /* increase by one Rect */ |
} |
HUnlock((*shortname)->pubRects); |
} |
HUnlock((Handle)shortname); |
return(gotIt); |
} |
/* end SearchPubs */ |
#undef __PUBLISH__ |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14