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.