This is HKGnatsReport.m in view mode; [Download] [Up]
/* * LEGAL NOTICE * * Copyright (c) 1994 WSC Investment Services, Inc. * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS" AND WSC INVESTMENT SERVICES (WSCIS) * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT * SHALL WSCIS BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE * USE OR PERFORMANCE OF THIS SOFTWARE. * * Users of this software agree to return to WSCIS any improvements * or extensions that they make and grant WSCIS the rights to * redistribute these changes. * * Export of this software is permitted only after complying with the * regulations of the U.S. Deptartment of Commerce relating to the * Export of Technical Data. */ #import "HKGnatsReport.h" #import "HKSendPr.h" #import <hk/HKString.h> #import <errno.h> #import <hk/HKDelimitedTable.h> #import <appkit/NXHelpPanel.h> @interface TextFieldCell(CheckIt) - (const char *)stringValue; @end @implementation TextFieldCell(CheckIt) - (const char *)stringValue; { const char * ret = [super stringValue]; return ret ? ret : ""; } @end @implementation HKGnatsReport static id sharedInstance = nil; - setupMenu; { int i, count; id menuMatrix, menuCell; id menu = [NXApp mainMenu]; if (installedMenu) return self; if (!menu) { return nil; } else { installedMenu = YES; } menuMatrix= [menu itemList]; count = [menuMatrix cellCount]; for(i = 0; (menuCell = [menuMatrix cellAt:i :0]); i++) { if(strncmp([menuCell title],"Info",strlen("Info")) == 0) { if ([menuCell hasSubmenu]){ id submenu = [menuCell target]; [[submenu addItem:"Bug Report..." action:@selector(showPanel:) keyEquivalent:0] setTarget:self]; } else { id newMenu= [[Menu alloc] initTitle:"Info"]; SEL oldAction = [menuCell action]; id cell; [menuMatrix removeRowAt:i andFree:NO]; [menuMatrix insertRowAt:i]; [[menuMatrix cellAt:i:0] setTitle:"Info"]; cell = [newMenu addItem:"Info..." action:oldAction keyEquivalent:0]; // the old switcheroo [[[[newMenu itemList] cellList] replaceObject:cell with:menuCell] free]; cell = [newMenu addItem:"Bug Report..." action:@selector(showPanel:) keyEquivalent:0]; [cell setTarget:self]; [menu setSubmenu:newMenu forItem:[menuMatrix cellAt:i:0]]; } break; } } // if (!menuCell) then add Info > Bug Report at the top return self; } - awakeFromNib; { float left,right,top,bottom; [self setupMenu]; [problemText getMarginLeft:&left right:&right top:&top bottom:&bottom]; left += 3.0; top += 3.0; [problemText setMarginLeft:left right:right top:top bottom:bottom]; return self; } - (BOOL)loadBundle:bundle; { char path[MAXPATHLEN+1]; BOOL errors = NO; /* * We have to load the categories before the nib */ if (![bundle getPath:path forResource:"categories" ofType:""]){ NXRunAlertPanel([self name],"Couldn't open \"categories\" in \"%s\" (%s)",0,0,0, [bundle directory],strerror(errno)); errors = YES; } else { [categories readFromFilename:path]; } /* * The nib comes second so we can configure it from * the categories. */ if (![bundle getPath:path forResource:"HKGnatsReport" ofType:"nib"]){ NXRunAlertPanel([self name],"Cound't find nib \"HKGnatsReport.nib\" (%s)",0,0,0, strerror(errno)); errors = YES; } else if (!([NXApp loadNibFile:path owner:self])){ NXRunAlertPanel([self name],"Couldn't open nib \"%s\" (%s)",0,0,0, path,strerror(errno)); errors = YES; } #if 0 if (![bundle getPath:path forResource:"HKGnatsBundleHelp" ofType:""]){ NXRunAlertPanel([self name],"Couldn't find HKGnatsBundleHelp in \"%s\" (%s)",0,0,0, [bundle directory],strerror(errno)); } else { [[NXHelpPanel new] addSupplement:"TableOfContents.rtf" inPath:path]; } #endif [panel setTitle:[categories line:0 field:1]]; return errors; } - init; { BOOL errors = NO; if (sharedInstance) { [NXApp delayedFree:self]; return sharedInstance; } else { id bundle; char path[MAXPATHLEN+1]; [super init]; sprintf(path,"%s/%s",[[NXBundle mainBundle] directory],"HKGnatsReport.bundle"); if (!(bundle = [[NXBundle alloc] initForDirectory:path])){ NXRunAlertPanel([self name],"Couldn't open bundle \"%s\" (%s).",0,0,0, path,strerror(errno)); errors = YES; } else { sendPr = [[HKSendPr alloc] init]; categories = [[HKDelimitedTable alloc] init]; [sendPr setup]; errors = [self loadBundle:bundle]; [bundle free]; } if (!errors) { [self setupMenu]; current = problem = [[HKString alloc] init]; howToRepeat = [[HKString alloc] init]; possibleFix = [[HKString alloc] init]; return self; } else { [NXApp delayedFree:self]; return nil; } } } - free; { if (sharedInstance != self) { return [super free]; } else { return nil; } } - changeExplanation:sender; { int tag = [[sender selectedCell] tag]; const char * exp = [categories line:tag field:1]; [panel setTitle:exp]; return self; } // configure popup lists - setCategoryPop:sender; { id matrix = [[sender target] itemList]; int i,count = [categories count]; categoryPop = sender; [matrix renewRows:count cols:1]; for(i=0;i<count;i++){ id cell = [matrix cellAt:i:0]; [cell setTitle:[categories line:i field:0]]; [cell setTag:i]; [cell setTarget:self]; [cell setAction:@selector(changeExplanation:)]; } [categoryPop setTitle:[[matrix cellAt:0:0] title]]; return self; } - setClassPop:sender; { id matrix = [[sender target] itemList]; classPop = sender; [[[matrix cellAt:0:0] setTitle:"Software Bug"] setTag:HK_SoftwareBug]; [[[matrix cellAt:0:1] setTitle:"Documentation Bug"] setTag:HK_DocumentationBug]; [[[matrix cellAt:0:2] setTitle:"Change Request"] setTag:HK_ChangeRequest]; [[[matrix cellAt:0:3] setTitle:"Support"] setTag:HK_Support]; return self; } - setPriorityPop:sender; { id matrix = [[sender target] itemList]; priorityPop = sender; [[[matrix cellAt:0:0] setTitle:"Low"] setTag:HK_LowPriority]; [[[matrix cellAt:0:1] setTitle:"Medium"] setTag:HK_MediumPriority]; [[[matrix cellAt:0:2] setTitle:"High"] setTag:HK_HighPriority]; return self; } - setSeverityPop:sender; { id matrix = [[sender target] itemList]; severityPop = sender; [[[matrix cellAt:0:0] setTitle:"Non-Critical"] setTag:HK_NonCriticalSeverity]; [[[matrix cellAt:0:1] setTitle:"Serious"] setTag:HK_SeriousSeverity]; [[[matrix cellAt:0:2] setTitle:"Critical"] setTag:HK_CriticalSeverity]; return self; } #define SUBMITTER "GnatsSubmitter" #define ORGANIZATION "ORGANIZATION" #define REPORTTO "GnatsReportTo" - set:field from:(const char *)name; { const char * sub = getenv(name); if (!sub) sub = NXReadDefault("Global",name); if (!sub) sub = NXReadDefault([NXApp appName],name); [field setStringValue:sub]; return self; } // configure fields - setSubmitterField:sender; { [self set:sender from:SUBMITTER]; submitterField = sender; return self; } - setOrganizationField:sender; { [self set:sender from:ORGANIZATION]; organizationField = sender; return self; } - setReportToField:sender; { [self set:sender from:REPORTTO]; if (!strlen([sender stringValue])){ [sender setStringValue:"bugs"]; } reportToField = sender; return self; } // actions - clear:sender; { [summaryField setStringValue:""]; [problemText setText:""]; [problem setStringValue:""]; [howToRepeat setStringValue:""]; [possibleFix setStringValue:""]; return self; } - (const char *)_version; { const char * release = 0; id del = [NXApp delegate]; if (del != self && [del respondsTo:@selector(version)]){ release = (const char *)[del perform:@selector(version)]; } else { release = [NXApp appName]; } return release; } - change:sender; { int len = [problemText textLength]; id other; char text[len+1]; [problemText getSubstring:text start:0 length:len]; text[len]='\0'; [current setStringValue:text]; switch([[sender selectedCell] tag]){ default: case 0: other = problem; break; case 1: other = howToRepeat; break; case 2: other = possibleFix; break; } if (current!=other){ current = other; [problemText setText:[current stringValue]]; } return self; } // could be better about this - writeAndTest:(const char *)defaultName with:(const char *)value; { NXWriteDefault([NXApp appName],defaultName,value); return self; } - check; { [self change:controlMatrix]; if (!strlen([summaryField stringValue])){ return nil; } if (!strlen([problem stringValue])){ return nil; } [self writeAndTest:ORGANIZATION with:[organizationField stringValue]]; [self writeAndTest:SUBMITTER with:[submitterField stringValue]]; [self writeAndTest:REPORTTO with:[reportToField stringValue]]; return self; } - submit:sender; { if ([self check]){ [sendPr setEmailTo:[reportToField stringValue]]; [sendPr setSubmitterID:[submitterField stringValue]]; [sendPr setOrganization:[organizationField stringValue]]; [sendPr setConfidential:[confidentialSwitch state]]; [sendPr setSynopsis:[summaryField stringValue]]; [sendPr setSeverity:[severityPop selectedTag]]; [(HKSendPr *)sendPr setPriority:[priorityPop selectedTag]]; [sendPr setBugClass:[classPop selectedTag]]; [sendPr setCategory:[categoryPop title]]; [sendPr setRelease:[self _version]]; [sendPr setDescription:[problem stringValue]]; [sendPr setHowToRepeat:[howToRepeat stringValue]]; [sendPr setHowToFix:[possibleFix stringValue]]; if (![sendPr send]){ NXRunAlertPanel([self name],"Problem sending bug report.",0,0,0); } else { [panel performClose:self]; } } else { NXRunAlertPanel([self name],"The problem report is incomplete.",0,0,0); } return self; } - showPanel:sender; { [panel makeKeyAndOrderFront:self]; return self; } // set these programatically - setReportTo:(const char *)name; { [reportToField setStringValue:name]; return self; } - setSubmitterID:(const char *)name; { [submitterField setStringValue:name]; return self; } // // Only if he's appDelegate. // - appDidInit:sender; { [self showPanel:self]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.