/* RelationshipInspector.m Author: Matt Rice Date: 2005, 2006 This file is part of DBModeler. DBModeler is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. DBModeler is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with DBModeler; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "RelationshipInspector.h" #include #include #include #include #include #include #ifdef NeXT_Foundation_LIBRARY #include #else #include #endif @implementation RelationshipInspector - (NSString *) displayName { return @"Relationship inspector"; } - (EOEntity *)selectedEntity { int row = [destEntity_tableView selectedRow]; NSArray *entities = [[[EOMApp activeDocument] model] entities]; if (row == -1 || row == NSNotFound || row >= [entities count]) return nil; return [[[[EOMApp activeDocument] model] entities] objectAtIndex:row]; } - (EOAttribute *)selectedDestinationAttribute { int row = [destAttrib_tableView selectedRow]; NSArray *attribs = [[self selectedEntity] attributes]; if (row == -1 || row == NSNotFound || row >= [attribs count]) return nil; return [attribs objectAtIndex:[destAttrib_tableView selectedRow]]; } - (EOAttribute *)selectedSourceAttribute { int row = [srcAttrib_tableView selectedRow]; NSArray *attribs = [[[self selectedObject] entity] attributes]; if (row == -1 || row == NSNotFound || row >= [attribs count]) return nil; return [attribs objectAtIndex:[srcAttrib_tableView selectedRow]]; } - (int) indexOfSourceAttribute:(EOAttribute *)srcAttrib { id tmp; int row; if (srcAttrib == nil) return NSNotFound; tmp = [self selectedObject]; if (tmp == nil) return NSNotFound; tmp = [tmp entity]; if (tmp == nil) return NSNotFound; tmp = [(EOEntity *)tmp attributes]; if (tmp == nil) return NSNotFound; row = [tmp indexOfObject:srcAttrib]; return row; } - (int) indexOfDestinationAttribute:(EOAttribute *)destAttrib { id tmp; int row; if (destAttrib == nil) return NSNotFound; tmp = [self selectedObject]; if (tmp == nil) return NSNotFound; tmp = [tmp destinationEntity]; if (tmp == nil) return NSNotFound; tmp = [(EOEntity *)tmp attributes]; if (tmp == nil) return NSNotFound; row = [tmp indexOfObject:destAttrib]; return row; } - (EOJoin *) joinWithSource:(EOAttribute *)srcAttrib destination:(EOAttribute *)destAttrib { NSArray *joins; int i,c; if (!srcAttrib && !destAttrib) return nil; joins = [[self selectedObject] joins]; c = [joins count]; for (i = 0; i < c; i++) { BOOL flag; id join = [joins objectAtIndex:i]; /* if both arguments are non-nil, both must be equal, * if one argument is nil the non-nil argument must be equal */ flag = ((srcAttrib && destAttrib && [srcAttrib isEqual:[join sourceAttribute]] && [destAttrib isEqual:[join destinationAttribute]]) || (srcAttrib && (destAttrib == nil) && [srcAttrib isEqual:[join sourceAttribute]]) || (destAttrib && (srcAttrib == nil) && [destAttrib isEqual:[join destinationAttribute]])); if (flag) { return join; } } return nil; } - (EOJoin *) selectedJoin { EOJoin *join = [self joinWithSource:[self selectedSourceAttribute] destination:[self selectedDestinationAttribute]]; return join; } - (void) awakeFromNib { [name_textField setDelegate:self]; [destEntity_tableView setAllowsEmptySelection:NO]; [srcAttrib_tableView setAllowsEmptySelection:NO]; [destAttrib_tableView setAllowsEmptySelection:NO]; } - (float) displayOrder { return 0; } - (BOOL) canInspectObject:(id)anObject { return [anObject isKindOfClass:[EORelationship class]]; } - (void) updateConnectButton { [connect_button setEnabled:([self selectedDestinationAttribute] != nil)]; [connect_button setState: ([self selectedJoin] != nil) ? NSOnState : NSOffState]; } - (void) refresh { EOModel *activeModel = [[EOMApp activeDocument] model]; EOEntity *destEntity; EOAttribute *srcAttrib, *destAttrib; NSArray *joins; unsigned int row = 0; [name_textField setStringValue:[(EORelationship *)[self selectedObject] name]]; [srcAttrib_tableView reloadData]; [destAttrib_tableView reloadData]; [destEntity_tableView reloadData]; destEntity = [[self selectedObject] destinationEntity]; if (destEntity) { row = [[activeModel entities] indexOfObject:destEntity]; if (row == NSNotFound) row = 0; } else if ([destEntity_tableView numberOfRows]) row = 0; [destEntity_tableView selectRow:row byExtendingSelection:NO]; joins = [[self selectedObject] joins]; if ([joins count]) { EOJoin *join = [joins objectAtIndex:0]; srcAttrib = [join sourceAttribute]; destAttrib = [join destinationAttribute]; row = [self indexOfSourceAttribute:srcAttrib]; if (row != NSNotFound) [srcAttrib_tableView selectRow:row byExtendingSelection:NO]; row = [self indexOfDestinationAttribute:srcAttrib]; if (row != NSNotFound) [destAttrib_tableView selectRow:row byExtendingSelection:NO]; } else { if ([self numberOfRowsInTableView:srcAttrib_tableView]) { [srcAttrib_tableView selectRow:0 byExtendingSelection:NO]; } if ([self numberOfRowsInTableView:destAttrib_tableView]) { [destAttrib_tableView selectRow:0 byExtendingSelection:NO]; } } [self updateConnectButton]; [joinCardinality_matrix selectCellWithTag:[[self selectedObject] isToMany]]; [joinSemantic_popup selectItemAtIndex: [joinSemantic_popup indexOfItemWithTag: [[self selectedObject] joinSemantic]]]; } - (int) numberOfRowsInTableView:(NSTableView *)tv { EOModel *activeModel = [[EOMApp activeDocument] model]; if (tv == destEntity_tableView) { return [[activeModel entities] count]; } else if (tv == srcAttrib_tableView) return [[(EOEntity *)[[self selectedObject] entity] attributes] count]; else if (tv == destAttrib_tableView) { int selectedRow = [destEntity_tableView selectedRow]; if (selectedRow == -1 || selectedRow == NSNotFound) return 0; return [[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] count]; } return 0; } - (id) tableView:(NSTableView *)tv objectValueForTableColumn:(NSTableColumn *)tc row:(int)rowIndex { EOModel *activeModel = [[EOMApp activeDocument] model]; if (tv == destEntity_tableView) { return [(EOEntity *)[[activeModel entities] objectAtIndex:rowIndex] name]; } else if (tv == srcAttrib_tableView) { return [(EOAttribute *)[[(EOEntity *)[[self selectedObject] entity] attributes] objectAtIndex:rowIndex] name]; } else if (tv == destAttrib_tableView) { int selectedRow = [destEntity_tableView selectedRow]; if (selectedRow == NSNotFound) [destEntity_tableView selectRow:0 byExtendingSelection:NO]; return [(EOAttribute *)[[(EOEntity *)[[activeModel entities] objectAtIndex:[destEntity_tableView selectedRow]] attributes] objectAtIndex:rowIndex] name]; } return nil; } - (void) tableViewSelectionDidChange:(NSNotification *)notif { NSTableView *tv = [notif object]; if (tv == destEntity_tableView) { [destAttrib_tableView reloadData]; } else if (tv == destAttrib_tableView) { EOJoin *join = [self joinWithSource:nil destination:[self selectedDestinationAttribute]]; int row = [self indexOfSourceAttribute:[join sourceAttribute]]; if (row != NSNotFound) [srcAttrib_tableView selectRow:row byExtendingSelection:NO]; } else if (tv == srcAttrib_tableView) { EOJoin *join = [self joinWithSource:[self selectedSourceAttribute] destination:nil]; int row = [self indexOfDestinationAttribute:[join destinationAttribute]]; if (row != NSNotFound) [destAttrib_tableView selectRow:row byExtendingSelection:NO]; } [self updateConnectButton]; } - (BOOL) tableView:(NSTableView *)tv shouldSelectRow:(int)rowIndex { if (tv == destEntity_tableView) { return [[self selectedObject] destinationEntity] == nil; } else { return YES; } } - (void) tableView:(NSTableView *)tv willDisplayCell:(NSCell *)cell forTableColumn:(id)tc row:(int)row { if (tv == destEntity_tableView) { NSColor *enabledText = [NSColor controlTextColor]; NSColor *disabledText = [NSColor disabledControlTextColor]; BOOL flag = ([[self selectedObject] destinationEntity] == nil); [(NSTextFieldCell *)cell setTextColor:(flag == YES) ? enabledText : disabledText]; } } - (void) connectionChanged:(id)sender { EOAttribute *srcAttrib; EOAttribute *destAttrib; EOJoin *join; EOEntity *destEnt = [[self selectedObject] destinationEntity]; destAttrib = [self selectedDestinationAttribute]; srcAttrib = [self selectedSourceAttribute]; if ([sender state] == NSOnState) { join = [[EOJoin alloc] initWithSourceAttribute:srcAttrib destinationAttribute:destAttrib]; [[self selectedObject] addJoin:join]; [join release]; } else { join = [self joinWithSource:srcAttrib destination:destAttrib]; [[self selectedObject] removeJoin:join]; } if (destEnt != [[self selectedObject] destinationEntity]) [destEntity_tableView reloadData]; } - (void) nameChanged:(id)sender { NSString *name = [name_textField stringValue]; [(EORelationship *)[self selectedObject] setName:name]; } - (void) semanticChanged:(id)sender { /* the tag in the nib must match the values in the EOJoinSemantic enum */ [[self selectedObject] setJoinSemantic: [[sender selectedItem] tag]]; } - (void) cardinalityChanged:(id)sender { /* the tag in the nib for to-one must be 0 to-many 1 */ [[self selectedObject] setToMany: [[sender selectedCell] tag]]; } - (void) controlTextDidEndEditing:(NSNotification *)notif { id sender = [notif object]; NSLog(@"%@ %@", NSStringFromSelector(_cmd), sender); if (sender == name_textField) [self nameChanged:sender]; } @end