diff options
Diffstat (limited to 'Source/SPUserManagerDelegate.m')
-rw-r--r-- | Source/SPUserManagerDelegate.m | 316 |
1 files changed, 316 insertions, 0 deletions
diff --git a/Source/SPUserManagerDelegate.m b/Source/SPUserManagerDelegate.m new file mode 100644 index 00000000..dc409308 --- /dev/null +++ b/Source/SPUserManagerDelegate.m @@ -0,0 +1,316 @@ +// +// $Id$ +// +// SPUserManagerDelegate.m +// sequel-pro +// +// Created by Mark Townsend on Jan 01, 2009 +// +// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// More info at <http://code.google.com/p/sequel-pro/> + +#import "SPUserManagerDelegate.h" +#import "SPUserMO.h" +#import "SPServerSupport.h" +#import "ImageAndTextCell.h" + +static NSString *SPGeneralTabIdentifier = @"General"; +static NSString *SPGlobalPrivilegesTabIdentifier = @"Global Privileges"; +static NSString *SPResourcesTabIdentifier = @"Resources"; +static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges"; + +@interface SPUserManager (SPDeclaredAPI) + +- (void)_initializeSchemaPrivs; +- (void)_initializeAvailablePrivs; +- (void)_selectParentFromSelection; +- (void)_selectFirstChildOfParentNode; +- (NSArray *)_fetchUserWithUserName:(NSString *)username; + +- (NSArray *)_fetchPrivsWithUser:(NSString *)username schema:(NSString *)selectedSchema host:(NSString *)host; + +@end + + +@implementation SPUserManager (SPUserManagerDelegate) + +#pragma mark - +#pragma mark SplitView delegate methods + +/** + * Return the maximum possible size of the splitview. + */ +- (CGFloat)splitView:(NSSplitView *)sender constrainMaxCoordinate:(CGFloat)proposedMax ofSubviewAt:(NSInteger)offset +{ + return proposedMax - 620; +} + +/** + * Return the minimum possible size of the splitview. + */ +- (CGFloat)splitView:(NSSplitView *)sender constrainMinCoordinate:(CGFloat)proposedMin ofSubviewAt:(NSInteger)offset +{ + return proposedMin + 120; +} + +#pragma mark - +#pragma mark TableView Delegate Methods + +- (void)tableViewSelectionDidChange:(NSNotification *)notification +{ + id object = [notification object]; + + if (object == schemasTableView) { + [grantedSchemaPrivs removeAllObjects]; + [grantedTableView reloadData]; + + [self _initializeAvailablePrivs]; + + if ([[treeController selectedObjects] count] > 0 && [[schemaController selectedObjects] count] > 0) { + NSManagedObject *user = [[treeController selectedObjects] objectAtIndex:0]; + + // Check to see if the user host node was selected + if ([user valueForKey:@"host"]) { + NSString *selectedSchema = [[schemaController selectedObjects] objectAtIndex:0]; + + NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"] + schema:[selectedSchema stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"] + host:[user valueForKey:@"host"]]; + + if ([results count] > 0) { + NSManagedObject *priv = [results objectAtIndex:0]; + + for (NSPropertyDescription *property in [priv entity]) + { + if ([[property name] hasSuffix:@"_priv"] && [[priv valueForKey:[property name]] boolValue]) + { + NSString *displayName = [[[property name] stringByReplacingOccurrencesOfString:@"_priv" withString:@""] replaceUnderscoreWithSpace]; + NSDictionary *newDict = [NSDictionary dictionaryWithObjectsAndKeys:displayName, @"displayName", [property name], @"name", nil]; + [grantedController addObject:newDict]; + + // Remove items from available so they can't be added twice. + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"displayName like[cd] %@", displayName]; + NSArray *previousObjects = [[availableController arrangedObjects] filteredArrayUsingPredicate:predicate]; + + for (NSDictionary *dict in previousObjects) + { + [availableController removeObject:dict]; + } + } + } + } + + [availableTableView setEnabled:YES]; + } + } + else { + [availableTableView setEnabled:NO]; + } + } + else if (object == grantedTableView) { + [removeSchemaPrivButton setEnabled:[[grantedController selectedObjects] count] > 0]; + } + else if (object == availableTableView) { + [addSchemaPrivButton setEnabled:[[availableController selectedObjects] count] > 0]; + } +} + +#pragma mark - +#pragma mark Tab View Delegate methods + +- (BOOL)tabView:(NSTabView *)tabView shouldSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + BOOL retVal = YES; + + if ([[treeController selectedObjects] count] == 0) return NO; + + // Currently selected object in tree + id selectedObject = [[treeController selectedObjects] objectAtIndex:0]; + + // If we are selecting a tab view that requires there be a child, + // make sure there is a child to select. If not, don't allow it. + if ([[tabViewItem identifier] isEqualToString:SPGlobalPrivilegesTabIdentifier] || + [[tabViewItem identifier] isEqualToString:SPResourcesTabIdentifier] || + [[tabViewItem identifier] isEqualToString:SPSchemaPrivilegesTabIdentifier]) { + + id parent = [selectedObject parent]; + + retVal = parent ? ([[parent children] count] > 0) : ([[selectedObject children] count] > 0); + + if (!retVal) { + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"User has no hosts", @"user has no hosts message") + defaultButton:NSLocalizedString(@"Add Host", @"Add Host") + alternateButton:NSLocalizedString(@"Cancel", @"cancel button") + otherButton:nil + informativeTextWithFormat:NSLocalizedString(@"This user doesn't have any hosts associated with it. It will be deleted unless one is added", @"user has no hosts informative message")]; + + if ([alert runModal] == NSAlertDefaultReturn) { + [self addHost:nil]; + } + } + + // If this is the resources tab, enable or disable the controls based on the server's support for them + if ([[tabViewItem identifier] isEqualToString:SPResourcesTabIdentifier]) { + + BOOL serverSupportsUserMaxVars = [serverSupport supportsUserMaxVars]; + + // Disable the fields according to the version + [maxUpdatesTextField setEnabled:serverSupportsUserMaxVars]; + [maxConnectionsTextField setEnabled:serverSupportsUserMaxVars]; + [maxQuestionsTextField setEnabled:serverSupportsUserMaxVars]; + } + } + + return retVal; +} + +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if ([[treeController selectedObjects] count] == 0) return; + + id selectedObject = [[treeController selectedObjects] objectAtIndex:0]; + + // If the selected tab is General and a child is selected, select the + // parent (user info). + if ([[tabViewItem identifier] isEqualToString:SPGeneralTabIdentifier]) { + if ([selectedObject parent]) { + [self _selectParentFromSelection]; + } + } + else if ([[tabViewItem identifier] isEqualToString:SPGlobalPrivilegesTabIdentifier] || + [[tabViewItem identifier] isEqualToString:SPResourcesTabIdentifier] || + [[tabViewItem identifier] isEqualToString:SPSchemaPrivilegesTabIdentifier]) { + // If the tab is either Global Privs or Resources and we have a user + // selected, then open tree and select first child node. + [self _selectFirstChildOfParentNode]; + } +} + +- (void)tabView:(NSTabView *)usersTabView willSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + if ([[tabViewItem identifier] isEqualToString:SPSchemaPrivilegesTabIdentifier]) { + [self _initializeSchemaPrivs]; + } +} + +#pragma mark - +#pragma mark Outline view Delegate Methods + +- (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell *)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + if ([cell isKindOfClass:[ImageAndTextCell class]]) + { + // Determines which Image to display depending on parent or child object + NSImage *image = [[NSImage imageNamed:[(NSManagedObject *)[item representedObject] parent] ? NSImageNameNetwork : NSImageNameUser] retain]; + + [image setScalesWhenResized:YES]; + [image setSize:(NSSize){16, 16}]; + [(ImageAndTextCell *)cell setImage:image]; + [image release]; + } +} + +- (BOOL)outlineView:(NSOutlineView *)olv isGroupItem:(id)item +{ + return NO; +} + +- (BOOL)outlineView:(NSOutlineView *)olv shouldSelectItem:(id)item +{ + return YES; +} + +- (BOOL)outlineView:(NSOutlineView *)olv shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item +{ + return ([[[item representedObject] children] count] == 0); +} + +- (void)outlineViewSelectionDidChange:(NSNotification *)notification +{ + if ([[treeController selectedObjects] count] == 0) return; + + id selectedObject = [[treeController selectedObjects] objectAtIndex:0]; + + if ([selectedObject parent] == nil && !([[[tabView selectedTabViewItem] identifier] isEqualToString:@"General"])) { + [tabView selectTabViewItemWithIdentifier:SPGeneralTabIdentifier]; + } + else { + if ([selectedObject parent] != nil && [[[tabView selectedTabViewItem] identifier] isEqualToString:@"General"]) { + [tabView selectTabViewItemWithIdentifier:SPGlobalPrivilegesTabIdentifier]; + } + } + + if ([selectedObject parent] != nil && [selectedObject host] == nil) + { + [selectedObject setValue:@"%" forKey:@"host"]; + [outlineView reloadItem:selectedObject]; + } + + [schemasTableView deselectAll:nil]; + [grantedTableView deselectAll:nil]; + [availableTableView deselectAll:nil]; +} + +- (BOOL)selectionShouldChangeInOutlineView:(NSOutlineView *)olv +{ + if ([[treeController selectedObjects] count] > 0) + { + id selectedObject = [[treeController selectedObjects] objectAtIndex:0]; + + // Check parents + if ([selectedObject valueForKey:@"parent"] == nil) + { + NSString *name = [selectedObject valueForKey:@"user"]; + NSArray *results = [self _fetchUserWithUserName:name]; + + if ([results count] > 1) { + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Duplicate User", @"duplicate user message") + defaultButton:NSLocalizedString(@"OK", @"OK button") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"A user with the name '%@' already exists", @"duplicate user informative message"), name]]; + [alert runModal]; + + return NO; + } + } + else + { + NSArray *children = [selectedObject valueForKeyPath:@"parent.children"]; + NSString *host = [selectedObject valueForKey:@"host"]; + + for (NSManagedObject *child in children) + { + if (![selectedObject isEqual:child] && [[child valueForKey:@"host"] isEqualToString:host]) + { + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Duplicate Host", @"duplicate host message") + defaultButton:NSLocalizedString(@"OK", @"OK button") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"A user with the host '%@' already exists", @"duplicate host informative message"), host]]; + + [alert runModal]; + + return NO; + } + } + } + } + + return YES; +} + +@end |