libs-gdl2/DBModeler/MainModelEditor.m
David Ayers efecac5875 DBModeler/ConsistencyChecker.m (+modelConsistencyCheck:): Honor
validation preferences.
	DBModeler/Modeler.m (-new:): Reimplement.
	(-setAdaptor:): Bail out it adaptor cannot be located.
	(-application:openFile:): Fine tune path checking and correct return
	values.
	(-openPrefs:): Implement.
	* DBModeler/Inspectors/RelationshipInspector.m
	(-displayName): Implement.
	(-selectedEntity): Validate selected row before commencing.
	(-selectedDestinationAttribute): Reimplement.
	(-updateConnectButton): Update enabled state of connect button.
	(-refresh): Correct handling of src/destAttrib_tableView.
	(-tableViewSelectionDidChange:): Allways call updateConnectButton.
	* DBModeler/SQLGenerator.m (-openSQLGenerator:): Reimplement.
	(-executeSQL:): Handle invalid adpator or connection information.
	(-saveAs:): Handle abort correctly.
	(-generate): Handle missing expression class.
	* DBModeler/ModelerTableEmbedibleEditor.h
	* DBModeler/ModelerEntityEditor.m (initWithParentEditor:): Correct
	autoresize behavior.
	(-activate): Update selection.
	(-needToFetch:): Do not reloadData in _topTable.
	(-displayGroupDidChangeSelection:): Update selection on parent.
	* DBModeler/ModelerTableEmbedibleEditor.m
	(-addDefaultTableColumnsForTableView:displayGroup:): Call tile instead
	of sizeToFit.
	* DBModeler/EOAdditions.m: Fix leaks.
	(setIsClassProperty): Reimplement.
	(-[setIsPrimaryKey:]): Ditto.
	(-[setIsClassProperty:]): Correct call to function.
	(-[isUsedForLocking]): Implement.
	(-[setIsUsedForLocking:]): Ditto.
	* DBModeler/MainModelEditor.h
	* DBModeler/MainModelEditor.m: Update view handling.
	* DBModeler/DefaultColumnProvider.m: Update handling of properties.
	* DBModeler/ModelerAttributeEditor.m: Update general GUI interaction.
	* DBModeler/Preferences.h: New file.
	* DBModeler/Preferences.m: Ditto.
	* DBModeler/Inspectors/RelationshipInspector.tiff: New file.
	* DBModeler/Inspectors/GNUmakefile: Add new file.
	* DBModeler/Resources/Preferences.gorm: New files.
	* DBModeler/Resources/Key_Header.tiff: Ditto.
	* DBModeler/Resources/ClassProperty_Header.tiff: Ditto.
	* DBModeler/Resources/Locking_On.tiff: Ditto.
	* DBModeler/Resources/Key_On.tiff: Ditto.
	* DBModeler/GNUmakefile: Add new files.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@23397 72102866-910b-0410-8b05-ffd578937521
2006-09-05 22:18:35 +00:00

475 lines
14 KiB
Objective-C

