libs-gdl2/DBModeler/Modeler.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

427 lines
12 KiB
Objective-C

/**
Modeler.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 "AdaptorsPanel.h"
#include "ConsistencyChecker.h"
#include "ConsistencyResults.h"
#include "MainModelEditor.h"
#include "Modeler.h"
#include "ModelerEntityEditor.h"
#include "SQLGenerator.h"
#include "Preferences.h"
#include <EOModeler/EOModelerApp.h>
#include <EOModeler/EOModelerEditor.h>
#include <EOModeler/EOModelerDocument.h>
#include <EOModeler/EOMInspectorController.h>
#include <EOAccess/EOModel.h>
#include <EOAccess/EOModelGroup.h>
#include <EOAccess/EOAdaptorChannel.h>
#include <EOAccess/EOAdaptorContext.h>
#include <EOAccess/EOAdaptor.h>
#include <AppKit/NSOpenPanel.h>
#include <Foundation/NSObject.h>
#include <Foundation/NSFileManager.h>
@interface NSMenu (im_lazy)
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s;
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s action: (SEL)sel;
@end
@interface EOModel (foo)
-(void)setCreatesMutableObjects:(BOOL)flag;
@end
@implementation NSMenu (im_lazy)
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s
{
return [self addItemWithTitle: s action: NULL keyEquivalent: nil];
}
-(id <NSMenuItem>) addItemWithTitle: (NSString *)s action: (SEL)sel
{
return [self addItemWithTitle: s action: sel keyEquivalent: nil];
}
@end
@implementation Modeler
-(void)bundleDidLoad:(NSNotification *)not
{
/* a place to put breakpoints? */
}
- (void) applicationWillFinishLaunching:(NSNotification *)not
{
int i,c;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *bundlesToLoad = RETAIN([defaults arrayForKey: @"BundlesToLoad"]);
NSMenu *mainMenu,*subMenu;
NSFileManager *fm = [NSFileManager defaultManager];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(bundleDidLoad:)
name:NSBundleDidLoadNotification
object:nil];
for (i=0, c = [bundlesToLoad count]; i < c; i++)
{
BOOL isDir;
NSString *path = [[bundlesToLoad objectAtIndex:i] stringByExpandingTildeInPath];
[fm fileExistsAtPath:path isDirectory:&isDir];
if (isDir)
{
NSLog(@"loading bundle: %@",path);
[[[NSBundle bundleWithPath: path] principalClass] class]; //call class so +initialize gets called
}
}
RELEASE(bundlesToLoad);
/* useful method for setting breakpoints after an adaptor is loaded */
mainMenu = [[NSMenu alloc] init];
[mainMenu setAutoenablesItems:YES];
subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Info...")
action: @selector(orderFrontStandardInfoPanel:)];
[subMenu addItemWithTitle: _(@"Preferences...")
action: @selector(openPrefs:)];
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Info")]];
[subMenu release];
subMenu = [[NSMenu alloc] init];
[subMenu addItemWithTitle: _(@"New...")
action: @selector(new:)
keyEquivalent: @"n"];
[subMenu addItemWithTitle: _(@"New from databse...")
action: @selector(newFromDatabase:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Open")
action: @selector(open:)
keyEquivalent: @"o"];
[subMenu addItemWithTitle: _(@"Save")
action: @selector(save:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Save As")
action: @selector(saveAs:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Revert")
action: @selector(revert:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Set Adaptor Info")
action: @selector(setAdaptor:)
keyEquivalent: @""];
[subMenu addItemWithTitle: _(@"Switch Adaptor")
action: @selector(switchAdaptor:)
keyEquivalent: @""];
[ConsistencyChecker class];
[[subMenu addItemWithTitle: _(@"Check consistency")
action: @selector(checkConsistency:)
keyEquivalent: @""] setRepresentedObject:[ConsistencyResults sharedConsistencyPanel]];
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle:_(@"Model")]];
[subMenu release];
subMenu = [[NSMenu alloc] init];
subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Copy")
action: @selector(copy:)
keyEquivalent:@"c"];
[subMenu addItemWithTitle: _(@"Cut")
action: @selector(cut:)
keyEquivalent:@"x"];
[subMenu addItemWithTitle: _(@"Paste")
action: @selector(paste:)
keyEquivalent:@"v"];
[mainMenu setSubmenu: subMenu forItem: [mainMenu addItemWithTitle: _(@"Edit")]];
[subMenu release];
subMenu = [[NSMenu alloc] init];
[subMenu addItemWithTitle:_(@"Inspector")
action: @selector(showInspector:)
keyEquivalent: @"i"];
[subMenu addItemWithTitle: _(@"Generate SQL")
action: @selector(generateSQL:)
keyEquivalent: @""];
[mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Tools")]];
[subMenu release];
subMenu = [[NSMenu alloc] init];
[subMenu setAutoenablesItems:YES];
[subMenu addItemWithTitle: _(@"Add entity")
action: @selector(addEntity:)
keyEquivalent: @"e"];
[subMenu addItemWithTitle: _(@"Add attribute")
action: @selector(addAttribute:)
keyEquivalent: @"a"];
[subMenu addItemWithTitle: _(@"Add relationship")
action: @selector(addRelationship:)
keyEquivalent: @"r"];
[subMenu addItemWithTitle: _(@"delete")
action: @selector(delete:)
keyEquivalent: @""];
[mainMenu setSubmenu:subMenu forItem:[mainMenu addItemWithTitle:_(@"Property")]];
[subMenu release];
[mainMenu addItemWithTitle: _(@"Hide")
action: @selector(hide:)
keyEquivalent: @"h"];
[mainMenu addItemWithTitle: _(@"Quit...")
action: @selector(terminate:)
keyEquivalent: @"q"];
[NSApp setMainMenu: mainMenu];
/* make this a default? */
[EOModelerDocument setDefaultEditorClass: NSClassFromString(@"MainModelEditor")];
}
- (void) _newDocumentWithModel:(EOModel *)newModel
{
EOModelerDocument *newModelerDoc;
EOModelerCompoundEditor *editor;
newModelerDoc = [[EOModelerDocument alloc] initWithModel: newModel];
editor = (EOModelerCompoundEditor*)[newModelerDoc addDefaultEditor];
[EOMApp setCurrentEditor: editor];
[EOMApp addDocument: newModelerDoc];
RELEASE(newModelerDoc);
[newModelerDoc activate];
}
- (void)new:(id)sender
{
EOModel *newModel = [[EOModel alloc] init];
NSString *modelName;
NSArray *docs = [EOMApp documents];
unsigned docNumber, c, i;
docNumber = [[EOMApp documents] count];
c = [docs count];
docNumber = c;
/* look for the largest NNNN in models named "Model_NNNN"
* or the total number of models whichever is greater.
*/
for (i = 0; i < c; i++)
{
NSString *name = [(EOModel*)[[docs objectAtIndex:i] model] name];
if ([name hasPrefix:@"Model_"])
{
NSRange range;
unsigned tmp;
name = [name substringFromIndex:6];
range = [name rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
if (!(range.location == NSNotFound) && !(range.length == 0))
continue;
range = [name rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]];
if (!(range.location == NSNotFound) && !(range.length == 0))
{
tmp = [name intValue];
docNumber = (docNumber < ++tmp) ? tmp : docNumber;
}
}
}
modelName = [NSString stringWithFormat:@"Model_%u",docNumber];
[newModel setName:modelName];
[self _newDocumentWithModel:newModel];
RELEASE(newModel);
}
- (void) newFromDatabase:(id)sender
{
NSString *adaptorName;
AdaptorsPanel *adaptorsPanel = [[AdaptorsPanel alloc] init];
adaptorName = [adaptorsPanel runAdaptorsPanel];
RELEASE(adaptorsPanel);
if (adaptorName)
{
EOAdaptor *adaptor;
EOAdaptorChannel *channel;
EOAdaptorContext *ctxt;
EOModel *newModel;
NSDictionary *connDict;
adaptor = [EOAdaptor adaptorWithName:adaptorName];
connDict = [adaptor runLoginPanel];
if (connDict)
{
[adaptor setConnectionDictionary:[adaptor runLoginPanel]];
ctxt = [adaptor createAdaptorContext];
channel = [ctxt createAdaptorChannel];
[channel openChannel];
newModel = [channel describeModelWithTableNames:[channel describeTableNames]];
[newModel setConnectionDictionary:[adaptor connectionDictionary]];
[newModel setName: [[adaptor connectionDictionary] objectForKey:@"databaseName"]];
[channel closeChannel];
[self _newDocumentWithModel:newModel];
RELEASE(newModel);
}
}
}
- (BOOL) validateMenuItem:(NSMenuItem *)menuItem
{
if ([[menuItem title] isEqualToString:@"Set Adaptor Info"])
{
return ([EOMApp activeDocument] != nil);
}
return YES;
}
- (void) setAdaptor:(id)sender
{
NSString *adaptorName;
EOAdaptor *adaptor;
AdaptorsPanel *adaptorsPanel = [[AdaptorsPanel alloc] init];
adaptorName = [adaptorsPanel runAdaptorsPanel];
RELEASE(adaptorsPanel);
if (!adaptorName)
return;
[[[EOMApp activeDocument] model] setAdaptorName: adaptorName];
adaptor = [EOAdaptor adaptorWithName: adaptorName];
[[[EOMApp activeDocument] model] setConnectionDictionary:[adaptor runLoginPanel]];
}
- (void) showInspector:(id)sender
{
[EOMInspectorController showInspector];
}
- (BOOL) application:(NSApplication *)theApp openFile:(NSString *)filename
{
NSFileManager *fm = [NSFileManager defaultManager];
NSString *pathExt = [[filename pathExtension] lowercaseString];
BOOL flag;
#if 0
NSLog(@"%@ %@ %i %i %i %i %i", NSStringFromSelector(_cmd), filename,
[fm isReadableFileAtPath:filename] == YES,
[pathExt isEqual:@"eomodel"],
[pathExt isEqual:@"eomodeld"],
[fm fileExistsAtPath:filename isDirectory:&flag],
flag);
#endif
if (([fm isReadableFileAtPath:filename] == YES
&& [pathExt isEqual:@"eomodel"])
|| ([pathExt isEqual:@"eomodeld"]
&& [fm fileExistsAtPath:filename isDirectory:&flag] && flag))
{
EOModel *model;
NS_DURING
model = [[EOModel alloc] initWithContentsOfFile:filename];
NS_HANDLER
return NO;
NS_ENDHANDLER
[self _newDocumentWithModel:model];
RELEASE(model);
return YES;
}
return NO;
}
- (void) open:(id)sender
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
NSFileManager *fm = [NSFileManager defaultManager];
if ([panel runModalForTypes:[NSArray arrayWithObjects:@"eomodeld",@"eomodel",nil]] == NSOKButton)
{
NSArray *modelPaths = [panel filenames];
int i,c;
for (i = 0, c = [modelPaths count]; i < c; i++)
{
NSString *modelPath = [modelPaths objectAtIndex:i];
NSString *pathExt = [[modelPath pathExtension] lowercaseString];
if ([fm isReadableFileAtPath:modelPath] == YES
&& ([pathExt isEqual:@"eomodeld"]
|| [pathExt isEqual:@"eomodel"]))
{
EOModel *model;
NS_DURING
model = [[EOModel alloc] initWithContentsOfFile:modelPath];
NS_HANDLER
return;
NS_ENDHANDLER
[self _newDocumentWithModel:model];
RELEASE(model);
}
}
}
}
- (void) generateSQL:(id)sender
{
[[SQLGenerator sharedGenerator] openSQLGenerator:self];
}
- (void) openPrefs:(id)sender
{
[[DBModelerPrefs sharedPreferences] showPreferences:self];
}
@end