This is SourceDoc.m in view mode; [Download] [Up]
// SourceDoc.m
//
// Free software created 1 Feb 1992
// by Paul Burchard <burchard@math.utah.edu>.
#import "Wais.h"
#import "WAISControl.h"
#import "SourceDoc.h"
#import "BrowserAssocTable.h"
#import "IconWellControl.h"
#import "IconWell.h"
#import "MailSpeaker.h"
#import "string.h"
#import <appkit/appkit.h>
@implementation SourceDoc
+ (const char *)fileType
{
return "src";
}
+ (const char *)nibName
{
return "SourceDoc.nib";
}
+ (const char *)miniIconName
{
return "WaisSource.tiff";
}
+ (const char *)defaultFolder
{
return [[WaisSource folderList] elementAt:0];
}
- updateFromWindow
{
static char buf[READ_BUF_SIZE];
[waisSource insertStringKey:":ip-name" value:[serverField stringValue]];
[waisSource insertStringKey:":tcp-port" value:[serviceField stringValue]];
[waisSource insertStringKey:":database-name"
value:[databaseField stringValue]];
[waisSource insertStringKey:":cost" value:[costField stringValue]];
[waisSource insertStringKey:":cost-unit" value:[unitsField stringValue]];
[waisSource insertStringKey:":maintainer"
value:[maintainerField stringValue]];
[[descriptionField docView] getSubstring:buf start:0 length:READ_BUF_SIZE];
[waisSource insertStringKey:":description" value:buf];
return self;
}
- updateToWindow
{
if([waisSource valueForStringKey:":ip-name"])
[serverField setStringValue:[waisSource valueForStringKey:":ip-name"]];
else if([waisSource valueForStringKey:":ip-address"])
[serverField setStringValue:[waisSource
valueForStringKey:":ip-address"]];
else [serverField setStringValue:""];
if([waisSource valueForStringKey:":tcp-port"])
[serviceField setStringValue:[waisSource
valueForStringKey:":tcp-port"]];
else [serviceField setStringValue:""];
if([waisSource valueForStringKey:":database-name"])
[databaseField setStringValue:[waisSource
valueForStringKey:":database-name"]];
else [databaseField setStringValue:""];
if([waisSource valueForStringKey:":cost"])
[costField setStringValue:[waisSource valueForStringKey:":cost"]];
else [costField setStringValue:""];
if([waisSource valueForStringKey:":cost-unit"])
[unitsField setStringValue:[waisSource
valueForStringKey:":cost-unit"]];
else [unitsField setStringValue:""];
if([waisSource valueForStringKey:":maintainer"])
[maintainerField setStringValue:[waisSource
valueForStringKey:":maintainer"]];
else [maintainerField setStringValue:""];
if([waisSource valueForStringKey:":description"])
[[descriptionField docView] setText:[waisSource
valueForStringKey:":description"]];
else [[descriptionField docView] setText:""];
return self;
}
- init
{
[super init];
waisSource = [[WaisSource alloc] initKey:NULL];
[waisSource insertStringKey:":tcp-port" value:"210"];
[waisSource insertStringKey:":maintainer" value:current_user_name()];
[waisSource insertStringKey:":cost" value:"0"];
[waisSource insertStringKey:":cost-unit" value:":free"];
[[descriptionField docView] setDelegate:self];
isPublic = NO;
[self updateToWindow];
return self;
}
- free
{
[waisSource free];
[indexIWC free];
[indexPanel free];
return [super free];
}
- dump:sender
{
if(!fileName) return nil;
[self updateFromWindow];
if(![waisSource writeWaisFile]) return nil;
return self;
}
- load:sender
{
if(!fileName) return nil;
if(![waisSource readWaisFile]) return nil;
[self updateToWindow];
return self;
}
- setFileName:(const char *)aName
{
id rtn = [super setFileName:aName];
if(rtn) [waisSource setKey:fileName];
return(rtn);
}
- (int)openFile:(const char *)name ok:(int *)flag
{
return [[NXApp delegate] openFile:name ok:flag];
}
- bugReport:sender
{
//!!! Note the "MailSendDemo" port is undocumented.
id mailSpeaker = [[MailSpeaker alloc] init];
port_t mailPort = NXPortFromName("MailSendDemo", NULL);
const char *maint;
maint = [waisSource valueForStringKey:":maintainer"];
if(!maint || !maint[0]) return nil;
if(!mailSpeaker || mailPort==PORT_NULL)
{ [mailSpeaker free]; return nil; }
[mailSpeaker setSendPort:mailPort];
[mailSpeaker openSend];
[mailSpeaker setTo:maint];
if([waisSource valueForStringKey:":database-name"])
[mailSpeaker setSubject:[waisSource
valueForStringKey:":database-name"]];
[mailSpeaker free];
port_deallocate(task_self(), mailPort);
return self;
}
- indexPanel:sender
{
int i, j, n, choice;
id data, stringTable;
const char *maint, *user;
// Just pop up panel if it already exists.
if(indexPanel)
{ [indexPanel makeKeyAndOrderFront:self]; return indexPanel; }
// Allow user to cancel if overwriting someone else's source.
maint = [waisSource valueForStringKey:":maintainer"];
user = current_user_name();
stringTable = [[NXApp delegate] stringTable];
if(maint && user && strcmp(maint, user)!=0)
{
if(stringTable) choice = NXRunAlertPanel(
[stringTable valueForStringKey:"Warning!"],
[stringTable valueForStringKey:"This database is maintained by %s. Are you sure you want to overwrite it?"],
[stringTable valueForStringKey:"Yes"],
[stringTable valueForStringKey:"Cancel"], NULL, maint);
else
{
fprintf(stderr,
"Warning! Overwriting WAIS source maintained by %s\n", maint);
fflush(stderr);
choice = NX_ALERTDEFAULT;
}
if(choice != NX_ALERTDEFAULT) return nil;
}
// Make user save new source first.
if(!fileName)
{
if(![[NXApp delegate] saveDoc:self as:YES]) return nil;
if(!fileName) return nil;
}
{//!!!
char *extn;
char hostname[1024];
//!!! messing with uniqued strings
if(!(extn = strrchr(fileName, '/'))) extn = fileName;
if(!(extn = strrchr(extn, '.'))) return nil;
if(strcmp(extn+1, [[self class] fileType]) != 0) return nil;
*extn = 0;
[waisSource insertStringKey:":database-name" value:fileName];
*extn = '.';
gethostname(hostname, 1024);
[waisSource insertStringKey:":ip-name" value:hostname];
if(![waisSource writeWaisFile]) return nil;
[self updateToWindow];
}
// Otherwise, load NIB and indexing information.
[NXApp loadNibSection:"Indexer.nib" owner:self];
[indexInputWell setDraggable:YES droppable:YES];
[indexScriptWell setDraggable:YES droppable:NO];
[[[indexFiles setEditable:YES] setAlphabetized:NO] setAbbreviated:NO];
[indexFiles setTarget:self];
[[indexFiles setAction:@selector(updateSelection:)]
setDoubleAction:@selector(updateSelection:)];
n = [[waisSource dataFileList] count];
for(i=0; i<n; i++)
{
data = [[waisSource dataFileList] objectAt:i];
j = [indexFiles indexAddEntry:[data valueForStringKey:"data-file"]];
[indexFiles
setAssocStringValue:[data valueForStringKey:":index-mode"] at:j];
}
// Now pop up new panel.
[indexPanel makeKeyAndOrderFront:self];
if(!indexIWC) indexIWC = [[IconWellControl alloc] initWindow:indexPanel];
return self;
}
- addToIndex:sender
{
id theTarget;
SEL theAction;
theTarget = [indexFiles target];
theAction = [indexFiles action];
[indexFiles setTarget:nil];
[indexFiles setAction:(SEL)0];
[indexFiles setStringValue:[indexInputWell stringValue]];
[indexFiles setTarget:theTarget];
[indexFiles setAction:theAction];
return [self applyIndexMode:self];
}
- applyIndexMode:sender
{
int i, n;
const char *mode = [[indexMode target] selectedItem];
if(!mode) mode = ":text";
n = [indexFiles count];
for(i=0; i<n; i++) if([indexFiles isEntrySelectedAt:i])
[indexFiles setAssocStringValue:mode at:i];
return self;
}
- makePrivate:sender
{
isPublic = NO;
return self;
}
- makePublic:sender
{
//!!!----DISABLED-----
NXRunAlertPanel("Publication",
"Sorry, Internet publication has been disabled in this version.",
"OK", NULL, NULL);
return nil;
/*!!!
int choice;
id stringTable;
// Let user cancel Internet publication.
if(!(stringTable = [[NXApp delegate] stringTable])) return nil;
choice = NXRunAlertPanel(
[stringTable valueForStringKey:"Warning!"],
[stringTable valueForStringKey:"Continuing will cause this source to be published on the Internet. Make sure public access has been enabled! Proceed?"],
[stringTable valueForStringKey:"OK"],
[stringTable valueForStringKey:"Cancel"], NULL);
if(choice == NX_ALERTALTERNATE)
{ [indexPrivate performClick:self]; return nil; }
isPublic = YES;
return self;
*/
}
- updateSelection:sender
{
id theTarget;
SEL theAction;
theTarget = [indexInputWell target];
theAction = [indexInputWell action];
[indexInputWell setTarget:nil];
[indexInputWell setAction:(SEL)0];
[indexInputWell setStringValue:[indexFiles stringValue]];
[indexInputWell setTarget:theTarget];
[indexInputWell setAction:theAction];
return self;
}
- createIndex:sender
{
int i, j, n, start_at, ok;
char *extn;
const char *mode;
const char *systemFolder = NXGetDefaultValue("WAIStation","SystemFolder");
id data;
FILE *cmdfile;
BOOL first;
// Reset source's :index-list and save.
//!!! waisindex overwrites this!!!
if(!fileName) return nil;
[waisSource clearDataFiles];
n = [indexFiles count];
for(i=0; i<n; i++)
{
data = [[WaisDataFile alloc] initKey:NULL];
[data insertStringKey:":data-file" value: [indexFiles entryAt:i]];
[data insertStringKey:":index-mode"
value: [indexFiles assocStringValueAt:i]];
[waisSource addDataFile:data];
}
if(![self dump:self]) return nil;
// Create shell script to index the data files.
//!!! How 'bout some alert panels here??
//!!! messing with uniqued strings
if(!fileName) return nil;
if(!(extn = strrchr(fileName, '/'))) extn = fileName;
if(!(extn = strrchr(extn, '.'))) return nil;
if(strcmp(extn+1, [[self class] fileType]) != 0) return nil;
[Wais lockFileIO];
strcpy(extn+1, "sh");
if(!(cmdfile = fopen(fileName, "w")))
{ [Wais unlockFileIO]; return nil; }
strcpy(extn+1, [[self class] fileType]);
fchmod(fileno(cmdfile), 0755);
// Write script header info.
fprintf(cmdfile, "#!/bin/sh\n");
fprintf(cmdfile, "# WAIS indexing script for %s\n", fileName);
fprintf(cmdfile, "# Created %s by WAIStation.app %s\n",
printable_time(), WAISTATION_VERSION);
// Group data files with same :mode into waisindex commands.
//!!! Should keep command length below some limit.
//!!! What about data file names with '\'' chars???
n = [indexFiles count];
for(first=YES, mode=0, start_at=0;
start_at>=0 && start_at<n; mode=0, first=NO)
for(i=start_at, start_at=(-1); i<n; i++)//!!!
{
if(!mode)
{
// Starting new :mode. Flush old cmd line and start new one.
mode = [indexFiles assocStringValueAt:i];
*extn = 0;
fprintf(cmdfile, "\n%s/bin/waisindex -d %s %s -r -export ",
(systemFolder ? systemFolder : ""),
fileName, (first ? "" : "-a"));
*extn = '.';
if(isPublic) fprintf(cmdfile, "-register ");
if(!mode || !mode[0]) fprintf(cmdfile, "-t text ");
else fprintf(cmdfile, "-t %s ", mode+1);
}
else if(strcmp(mode, [indexFiles assocStringValueAt:i]) != 0)
{
// Check if we saw this before.
for(j=0; j<i; j++)
if(strcmp([indexFiles assocStringValueAt:i],
[indexFiles assocStringValueAt:j]) == 0)
break;
if(j < i) continue;
// Found new :mode. Skip file and set pointer for next loop.
if(start_at < 0) start_at = i;
continue;
}
if(!mode || strlen(mode)==0) { [Wais unlockFileIO]; return nil; }
// Compile data file into command line.
fprintf(cmdfile, "\'%s\' ", [indexFiles entryAt:i]);
}
// Flush last cmd line.
fprintf(cmdfile, "\n");
// Have script refresh source in WAIStation by re-opening.
//!!! Check if WS running first?
fprintf(cmdfile, "open %s\n", fileName);
fclose(cmdfile);
[Wais unlockFileIO];
// Now run script and present it to the user for re-indexing.
ok = NO;
strcpy(extn+1, "sh");
[indexScriptWell setStringValue:fileName];
[self openFile:fileName ok:&ok];
strcpy(extn+1, [[self class] fileType]);
if(!ok) return nil;
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.