libs-gscoredata/DataBuilder/RelationshipEditor.m

351 lines
9.4 KiB
Mathematica
Raw Permalink Normal View History

/*
RelationshipEditor.m
Implementation of the RelationshipEditor class for the DataBuilder
application.
Copyright (C) 2005 Saso Kiselkov
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#import "Private.h"
#import "RelationshipEditor.h"
#import "Document.h"
#import "DocumentWindowController.h"
@interface RelationshipEditor (Private)
- (void) setControlsEnabled: (BOOL) flag;
/**
* Validates whether the inverse relationship button should be
* enabled and sets it up.
*/
- (void) updateEnablingOfInverseRelationshipSwitch;
@end
@implementation RelationshipEditor (Private)
- (void) setControlsEnabled: (BOOL) flag
{
[name setEditable: flag];
[transient setEnabled: flag];
[optional setEnabled: flag];
[destinationEntity setEnabled: flag];
[maxCount setEditable: flag];
[minCount setEditable: flag];
[toMany setEnabled: flag];
}
- (void) updateEnablingOfInverseRelationshipSwitch
{
NSEntityDescription * destEntity;
[inverseRelationship removeAllItems];
destEntity = [relationship destinationEntity];
if (destEntity != nil)
{
[inverseRelationship setEnabled: YES];
[inverseRelationship addItemWithTitle: @""];
[inverseRelationship addItemsWithTitles: [[[destEntity
relationshipsByName] allKeys]
sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)]];
[inverseRelationship selectItemWithTitle: [[relationship
inverseRelationship] name]];
}
else
{
[inverseRelationship setEnabled: NO];
}
}
@end
@implementation RelationshipEditor
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
TEST_RELEASE(relationship);
TEST_RELEASE(entity);
TEST_RELEASE(configuration);
[super dealloc];
}
- (id) initWithModel: (NSManagedObjectModel *) aModel
document: (Document *) aDocument
{
if ((self = [super initWithModel: aModel document: aDocument]))
{
[NSBundle loadNibNamed: @"RelationshipEditor" owner: self];
// watch for changes in the entity's property list - in case
// the relationship we're editing is removed, reset our display.
[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(notePropertiesChanged:)
name: PropertiesDidChangeNotification
object: model];
}
return self;
}
- (void) setupWithRelationship: (NSRelationshipDescription *) aRelationship
inEntity: (NSEntityDescription *) anEntity
configuration: (NSString *) aConfiguration
{
NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
if (relationship != nil)
{
[nc removeObserver: self];
}
ASSIGN(relationship, aRelationship);
ASSIGN(entity, anEntity);
ASSIGN(configuration, aConfiguration);
if (relationship != nil)
{
[nc addObserver: self
selector: @selector(noteRelationshipChanged:)
name: PropertyDidChangeNotification
object: relationship];
[self setControlsEnabled: YES];
}
else
{
[self setControlsEnabled: NO];
}
[self refresh: nil];
}
- (void) refresh: sender
{
NSArray * entityNames;
if (configuration == nil)
{
entityNames = [[[model entitiesByName] allKeys]
sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
}
else
{
entityNames = [[[model entitiesByNameForConfiguration: configuration]
allKeys] sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)];
}
[name setStringValue: [relationship name]];
[transient setState: [relationship isTransient]];
[optional setState: [relationship isOptional]];
[maxCount setIntValue: [relationship maxCount]];
[minCount setIntValue: [relationship minCount]];
[toMany setState: [relationship isToMany]];
[deleteRule selectItemAtIndex: [relationship deleteRule]];
[destinationEntity removeAllItems];
[destinationEntity addItemWithTitle: @""];
[destinationEntity addItemsWithTitles: entityNames];
[destinationEntity selectItemWithTitle: [[relationship
destinationEntity] name]];
[self updateEnablingOfInverseRelationshipSwitch];
}
- (void) updateTransient: (id)sender
{
[[document undoManager] setActionName: [transient state] ?
_(@"Set Transient") : _(@"Unset Transient")];
[document setTransient: [transient state] ofProperty: relationship];
}
- (void) updateName: (id)sender
{
NSString * newName = [name stringValue];
if ([newName length] == 0)
{
NSRunAlertPanel(_(@"Invalid name"),
_(@"You must specify a name for the relationship."),
nil, nil, nil);
return;
}
if ([[[entity propertiesByName] allKeys] containsObject: newName])
{
NSRunAlertPanel(_(@"Name already in use"),
_(@"The name you have entered is already in use."),
nil, nil, nil);
return;
}
[[document undoManager] setActionName: _(@"Rename Relationship")];
[document setName: newName
ofProperty: relationship
inEntity: entity
configuration: configuration];
}
- (void) updateOptional: (id)sender
{
[[document undoManager] setActionName: [optional state] ?
_(@"Set Optional") : _(@"Unset Optional")];
[document setOptional: [optional state] ofProperty: relationship];
}
- (void) noteRelationshipChanged: (NSNotification *) notif
{
if (relationship == [notif object])
{
[self refresh: nil];
}
}
- (void) updateDestinationEntity: sender
{
NSDictionary * entitiesByName;
if (configuration == nil)
{
entitiesByName = [model entitiesByName];
}
else
{
entitiesByName = [model entitiesByNameForConfiguration: configuration];
}
[[document undoManager] setActionName: _(@"Set Destination Entity")];
[document setDestinationEntity: [entitiesByName objectForKey:
[destinationEntity titleOfSelectedItem]]
ofRelationship: relationship];
[self updateEnablingOfInverseRelationshipSwitch];
}
- (void) updateInverseRelationship: sender
{
if ([inverseRelationship indexOfSelectedItem] > 0)
{
NSEntityDescription * destEntity;
NSRelationshipDescription * invRelationship;
destEntity = [relationship destinationEntity];
NSAssert(destEntity != nil, _(@"Destination entity not found."));
invRelationship = [[destEntity relationshipsByName] objectForKey:
[inverseRelationship titleOfSelectedItem]];
NSAssert(invRelationship != nil, _(@"Inverse relationship not found."));
[[document undoManager] setActionName: _(@"Set Inverse Relationship")];
[document setInverseRelationship: invRelationship
ofRelationship: relationship];
}
else
{
[[document undoManager] setActionName: _(@"Unset Inverse Relationship")];
[document setInverseRelationship: nil ofRelationship: relationship];
}
}
- (void) updateMaxCount: sender
{
int value = [maxCount intValue];
if (value >= [relationship minCount])
{
[[document undoManager] setActionName: _(@"Set Maximum Count")];
[document setMaxCount: value ofRelationship: relationship];
[toMany setState: [relationship isToMany]];
}
else
{
NSRunAlertPanel(_(@"Invalid value"),
_(@"You must specify an integer greater than or equal to "
@"the minumum count."), nil, nil, nil);
}
}
- (void) updateMinCount: sender
{
int value = [minCount intValue];
if (value <= [relationship maxCount])
{
[[document undoManager] setActionName: _(@"Set Minimum Count")];
[document setMinCount: value ofRelationship: relationship];
}
else
{
NSRunAlertPanel(_(@"Invalid value"),
_(@"You must specify an integer lower than or equal to "
@"the maximum count."), nil, nil, nil);
}
}
- (void) updateToMany: sender
{
if ([toMany state] == YES)
{
[[document undoManager] setActionName: _(@"Set To Many")];
[document setMaxCount: 2 ofRelationship: relationship];
}
else
{
[[document undoManager] setActionName: _(@"Unset To Many")];
// this may need to be set lower too
if ([relationship minCount] > 1)
{
[document setMinCount: 1 ofRelationship: relationship];
}
[document setMaxCount: 1 ofRelationship: relationship];
}
}
- (void) updateDeleteRule: sender
{
[[document undoManager] setActionName: _(@"Set Delete Rule")];
[document setDeleteRule: [deleteRule indexOfSelectedItem]
ofRelationship: relationship];
}
- (void) notePropertiesChanged: (NSNotification *) notif
{
// reset our display if the relationship we've been editing has been removed
if (![[entity properties] containsObject: relationship])
{
[self setupWithRelationship: nil
inEntity: nil
configuration: nil];
}
}
@end