This is BrowserController.m in view mode; [Download] [Up]
// Copyright H. Giesen, University of Koblenz-Landau 1996 #import "BrowserController.h" #import "Controller.h" #import "MyBrowserCell.h" #import "BibliographicFile.h" #import "BibTeXObject.h" #import "DragView.h" #import "Preferences.h" #define NORMAL // #define LAZY // #define VERY_LAZY @implementation BrowserController - (void) setUpPopUpListAt:(int)inx { NXRect titleFrame; if( [theBrowser getTitleFrame:&titleFrame ofColumn:inx]==NULL ) if( [theBrowser getTitleFrame:&titleFrame ofColumn:0]==NULL ) return; titleFrame.W -= 4; titleFrame.H -= 4; titleFrame.X += 2; titleFrame.Y += 2; if( popUpMatrix[inx].button ) return; // already defined popUpMatrix[inx].button = [[Button alloc] initFrame:&titleFrame]; // the tag of this button is the selected (default) popUpType popUpMatrix[inx].list = [[PopUpList alloc] init]; // the tag of listitems (MenuCells) is the corresponding popUpType // the tag of list's Matrix is the corresponding browser column [[popUpMatrix[inx].list setAction:@selector(bibPopup:)] setTarget:self]; NXAttachPopUpList( popUpMatrix[inx].button, popUpMatrix[inx].list ); // fill the popUpMenu and set the initial text // addItem creates and returns a MenuCell // if( inx==0 ){ [[popUpMatrix[inx].list addItem:"file"] setTag:D_FILE]; [popUpMatrix[inx].button setTitle:"file"]; [popUpMatrix[inx].button setTag:D_FILE]; } if( inx==1 ){ [[popUpMatrix[inx].list addItem:"keys (sorted)"] setTag:D_KEY_SORTED]; [[popUpMatrix[inx].list addItem:"keys (as read)"] setTag:D_KEY_AS_READ]; [[popUpMatrix[inx].list addItem:"entries"] setTag:D_ENTRY]; [popUpMatrix[inx].button setTitle:"keys (sorted)"]; [popUpMatrix[inx].button setTag:D_KEY_SORTED]; } if( inx>1 ){ [[popUpMatrix[inx].list addItem:"keys (sorted)"] setTag:D_KEY_SORTED]; [[popUpMatrix[inx].list addItem:"keys (as read)"] setTag:D_KEY_AS_READ]; [popUpMatrix[inx].button setTitle:"keys (sorted)"]; [popUpMatrix[inx].button setTag:D_KEY_SORTED]; } [popUpMatrix[inx].list sizeToFit]; [theBrowser addSubview:popUpMatrix[inx].button]; // itemlist is the matrix of MenuCells used by the Menu [[popUpMatrix[inx].list itemList] setTag:inx]; [popUpMatrix[inx].button display]; } - (void) setUp { int i; preferences = [Preferences new]; [theBrowser setCellClass:[MyBrowserCell class]]; [theBrowser setTitle:"bibFile" ofColumn:0]; [theBrowser setAction:@selector(singleClick:)]; [theBrowser setDoubleAction:@selector(doubleClick:)]; [theBrowser reuseColumns:YES]; [theBrowser setMultipleSelectionEnabled:YES]; [theBrowser setBranchSelectionEnabled:YES]; [theBrowser useScrollBars:YES]; [theBrowser useScrollButtons:YES]; // the theBrowser must be the first responder : [theBrowser acceptArrowKeys:YES andSendActionMessages:YES]; [theBrowser setTarget:self]; [theBrowser setAutodisplay:NO]; [theBrowser setMaxVisibleColumns:3]; for(i=0; i<2; i++){ [self setUpPopUpListAt:i]; } } // both "icons" are of class DragView - (void) setUpIcons:fIcon :eIcon { entryIcon = eIcon; fileIcon = fIcon; [fileIcon clear]; [entryIcon clear]; } - (NXBrowser *) theBrowser { return theBrowser; } // return a list of NXBrowserCells - (List *)selectedFiles { if( tempList ) [tempList empty]; else tempList = [[List alloc] initCount:10]; [[theBrowser matrixInColumn:0] getSelectedCells:tempList]; return tempList; } - (BibliographicFile *)selectedFile { List *aList = [self selectedFiles]; if( [aList count]==0 ) return nil; return [[aList objectAt:0] fileObject]; } - bibPopup:sender // sender is matrix of a popUpList { int col = [sender tag]; // tag is the browsercolumn if( col<0 ) return self; [popUpMatrix[col].button setTag:[[sender selectedCell] tag]]; [theBrowser doClick:[theBrowser matrixInColumn:(col>0)?col-1:0]]; return self; } - singleClick:sender // sender is BibBrowser { int i = 0; int selCol = [sender selectedColumn]; Matrix *matrix; List *selList; char locBuffer[256]; if( selCol<0 ) return self; matrix = [sender matrixInColumn:selCol]; selList = [matrix getSelectedCells:nil]; if( [selList count]==0 ){ // nothing selected [sender getPath:locBuffer toColumn:selCol]; if( locBuffer[0] == '\0' ){ locBuffer[0] = '/'; locBuffer[1] = '\0'; } [sender setPath:locBuffer]; [entryIcon clear]; if( [self displayTypeInCol:selCol]==D_FILE ) [fileIcon clear]; [[NXApp delegate] browserDidChange:sender]; [[[bibWindow reenableDisplay] displayIfNeeded] reenableFlushWindow]; [sender displayColumn:selCol]; [selList free]; return self; } if( [self displayTypeInCol:selCol]==D_FILE ){ [[NXApp delegate] P:self]; [fileIcon setList:selList]; [entryIcon clear]; [selList free]; [[NXApp delegate] browserDidChange:sender]; [[[bibWindow reenableDisplay] displayIfNeeded] reenableFlushWindow]; [[NXApp delegate] V:self]; return self; } // show column entrytypes ? if( [self displayTypeInCol:selCol]==D_ENTRY ){ [entryIcon clear]; [selList free]; [[NXApp delegate] browserDidChange:sender]; [[[bibWindow reenableDisplay] displayIfNeeded] reenableFlushWindow]; return self; } // [self displayTypeInCol:selCol]==D_KEY_SORTED [entryIcon setList:selList]; [selList free]; [[NXApp delegate] browserDidChange:sender]; //[selectionButton display]; while( popUpMatrix[i].button ){ [popUpMatrix[i++].button display]; } [[[bibWindow reenableDisplay] displayIfNeeded] reenableFlushWindow]; return self; } - doubleClick:sender { NXTextStyle *theStyle; int selCol; Matrix *matrix; BibliographicFile *fileObj; char locBuffer[1024]; selCol = [sender selectedColumn]; matrix = [sender matrixInColumn:selCol]; fileObj = [[matrix selectedCell] fileObject]; switch( [self displayTypeInCol:selCol] ){ case D_FILE : { if( BIBTEST==NO ) return self; [fileObj showFile]; return self; } case D_KEY_SORTED : case D_KEY_AS_READ : { BibTeXObject *obj = [[matrix selectedCell] object]; // ????? locType theRange = [obj range]; char *buf = [obj buffer]; [testDocView setSel:0 :[testDocView textLength]]; theStyle = [testDocView defaultParaStyle]; [testDocView setParaStyle:theStyle]; [testDocView replaceSel:&buf[theRange.start] length:theRange.length]; [testDocView setSel:0 :0]; [testDocView scrollSelToVisible]; [testPanel setDelegate:self]; sprintf( locBuffer, "%s in %s", [[matrix selectedCell] stringValue], [fileObj fileName] ); [testPanel setTitle:locBuffer]; [testPanel orderFront:self]; [asciiDragView setTextObject:testDocView]; [testDocView addText:"\n"]; if(0)[obj callTheEditorForFile:[fileObj fullPath] inLine:[obj line]]; return self; } case D_ENTRY : return self; default : return self; } return self; } - entryObjectChanged:(BibTeXObject *)obj { int pos; int lastCol = [theBrowser lastColumn]; int dspType = [self displayTypeInCol:lastCol]; List *objList; Matrix *matrix = [theBrowser matrixInColumn:lastCol]; int selRow = [matrix selectedRow]; MyBrowserCell *selCell = [theBrowser selectedCell]; MyBrowserCell *newCell; if( dspType!=D_KEY_SORTED ) if( dspType!=D_KEY_AS_READ ) return self; if( [self displayTypeInCol:lastCol-1]!=D_FILE ){ objList = [[selCell fileObject] listForType:[[theBrowser matrixInColumn:lastCol-1] selectedRow] sorted:dspType==D_KEY_SORTED]; } else if( [self displayTypeInCol:[theBrowser lastColumn]]==D_KEY_AS_READ ) objList = [[selCell fileObject] listOfBibObjects]; else objList = [[selCell fileObject] listOfSortedBibObjects]; usedEntryList = objList; if( obj==[selCell object] ){ [[matrix removeRowAt:selRow andFree:NO] sizeToCells]; } pos = [objList indexOf:obj]; if( pos<0 ){ newCell = nil; } else{ //NORMALBROWSER [matrix insertRowAt:pos]; //newCell = [matrix cellAt:pos :0]; newCell = [theBrowser getLoadedCellAtRow:pos inColumn:lastCol]; [newCell setEnabled:YES]; [obj setStringOf:[obj key] to:newCell]; [newCell setLeaf:YES]; [newCell setObject:obj inFile:[selCell fileObject]]; [newCell setLoaded:YES]; } [matrix sizeToCells]; [matrix selectCell:newCell]; { List *selList = [matrix getSelectedCells:nil]; [entryIcon setList:selList]; [selList free]; } [matrix scrollCellToVisible:pos :0]; [theBrowser displayColumn:[theBrowser lastColumn]]; return self; } // includesType() returns YES if type is included within types. BOOL includesType (const NXAtom *types, NXAtom type) { if (types) while (*types){ //fprintf( stderr, "%s\n", *types ); if (*types++ == type) return YES; } return NO; } - getBibdata:(id)pasteboard userData:(const char *)serviceArgs error:(char **)errorMessage { int length; const char *data; if( includesType([pasteboard types], NXAsciiPboardType) ){ [pasteboard readType:NXAsciiPboardType data:&data length:&length]; [testDocView setSel:0 :[testDocView textLength]]; [testDocView setParaStyle:[testDocView defaultParaStyle]]; [testDocView replaceSel:data length:length]; [testDocView setSel:0 :0]; [testDocView scrollSelToVisible]; [testPanel setDelegate:self]; [testPanel orderFront:self]; [asciiDragView setTextObject:testDocView]; } else *errorMessage = "could not copy selection"; return self; } - selectFile:(BibliographicFile *)aFile { Matrix *matZero = [theBrowser matrixInColumn:0]; int rowCount, colCount, i; [matZero getNumRows:&rowCount numCols:&colCount]; [matZero selectCellAt:-1 :-1]; // deselect for( i=0; i<rowCount; i++ ){ if( [[theBrowser getLoadedCellAtRow:i inColumn:0] fileObject]==aFile ){ [[matZero selectCellAt:i :0] scrollCellToVisible:i :0]; [matZero sendAction]; // calls - singleClick: [theBrowser displayColumn:0]; //[theBrowser loadColumnZero]; return self; } } return self; } - (int) fillMatrix:locMatrix withFiles:(List *)listOfFiles { int i; // listOfFiles is the sorted list of all loaded files if( (listOfFiles==nil) || ([listOfFiles count]==0) ){ [fileIcon clear]; // no file selected [entryIcon clear]; return 0; } for( i=0; i<[listOfFiles count]; i++ ){ NXBrowserCell *newCell; BibliographicFile *fileObj = [listOfFiles objectAt:i]; [locMatrix addRow]; newCell = [locMatrix cellAt:i :0]; [newCell setEnabled:YES]; [[[[newCell setStringValue:[fileObj fileName]] setLeaf:NO] setLoaded:YES] setObject:nil inFile:fileObj]; } [fileIcon clear]; // no file selected [entryIcon clear]; return [listOfFiles count]; } - resetBrowser:sender { [theBrowser loadColumnZero]; [[[bibWindow reenableDisplay] displayIfNeeded] reenableFlushWindow]; return self; } - (int) fillMatrix:locMatrix withKeysForFile:(BibliographicFile *)file display:(int)dspType { int i; MyBrowserCell *newCell; BibTeXObject *litObj; List *theList; [[bibWindow disableDisplay] disableFlushWindow];// enabled in singleClick [entryIcon clear]; if( dspType==D_KEY_AS_READ ) theList = [file listOfBibObjects]; else theList = [file listOfSortedBibObjects]; usedEntryList = theList; litObj = [theList objectAt:0]; for( i=0; litObj; i++ ) { [locMatrix addRow]; newCell = [locMatrix cellAt:i :0]; [newCell setEnabled:YES]; [litObj setStringOf:[litObj key] to:newCell]; [newCell setLeaf:YES]; [newCell setObject:litObj inFile:file]; [newCell setLoaded:YES]; litObj = [theList objectAt:i+1]; } return i; } - (int) fillMatrix:locMatrix withKeysForFile:(BibliographicFile *)file andEntryType:(int)entryType display:(int)dspType { int i; BibTeXObject *litObj; List *typedList; NXBrowserCell *newCell; [[bibWindow disableDisplay] disableFlushWindow];// enabled in singleClick [entryIcon clear]; typedList = [file listForType:entryType sorted:dspType==D_KEY_SORTED]; usedEntryList = typedList; for( i=0; i<[typedList count]; i++ ){ litObj = [typedList objectAt:i]; [locMatrix addRow]; newCell = [locMatrix cellAt:i :0]; [newCell setEnabled:YES]; [litObj setStringOf:[litObj key] to:newCell]; [[newCell setLeaf:YES] setObject:litObj inFile:file]; [newCell setLoaded:YES]; } return [typedList count]; } - (int) fillMatrix:locMatrix withEntryTypesForFile:(BibliographicFile *)file { int i; NXBrowserCell *newCell; List *entryNameList = [preferences entryNameList]; [[bibWindow disableDisplay] disableFlushWindow];// enabled in singleClick for( i=0; i<[entryNameList count]; i++ ){ [locMatrix addRow]; newCell = [locMatrix cellAt:i :0]; [newCell setStringValue:(const char *)[entryNameList objectAt:i]]; [[newCell setLeaf:NO] setObject:nil inFile:file]; [newCell setLoaded:YES]; [newCell setEnabled:([file countForType:i]!=0)]; } return [entryNameList count]; } - (Matrix *) matrixInColumn:(int) col { return [theBrowser matrixInColumn:col]; } - (void) entryListDidChange:(int)row to:(int)nr { int lastColumn = [theBrowser lastColumn]; Matrix *matrix; if( lastColumn==0 ) return; if( [self displayTypeInCol:lastColumn-1]!=D_ENTRY ) return; matrix = [theBrowser matrixInColumn:lastColumn-1]; [[theBrowser getLoadedCellAtRow:row inColumn:lastColumn-1] setEnabled:nr>0]; if( nr==0 ) [matrix selectCellAt:-1 :-1]; // deselect [matrix display]; } - (void) deselectColumn:(int)col { if( col<0 ) col = [theBrowser lastColumn]; [entryIcon setList:nil]; [[theBrowser matrixInColumn:col] selectCellAt:-1 :-1]; // deselect } - (void) selectList:(List *)aList inColumn:(int)column { int i, row=0; Matrix *matrix = [theBrowser matrixInColumn:column]; [matrix selectCellAt:-1 :-1]; // deselect all for( i= [aList count]-1; i>=0; i-- ){ row = [usedEntryList indexOf:[aList objectAt:i]]; if( row>=0 ) [matrix setSelectionFrom:row to:row anchor:row lit:YES]; } [matrix scrollCellToVisible:row :0]; // scroll to last row } - (void) selectEntryObjects:(List *)aList { int i, row=0; int column = [theBrowser lastColumn]; int dspType = [self displayTypeInCol:column]; Matrix *matrix = [theBrowser matrixInColumn:column]; List *selList; [matrix selectCellAt:-1 :-1]; // deselect all if( (dspType!=D_KEY_SORTED) ) if( (dspType!=D_KEY_AS_READ) ) return; for( i= [aList count]-1; i>=0; i-- ){ row = [usedEntryList indexOf:[aList objectAt:i]]; if( row>=0 ) [matrix setSelectionFrom:row to:row anchor:row lit:YES]; } selList = [matrix getSelectedCells:nil]; [entryIcon setList:selList]; [selList free]; [matrix scrollCellToVisible:row :0]; // scroll to last row [[NXApp delegate] browserDidChange:self]; } - (int)displayTypeInCol:(int)col { return [popUpMatrix[col].button tag]; } - (int) fillMatrix:locMatrix forFile:(BibliographicFile *)aFile display:(int)dspType select:(int)entryType { if( dspType==D_ENTRY ){ return [self fillMatrix:locMatrix withEntryTypesForFile:aFile]; } if( entryType==-1 ){ // show all keys return [self fillMatrix:locMatrix withKeysForFile:aFile display:dspType]; } // show keys for a selected entryType only return [self fillMatrix:locMatrix withKeysForFile:aFile andEntryType:entryType display:dspType]; return 0; } - browserDidScroll:sender { //[[sender reenableDisplay] display]; if(0)fprintf( stderr, "%s didScroll %d %d (%d)\n", [sender name], [sender firstVisibleColumn], [sender lastVisibleColumn], [sender lastColumn] ); [self windowDidResize:sender]; return self; } #ifdef VERY_LAZY - browser:sender loadCell:cell atRow:(int)row inColumn:(int)column { if(0)fprintf( stderr, "loadCellat %d %d isLoaded=%d\n", row, column, [cell isLoaded] ); if( column==0 ){ BibliographicFile *fileObj = [[[NXApp delegate] listOfFiles] objectAt:row]; [cell setEnabled:YES]; [cell setStringValue:[fileObj fileName]]; [cell setLeaf:NO]; [cell setLoaded:YES]; [cell setObject:nil inFile:fileObj]; [fileIcon clear]; // no file selected [entryIcon clear]; return self; } if( column==1 ){ BibliographicFile *selFile= [[[self matrixInColumn:0] selectedCell] fileObject]; BibTeXObject *litObj; usedEntryList = [selFile listOfBibObjects]; litObj = [usedEntryList objectAt:row]; [cell setEnabled:YES]; [litObj setStringOf:[litObj key] to:cell]; [cell setLeaf:YES]; [cell setObject:litObj inFile:selFile]; [cell setLoaded:YES]; return self; } return self; } - (int) browser:sender getNumRowsInColumn:(int)column { //fprintf( stderr, "getNumRowsInColumn %d\n", column ); if( column==0 ){ return [[[NXApp delegate] listOfFiles] count]; } if( column==1 ){ BibliographicFile *selFile= [[[self matrixInColumn:0] selectedCell] fileObject]; return [[selFile listOfBibObjects] count]; } return 2; } #endif // very lazy #ifdef NORMAL - (int) browser:sender fillMatrix:locMatrix inColumn:(int)column { int count, dspType, eType; BibliographicFile *selFile= [[[self matrixInColumn:0] selectedCell] fileObject]; Matrix *matrix = [theBrowser matrixInColumn:column-1]; int index = [matrix selectedRow]; if( popUpMatrix[column].button==nil ){ //fprintf( stderr, "new button\n" ); [self setUpPopUpListAt:column]; [popUpMatrix[column].button display]; } if( column==0 ){ count = [self fillMatrix:locMatrix withFiles:[[NXApp delegate] listOfFiles] ]; [[NXApp delegate] colZeroIsFilled]; return count; } if( [self displayTypeInCol:column-1]==D_FILE ) eType = -1; // display keys for all entryTypes else eType = index; // entryType is the selectedRow (by accident) switch( dspType = [self displayTypeInCol:column] ){ case D_FILE : break; // col 0 ??? case D_ENTRY: case D_KEY_SORTED : case D_KEY_AS_READ : return [self fillMatrix:locMatrix forFile:selFile display:dspType select:eType]; default : return 0; } fprintf( stderr, "ERROR in fillmatrix\n" ); return 0; } #endif // normal // returns the new state of the menuCell // YES = enabled // NO = disabled - (BOOL)updateMenuFor:menuCell { BOOL newState=NO; // .. and the compiler keeps silent switch( [menuCell tag] ){ case CUT : case COPY : case PASTE : case SELECTALL : case ENTERSELECTION : newState = YES; break; default : newState = [[NXApp delegate]updateMenuFor:menuCell]; break; } return newState; } // copy selected text to findPasteBoard - enterSelection:sender { [[NXApp delegate] enterSelectionFor:testDocView]; return self; } - windowDidResize:sender { NXRect titleFrame; int i = 0; while( popUpMatrix[i].button ){ if( [theBrowser getTitleFrame:&titleFrame ofColumn:i] ){ titleFrame.W -= 4; titleFrame.H -= 4; titleFrame.X += 2; titleFrame.Y += 2; if( [popUpMatrix[i].button superview]==nil ) [theBrowser addSubview:popUpMatrix[i].button]; [popUpMatrix[i].button setFrame:&titleFrame]; } else [popUpMatrix[i].button removeFromSuperview]; i++; } return self; } - selectAllIn:matrix column:(int)col { List *selList = nil; switch( [self displayTypeInCol:col] ){ case D_FILE : selList = [matrix getSelectedCells:nil]; [fileIcon setList:selList]; break; case D_KEY_SORTED : case D_KEY_AS_READ : selList = [matrix getSelectedCells:nil]; [entryIcon setList:selList]; default : break; } if( selList ) [selList free]; [[NXApp delegate] browserDidChange:self]; return self; } - (BOOL)browser:sender columnIsValid:(int)column { return YES; } - (BOOL)browser:sender selectCell:(const char *)entry inColumn:(int)column { return YES; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.