This is BrowserViewMgr.m in view mode; [Download] [Up]
/*
* For legal stuff see the file COPYRIGHT
*/
#import "BrowserViewMgr.h"
#import "ClientInspector.h"
#import "Controller.h"
#import "ColCell.h"
#import "SessionEditor.h" /* later, this should be the abstract superclass... */
@implementation BrowserViewMgr
- awakeFromNib
{
[browser setCellClass:[ColCell class]];
[browser setTarget:self];
[browser setAction:@selector(browserClick:)];
[browser setDoubleAction:@selector(browserDoubleClick:)];
selectedCells = [[List alloc] init];
return self;
}
- mgrShow:(ClientInspector *)inspector
{
[browser loadColumnZero];
[self displaySummary];
return self;
}
/*
* On a double-click in the main client browser, add a new
* item for the selected client.
*/
- (BOOL)mgrDoubleClick:(ClientInspector *)inspector
{
return [self mgrAdd:inspector];
}
/*
* Assumes the cells in the browsers respond to cellData method.
*/
- (void)selectCellWithItem:item
{
Matrix *matrix = [browser matrixInColumn:0];
List *list = [matrix cellList];
ColCell *cell;
int i, count = [list count];
for ( i = 0; i < count; i++ ) {
cell = [list objectAt:i];
if ( [cell cellData] == item ) {
//[matrix highlightCellAt:i :0 lit:YES];
[matrix selectCell:cell];
[matrix scrollCellToVisible:i :0];
}
}
}
/*
* Allow the user to fill in a new item manually.
*/
- (BOOL)mgrAdd:(ClientInspector *)inspector
{
ClientInfo *info = [inspector selectedClient];
id item = [[self itemEditor] editItem:nil]; /* new method: editItem */
if ( item == nil )
return NO;
[info perform:[self addMethod] with:item];
[self mgrShow:inspector];
[self selectCellWithItem:item];
return YES;
}
/*
* Delete the selected expense, saving it on the undelete list
*/
- (BOOL)mgrDelete:(ClientInspector *)inspector
{
ClientInfo *info = [inspector selectedClient];
int i, count;
id item;
Matrix *matrix;
[selectedCells empty];
[browser getSelectedCells:selectedCells];
if ( (count = [selectedCells count]) == 0 )
return NO;
for ( i = 0; i < count; i++ ) {
item = [[selectedCells objectAt:i] cellData];
[info perform:[self deleteMethod] with:item];
[self saveDeletedItem:item];
}
[self mgrShow:inspector];
/* Select the first cell, for lack of anything better... */
matrix = [browser matrixInColumn:0];
[matrix scrollCellToVisible:0 :0];
[matrix selectCellAt:0 :0];
return YES;
}
- (BOOL)mgrUndelete:(ClientInspector *)inspector
{
id item = [self getDeletedItem];
ClientInfo *info = [inspector selectedClient];
if ( item ) {
[info perform:[self addMethod] with:item];
// Select the added item!
[self mgrShow:inspector];
[self selectCellWithItem:item];
return YES;
}
return NO; /* indicate that no save is required */
}
/*
* Modify the selected expense.
*/
- (BOOL)mgrModify:(ClientInspector *)inspector
{
ClientInfo *info = [inspector selectedClient];
id item = [self selectedItem];
if ( item == nil || [[self itemEditor] editItem:item] == nil )
return NO;
[info perform:[self sortMethod]];
[info computeTotalMins];
[self mgrShow:inspector];
[self selectCellWithItem:item];
return YES;
}
- (BOOL)canAdd
{
return YES;
}
/*
* We can use the modify only if there is exactly one
* item selected.
*/
- (BOOL)canModify
{
[selectedCells empty];
[browser getSelectedCells:selectedCells];
return ([selectedCells count] == 1 ? YES : NO);
}
/*
* We can use the delete button if there are any items selected.
*/
- (BOOL)canDelete
{
return [[browser matrixInColumn:0] selectedCell] ? YES : NO;
}
- (SEL)addMethod
{
[self subclassResponsibility:_cmd];
return (SEL)0;
}
- (SEL)deleteMethod
{
[self subclassResponsibility:_cmd];
return (SEL)0;
}
- (SEL)sortMethod
{
[self subclassResponsibility:_cmd];
return (SEL)0;
}
- itemEditor
{
[self subclassResponsibility:_cmd];
return self;
}
/*
* This must be implemented per subclass, so the right list is accessed
*/
- info:(ClientInfo *)info itemAt:(int)position
{
[self subclassResponsibility:_cmd];
return self;
}
/*
* Must be implemented per subclass
*/
- (int)itemCount:(ClientInfo *)info
{
[self subclassResponsibility:_cmd];
return 0;
}
@implementation BrowserViewMgr(PRIVATE)
- (int)selectedRow
{
return [[browser matrixInColumn:0] selectedRow];
}
- selectedItem
{
ClientInfo *info = [[ClientInspector sharedInstance] selectedClient];
return [self info:info itemAt:[self selectedRow]];
}
- (void)displaySummary
{
[self subclassResponsibility:_cmd];
}
- selectAll:sender
{
id result = [browser selectAll:sender];
[ClientInspector updateButtons];
return result;
}
- browserClick:sender
{
[ClientInspector updateButtons];
return self;
}
- browserDoubleClick:sender
{
/*
* Since the cell is still activated, make this happen next event pass. This
* seems to be a bug in NXBrowser, since this only is necessary if multiple
* select is enabled...
*/
[[ClientInspector sharedInstance] perform:@selector(performModify)
with:nil afterDelay:1 cancelPrevious:YES];
return nil;
}
- (int)browser:sender fillMatrix:matrix inColumn:(int)column
{
ClientInfo *info = [[ClientInspector sharedInstance] selectedClient];
int i, count = [self itemCount:info];
ColCell *cell;
id item;
[matrix renewRows:0 cols:0];
for ( i = 0; i < count; i++ ) {
[matrix addRow];
item = [self info:info itemAt:i];
cell = [matrix cellAt:i :0];
[cell setCellData:item]; /* our custom cell draws multi-column */
[cell setLoaded:YES];
[cell setLeaf:YES];
}
return count ;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.