This is ClientInspector.m in view mode; [Download] [Up]
/* * For legal stuff see the file COPYRIGHT */ #import "ClientInfo.h" #import "ClientInspector.h" #import "SessionEditor.h" #import "ExpenseEditor.h" #import "Controller.h" @interface ClientInspector(PRIVATE) - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag; - (void)enableAdd:(BOOL)flag; - (void)enableModify:(BOOL)flag; - (void)enableDelete:(BOOL)flag; - (void)enableUndelete:(BOOL)flag; - showView:newView mgr:(ViewMgr *)mgr; - (void)updateButtons; @end @implementation ClientInspector /* * Allow only one ClientInspector object to be created. */ + sharedInstance { static id obj; if ( ! obj ) { obj = [[ClientInspector alloc] init]; [NXApp loadNibSection:"ClientInspector.nib" owner:obj withNames:NO]; } return obj; } + (void)updateButtons { [[self sharedInstance] updateButtons]; } - awakeFromNib { NXRect frameRect; if (![popUpList isKindOf:[PopUpList class]]) popUpList = [popUpButton target]; [currentView getFrame:&frameRect]; [[sessionView removeFromSuperview] setFrame:&frameRect]; [[expenseView removeFromSuperview] setFrame:&frameRect]; [[clientView removeFromSuperview] setFrame:&frameRect]; [[panel contentView] replaceSubview:currentView with:sessionView]; currentView = sessionView; [viewsPanel free]; [panel setFrameAutosaveName:"ClientInspector"]; [self windowDidResize:panel]; /* make swap views adjust to saved size */ [browser setDoubleAction:@selector(browserDoubleClick:)]; controller = [NXApp delegate]; [self decacheBrowser]; /* requires 'controller' to be set first... */ [[browser matrixInColumn:0] selectCellAt:0 :0]; return self; } - (void)decacheBrowser { ClientInfo *info = [self selectedClient]; /* remember the selection */ [[controller clientList] sort]; /* in case the name was modified */ [browser loadColumnZero]; /* redisplay */ [self selectClient:info]; /* reinstate the selection */ } /* * Redraw the current view, but don't expose the window */ - (void)decacheView { List *clientList = [controller clientList]; /* * If there are no clients, force the display the Client View, * since it's the only meaningful one. */ if ( [clientList count] == 0 ) [self showClient:nil]; [currentMgr mgrShow:self]; [self updateButtons]; } /* * Called by Controller */ - display { [self decacheView]; [panel makeKeyAndOrderFront:nil]; /* was just "orderFront:" */ return self; } - (void)selectClientAt:(int)row { Matrix *matrix = [browser matrixInColumn:0]; [matrix selectCellAt:row :0]; } - selectClient:(ClientInfo *)info { id matrix = [browser matrixInColumn:0]; List *clientList = [controller clientList]; int i = [clientList indexOf:info]; [matrix selectCellAt:i :0]; return self; } - addClient:(ClientInfo *)info { List *clientList = [controller clientList]; [clientList addObjectIfAbsent:info]; [self decacheBrowser]; [controller decacheBrowser]; [self selectClient:info]; return self; } /* * Generic delete button - invoke the delete method of the * currently selected view. If the return value is non-nil, * we save the modified data structure to disk. */ - delete:sender { if ( [currentMgr mgrDelete:self] ) { [controller saveClientInfo]; [self updateButtons]; } return self; } - undelete:sender { if ( [currentMgr mgrUndelete:self] ) { [controller saveClientInfo]; [self updateButtons]; } return self; } - add:sender { if ( [currentMgr mgrAdd:self] ) { [controller saveClientInfo]; [self updateButtons]; } return self; } - modify:sender { if ( [currentMgr mgrModify:self] ) { [controller saveClientInfo]; [self updateButtons]; } return self; } - (void)performAdd { [addButton performClick:self]; } - (void)performModify { [modifyButton performClick:self]; } /* * Called when the client is selected in the inspector's top browser */ - browserClick:sender { [currentMgr mgrShow:self]; [self updateButtons]; return self; } - browserDoubleClick:sender { if ( [currentMgr mgrDoubleClick:self] ) { [controller saveClientInfo]; [self updateButtons]; } return self; } /* * Called by the Client mgr when the delete button is pressed. */ - (ClientInfo *)deleteSelectedClient { List *clientList = [controller clientList]; ClientInfo *info = [clientList removeObject:[self selectedClient]]; [self decacheBrowser]; [controller decacheBrowser]; return info; } - (ClientInfo *)selectedClient { id matrix = [browser matrixInColumn:0]; List *clientList = [controller clientList]; return [clientList objectAt:[matrix selectedRow]]; } /* * Called when a new session has been added via the main control panel. * This allows the browser to update if necessary. */ - updatedInfo:info { if ( info == [self selectedClient] ) [currentMgr mgrShow:self]; /* force redisplay */ return self; } /* * Delegated methods of NXBrowser */ - (int)browser:sender fillMatrix:matrix inColumn:(int)column { List *clientList = [controller clientList]; int i, count = [clientList count]; const char *name; id cell; for ( i = 0; i < count; i++ ) { [matrix addRow]; name = [[clientList objectAt:i] clientName]; cell = [matrix cellAt:i :0]; /* 1 dimen. matrix: always use col 0! */ [cell setStringValue:name]; [cell setLoaded:YES]; [cell setLeaf:YES]; } return count ; } - (void)closeMonth { [sessionMgr forgetDeletions]; [expenseMgr forgetDeletions]; [clientMgr forgetDeletions]; } /* * Force button title to the right state. This is necessary * because PopupLists are a kludge. */ - (void)chooseCell:cell { [popUpButton setTitle:[cell title]]; [[popUpList itemList] selectCell:cell]; } - showClient:sender { [self chooseCell:clientMenuCell]; [self showView:clientView mgr:clientMgr]; return self; } - showHours:sender { [self chooseCell:sessionMenuCell]; [self showView:sessionView mgr:sessionMgr]; return self; } - showExpenses:sender { [self chooseCell:expenseMenuCell]; [self showView:expenseView mgr:expenseMgr]; return self; } - setDocEdited:(BOOL)flag { [panel setDocEdited:flag]; return self; } /* * Delegated methods of Window */ - windowDidResize:sender { NXRect frameRect; [currentView getFrame:&frameRect]; /* Tell the other swap views their new size */ [sessionView setFrame:&frameRect]; [expenseView setFrame:&frameRect]; [clientView setFrame:&frameRect]; return self; } @end @implementation ClientInspector(PRIVATE) - enableAdd:(BOOL)addFlag delete:(BOOL)delFlag modify:(BOOL)modFlag { [controller enableAdd:addFlag]; [controller enableModify:modFlag]; [self enableAdd:addFlag]; [self enableModify:modFlag]; [self enableDelete:delFlag]; [self enableUndelete:[currentMgr canUndelete]]; return self; } - showView:newView mgr:(ViewMgr *)mgr { [panel disableFlushWindow]; if (newView != currentView) { /* Bail out if the user want to save their edits */ if ( [currentMgr isEditing] == NO || NXRunAlertPanel( [NXApp appName], "Modified data has not been saved", "Let me save it!", "I don't give a hoot", NULL ) != NX_ALERTDEFAULT ) { [[panel contentView] replaceSubview:currentView with:newView]; currentView = newView; currentMgr = mgr; [mgr mgrShow:self]; [self setDocEdited:[mgr isEditing]]; [panel display]; [self updateButtons]; } } [[panel reenableFlushWindow] flushWindow]; [panel makeKeyAndOrderFront:nil]; /* was just orderFront: before */ return self; } /* * These are packaged as methods so we can easily add accelerator * keys that are controlled at the same time... */ - (void)enableAdd:(BOOL)flag { [addButton setEnabled:flag]; } - (void)enableModify:(BOOL)flag { [modifyButton setEnabled:flag]; } - (void)enableDelete:(BOOL)flag { [controller enableDelete:flag]; [deleteButton setEnabled:flag]; } /* * Control the menu item from here... */ - (void)enableUndelete:(BOOL)flag { [controller enableUndelete:flag]; } - (void)updateButtons { BOOL flag = ([[controller clientList] count] == 0 ? NO : YES); [self enableAdd:[currentMgr canAdd] delete:[currentMgr canDelete] modify:[currentMgr canModify]]; /* Enable these when there are clients */ [sessionMenuCell setEnabled:flag]; [expenseMenuCell setEnabled:flag]; } /* * First responder method - pass to view manager */ - selectAll:sender { if ( [currentMgr respondsTo:@selector(selectAll:)] ) return [currentMgr selectAll:sender]; return nil; /* is this the right thing to do? */ } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.