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;
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.