This is eTLink.m in view mode; [Download] [Up]
/////////////////////////////////////////////////////////////////////////////// // FILENAME: eTLink.m // SUMMARY: Implementation of link buttons in eText documents // SUPERCLASS: Object:eTImage // INTERFACE: None // PROTOCOLS: <Annotation,HTMDSupport,ASCIISupport,LaTeXSupport,Tool, // InspectableTarget> // AUTHOR: Rohit Khare // COPYRIGHT: (c) 1994 California Institure of Technology, eText Project /////////////////////////////////////////////////////////////////////////////// // DESCRIPTION // Does its job by holding doc/anchorIDs and yelling at NXApp. /////////////////////////////////////////////////////////////////////////////// // HISTORY // 10/30/94: Modified to support <InspectableTarget> // 07/21/94: Revamped for PR1 and eTImage[Component] support // 07/09/94: URLRep added by RK and TRZ (Removed 7/21) // 07/07/94: Rewritten as subclass of imageAnnotation // 07/03/94: Added eTLinkUI integration for image-links. // 06/17/94: HTMDSupport added. RK and TRZ // 02/04/94: Created. First actual implementation. /////////////////////////////////////////////////////////////////////////////// #import "eTLink.h" #define _eTLinkVERSION 10 @implementation eTLink // long anchorID; // long docID; // etfLink theLink; // NXAtom URLRep; + toolAwake:theApp { [theApp registerAnnotation: [eTLink class] name: "eTLink" RTFDirective: "eTLink" menuLabel: NULL menuKey: '\0' menuIcon: (NXImage *) nil]; [theApp registerType:NXCreateFileContentsPboardType("etfd") for:[eTLink class]]; [theApp registerType:NXCreateFileContentsPboardType("etfLink") for:[eTLink class]]; return self; } - init { [super init]; docID = anchorID = 0; theLink.docID = theLink.anchorID = theLink.docTitle = theLink.anchorTitle = NXUniqueString(""); [self setImageComponent:[eTImageComponent newImageNamed:"NXLinkButton"]]; [self setAltImageComponent:[eTImageComponent newImageNamed:"NXLinkButtonH"]]; [self setDraggable:YES]; return self; } - free { return self = [super free]; } - setImageComponent:newImageComponent { const char *name; name = [[newImageComponent theImage] name]; if (name && !strcmp(name,"NXLinkButton")) usesButtonStyle = NO; else usesButtonStyle = YES; return [super setImageComponent:newImageComponent]; } - initFromPboard:thePB inDoc:theDoc linked:(BOOL) linked { NXAtom types[5]; char *data; int len; [super initFromPboard:thePB inDoc:theDoc linked: linked]; [self init]; types[0] = NXCreateFileContentsPboardType("etfLink"); types[1] = NXCreateFileContentsPboardType("etfd"); types[2] = NXCreateFileContentsPboardType(ANY_TYPE); types[3] = NXFilenamePboardType; types[4] = [thePB findAvailableTypeFrom:types num:4]; if (!types[4]) return self; if (types[4]) { [thePB readType:NXFilenamePboardType data:&data length:&len]; if (index(data,'\t')) *(index(data,'\t'))=0; [self initFromFile:data]; [thePB deallocatePasteboardData:data length:len]; } else { NXLogError("%s got fcontents without fnamepboard! %s instead.", [[self class] name], types[4]); } return self; } - initFromFile: (const char *) theFile { id theTable; [self init]; if (!strcmp("etfLink", rindex(theFile, '.')+1)) { theTable = [[NXStringTable alloc] init]; if ([theTable readFromFile:theFile]) { sscanf([theTable valueForStringKey:DOCID], "%x", &docID); sscanf([theTable valueForStringKey:ANCHORID], "%x", &anchorID); theLink.docID = NXUniqueString([theTable valueForStringKey:DOCID]); theLink.anchorID = NXUniqueString([theTable valueForStringKey:ANCHORID]); theLink.docTitle = NXUniqueString([theTable valueForStringKey:DOCTITLE]); theLink.anchorTitle = NXUniqueString([theTable valueForStringKey:ANCHORTITLE]); } theTable = [[theTable empty] free]; // free even if read from file failed } else if (!strcmp(ETFD_EXT, rindex(theFile, '.')+1)) { // find a docID for this file, stash it away theTable = [[[eTDocInfo alloc] init] readComponentFromPath:theFile]; if (theTable){ docID = [theTable docID]; anchorID = 0; theLink.docID = NXUniqueString([theTable docIDStr]); theLink.anchorID = NXUniqueString("0"); theLink.anchorTitle = theLink.docTitle = NXUniqueString([theTable title]); theTable = [theTable free]; } } else { NXLogError("eTLink asked to init from:%s; cannot.", theFile); } return self; } - readRichText:(NXStream *)stream forView:view { int i; char buf[MAXPATHLEN]; NXScanf(stream, "%d ", &i); if (i != _eTLinkVERSION) { // bad version block. NXLogError("eTLink found unparseable version %d at position %d", i, NXTell(stream)); return nil; } NXScanf(stream, "%s ", buf); theLink.docID = NXUniqueString(buf); sscanf(theLink.docID, "%x", &docID); NXScanf(stream, "%s", buf); theLink.anchorID = NXUniqueString(buf); sscanf(theLink.anchorID, "%x", &anchorID); NXScanf(stream, "%d", &i); NXGetc(stream); //space-eater if (i) NXRead(stream, buf, i); buf[i] = 0; theLink.docTitle = NXUniqueString(buf); NXScanf(stream, "%d", &i); NXGetc(stream); //space-eater if (i) NXRead(stream, buf, i); buf[i] = 0; theLink.anchorTitle = NXUniqueString(buf); NXGetc(stream); // extra space char. [super readRichText:stream forView:view]; return self; } - writeRichText:(NXStream *)stream forView:view { id dI=nil; // maintain docID-docTitle consistency dI = [eTDocInfo findDocInfo:docID]; if (dI) theLink.docTitle= NXUniqueString([dI docTitle]); NXPrintf(stream, "%d %s %s %d %s %d %s ", _eTLinkVERSION, theLink.docID, theLink.anchorID, strlen(theLink.docTitle), theLink.docTitle, strlen(theLink.anchorTitle), theLink.anchorTitle); [super writeRichText:stream forView:view]; return self; } - writeASCIIRef:(NXStream *)stream forView:view { if(*theLink.docID) { if(theLink.anchorID && anchorID) NXPrintf(stream, "See %y in %y [%s in %s]\n\t", theLink.anchorTitle, theLink.docTitle, theLink.anchorID, theLink.docID); else NXPrintf(stream, "See %y [%s]\n\t", theLink.docTitle, theLink.docID); } [super writeASCIIRef:stream forView:view]; return self; } - writeLaTeX:(NXStream*)stream forView:view { [super writeLaTeX:stream forView:view]; if(*theLink.docID) { if(theLink.anchorID && anchorID) NXPrintf(stream, "\n\\footnote{See %w in %w [%w in %w]}\n", theLink.anchorTitle, theLink.docTitle, theLink.anchorID, theLink.docID); else NXPrintf(stream, "\n\\footnote{See %w [%w]}\n", theLink.docTitle, theLink.docID); } return self; } - writeHTML:(NXStream *)stream forView:view { char tmp[MAXPATHLEN]; id theDocInfo = [eTDocInfo findDocInfo:docID]; if(!theDocInfo) return self; if(*theLink.docID) { strcpy(tmp, [theDocInfo docPath]); *rindex(tmp,'.')=0; NXPrintf(stream,"<A HREF=\"../%V."HTMD_EXT"/"HTML_INDEX,rindex(tmp,'/')+1); if(anchorID) NXPrintf(stream,"#%s", theLink.anchorID); NXPrintf(stream, "\">"); // if (theLink.anchorTitle && *theLink.anchorTitle) { // NXPrintf(stream,"\"><%v>", theLink.anchorTitle); [super writeHTML:stream forView:view]; NXPrintf(stream,"</A>"); // } // else // NXPrintf(stream,"\"><Click Here></A>"); } return self; } #define NXLINK "NXLinkButton" #define NXLINK_GIF NXLINK".gif" - writeComponentToPath:(NXAtom)path inFormat:(int) theFormat { const char *name; if(!etDoc) NXLogError("etDoc is nil at %s %u",__FILE__,__LINE__); name = [[imageComponent theImage] name]; if ((theFormat == HTMD_FMT) && name && !strcmp(name,NXLINK)) { char cmd[2*MAXPATHLEN]; sprintf(cmd,"%s/"NXLINK_GIF, [[NXBundle mainBundle] directory]); if (!access(cmd, F_OK|R_OK)) { sprintf(cmd,"cp -rp \"%s/"NXLINK_GIF"\" \"%s/"NXLINK_GIF"\"", [[NXBundle mainBundle] directory], path); system(cmd); [etDoc registerComponent:NXLINK_GIF]; } else { [super writeComponentToPath:path inFormat:theFormat]; } } else [super writeComponentToPath:path inFormat:theFormat]; return self; } - doubleClick2:sender { if (docID && [eTDocInfo findDocInfo:docID]) { [[NXApp etApp] openID:docID]; [[[objc_lookUpClass("eTBookmarkBinder") new] bookmarkForID:anchorID] highlight:sender]; } else { NXRunAlertPanel("eTLink", "Could not locate docID %x","OK", NULL, NULL,docID); } return self; } - doubleClick:(NXEvent *) e { [self perform:@selector(doubleClick2:) with:self afterDelay:0 cancelPrevious:YES]; return self; } - inspect:(NXEvent *) e { [[NXApp inspector] inspect:self]; return self; } - (id <Inspectable>) inspectableDelegate { return [[eTLinkUI new] setAnnotation:self]; } - (NXAtom)anchorTitle {return ((theLink.anchorTitle) ? theLink.anchorTitle : "");} - (NXAtom)anchorID {return ((theLink.anchorID) ? theLink.anchorID : "");} - (NXAtom)docTitle {return ((theLink.docTitle) ? theLink.docTitle : "");} - (NXAtom)docID {return ((theLink.docID) ? theLink.docID : "");} - drag: (Pasteboard *)draggingPboard image:(NXImage **)proxyImage { id theTable; char filename[MAXPATHLEN]; theTable = [[NXStringTable alloc] init]; [theTable insertKey:DOCID value: NXCopyStringBuffer(theLink.docID)]; [theTable insertKey:ANCHORID value: NXCopyStringBuffer(theLink.anchorID)]; [theTable insertKey:DOCTITLE value: NXCopyStringBuffer(theLink.docTitle)]; [theTable insertKey:ANCHORTITLE value: NXCopyStringBuffer(theLink.anchorTitle)]; sprintf(filename, "/tmp/%s.etfLink", theLink.anchorTitle); [theTable writeToFile:filename]; theTable = [[theTable empty] free]; [draggingPboard declareTypes:&NXFilenamePboardType num:1 owner:nil]; [draggingPboard writeType: NXFilenamePboardType data: filename length: strlen(filename)]; *proxyImage = [[eTImageComponent newImageNamed:"NXLinkButton"] theImage]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.