This is MacroDB.m in view mode; [Download] [Up]
// Copyright H. Giesen, University of Koblenz-Landau 1996 #import "MacroDB.h" #import "Controller.h" #import "BibliographicFile.h" #import "Preferences.h" #import "BibTexView.h" #import "TabMatrix.h" #import <dbkit/dbkit.h> static id macroDB = nil; #define STRING_MODE 301 #define MACRO_MODE 302 #define STYLE_MODE 303 @implementation MacroDB + new { if( macroDB==nil ){ macroDB = [[super alloc] init]; } return macroDB; } + alloc { return [self notImplemented:_cmd]; } - (void)alert:(const char *)txt :(const char *)para { NXRunAlertPanel("Bibliography", txt, " OK ", // 1: default button NULL, // 0: alternate NULL, //-1: other para ); } - makeTabMatrix { NXRect backgroundRect,matrixRect; TabSelectionCell *aCell; unsigned int entryFormMask = [tabCellView autosizing]; //€as set in IB /* Set tabCellView to be flipped ('cause Matrices are flipped) */ [tabCellView setFlipped:YES]; /* Get the tabCellView's dimensions */ [tabCellView getBounds:&backgroundRect]; /* Set up the matrix bounds */ matrixRect = backgroundRect; matrixRect.origin.y = NX_MAXY(&matrixRect) - 17.0; /* Prepare a matrix to go inside the tabCellView */ tabMatrix = [[Matrix allocFromZone:[self zone]] initFrame:&matrixRect mode:NX_RADIOMODE cellClass:[TabSelectionCell class] numRows:1 numCols:3]; /* Set the background gray of tabMatrix to NX_DKGRAY */ [tabMatrix setBackgroundGray:NX_DKGRAY]; /* Set the autosizing and autoscrolling attributes of the matrix */ [tabMatrix setAutosizing:entryFormMask]; //[tabMatrix setAutoscroll:YES]; [tabMatrix setAutosizeCells:YES]; /* Stick the matrix in our scrollView */ [tabCellView addSubview:tabMatrix]; [tabCellView setAutoresizeSubviews:YES]; [tabCellView setAutosizing:entryFormMask]; /* Set our target and single-click actions */ [tabMatrix setTarget:self]; [tabMatrix setAction:@selector(tabMatrixAction:)]; aCell = [tabMatrix cellAt:0 :0]; [aCell initTextCell:"strings"]; aCell = [tabMatrix cellAt:0 :1]; [aCell initTextCell:"macros"]; aCell = [tabMatrix cellAt:0 :2]; [aCell initTextCell:"styles"]; /* Size tabMatrix to its cells and display it */ [tabMatrix sizeToCells]; [tabMatrix display]; return self; } - tabMatrixAction:sender { [[mainBox window] disableDisplay]; displayMode = [sender selectedCol] + STRING_MODE; switch( displayMode ){ case STRING_MODE: case MACRO_MODE: [mainBox setContentView:stringView]; [self show:self]; break; case STYLE_MODE: [mainBox setContentView:styleBrowserBox]; break; default : break; } [[mainBox window] reenableDisplay]; [mainBox display]; return self; } - awakeFromNib { [[mainBox window] setFrameUsingName:"MacroWindow"]; [[mainBox window] setFrameAutosaveName:"MacroWindow"]; [stringView setRowHeadingVisible:NO]; [stringView setColumnHeadingVisible:YES]; [stringView allowVectorReordering:YES]; [stringView allowVectorResizing:YES]; [stringView setDataSource:self]; [stringView setTarget:self]; [stringView setDelegate:self]; [stringView setAction:@selector(tableViewSingleClick:)]; [stringView setDoubleAction:@selector(tableViewDoubleClick:)]; [stringView setGridVisible:YES]; preferences = [Preferences new]; STRING = [preferences indexOfEntryname:"STRING"]; NOTE = [preferences indexOfFieldname:"NOTE"]; [mainBox setContentView:stringView]; displayMode = STRING_MODE; // style browser [styleBrowser setDelegate:self]; [styleBrowser setTarget:self]; [styleBrowser setAction:@selector(styleSingleClick:)]; [styleBrowser setDoubleAction:@selector(styleDoubleClick:)]; [styleBrowser setMinColumnWidth:22]; [styleBrowser setMaxVisibleColumns:2]; [styleBrowser setTitle:"TEXINPUTS" ofColumn:0]; styleFile = NXCopyStringBuffer( "no style file selected" ); [self makeTabMatrix]; return self; } - fileDidChangeTo:theFile { if( dbWindow && [dbWindow isVisible] && (displayMode==STRING_MODE) ){ [self show:self file:theFile]; } return self; } /*====================================================================== * methods (delegate methods and others) for the style browser *======================================================================*/ // browser delegate methods #include <sys/dir.h> /* POSIX applications #include <dirent.h> */ - (BOOL)isDirectory:(const char *)path { struct stat fBuf; int rtn = stat(path, &fBuf); if( rtn<0 ){ perror("stat error"); return NO; } return (S_IFDIR & fBuf.st_mode) != 0; } - styleSingleClick:sender { //NXRect aRect; //NXStream *localStream = NXOpenMemory( NULL, 0, NX_READWRITE ); return self; //fprintf( stderr, "styleSingleClick\n" ); //[stringButton printPSCode:self]; // TEST //[stringButton getFrame:&aRect]; //[stringButton convertRect:&aRect fromView:nil]; //[stringButton copyPSCodeInside:&aRect to:localStream]; //NXSaveToFile(localStream, "/tmp/abcde.eps"); //return self; } - (char *)nextFunctionName:(NXStream *)aStream { char buf[1024]; int i = 0; while( (mc!=EOF) && NXIsAlpha(mc) ){ buf[i++] = mc; mc = NXGetc( aStream ); } buf[i] = '\0'; //fprintf( stderr, ">%s<\n", buf ); return buf; } - skipEmptyText:(NXStream *)aStream { while( (mc!=EOF) && (NXIsSpace(mc) || (mc=='%')) ){ if( mc=='%' ){ mc = NXGetc( aStream ); // skip '%' while( (mc!=EOF) && (mc!='\n') ) mc = NXGetc( aStream ); // mc == '\n' || mc==EOF } else mc = NXGetc( aStream ); } return self; } - skipString:(NXStream *)aStream { if( mc!='"' ) return self; // internal error mc = NXGetc( aStream ); // skip stringquote while( YES ){ if( (mc=='"') || (mc==EOF) ) return self; mc = NXGetc( aStream ); } return self; } - skipParameter:(NXStream *)aStream { int braceLevel = 1; // mc == LBRACE while( braceLevel && (mc!=EOF) ){ mc = NXGetc( aStream ); if( mc=='%' ) [self skipEmptyText:aStream]; if( mc=='"' ) [self skipString:aStream]; if( mc==RBRACE ) braceLevel--; if( mc==LBRACE ) braceLevel++; } mc = NXGetc( aStream ); // skip RBRACE return self; } - readMacro:(NXStream *)aStream { // we need a stream for the definitions if( !texStream ){ texStream = NXOpenMemory(NULL, 0, NX_READWRITE); NXSeek(texStream, 0, NX_FROMSTART); NXPrintf( texStream, "macros "); // we may not start with index 0 ! } [self skipEmptyText:aStream]; // mc must now be LBRACE mc = NXGetc( aStream ); // skip LBRACE [self skipEmptyText:aStream]; // collect the macro name [macroList addObject:(id)NXTell( texStream )]; // here starts the macro while( NXIsAlpha(mc) ){ NXPutc( texStream, mc); mc = NXGetc( aStream ); } NXPutc( texStream, '\0'); [self skipEmptyText:aStream]; mc = NXGetc( aStream ); // skip RBRACE [self skipEmptyText:aStream]; // mc must be LBRACE mc = NXGetc( aStream ); // skip LBRACE // collect the macro text while( mc!=RBRACE ){ NXPutc( texStream, mc); mc = NXGetc( aStream ); } NXPutc( texStream, '\0'); mc = NXGetc( aStream ); // skip RBRACE return self; } - initFromStream:(NXStream *)aStream { char *theName; styleStream = aStream; if( styleStream==NULL ){ //[self alert:"cannot open %s" :fname]; return self; } // we need a stream for the macro definitions if( !texStream ){ texStream = NXOpenMemory(NULL, 0, NX_READWRITE); } NXSeek(texStream, 0, NX_FROMSTART); NXPrintf( texStream, "macros "); // we may not start with index 0 ! if( macroList==nil ) macroList = [[List alloc] initCount:50]; [macroList empty]; mc = NXGetc( styleStream ); while( (mc!=EOF) ){ [self skipEmptyText:styleStream]; theName = [self nextFunctionName:styleStream]; if( strcasecmp( theName, "macro" )==0 ){ [self readMacro:styleStream]; } [self skipEmptyText:styleStream]; while( mc==LBRACE ){ // skip a parameter list [self skipParameter:styleStream]; } } return self; } - (BOOL) initFromFile:(const char *)fname { NXStream *fileStream = NXMapFile(fname, NX_READONLY); if( fileStream==NULL ){ [self alert:"cannot open file %s" :fname]; return NO; } if( styleFile ) free( styleFile ); styleFile = NXCopyStringBuffer( fname ); [self initFromStream:fileStream]; NXCloseMemory( fileStream, NX_FREEBUFFER ); return YES; } - styleDoubleClick:sender { char path[1024]; int selCol = [sender selectedColumn]; //fprintf( stderr, "styleDoubleClick\n" ); if( selCol==0 ) return self; [styleBrowser getPath:path toColumn:selCol+1]; // starts with // if( [self initFromFile:(path+1)]==NO ) return self; if(0)[[Application workspace] openFile:(path+1) withApplication:[preferences theEditor]]; //[popUpButton setTitle:"macros"]; [tabMatrix selectCellAt:0 :1]; [dbWindow disableDisplay]; [mainBox setContentView:stringView]; displayMode = MACRO_MODE; [self show:self]; return self; } - (int)fillColZero:locMatrix { int i=0, row=0; id newCell; char buffer[1024]; List *args = [preferences shellArgsOf:"TEXINPUTS" toBuffer:buffer size:1024]; if (args==nil ){ //fprintf( stderr, "Erorr: no variable TEXINPUTS\n" ); args = [[List alloc] init]; [args addObject:(id)"."]; [args addObject:(id)"/usr/lib/tex/inputs"]; // default } for( i=0; i<[args count]; i++ ){ const char *para = (const char *)[args objectAt:i]; if( para[0]=='\0' ) continue; // (empty string) [locMatrix addRow]; newCell = [locMatrix cellAt:row :0]; row++; if( strcmp(para, ".")==0 ){ [newCell setStringValue:[preferences tempDirectory]]; //[newCell setStringValue:NXHomeDirectory()]; } else{ [newCell setStringValue:para]; } [newCell setLeaf:NO]; [newCell setLoaded:YES]; } [args free]; return row; } - (int)fillMatrix:locMatrix { DIR *dirp; struct direct *dp; int length; int count = 0; id newCell; char path[1024]; char buffer[1024]; [styleBrowser getPath:path toColumn:[styleBrowser selectedColumn]+1]; // path starts with "//", do not use the first character dirp = opendir( path+1 ); if( dirp==NULL ){ sprintf( buffer, "%s\n%s", path+1, strerror(errno) ); [self alert:" %s" :buffer]; return 0; } for( dp = readdir(dirp); dp != NULL; dp = readdir(dirp) ) { length = strlen( dp->d_name ); if( length<=4 ) continue; // show also directories sprintf( buffer, "%s/%s", path+1, dp->d_name ); if( NO && [self isDirectory:buffer] ){ [locMatrix addRow]; newCell = [locMatrix cellAt:count :0]; [newCell setStringValue:dp->d_name]; [newCell setLeaf:NO]; [newCell setLoaded:YES]; count++; continue; } if( dp->d_name[length-4]=='.' && dp->d_name[length-3]=='b' && dp->d_name[length-2]=='s' && dp->d_name[length-1]=='t' ){ [locMatrix addRow]; newCell = [locMatrix cellAt:count :0]; [newCell setStringValue:dp->d_name]; [newCell setLeaf:YES]; [newCell setLoaded:YES]; count++; } } closedir(dirp); return count; } - (int)browser:sender fillMatrix:locMatrix inColumn:(int)column { //id matrix = [theBrowser matrixInColumn:column-1]; //int index = [matrix selectedRow]; if( column==0 ){ return [self fillColZero:locMatrix]; } return [self fillMatrix:locMatrix]; } /*======================================================================*/ - tableViewSingleClick:sender { int col = [sender selectedColumn]; int row = [sender selectedRow]; View *colHead = [sender columnHeading]; NXRect aRect; [colHead getVisibleRect:&aRect]; if( row<0 ){ [stringButton setEnabled:NO]; [expndStrButton setEnabled:NO]; } else{ [stringButton setEnabled:YES]; [expndStrButton setEnabled:YES]; } if(0)fprintf( stderr, "selection is row(%d/%d) col(%d/%d)\n", [sender selectedRow], [sender rowCount], col, [sender columnCount] ); return self; } - tableViewDoubleClick:sender { //fprintf( stderr, "tableViewDoubleClick %s\n", [sender name] ); return self; } - insertString:sender { id <DBTableVectors> vector; id rowIdentifier; int here; int row = [stringView selectedRow]; char buf[1024]; if( row<0 ) return self; vector = [stringView rowAt:row]; rowIdentifier = [vector identifier]; switch( displayMode ){ case STRING_MODE : [rowIdentifier parseSelf]; [rowIdentifier copyRange:[rowIdentifier key] toBuffer:(buf+1)]; break; case MACRO_MODE : here = (int)[macroList objectAt:(int)rowIdentifier]; sprintf( (buf+1), ¯oBuffer[here] ); break; default : return self; } buf[0] = '@'; [[BibTexView new] insertMacro:buf isRaw:NO]; return self; } - insertExpandedString:sender { int here; id <DBTableVectors> vector; id rowIdentifier; int row = [stringView selectedRow]; char buf[1024]; if( row<0 ) return self; vector = [stringView rowAt:row]; rowIdentifier = [vector identifier]; switch( displayMode ){ case STRING_MODE : [rowIdentifier parseSelf]; [rowIdentifier convertRawField:[rowIdentifier fieldFor:NOTE] to:buf]; [[BibTexView new] insertMacro:buf isRaw:NO]; break; case MACRO_MODE : here = (int)[macroList objectAt:(int)rowIdentifier]; while( macroBuffer[here++] ); // skip the definition [[BibTexView new] insertMacro:¯oBuffer[here] isRaw:YES]; break; default : return self; } return self; } - show:sender file:selFile { int i; char buffer[128]; id <DBTableVectors> vector; ///id selFile = [[NXApp delegate] selectedFile]; id anObj; id typedList; if( !dbWindow ){ // first call [NXApp loadNibSection:"macroWindow.nib" owner:self]; } if( sender!=self )[dbWindow orderFront:self]; if( displayMode==STYLE_MODE ) return self; if(0)fprintf( stderr, "show obj %08x\n", (unsigned)selFile ); if(0)fprintf( stderr, "show file %s\n", [selFile fullPath] ); [stringButton setEnabled:NO]; [expndStrButton setEnabled:NO]; //if( selFile==nil ) return self; if( [dbWindow isDisplayEnabled] ) [dbWindow disableDisplay]; for(i=[stringView rowCount]-1; i>=0; i-- ){ id row = [stringView rowAt:i]; [stringView removeRowAt:i]; // remove from display [row free]; } for(i=[stringView columnCount]-1; i>=0; i-- ){ id col = [stringView columnAt:i]; [stringView removeColumnAt:i]; // remove from display [col free]; } if( displayMode==MACRO_MODE ){ //show MACRO [stringButton setTitle:"insert macro"]; [expndStrButton setTitle:"insert expanded macro"]; [stringView addColumn:(id)0 withTitle:"Macro"]; [stringView addColumn:(id)1 withTitle:styleFile ]; if( macroList && texStream ){ NXGetMemoryBuffer( texStream, ¯oBuffer, &len, &maxLength); for( i=0; i<[macroList count]; i++ ){ [stringView addRow:(id)i withTitle: ¯oBuffer[(int)[macroList objectAt:i]] ]; } } } else{ //show @STRING [stringButton setTitle:"insert string"]; [expndStrButton setTitle:"insert expanded string"]; [stringView addColumn:(id)0 withTitle:"String"]; if( selFile==nil ){ [stringView addColumn:(id)1 withTitle:"no or multiple selection" ]; } else { [stringView addColumn:(id)1 withTitle:[selFile fullPath] ]; typedList = [selFile listForType:STRING sorted:YES]; for( i=0; i<[typedList count]; i++ ){ anObj = [typedList objectAt:i]; [anObj copyRange:[anObj key] toBuffer:buffer]; [stringView addRow:anObj withTitle:buffer]; //[stringView addRow:anObj at:i+1]; } } } vector = [stringView columnAt:0]; [vector setMaxSize:100.0]; [stringView layoutChanged:self]; if( sender!=self )[dbWindow orderFront:self]; [dbWindow reenableDisplay]; [dbWindow display]; [stringView setEditable:YES]; return self; } - show:sender { return [self show:sender file:[[NXApp delegate] selectedFile]]; } /*====================================================================== * DBTableView data source (pseudo-delegate) methods *======================================================================*/ - tableViewDidChangeSelection:aTableView { [self tableViewSingleClick:aTableView]; return self; } - (unsigned int)rowCount { //fprintf( stderr, "rowCount\n" ); return 0; } - (unsigned int)columnCount { fprintf( stderr, "columnCount\n" ); return 2; } /* DBTV sends this message when it needs to know what to display */ - getValueFor:identifier at:(unsigned int)aPosition into:aValue { //fprintf( stderr, "getValueFor %d at %d\n", (int)identifier, aPosition ); [aValue setIntValue:5*aPosition]; return nil; } /* DBTV sends this message when it needs to know what to display */ - getValueFor:rowIdentifier :colIdentifier into:aValue { int here; if(0)fprintf( stderr, "getValueFor row(%d)/col(%d)\n", (unsigned)rowIdentifier, (unsigned)colIdentifier ); if( displayMode==STRING_MODE ){ // show @STRING // rowIdentifier is an entryObject // colIdentifier is the column number [rowIdentifier parseSelf]; if( (int)colIdentifier==0 ){ //String [rowIdentifier setStringOf: [rowIdentifier key] to:aValue]; } if( (int)colIdentifier==1 ){ //Expansion [rowIdentifier setStringOf: [rowIdentifier fieldFor:NOTE] to:aValue]; } return nil; } // displayMode==MACRO_MODE // rowIdentifier is the row number ( = index in macroList) // colIdentifier is the column number here = (int)[macroList objectAt:(int)rowIdentifier]; if( (int)colIdentifier==0 ){ // macro name [aValue setStringValue: ¯oBuffer[here]]; //fprintf( stderr, "0: %s\n", ¯oBuffer[here] ); } if( (int)colIdentifier==1 ){ //Expansion while( macroBuffer[here++] ); // skip the definition //fprintf( stderr, "0: %s\n", ¯oBuffer[here] ); [aValue setStringValue: ¯oBuffer[here]]; } return nil; } /* DBTV sends this message when data in a cell has changed */ - setValueFor:identifier at:(unsigned int)aPosition from:aValue { fprintf( stderr, "setValueFor at %d\n", aPosition ); return nil; } - setValueFor:rowIdentifier :columnIdentifier from:aValue { fprintf( stderr, "setValueFor row=%d col=%d\n", (int)rowIdentifier, (int)columnIdentifier ); return nil; } /*====================================================================== * end of DBTableView data *======================================================================*/ @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.