/**
MainModelEditor.m
Author: Matt Rice <ratmice@yahoo.com>
Date: Apr 2005
This file is part of DBModeler.
<license>
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 2 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
</license>
**/
#include <Foundation/NSRunLoop.h>
#include "MainModelEditor.h"
#include "ModelerEntityEditor.h"
#include <EOModeler/EOModelerApp.h>
#include <EOModeler/EOModelerDocument.h>
#include <EOModeler/EOModelerEditor.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EOEntity.h>
#include <EOAccess/EOAttribute.h>
#include <EOControl/EOObserver.h>
#include <EOControl/EOEditingContext.h>
#include <AppKit/NSPanel.h>
#include <AppKit/NSImage.h>
#include <AppKit/NSOutlineView.h>
#include <AppKit/NSPasteboard.h>
#include <AppKit/NSScrollView.h>
#include <AppKit/NSSplitView.h>
#include <AppKit/NSTableColumn.h>
#include <AppKit/NSView.h>
#include <Foundation/NSNotification.h>
#define DEBUG_STUFF 0
@interface ModelerOutlineView : NSOutlineView
@end
@implementation ModelerOutlineView
- (NSImage *) dragImageForRows:(NSArray *)dragRows
event: (NSEvent *)dragEvent
dragImageOffset: (NSPoint *)dragImageOffset
{
id foo = [self itemAtRow:[[dragRows objectAtIndex:0] intValue]];
NSImage *img = nil;
if ([foo isKindOfClass: [EOEntity class]]
|| [foo isKindOfClass:[EORelationship class]])
{
img = [NSImage imageNamed:@"ModelDrag"];
[img setScalesWhenResized:NO];
}
return img;
}
@end
@implementation MainModelEditor
- (id) initWithDocument:(EOModelerDocument *)document
{
if ((self = [super initWithDocument:document]))
{
NSTableColumn *_col;
NSScrollView *sv = [[NSScrollView alloc] initWithFrame:NSMakeRect(0,0,100,400)];
_vSplit = [[NSSplitView alloc] initWithFrame:NSMakeRect(0,0,600,400)];
[_vSplit setVertical:YES];
_iconPath = [[ModelerOutlineView alloc] initWithFrame:NSMakeRect(0,0,100,400)];
[_iconPath setIndentationPerLevel:8.0];
[_iconPath setIndentationMarkerFollowsCell:YES];
[_iconPath setDelegate:self];
[_iconPath setDataSource:self];
_col = [(NSTableColumn *)[NSTableColumn alloc] initWithIdentifier:@"name"];
[_iconPath addTableColumn:_col];
[_iconPath setOutlineTableColumn:AUTORELEASE(_col)];
[_iconPath setAutoresizesAllColumnsToFit:YES];
[_iconPath sizeToFit];
_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(20,80,600,400)
styleMask: NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask
backing:NSBackingStoreBuffered
defer:YES];
[_window setReleasedWhenClosed:NO];
[sv setHasHorizontalScroller:YES];
[sv setHasVerticalScroller:YES];
[sv setAutoresizingMask: NSViewWidthSizable];
[_iconPath setAutoresizingMask: NSViewWidthSizable|NSViewHeightSizable];
[sv setDocumentView:_iconPath];
RELEASE(_iconPath);
[_vSplit addSubview:sv];
RELEASE(sv);
_editorView = [[NSBox alloc] initWithFrame:NSMakeRect(0,0,500,400)];
[_vSplit addSubview: _editorView];
RELEASE(_editorView);
[_vSplit setAutoresizesSubviews:YES];
[_vSplit setAutoresizingMask: NSViewWidthSizable
| NSViewHeightSizable];
[_vSplit adjustSubviews];
[[_window contentView] addSubview:_vSplit];
RELEASE(_vSplit);
/* so addEntity: addAttribute: ... menu items work */
[_window setDelegate: document];
[[NSNotificationCenter defaultCenter] addObserver: self
selector:@selector(ecStuff:)
name: EOObjectsChangedInEditingContextNotification
object: [[self document] editingContext]];
[self setViewedObjectPath:[NSArray arrayWithObject:[document model]]];
}
return self;
}
- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver: self];
RELEASE(_window);
[super dealloc];
}
- (void) ecStuff:(NSNotification *)notif
{
if ([[notif object] isKindOfClass:[EOEditingContext class]])
{
[_iconPath reloadData];
}
}
- (void)activateEmbeddedEditor:(EOModelerEmbedibleEditor *)editor
{
NSView *mainView = [editor mainView];
int i, count;
NSArray *subviews;
subviews = [mainView subviews];
count = [subviews count];
[super activateEmbeddedEditor:editor];
for (i = 0; i < count; i++)
{
NSView *aView = [subviews objectAtIndex:i];
[aView setAutoresizesSubviews:YES];
[aView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
}
[mainView setAutoresizesSubviews:YES];
[mainView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
[mainView setFrame: [_editorView frame]];
[_vSplit replaceSubview:_editorView with:mainView];
_editorView = mainView;
[_editorView setNeedsDisplay:YES];
}
- (void)activateEditorWithClass:(Class)embedibleEditorClass
{
[super activateEditorWithClass:embedibleEditorClass];
[self activateEmbeddedEditor:
[self embedibleEditorOfClass:embedibleEditorClass]];
[_iconPath reloadData];
}
- (void) activate
{
if (![_window isVisible] || ![_window isKeyWindow])
{
[_window makeKeyAndOrderFront:self];
[self activateEmbeddedEditor:
[self embedibleEditorOfClass:
NSClassFromString(@"ModelerEntityEditor")]];
}
[_iconPath reloadData];
[super activate];
}
- (void) viewSelectedObject
{
id selection;
if ([[self selectionWithinViewedObject] count] == 0)
return;
selection = [[self selectionWithinViewedObject] objectAtIndex:0];
#if DEBUG_STUFF == 1
GSPrintf(stderr, @"viewing %@(%@)\n", NSStringFromClass([selection class]), [(EOModel *)selection name]);
#endif
if ([[self activeEditor] canSupportCurrentSelection])
[self activateEmbeddedEditor: [self activeEditor]];
else
{
NSArray *friends = [[self activeEditor] friendEditorClasses];
int editorsCount;
int i,j,c;
/* first look for instances of our friend classes that can support the
current selection */
for (i = 0, c = [friends count]; i < c; i++)
{
for (j = 0,editorsCount = [_editors count]; j < editorsCount; j++)
{
id friendEditor = [_editors objectAtIndex:j];
id friendClass = [friends objectAtIndex:i];
if ([friendEditor isKindOfClass: friendClass])
{
if ([friendEditor canSupportCurrentSelection])
{
[self activateEmbeddedEditor:friendEditor];
[super viewSelectedObject];
return;
}
}
}
}
/* instantiate friends to see if we can support the current selection */
for (i = 0,c = [friends count]; i < c; i++)
{
id friendClass = [friends objectAtIndex:i];
id friend = [[friendClass alloc] initWithParentEditor:self];
if ([friend canSupportCurrentSelection])
{
[self activateEmbeddedEditor:friend];
RELEASE(friend);
[super viewSelectedObject];
return;
}
RELEASE(friend);
}
/* look for any old editor this isn't very nice...
* because it only works with registered editors, and we can only
* register instances of editors, so a) can't load on demand non-friend
* editors, or b) we should register instances of all editors */
for (i = 0, c = [_editors count]; i < c; i++)
{
id anEditor = [_editors objectAtIndex:i];
if ([anEditor canSupportCurrentSelection])
{
[self activateEmbeddedEditor:anEditor];
[super viewSelectedObject];
return;
}
}
}
[super viewSelectedObject];
}
/* NSOutlineView datasource stuff */
- (BOOL)outlineView: (NSOutlineView *)outlineView
isItemExpandable: (id)item
{
BOOL ret = NO;
if (item == nil)
ret = ([[[_document model] entities] count] > 0);
else if ([item isKindOfClass:[EOModel class]])
ret = ([[item entities] count] > 0);
else if ([item isKindOfClass:[EOEntity class]])
ret = ([[item relationships] count] > 0);
else if ([item isKindOfClass:[EORelationship class]])
ret = 0;
#if DEBUG_STUFF == 1
NSLog(@"%@\n\t %@ %i", NSStringFromSelector(_cmd), [item class], ret);
#endif
return ret;
}
- (int) outlineView: (NSOutlineView *)outlineView
numberOfChildrenOfItem: (id)item
{
int ret = 0;
if (item == nil)
ret = 1;
else if ([item isKindOfClass: [EOModel class]])
ret = [[item entities] count];
else if ([item isKindOfClass: [EOEntity class]])
ret = [[item relationships] count];
else if ([item isKindOfClass: [EORelationship class]])
ret = 0;
#if DEBUG_STUFF == 1
NSLog(@"%@\n\t %i %@", NSStringFromSelector(_cmd), ret, [item class]);
#endif
return ret;
}
- (id)outlineView: (NSOutlineView *)outlineView
child: (int)index
ofItem: (id)item
{
id ret = @"blah.";
if (item == nil)
ret = [_document model];
else if ([item isKindOfClass: [EOModel class]])
ret = [[item entities] objectAtIndex:index];
else if ([item isKindOfClass: [EOEntity class]])
ret = [[item relationships] objectAtIndex:index];
else if ([item isKindOfClass: [EORelationship class]])
ret = nil;
#if DEBUG_STUFF == 1
NSLog(@"%@\n\tchild %@ atIndex: %i ofItem %@", NSStringFromSelector(_cmd), [ret class], index, [item class]);
#endif
return ret;
}
- (id) outlineView: (NSOutlineView *)outlineView
objectValueForTableColumn: (NSTableColumn *)tableColumn
byItem: (id)item
{
id ret;
if (item == nil)
ret = [[_document model] name];
else
ret = [item valueForKey:@"name"];
#if DEBUG_STUFF == 1
NSLog(@"objectValue: %@", ret);
#endif
return ret;
}
- (void) outlineViewSelectionDidChange:(NSNotification *)notif
{
NSMutableArray *foo = [[NSMutableArray alloc] init];
EOModel *bar = [_document model];
id item = nil;
int selectedRow = [_iconPath selectedRow];
if (selectedRow == -1)
return;
while (bar != item)
{
if (item == nil)
{
item = [_iconPath itemAtRow:selectedRow];
[foo insertObject:[NSArray arrayWithObject:item] atIndex:0];
}
else if ([item isKindOfClass:[EOEntity class]])
{
item = [item model];
[foo insertObject:item atIndex:0];
}
else if ([item isKindOfClass:[EORelationship class]])
{
item = [item entity];
[foo insertObject:item atIndex:0];
}
}
#if DEBUG_STUFF == 1
{
int i,c;
NSArray *selpath = [self selectionPath];
NSLog(@"current selection path");
for (i = 0, c = [selpath count]; i < c; i++)
{
id obj = [selpath objectAtIndex:i];
if ([obj isKindOfClass:[NSArray class]])
{
int j,d;
for (j = 0, d = [obj count]; j < d; j++)
{
GSPrintf(stderr, @"* %@(%@)\n", [[obj objectAtIndex:j] class], [(EOModel *)[obj objectAtIndex:j] name]);
}
}
else
GSPrintf(stderr, @"%@(%@)\n", [obj class], [(EOModel *)obj name]);
}
NSLog(@"changing to");
selpath = foo;
for (i = 0, c = [selpath count]; i < c; i++)
{
id obj = [selpath objectAtIndex:i];
if ([obj isKindOfClass:[NSArray class]])
{
int j,d;
for (j = 0, d = [obj count]; j < d; j++)
{
GSPrintf(stderr, @"* %@(%@)\n", [[obj objectAtIndex:j] class], [(EOModel *)[obj objectAtIndex:j] name]);
}
}
else
GSPrintf(stderr, @"%@(%@)\n", [obj class], [(EOModel *)obj name]);
}
}
#endif
[self setSelectionPath:AUTORELEASE(foo)];
[self viewSelectedObject];
}
- (BOOL) outlineView:(NSOutlineView *)view
writeItems:(NSArray *)rows
toPasteboard:(NSPasteboard *)pboard
{
NSMutableArray *foo = [[NSMutableArray alloc] init];
EOModel *bar = [_document model];
int selectedRow = [_iconPath selectedRow];
id item = [_iconPath itemAtRow:selectedRow];
if (selectedRow == -1)
return NO;
while (item != nil)
{
if (item == bar)
{
NSString *modelPath = [item valueForKey:@"path"];
if (modelPath == nil)
{
NSRunAlertPanel(@"Error", @"Must save before dragging", @"OK",@"Cancel",nil);
return NO;
}
[foo insertObject:modelPath atIndex:0];
item = nil;
}
else if ([item isKindOfClass:[EOEntity class]])
{
[foo insertObject:[item valueForKey:@"name"] atIndex:0];
item = [item model];
}
else if ([item isKindOfClass:[EORelationship class]])
{
[foo insertObject:[item valueForKey:@"name"] atIndex:0];
item = [item entity];
}
}
[pboard declareTypes: [NSArray arrayWithObject: EOMPropertyPboardType] owner:nil];
[pboard setPropertyList:foo forType:EOMPropertyPboardType];
return YES;
}
#if 0
- (void) outlineView: (NSOutlineView *)outlineView
willDisplayCell:(NSCell *)cell
forTableColumn:(NSTableColumn *)tc
item:(id)item
{
//if (![[tc identifier] isEqual:@"name"])
// return;
if ([item isKindOfClass:[EOModel class]])
[cell setImage: [NSImage imageNamed:@"Model_small.tiff"]];
if ([item isKindOfClass:[EOEntity class]])
[cell setImage: [NSImage imageNamed:@"Entity_small.tiff"]];
if ([item isKindOfClass:[EORelationship class]])
[cell setImage: [NSImage imageNamed:@"Relationship_small.tiff"]];
}
#endif
@end