|
|
1.1 ! root 1: /* MainController.m ! 2: * You may freely copy, distribute, and reuse the code in this example. ! 3: * NeXT disclaims any warranty of any kind, expressed or implied, as to its ! 4: * fitness for any particular use. ! 5: * ! 6: * Written by Mai Nguyen, NeXT Developer Support ! 7: * ! 8: */ ! 9: ! 10: #import "MainController.h" ! 11: #import "Department.h" ! 12: #import "strings.h" ! 13: ! 14: @implementation MainController ! 15: ! 16: - init ! 17: { ! 18: [super init]; ! 19: return self; ! 20: } ! 21: ! 22: - appDidInit:sender ! 23: { ! 24: ! 25: dbDataSource = [masterController dataSource]; ! 26: dbChannel = [dbDataSource databaseChannel]; ! 27: adaptorChannel = [dbChannel adaptorChannel]; ! 28: eoAdaptor = [[adaptorChannel adaptorContext] adaptor]; ! 29: ! 30: ! 31: // Bring up a login panel and get the valid connection dictionary ! 32: ! 33: if(![eoAdaptor runLoginPanelAndValidateConnectionDictionary]) ! 34: [NXApp terminate:self]; ! 35: [eoAdaptor setConnectionDictionary: [eoAdaptor connectionDictionary]]; ! 36: ! 37: rootEntity = [dbDataSource entity]; ! 38: ! 39: [self setDelegates]; ! 40: ! 41: // set up the controller to not alter the selection after a fetch ! 42: [masterController setSelectsFirstObjectAfterFetch:NO]; ! 43: ! 44: [self fetch:sender]; ! 45: return self; ! 46: } ! 47: ! 48: // Perform a fetch based on the latest options specified by user. ! 49: ! 50: - fetch:sender ! 51: { ! 52: if (optionsPanel) ! 53: [optionsPanel orderOut:sender]; ! 54: ! 55: [self setUpFetch:sender]; ! 56: ! 57: [masterController fetch]; ! 58: return self; ! 59: } ! 60: ! 61: - newRecord:sender ! 62: { ! 63: int i; ! 64: ! 65: // Clear all the current values in the form cells to prepare ! 66: // for the insertion of a new record. ! 67: ! 68: for (i = 0; i < 5; i++) ! 69: [formMatrix setStringValue:"" at:i]; ! 70: return self; ! 71: } ! 72: ! 73: - insert:sender ! 74: { ! 75: // Disable the INSERT Button if the input is not valid ! 76: if ([self validateRecord] == NO) { ! 77: [insertButton setState:0]; ! 78: NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL); ! 79: } ! 80: else { ! 81: [insertButton setState:1]; ! 82: [masterController insert:sender]; ! 83: } ! 84: return self; ! 85: } ! 86: ! 87: ! 88: // Set up the fetch order and specify a qualifier ! 89: // for the master table "Department" ! 90: ! 91: - setUpFetch:sender ! 92: { ! 93: const char *inputString; ! 94: const char *attrName = NULL; ! 95: EOQualifier *aQualifier; ! 96: id fetchOrder; ! 97: id sortAttribute; ! 98: int orderType; ! 99: ! 100: // build the qualifier. ! 101: // If the input string is empty, fetch all records. ! 102: ! 103: inputString = [(TextField *)textField stringValue]; ! 104: ! 105: if (inputString == NULL) ! 106: [dbDataSource setQualifier: [rootEntity qualifier]]; ! 107: else { ! 108: aQualifier = [[[EOQualifier alloc] initWithEntity:rootEntity ! 109: qualifierFormat:@"%A >= %d", @"DeptId", ! 110: [textField intValue]] autorelease]; ! 111: [dbDataSource setQualifier:aQualifier]; ! 112: } ! 113: ! 114: // build the fetch order based on the first column of the master ! 115: // tableview ! 116: ! 117: orderType = [sortMatrix selectedTag]; ! 118: attrName = [[masterTableview columnAt:0] title]; ! 119: sortAttribute = [rootEntity attributeNamed:[ [[NSString alloc] ! 120: initWithCString:attrName] autorelease]]; ! 121: fetchOrder = [NSArray arrayWithObject:[[[EOAttributeOrdering alloc] ! 122: initWithAttribute:sortAttribute ordering: orderType] autorelease]]; ! 123: ! 124: [dbDataSource setFetchOrder:fetchOrder]; ! 125: return self; ! 126: } ! 127: ! 128: ! 129: - (BOOL) validateRecord ! 130: { ! 131: int newId, newLocation; ! 132: BOOL result = YES; ! 133: ! 134: newId = [formMatrix intValueAt:0]; ! 135: newLocation = [formMatrix intValueAt:2]; ! 136: ! 137: // Do validation here ! 138: if ( newId < 100 || newId > 999) { ! 139: NXRunAlertPanel(NULL, ERR_INVALID_ID, NULL, NULL, NULL); ! 140: result = NO; ! 141: } ! 142: if ( newLocation != 1101 && newLocation != 1103 ! 143: && newLocation != 1104 && newLocation != 1106 ! 144: && newLocation != 1207) { ! 145: NXRunAlertPanel(NULL, ERR_INVALID_LOCATION, NULL, NULL, NULL); ! 146: result = NO; ! 147: } ! 148: return result; ! 149: ! 150: } ! 151: - setDelegates ! 152: { ! 153: #ifdef DEBUG ! 154: [adaptorChannel setDebugEnabled:YES]; ! 155: #endif ! 156: [adaptorChannel setDelegate:self]; ! 157: [(EOController *) masterController setDelegate:self]; ! 158: ! 159: return self; ! 160: } ! 161: ! 162: @end ! 163: ! 164: @implementation MainController (EOAdaptorDelegation) ! 165: ! 166: //This method is useful to trace SQL queries ! 167: - (void)adaptorChannel:channel ! 168: didEvaluateExpression:(NSString *)expression ! 169: { ! 170: if (sqlPanel) { ! 171: [text appendToText:"SQL Query:\n"]; ! 172: [text appendToText:[expression cString]]; ! 173: [text appendToText:"\n"]; ! 174: } ! 175: } ! 176: @end ! 177: ! 178: ! 179: @implementation MainController (EOControllerDelegation) ! 180: ! 181: // This method is called before each update. Since the controller has ! 182: // buffer edits turned ON, this method is called when the user explicitly ! 183: // presses the UPDATE button. ! 184: ! 185: - (NSDictionary *)controller:(EOController *)controller ! 186: willSaveEdits: (NSDictionary *)edits ! 187: toObject:object ! 188: { ! 189: if ([self validateRecord] == YES) ! 190: return edits; ! 191: else { ! 192: NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL); ! 193: return nil; ! 194: } ! 195: } ! 196: ! 197: // Take the input from the formcells and create a new record. ! 198: // This delegate method can be used to set up the default values of a newly ! 199: // created EO. By default, we use the current user input in the formcells ! 200: // to create a new record. ! 201: ! 202: ! 203: - (BOOL)controller:(EOController *)controller willInsertObject:object atIndex: (unsigned)newIndex ! 204: { ! 205: [object setDeptId: (int)[formMatrix intValueAt:0]]; ! 206: [object setDepartmentName:[[[NSString alloc] initWithCString: ! 207: [formMatrix stringValueAt:1]] autorelease]]; ! 208: [object setLocationId:(int)[formMatrix intValueAt:2]]; ! 209: // The to-many relationship points to an empty autoreleased array ! 210: [object setToEmployee:[NSArray array]]; ! 211: return YES; ! 212: ! 213: } ! 214: ! 215: // After insertion, refetch object so that the derived attributes are ! 216: // properly redisplayed. ! 217: ! 218: - (void)controller:(EOController *)controller didInsertObject:object ! 219: inDataSource:dataSource ! 220: { ! 221: [dbChannel refetchObject:object]; ! 222: } ! 223: ! 224: // After an update, refetch object so that the derived attributes are ! 225: // properly redisplayed. ! 226: ! 227: - (void)controller:(EOController *)controller didUpdateObject:object ! 228: inDataSource:dataSource ! 229: { ! 230: [dbChannel refetchObject:object]; ! 231: } ! 232: ! 233: // When the insert operation failed, remove the wrong record and rollback ! 234: // the data source. A failure usually happens when trying to insert a duplicate ! 235: // key. Since an insert operation adds a new record after the current ! 236: // selection, the index has to be computed accordingly. ! 237: ! 238: ! 239: - (EODataSourceFailureResponse)controller:(EOController *)controller ! 240: failedToInsertObject:object ! 241: inDataSource:dataSource; ! 242: { ! 243: NXRunAlertPanel(NULL, ERR_INSERT_FAIL, NULL, NULL, NULL); ! 244: ! 245: [controller deleteObjectAtIndex:([masterTableview selectedRow] + 1)]; ! 246: ! 247: return EORollbackDataSourceFailureResponse; ! 248: } ! 249: ! 250: - (EODataSourceFailureResponse) controller:(EOController *)controller ! 251: failedToUpdateObject:object ! 252: inDataSource:dataSource ! 253: { ! 254: NXRunAlertPanel(NULL, ERR_UPDATE_FAIL, NULL, NULL, NULL); ! 255: // Restore object to its previous state ! 256: [dbChannel refetchObject:object]; ! 257: ! 258: return EORollbackDataSourceFailureResponse; ! 259: } ! 260: ! 261: ! 262: // When deleting a department, we need to null all the references ! 263: // to that department. Therefore, the "toEmployee" relationship is ! 264: // used to find the employee records attached to a given department. ! 265: // All department ids will then be nulled out. ! 266: ! 267: ! 268: - (BOOL)controller:controller willDeleteObject:object ! 269: { ! 270: ! 271: NSArray *employeeArray = [object toEmployee]; ! 272: NSEnumerator *enumerator = [employeeArray objectEnumerator]; ! 273: EOGenericRecord *employee; ! 274: ! 275: while((employee = [enumerator nextObject]) != nil) { ! 276: [employee setObject:[EONull null] forKey:@"DeptId"]; ! 277: [(id)[controller dataSource] updateObject:employee]; ! 278: } ! 279: ! 280: return YES; ! 281: } ! 282: ! 283: ! 284: // Implementing this delegate method allows the controller to discard ! 285: // pending edits. In this example, pending edits are edits rejected by ! 286: // the validation mechanism, hence they can be discarded. ! 287: ! 288: - (BOOL) controllerWillDiscardEdits:(EOController *)controller ! 289: { ! 290: return YES; ! 291: } ! 292: ! 293: @end ! 294: ! 295: @implementation Text(printResults) ! 296: ! 297: - appendToText:(const char *)newText ! 298: { ! 299: int currentLength = [self textLength]; ! 300: ! 301: [self setSel:currentLength :currentLength]; ! 302: [self replaceSel:newText]; ! 303: [self scrollSelToVisible]; ! 304: return self; ! 305: } ! 306: ! 307: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.