This is InspectTuple.m in view mode; [Download] [Up]
/* InspectTuple by Paul Kunz October 1991 * The supervisor for the tuple inspection panel * * Copyright (C) 1991 The Board of Trustees of * The Leland Stanford Junior University. All Rights Reserved. */ #import "Draw.subproj/draw.h" #import "HGraphicView.h" #import "InspectTuple.h" const char InspectTuple_h_rcsid[] = INSPECTTUPLE_H_ID; const char InspectTuple_m_rcsid[] = "$Id: InspectTuple.m,v 2.35.2.3 1994/02/08 20:29:50 rensing Exp $"; #import "HDrawApp.h" #import "HTuple.h" #import "NewInspector.h" #import "Plot.h" #define FN_INDEX 0 #define BY_INDEX 1 #define COL_INDEX 2 #define ROW_INDEX 3 #define MB_INDEX 4 #define LOW_RANGE 0 #define HIGH_RANGE 1 #define LOW_X 0 #define LOW_Y 1 #define HIGH_X 2 #define HIGH_Y 3 #define MAX_VALUE 0 #define MIN_VALUE 1 #define SUM_VALUE 2 #define AX_X 0 #define AX_Y 1 #define AX_Z 2 #define AX_W 2 #define AX_XE 3 #define AX_YE 4 @interface InspectTuple(PrivateMethods) - hTupleForTuple:(ntuple) nt; /* * Returns the HTuple object managing the ntuple nt, or * nil if none found. */ - (BOOL) isNewTupleFile:(const char *)filename; /* return YES if tuple file with filename is not in list of * currently opened files, otherwise returns NO. */ - (BOOL) isReplaceOK:(List *)list with:(HTuple *)tuple; /* * Checks to see if tuple can be used as replacement for list of Plots * in list. Checks all binding axes of displays and plot and * cut binding if any. */ - openTupleFile; /* * Opens the tuple file selected by the OpenPanel. This method * does not run the OpenPanel, rather it is called after it has been run. */ - openTupleFromFile:(const char *)filename by:(BOOL)refFlag; /* * Opens ntuple file filename and returns a List of * HTuple objects created or nil if file could not be opened. * The refFlag is passed to each HTuple object. */ - (int) openAltTupleFile:(const char *)filename; /* * Runs the OpenPanel to select a file to replace filename and * opens the selected n-tuple file. The altfilename of the * opened Tuples is set to filename. This method is used * when opening a document with tuples by reference, and the * ntuple file has changed it's path or doesn't exists */ - closeTupleFile:(const char *)filename; /* * Close an n-tuple file after informing each DrawDocument's View * that file is about to close. */ - (int) runModelForTypes; /* * Runs the openPanel to select tuple binary file with suffix .hippo. * Returns HD_OK on success, HD_CANCEL if user canceled. */ - showPanel; /* * Orders the NewInspector panel to show the Tuple List and brings * Panel front */ - replaceWithCuts:hTuple; /* * Replaces the HTuple of selected Plots, their cuts, and * all plots dependent on those cuts. */ - setButtonsAndTitles; /* * Enables appropriate axis buttons and titles */ - setDisable:(int) axisIndex; /* * Disables axis button and clears Form for specified Axis index. */ - setEnable:(int) axisIndex; /* * Enables axis button and sets label for specified Axis index. */ - showBinding; /* * Updates inspector view to show bindings of selected plot */ - updateFileForm; /* * Updates the information Form and copyButton. */ @end @implementation InspectTuple - initInspFor:aDraw { PopUpList *popUpList; NXBundle *bundle; char buffer[MAXPATHLEN+1]; [super initInspFor:aDraw]; bundle = [NXBundle bundleForClass:[self class]]; if ( [bundle getPath:buffer forResource:"InspectTuple" ofType:"nib"] ) { [NXApp loadNibFile:buffer owner:self withNames:NO fromZone:[self zone]]; } [theInspector addView:[contentBox contentView] withName:"Data Selection" withSupervisor:self]; [colBrowser setDoubleAction:@selector(colBrowserDoubleClicked:)]; openPanel = [OpenPanel new]; /* the following avoids getting "/private/Net/..." as default */ [openPanel setDirectory:NXHomeDirectory()]; tupleList = [[ List allocFromZone:[self zone]] init]; popUpList = [popUpButton target]; [popUpList setTarget:self]; [popUpList setAction:@selector(formChange:)]; graphtype = HISTOGRAM; tpAxisIndex[0] = 0; tpAxisIndex[1] = 0; tpAxisIndex[2] = -1; tpAxisIndex[3] = -1; tpAxisIndex[4] = -1; return self; } /* Action methods */ - axisMatrixClick:sender { Matrix *colBrowserCells; int currentButton; currentButton = [tpAxisButtons selectedRow]; colBrowserCells = [colBrowser matrixInColumn:0]; [colBrowserCells selectCellAt:tpAxisIndex[currentButton] :0 ]; [colBrowserCells scrollCellToVisible:tpAxisIndex[currentButton] :0]; return self; } - colBrowserSingleClicked:sender { Matrix *colBrowserCells; int tpColSelected, currentButton; static int previousTupleN = -1, previousButton = -1; colBrowserCells = [colBrowser matrixInColumn:0]; tpColSelected = [colBrowserCells selectedRow ]; currentButton = [tpAxisButtons selectedRow]; if ( popUpRow == 0 ) { [infoForm setStringValue: [[colBrowserCells cellAt:tpColSelected :0] stringValue] at:currentButton]; } switch( currentButton ) { case AX_X: tpAxisIndex[0] = tpColSelected; break; case AX_Y: tpAxisIndex[1] = tpColSelected; break; case AX_W: /* or AX_Z */ if (graphtype == THREEDSCATTER) { /* case AX_Z: */ tpAxisIndex[2] = tpColSelected; break; } else { /* case AX_W: */ if (tpColSelected == previousTupleN && currentButton == previousButton ) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_W]; } } tpAxisIndex[2] = tpColSelected; previousTupleN = tpColSelected; previousButton = currentButton; break; } case AX_XE: if (graphtype == XYPLOT || graphtype == STRIPCHART) { if (tpColSelected == previousTupleN && currentButton == previousButton) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_XE]; } } tpAxisIndex[3] = tpColSelected; } previousTupleN = tpColSelected; previousButton = currentButton; break; case AX_YE: if ( tpColSelected == previousTupleN && currentButton == previousButton ) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_YE]; } } tpAxisIndex[4] = tpColSelected; previousTupleN = tpColSelected; previousButton = currentButton; break; } return self; } - colBrowserDoubleClicked:sender { Matrix *colBrowserCells; int tpColSelected, currentButton; static int previousTupleN = -1, previousButton = -1; colBrowserCells = [colBrowser matrixInColumn:0]; tpColSelected = [colBrowserCells selectedRow ]; currentButton = [tpAxisButtons selectedRow]; if ( popUpRow == 0 ) { [infoForm setStringValue: [[colBrowserCells cellAt:tpColSelected :0] stringValue] at:currentButton]; } switch( currentButton ) { case AX_X: [graphicView graphicsPerform:@selector(bindAxisX:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[0] = tpColSelected; break; case AX_Y: [graphicView graphicsPerform:@selector(bindAxisY:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[1] = tpColSelected; break; case AX_W: /* or AX_Z */ if (graphtype == THREEDSCATTER) { /* case AX_Z: */ [graphicView graphicsPerform:@selector(bindAxisZ:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[2] = tpColSelected; break; } else { /* case AX_W: */ if (tpColSelected == previousTupleN && currentButton == previousButton ) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_W]; } } [graphicView graphicsPerform:@selector(bindAxisW:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[2] = tpColSelected; previousTupleN = tpColSelected; previousButton = currentButton; break; } case AX_XE: if (graphtype == XYPLOT || graphtype == STRIPCHART) { if (tpColSelected == previousTupleN && currentButton == previousButton) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_XE]; } } [graphicView graphicsPerform:@selector(bindAxisXE:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[3] = tpColSelected; } previousTupleN = tpColSelected; previousButton = currentButton; break; case AX_YE: if ( tpColSelected == previousTupleN && currentButton == previousButton ) { tpColSelected = -1; if ( popUpRow == 0 ) { [infoForm setStringValue:"" at:AX_YE]; } } [graphicView graphicsPerform:@selector(bindAxisYE:) with :(id)&tpColSelected andDraw:YES]; tpAxisIndex[4] = tpColSelected; previousTupleN = tpColSelected; previousButton = currentButton; break; } [[[graphicView window] flushWindow] makeKeyWindow]; return self; } - graphOption:sender { int color; drawtype_t dt; if ( [selectedPlot hasFunction] ) { NXRunAlertPanel( "Alert", "Can not change plot with function attached", NULL, NULL, NULL ); return self; } graphtype = [[graphTypMatrix selectedCell] tag]; color = 0; if ((abs(graphtype) == COLORPLOT) && graphtype > 0) color = 1; graphtype = abs(graphtype); if (graphtype == XYPLOT || graphtype == STRIPCHART) { [selectedPlot getDrawType: &dt]; if (!(dt & (LINE+POINT+ERRBAR))) { dt += POINT; [graphicView graphicsPerform:@selector(setDrawType:) with :(id)&dt andDraw:NO]; } } if (graphtype == THREEDSCATTER) { if (tpAxisIndex[2] == -1) tpAxisIndex[2] = 0; } [graphicView graphicsPerform:@selector(setDispType:) with :(id)&graphtype andDraw:NO]; [graphicView graphicsPerform:@selector(setColorType:) with :(id)&color andDraw:YES]; [[[graphicView window] flushWindow] makeKeyWindow]; lastPlot = nil; if(!selectedPlot && !firstPlot) [self setButtonsAndTitles]; return self; } - addPlot:sender { Matrix *colCells; Cell *aCell; Plot *plot = nil; graphtype_t plotType; int i, count; int color, curAxis; if ( !selectedTuple ) { return self; } colCells = [colBrowser matrixInColumn:0]; count = [colCells cellCount]; if ( !count ) return self; [graphicView deselectAll:self]; plotType = [[graphTypMatrix selectedCell] tag]; color = 0; if ( ( abs(plotType) == COLORPLOT) && plotType > 0 ) { color = 1; } plotType = abs(plotType); curAxis = [tpAxisButtons selectedRow]; for ( i = 0; i < count; i++ ) { aCell = [colCells cellAt:i :0]; if ( [aCell isHighlighted] ) { tpAxisIndex[curAxis] = i; plot = [self addPlotOfType:plotType]; if ( color ) { [plot setColorType:&color]; } [graphicView addPlot:plot andSelect:NO]; } } [plot select]; [graphicView getSelection]; [graphicView recacheSelection]; [[[graphicView window] flushWindow] makeKeyWindow]; return self; } - openTuple:sender { [openPanel setAccessoryView:nil]; if ( [self runModelForTypes] != HD_CANCEL ) { [self openTupleFile]; } return self; } - openTupleAsText:sender { [openPanel setAccessoryView:nil]; if ( ![openPanel runModal] ) { return self; } [self openTupleFile]; return self; } - tupleBrowserClick:sender { List *slist; id browserMatrix; id doc; id hTuple; int irc, index; BOOL ok; browserMatrix = [tupleBrowser matrixInColumn:0]; index = [browserMatrix selectedRow]; if ( index < 0 ) { [self setTuple: NULL]; return self; } hTuple = [tupleList objectAt:index]; selectedTuple = [hTuple ntuple]; [self updateColBrowser]; [self updateFileForm]; doc = [drawInstance currentDocument]; if ( !doc ) return self; graphicView = [doc view]; if ( [graphicView hasCutsSelected] ) { irc = NXRunAlertPanel( "Alert", "Selected Plot(s) contain cuts," " replacing ntuple will effect multiple plots.", "OK", "Cancel", NULL); if ( irc == NX_ALERTDEFAULT ) { [self replaceWithCuts:hTuple]; } } else { slist = [graphicView selectedGraphics]; ok = [self isReplaceOK:slist with:hTuple]; if ( !ok ) return self; [graphicView graphicsPerform:@selector(replaceTupleWith:) with: hTuple andDraw:YES ]; [[graphicView window] flushWindow]; } return self; } - closeTuple:sender { id windowList; id window, document, view; id usedTupleList; id hTuple; id browserMatrix; int wcount; int i, irc, index; browserMatrix = [tupleBrowser matrixInColumn:0]; index = [browserMatrix selectedRow]; if ( index < 0 ) return self; hTuple = [tupleList objectAt:index]; windowList = [NXApp windowList]; wcount = [windowList count]; while ( wcount-- ) { window = [windowList objectAt:wcount]; document = [window delegate]; if ( [document isKindOf:[DrawDocument class]] ) { view = [document view]; usedTupleList = [view tupleList]; i = [usedTupleList indexOf:hTuple]; if ( i != NX_NOT_IN_LIST ) { irc = NXRunAlertPanel( "Close", "Tuple in use", "OK", NULL, NULL); return self; } } } [self closeTupleFile:[hTuple filename]]; // since this tuple is not in use, there must be no plot selected. // make sure selectedPlot == nil in case it has not been updated. selectedPlot = nil; firstPlot = nil; [self tupleBrowserClick: self]; /* * force an update. * make sure to get the current view. it may have been freed. */ [self load:[[drawInstance currentDocument] view]]; return self; } - changeImportMode:sender { id hTuple; hTuple = [self currentHTuple]; if ( [hTuple isRef ] ) { [hTuple setIsRef:NO]; } else { [hTuple setIsRef:YES]; } [self updateFileForm]; return self; } - formChange:sender { popUpRow = [sender selectedRow]; switch (popUpRow ) { case 0 : [self setButtonsAndTitles]; break; case 1 : [self updateFileForm]; break; default : ; /* should never happen */ } return self; } /* Methods invoked by other objects */ - hTupleForFile:(const char *)filename index:(int)iValue { const char *altfile; id hTuple; int i; i = [tupleList count]; while ( i-- ) { hTuple = [tupleList objectAt:i]; if ( [hTuple index] == iValue ) { if ( strcmp( [hTuple filename], filename ) == 0 ) { return hTuple; } altfile = [hTuple altfilename]; if ( altfile && (strcmp(altfile, filename) == 0 ) ) { return hTuple; } } } return nil; } - openTuple:pasteBoard userData:(const char *)args error:(char **)errorMsg { id hTuple; FILE *infile; ntuple *ntlist; const char *const *ptypes; const char *data; char filename[25]; char *outbuffer; int i, irc, length; BOOL binFlag; ptypes = [pasteBoard types]; for ( i = 0; ptypes[i]; i++ ) { if ( !strcmp(ptypes[i], NXAsciiPboardType) ) { [pasteBoard readType:ptypes[i] data:&data length:&length]; NX_ZONEMALLOC([self zone], outbuffer, char, (length+2) ); strncpy( outbuffer, data, length); outbuffer[length] = '\n'; outbuffer[length+1] = '\0'; strcpy(filename,"/tmp/file000000Selection" ); NXGetTempFilename(filename,9); infile=fopen(filename,"w"); fprintf(infile,outbuffer); fclose(infile); NXZoneFree([self zone], outbuffer); if ( (infile = fopen(filename, "r") ) == NULL ) { *errorMsg = "Couldn't open /tmp file"; return nil; } binFlag = NO; NX_ZONEMALLOC( [self zone], ntlist, ntuple, 2 ); if ( !(ntlist[0] = h_fileParse( infile, NULL, 0) ) ) { NXZoneFree([self zone], ntlist); *errorMsg = "Couldn't interpret data as n-tuple"; return nil; } ntlist[1] = NULL; irc = fclose( infile ); unlink(filename); hTuple = [[HTuple allocFromZone:[self zone]] initTuple:ntlist[0] file:"From Pasteboard" by:NO mode:NO index:0]; [hTuple setFakeFilename:YES]; [tupleList addObject:hTuple]; [tupleBrowser loadColumnZero]; [self setTuple:ntlist[0] ]; [self showPanel]; } } return self; } - addTuple:(ntuple) nt { id hTuple; hTuple = [[HTuple allocFromZone:[self zone]] initTuple:nt file:"none" by:NO mode:YES index:0]; [hTuple setFakeFilename:YES]; [tupleList addObject:hTuple]; [tupleBrowser loadColumnZero]; [ self setTuple:nt]; return hTuple; } - addPlotOfType:(graphtype_t) plotType { HTuple *hTuple; Plot *plot; drawtype_t drawtype; int saveAxisIndex[5]; int i, max; if ( !selectedTuple ) { ntuple nt = [self currentTuple]; if ( !nt ) return nil; [self setTuple:nt]; } if ( (plotType !=HISTOGRAM) && (h_getNtDim(selectedTuple) < 2) ) { return nil; } if ( !graphicView ) { return nil; } [self load:graphicView]; /* force an update */ hTuple = [self currentHTuple]; plot = [[Plot allocFromZone:[graphicView zone]] initPlotWithTuple:hTuple Type:plotType]; max = h_getNtDim(selectedTuple) - 1; for ( i = 0; i < 5; i++ ) { saveAxisIndex[i] = MIN( tpAxisIndex[i], max ); } /* do bindings as neccessary */ [plot bindAxisX:&saveAxisIndex[0]]; if (plotType != HISTOGRAM) { saveAxisIndex[1] = MAX(0, saveAxisIndex[1]); [plot bindAxisY:&saveAxisIndex[1]]; } if (plotType == XYPLOT) { if ( saveAxisIndex[3] >= 0 || saveAxisIndex[4] >= 0 ) { drawtype = POINT + ERRBAR; } else { drawtype = POINT; } [plot setDrawType:&drawtype]; [plot bindAxisXE:&saveAxisIndex[3]]; [plot bindAxisYE:&saveAxisIndex[4]]; } else { if (plotType == THREEDSCATTER) { saveAxisIndex[2] = MAX(0, saveAxisIndex[2]); [plot bindAxisZ:&saveAxisIndex[2]]; } else { [plot bindAxisW:&saveAxisIndex[2]]; } } /* bindings done */ [self setInspectorFor:plot]; return plot; } - (ntuple) currentTuple { id browserMatrix; id hTuple; ntuple nt; int index; browserMatrix = [tupleBrowser matrixInColumn:0]; index = [browserMatrix selectedRow]; if ( index >= 0 ) { hTuple = [tupleList objectAt:index]; nt = [hTuple ntuple]; } else { nt = NULL; } return nt; } - currentHTuple { id browserMatrix; id hTuple; int index; browserMatrix = [tupleBrowser matrixInColumn:0]; index = [browserMatrix selectedRow]; if ( index >= 0 ) { hTuple = [tupleList objectAt:index]; } else { hTuple = nil; } return hTuple; } - bindDisplays { id windowList; id window, document, view; int wcount; windowList = [NXApp windowList]; wcount = [windowList count]; while ( wcount-- ) { window = [windowList objectAt:wcount]; document = [window delegate]; if ( [document isKindOf:[DrawDocument class]] ) { view = [document view]; [view bindDisplays]; [view reDrawPlot]; } } return self; } - (int) addTuplesIfAbsent:newList { id newTuple, hTuple; int newCount, count; int i, j, irc; BOOL isNew; graphicView = nil; /* to keep open methods from messaging the view */ newCount = [newList count]; for ( i = 0; i < newCount; i++ ) { newTuple = [newList objectAt:i]; isNew = YES; count = [tupleList count]; for ( j = 0; j < count; j++ ) { hTuple = [tupleList objectAt:j]; if ( [hTuple isSameTupleAs:newTuple] ) { isNew = NO; [newList replaceObjectAt:i with:hTuple]; [newTuple free]; break; } } if ( isNew ) { if ( [newTuple isRef ] ) { irc = [self openTupleFile:[newTuple filename] by:YES]; if ( irc == HD_NOTEXIST ) { irc = [ self openAltTupleFile:[newTuple filename]]; if (irc != HD_OK) return irc; } j = [tupleList count]; while ( j-- ) { hTuple = [tupleList objectAt:j]; if ( [hTuple isSameTupleAs:newTuple] ) { [hTuple takeFunctionList:[newTuple functionList]]; [newList replaceObjectAt:i with:hTuple]; [newTuple free]; break; } } } else { [tupleList addObject:newTuple]; [tupleBrowser loadColumnZero]; [ self setTuple:[newTuple ntuple]]; } } } [self showPanel]; return HD_OK; } - (int) openTupleFile:(const char *)filename by:(BOOL) refFlag { id newTupleList; struct stat statbuf; int irc, rvalue; if ( stat(filename, &statbuf) ) { return HD_NOTEXIST; } rvalue = HD_OK; if( ![self isNewTupleFile:filename] ) { irc = NXRunAlertPanel( "Open", "Tuple file already open", "Replace", "Cancel", NULL); if ( irc != NX_ALERTDEFAULT ) { return HD_CANCEL; } [self closeTupleFile:filename]; rvalue = HD_REPLACE; } if ( !(newTupleList = [self openTupleFromFile:filename by:refFlag]) ) { irc = NXRunAlertPanel("Open", "Couldn't open file", "OK", NULL, NULL); return HD_CANCEL; } [newTupleList free]; return rvalue; } - saveAsExportFile:(const char *)filename { HTuple *htuple; ntuple nt; display disp; display *dispList; const char *ntFilename; int i, irc; BOOL refFlag; dispList = [graphicView displayList]; if ( dispList == NULL ) { return self; } /* update the ntuple filename for referenced tuples before saving */ for ( i = 0; (disp = dispList[i]) != NULL; i++) { h_setNtByRef( disp, NO, filename ); } if ( h_write( filename, dispList, NULL ) ) { irc = NXRunAlertPanel("Alert", "Couldn't save export file", "OK", NULL, NULL); } for ( i = 0; (disp = dispList[i]) != NULL; i++) { nt = h_getNtuple( disp ); htuple = [self hTupleForTuple:nt]; refFlag = [htuple isRef]; ntFilename = [htuple filename]; h_setNtByRef( disp, refFlag, ntFilename ); } return self; } - tupleList { return tupleList; } - tupleListForFile:(const char *) filename { id hTuple; int i, count; if ( tmpTupleList ) { [tmpTupleList empty]; } else { tmpTupleList = [[List allocFromZone:[self zone]] initCount: 0]; } count = [tupleList count]; for ( i = 0; i < count; i++ ) { hTuple = [tupleList objectAt:i]; if ( strcmp( [hTuple filename], filename ) == 0 ) { [tmpTupleList addObject:hTuple]; } } return tmpTupleList; } - replaceNtuple:(ntuple)oldnt with:(ntuple)newnt andFree:(BOOL)flag { id oldTuple, newTuple; id document; List *windowList; id view; Window *window; int i, j; i = [tupleList count]; while (i--) { oldTuple = [tupleList objectAt:i]; if ( oldnt == [oldTuple ntuple] ) { newTuple = [self addTuple:newnt]; [newTuple takeFunctionList:[oldTuple functionList]]; windowList = [NXApp windowList]; j = [windowList count]; while (j-- ) { window = [windowList objectAt:j]; document = [window delegate]; if ( [document isKindOf:[DrawDocument class]] ) { view = [document view]; [view replace:oldTuple with:newTuple]; } } if ( flag ) { [tupleList removeObject:oldTuple]; [oldTuple free]; } } break; } [tupleBrowser reloadColumn:0]; [self updateFileForm]; return self; } - setInspectorFor:(Plot *)plot { display disp; graphtype_t type; disp = [plot histDisplay]; type = h_getDispType(disp); if ([plot isCutPlot]) [plot setInspector : [hDraw inspectCut]]; else [plot setInspector:[hDraw inspectAxes]]; return self; } - updateView { if ( lastPlot == firstPlot && selectedTuple == [firstPlot ntuple] ) { return self; } if ( firstPlot ) { [self setTuple:[firstPlot ntuple] ]; [self showBinding]; lastPlot = firstPlot; } else { lastPlot = nil; } return self; } - updateEmptySelection { unsigned int i; lastPlot = nil; if ( popUpRow != 0 ) return self; for ( i = 0; i < 5; i++ ) { [[tpAxisButtons cellAt:i :0] setEnabled:YES]; } if (comingForward) { [self setButtonsAndTitles]; } if (!selectedTuple) [self updateColBrowser]; return self; } - setTuple:(ntuple) atuple { id browserMatrix; id hTuple; display disp; unsigned int i, count; if (selectedTuple == atuple) return self; selectedTuple = atuple; [self updateColBrowser]; if (selectedTuple == NULL) return self; browserMatrix = [tupleBrowser matrixInColumn:0]; count = [tupleList count]; for ( i = 0; i < count; i++ ) { hTuple = [tupleList objectAt:i]; if ( selectedTuple == [hTuple ntuple] ) { [ browserMatrix selectCellAt:i :0]; [ self updateFileForm]; break; } } if ( firstPlot && graphicView ) { disp = [firstPlot histDisplay]; graphtype = h_getDispType( disp ); if ( graphtype == XYPLOT ) { [tpAxisButtons selectCellAt:AX_Y :0]; } } return self; } - updateColBrowser { [colBrowser loadColumnZero]; [self showBinding]; return self; } - startUnarchivingFrom:(const char *)directory { return self; } /* Delegate Methods for NXBrowsers */ - (BOOL)browser:sender columnIsValid:(int)column; { return YES; } - (BOOL)browser:sender selectCell:(const char *)title inColumn:(int)column { return YES; } - (int) browser: sender fillMatrix: matrix inColumn: (int) column { int nrows = 0; if ( sender == tupleBrowser ) { nrows = [self fillTupleMatrix: matrix]; } else if ( sender == colBrowser ) { nrows = [self fillColumnMatrix: matrix]; } return nrows; } - (int) fillTupleMatrix:matrix { NXBrowserCell *aCell; HTuple *hTuple; const char *title; int i, nrows = 0; nrows = [tupleList count]; for (i = 0; i < nrows; i++) { [matrix insertRowAt:i]; aCell = [matrix cellAt:i :0]; hTuple = [tupleList objectAt:i]; title = [hTuple title]; if ( title && strcmp(title, "") ) { [aCell setStringValue:title]; } else { [aCell setStringValue:"<none>"]; } [aCell setLeaf:YES]; [aCell setLoaded:YES]; } [matrix setEmptySelectionEnabled:NO]; return nrows; } - (int) fillColumnMatrix:matrix { NXBrowserCell *aCell; int i, nrows = 0; if ( selectedTuple ) { nrows = h_getNtDim(selectedTuple); } else { nrows = 0; } for (i = 0; i < nrows; i++) { [matrix insertRowAt:i]; aCell = [matrix cellAt:i :0]; [aCell setStringValue:h_getNtLabel(selectedTuple, i)]; [aCell setLeaf:YES]; [aCell setLoaded:YES]; } return nrows; } - setMsgMatrix:anObject { float gray; int i, rows, cols; msgMatrix = anObject; gray = [msgMatrix backgroundGray ]; [msgMatrix getNumRows:&rows numCols:&cols]; for ( i = 0; i < rows; i++ ) { [[msgMatrix cellAt:i :0] setTextGray:gray]; } return self; } /* Obsolete methods, maintained for backward compatibility */ - newTuple:(ntuple) nt { [self addTuple:nt]; return self; } @end @implementation InspectTuple(PrivateMethods) - hTupleForTuple:(ntuple) nt { HTuple *hTuple; int i; i = [tupleList count]; while ( i-- ) { hTuple = [tupleList objectAt:i]; if ( nt == [hTuple ntuple] ) { return hTuple; } } return nil; } - (BOOL) isNewTupleFile:(const char *)filename { HTuple *hTuple; int i; i = [tupleList count]; while ( i-- ) { hTuple = [tupleList objectAt:i]; if ( strcmp( [hTuple filename], filename ) == 0 ) { return NO; } } return YES; } - (BOOL) isReplaceOK:(List *)list with:(HTuple *)tuple { Plot *plot; ntuple nt; display disp; func_id cut = NULL; int i, j, ndim; BOOL ok = YES; nt = [tuple ntuple]; ndim = h_getNtDim(nt); i = [list count]; while( i-- ) { plot = [list objectAt:i]; disp = [plot histDisplay]; for ( j = 0; j < 5; j++ ) { if ( h_getBinding( disp, j) >= ndim ) { ok = NO; break; } } if ( !ok ) break; if ( [plot hasCut] ) { cut = NULL; while ( (cut = h_nextCut( disp, cut ) ) != NULL ) { if ( (int)cut->paramBlk[0] >= ndim ) { ok = NO; break; } } } if ( !ok ) break; } if ( !ok ) { NXRunAlertPanel( "Alert", "Replacement n-tuple does not have" " enough columns to be used on effected plots." " No replacement made", "OK", NULL, NULL); selectedTuple = NULL; [self updateView]; } return ok; } - openTupleFile { const char *filename; int irc; BOOL refFlag; filename = [openPanel filename]; refFlag = YES; irc = [self openTupleFile:filename by:refFlag]; if ( irc == HD_REPLACE ) { [self bindDisplays]; } [self showPanel]; return self; } - openTupleFromFile:(const char *)filename by:(BOOL)refFlag { List *newTupleList; HTuple *hTuple; FILE *infile; ntuple *ntlist = NULL; display *dlist = NULL; int i; BOOL binFlag; if (h_isHippoFile(filename)) { binFlag = YES; if (h_read(filename, &dlist, &ntlist) != 0) { return nil; } } else { if ((infile = fopen(filename, "r")) == NULL) { NXRunAlertPanel("Reason Alert", "Couldn't open file", "OK", NULL, NULL); return nil; } binFlag = NO; NX_ZONEMALLOC([self zone], ntlist, ntuple, 2); if (!(ntlist[0] = h_fileParse(infile, NULL, 0))) { NXZoneFree([self zone], ntlist); return nil; } ntlist[1] = NULL; fclose(infile); } newTupleList = [[List allocFromZone:[self zone]] initCount:0]; for (i = 0; ntlist[i] != NULL; i++) { hTuple = [[HTuple allocFromZone:[self zone]] initTuple:ntlist[i] file:filename by:refFlag mode:binFlag index:i]; [tupleList addObject:hTuple]; [newTupleList addObject:hTuple]; } /* update graphicView because old one could have been freed */ graphicView = [[drawInstance currentDocument] view]; [graphicView deselectAll:self]; firstPlot = nil; lastPlot = nil; [tupleBrowser loadColumnZero]; [self setTuple:ntlist[0]]; return newTupleList; } - (int) openAltTupleFile:(const char *)filename { List *newTupleList; HTuple *hTuple; const char *newfilename; char *suffix; float gray; int i, count; int rows, cols; int irc; BOOL refFlag; [msgMatrix getNumRows:&rows numCols:&cols]; for (i = 0; i < rows; i++) { [[msgMatrix cellAt:i :0] setTextGray:0.]; } [[msgMatrix cellAt:1 :0] setStringValue:filename]; [openPanel setAccessoryView:accessoryView]; suffix = rindex(filename, '.'); if (suffix && !strcmp(suffix, ".hippo") ) { irc = [self runModelForTypes]; } else { if ( ![openPanel runModal] ) { irc = HD_CANCEL; } else { irc = HD_OK; } } gray = [msgMatrix backgroundGray]; for (i = 0; i < rows; i++) { [[msgMatrix cellAt:i :0] setTextGray:gray]; } if ( irc == HD_CANCEL ) { return irc; } newfilename = [openPanel filename]; if ( ![self isNewTupleFile:newfilename] ) { newTupleList = [self tupleListForFile:newfilename]; count = [newTupleList count]; for ( i = 0; i < count; i++ ) { hTuple = [newTupleList objectAt:i]; [hTuple setAltFilename:filename]; } return HD_OK; } refFlag = YES; if ( !(newTupleList = [self openTupleFromFile:newfilename by:refFlag]) ) { irc = NXRunAlertPanel("Open", "Couldn't open file", "OK", NULL, NULL); return HD_CANCEL; } count = [newTupleList count]; for ( i = 0; i < count; i++ ) { hTuple = [newTupleList objectAt:i]; [hTuple setAltFilename:filename]; } return HD_OK; } - closeTupleFile:(const char *)filename { List *windowList; Window *window; DrawDocument *document; HGraphicView *view; HTuple *hTuple; int count; windowList = [NXApp windowList]; count = [windowList count]; while ( count-- ) { window = [windowList objectAt:count]; document = [window delegate]; if ( [document isKindOf:[DrawDocument class]] ) { view = [document view]; [view closeTupleFile:filename]; } } tmpTupleList = [self tupleListForFile:filename]; count = [tmpTupleList count]; while ( count-- ) { hTuple = [tmpTupleList objectAt:count]; [tupleList removeObject:hTuple]; } [tupleBrowser reloadColumn:0]; [self updateFileForm]; [tmpTupleList freeObjects]; return self; } - (int) runModelForTypes { static const char *const filetype[2] = {"hippo", NULL}; if ( ![openPanel runModalForTypes:filetype] ) { return HD_CANCEL; } return HD_OK; } - replaceWithCuts:hTuple { List *plotList, *slist; List *list, *cutList; List *depList; Plot *cut, *plot; int i, j; BOOL ok; /* make plotList list of Plots amongst selected graphics */ slist = [graphicView selectedGraphics]; plotList = [[List allocFromZone:[self zone]] initCount:0]; [slist makeObjectsPerform:@selector(addPlotToList:) with:plotList]; [graphicView deselectAll:self]; slist = [graphicView selectedGraphics]; /* add to plotList and Plots dependent on cuts amongst selected graphics */ depList = [[plotList copyFromZone:[self zone]] initCount:0]; i = [depList count]; while (i--) { cut = [depList objectAt:i]; if ( [cut isCutPlot] ) { list = [cut dependList]; j = [list count]; while (j--) { plot = [list objectAt:i]; [plotList addObjectIfAbsent:plot]; } } } [depList free]; /* find the complete list of cuts and updated slist from plotList */ cutList = [[List allocFromZone:[self zone]] initCount:0]; i = [plotList count]; while (i--) { plot = [plotList objectAt:i]; [slist addObjectIfAbsent:plot]; list = [plot cutList]; j = [list count]; while (j--) { cut = [list objectAt:j]; [cutList addObjectIfAbsent:cut]; } } [plotList free]; /* update slist with cutList and each cut's depend list */ i = [cutList count]; while (i--) { cut = [cutList objectAt:i]; [slist addObjectIfAbsent:cut]; list = [cut dependList]; j = [list count]; while ( j-- ) { plot = [list objectAt:j]; [slist addObjectIfAbsent:plot]; } } [cutList free]; ok = [self isReplaceOK:slist with:hTuple]; if ( !ok ) { return self; } [graphicView recacheSelection]; [graphicView graphicsPerform:@selector(replaceTupleWith:) with: hTuple andDraw:YES ]; [[graphicView window] flushWindow]; return self; } - showPanel { [theInspector showPanelWithName:"Data Selection"]; [theInspector orderFrontPanel:self]; [[graphicView window] orderFront:self]; return self; } - setDisable:(int) axisIndex { if ( popUpRow != 0 ) return self; [[tpAxisButtons cellAt:axisIndex :0] setTitle:""]; [[tpAxisButtons cellAt:axisIndex :0] setEnabled:NO]; [infoForm setStringValue:"" at:axisIndex]; [infoForm drawCellAt:axisIndex :0]; return self; } - setEnable:(int) axisIndex { char *titles[5] = {"x-axis", "y-axis", "weight", "x-error", "y-error"}; if ( popUpRow != 0 ) return self; [[tpAxisButtons cellAt:axisIndex :0] setTitle:titles[axisIndex]]; if ((graphtype == THREEDSCATTER) && (axisIndex == AX_Z)) [[tpAxisButtons cellAt:axisIndex :0] setTitle:"z-axis"]; [[tpAxisButtons cellAt:axisIndex :0] setEnabled:YES]; /* add tuple column name if anything selected, else blank */ if (tpAxisIndex[axisIndex] >= 0) [infoForm setStringValue:h_getNtLabel(selectedTuple, tpAxisIndex[axisIndex]) at:axisIndex]; else [infoForm setStringValue:"" at:axisIndex]; [infoForm drawCellAt:axisIndex :0]; return self; } - setButtonsAndTitles { if (!selectedTuple) { [self setDisable:AX_X]; /* disable everything if no tuple */ [self setDisable:AX_Y]; [self setDisable:AX_W]; [self setDisable:AX_XE]; [self setDisable:AX_YE]; return self; } switch (graphtype) { case HISTOGRAM: [self setEnable:AX_X]; [self setDisable:AX_Y]; [self setEnable:AX_W]; [self setDisable:AX_XE]; [self setDisable:AX_YE]; break; case XYPLOT: case STRIPCHART: [self setEnable:AX_X]; [self setEnable:AX_Y]; [self setDisable:AX_W]; [self setEnable:AX_XE]; [self setEnable:AX_YE]; break; case SCATTERPLOT: [self setEnable:AX_X]; [self setEnable:AX_Y]; [self setDisable:AX_W]; [self setDisable:AX_XE]; [self setDisable:AX_YE]; break; case COLORPLOT: case LEGOPLOT: [self setEnable:AX_X]; [self setEnable:AX_Y]; [self setEnable:AX_W]; [self setDisable:AX_XE]; [self setDisable:AX_YE]; break; case THREEDSCATTER: [self setEnable:AX_X]; [self setEnable:AX_Y]; [self setEnable:AX_Z]; [self setDisable:AX_XE]; [self setDisable:AX_YE]; break; } return self; } - showBinding /* * called when we click on a different plot - * load up the options panel to correspond to the selected plot */ { int pos; int neg; int row; display adisplay; drawtype_t drawtype; if ( !firstPlot ) return self; adisplay = [firstPlot histDisplay]; if ( !adisplay ) return self; graphtype = h_getDispType(adisplay); pos = graphtype; neg = -pos; if ( graphtype != COLORPLOT ) { [graphTypMatrix selectCellWithTag:pos]; } else { [selectedPlot getDrawType:(drawtype_t *) &drawtype]; if ( drawtype & COLOR ) { [graphTypMatrix selectCellWithTag:pos]; } else { [graphTypMatrix selectCellWithTag:neg]; } } if ( [selectedPlot isCutPlot] ) { [graphTypMatrix setEnabled:NO]; } else { [graphTypMatrix setEnabled:YES]; } [graphTypMatrix display]; /* * get the current bindings */ tpAxisIndex[0] = h_getBinding(adisplay, XAXIS); tpAxisIndex[1] = h_getBinding(adisplay, YAXIS); tpAxisIndex[2] = h_getBinding(adisplay, WEIGHT); if (graphtype == THREEDSCATTER) { tpAxisIndex[2] = h_getBinding(adisplay, ZAXIS); } else { tpAxisIndex[2] = h_getBinding(adisplay, WEIGHT); }; tpAxisIndex[3] = h_getBinding(adisplay, XERROR); tpAxisIndex[4] = h_getBinding(adisplay, YERROR); /* * enable buttons and show titles */ [self setButtonsAndTitles]; /* * click on the X Axis button as a starting default */ row = [ tpAxisButtons selectedRow ]; if ( row < 0 ) { [tpAxisButtons selectCellAt:AX_X :0]; } if ( ![[tpAxisButtons cellAt:row :0] isEnabled] ) { [tpAxisButtons selectCellAt:AX_X :0]; } [self axisMatrixClick:self]; return self; } - updateFileForm { Matrix *browserMatrix; HTuple *hTuple; id cell; ntuple nt; char filename[FILENAME_MAX]; float mb; int i, index, rows, cols; char *titles[5] = {"file", "mode", "cols", "rows", "size"}; if ( popUpRow != 1 ) return self; for ( i = 0; i < 5; i++ ) { cell = [tpAxisButtons cellAt:i :0]; [cell setTitle:titles[i]]; [cell setEnabled:YES]; } browserMatrix = [tupleBrowser matrixInColumn:0]; index = [browserMatrix selectedRow]; if ( index < 0 ) { for ( i = 0; i < 5; i ++ ) { [infoForm setStringValue:"" at:i]; [infoForm display]; } [copyButton setEnabled:NO]; return self; } hTuple = [tupleList objectAt:index]; nt = [hTuple ntuple]; rows = h_getNtNdata(nt); cols = h_getNtDim(nt); mb = (4*rows*cols)/1000000.; strcpy( filename, NXHomeDirectory() ); index = strspn( [hTuple filename], filename ); if ( index != (strlen(filename) + 1) ) { strcpy( filename, [hTuple filename]); /* not in home directory */ } else { strcpy( filename, "~"); /* file in home directory */ strcat( filename, [hTuple filename]+(index-1) ); } if ( [hTuple isFakeFilename] ) { [copyButton setEnabled:NO]; } else { [copyButton setEnabled:YES]; } [ infoForm setStringValue:filename at:FN_INDEX]; if ( [hTuple isRef ] ) { [infoForm setStringValue:"Imported by reference" at:BY_INDEX]; } else { [infoForm setStringValue:"Imported by copy" at:BY_INDEX]; } [ infoForm setIntValue:cols at:COL_INDEX]; [ infoForm setIntValue:rows at:ROW_INDEX]; [ infoForm setFloatValue:mb at:MB_INDEX]; [ infoForm display]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.