diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/SPUserManager.m | 307 | ||||
-rw-r--r-- | Source/SPUserManagerDataSource.h | 35 | ||||
-rw-r--r-- | Source/SPUserManagerDataSource.m | 51 | ||||
-rw-r--r-- | Source/SPUserManagerDelegate.h | 35 | ||||
-rw-r--r-- | Source/SPUserManagerDelegate.m | 335 |
5 files changed, 307 insertions, 456 deletions
diff --git a/Source/SPUserManager.m b/Source/SPUserManager.m index c06025d2..397275cb 100644 --- a/Source/SPUserManager.m +++ b/Source/SPUserManager.m @@ -44,6 +44,12 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; +static NSString *SPGeneralTabIdentifier = @"General"; +static NSString *SPGlobalPrivilegesTabIdentifier = @"Global Privileges"; +static NSString *SPResourcesTabIdentifier = @"Resources"; +static NSString *SPSchemaPrivilegesTabIdentifier = @"Schema Privileges"; + + @interface SPUserManager () - (void)_initializeTree:(NSArray *)items; @@ -64,6 +70,7 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; - (BOOL)_renameUserFrom:(NSString *)originalUser host:(NSString *)originalHost to:(NSString *)newUser host:(NSString *)newHost; - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void*)context; - (void)contextWillSave:(NSNotification *)notice; +- (void)_selectFirstChildOfParentNode; @end @@ -1520,6 +1527,306 @@ static NSString * const SPTableViewNameColumnID = @"NameColumn"; return YES; } +#pragma mark - SPUserManagerDelegate + +#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 && [[schemasTableView selectedRowIndexes] count] > 0) { + SPUserMO *user = [[treeController selectedObjects] objectAtIndex:0]; + + // Check to see if the user host node was selected + if ([user valueForKey:@"host"]) { + NSString *selectedSchema = [schemas objectAtIndex:[schemasTableView selectedRow]]; + + 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]; + } +} + +- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex +{ + if (tableView == schemasTableView) { + NSString *schemaName = [schemas objectAtIndex:rowIndex]; + + // Gray out the "all database" entries + if ([schemaName isEqualToString:@""] || [schemaName isEqualToString:@"%"]) { + [cell setTextColor:[NSColor lightGrayColor]]; + } else { + [cell setTextColor:[NSColor blackColor]]; + } + + // If the schema has permissions set, highlight with a yellow background + BOOL enabledPermissions = NO; + SPUserMO *user = [[treeController selectedObjects] objectAtIndex:0]; + NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"] + schema:[schemaName stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"] + host:[user valueForKey:@"host"]]; + if ([results count]) { + NSManagedObject *schemaPrivs = [results objectAtIndex:0]; + for (NSString *itemKey in [[[schemaPrivs entity] attributesByName] allKeys]) { + if ([itemKey hasSuffix:@"_priv"] && [[schemaPrivs valueForKey:itemKey] boolValue]) { + enabledPermissions = YES; + break; + } + } + } + + if (enabledPermissions) { + [cell setDrawsBackground:YES]; + [cell setBackgroundColor:[NSColor colorWithDeviceRed:1.f green:1.f blue:0.f alpha:0.2]]; + } else { + [cell setDrawsBackground:NO]; + } + } +} + +#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; + + if (![treeController commitEditing]) { + 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]; + } +} + +#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:[(SPUserMO *)[item representedObject] parent] ? NSImageNameNetwork : NSImageNameUser] retain]; + + [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]; + [schemasTableView setNeedsDisplay:YES]; + [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: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:NSLocalizedString(@"A user with the host '%@' already exists", @"duplicate host informative message"), host]; + + [alert runModal]; + + return NO; + } + } + } + } + + return YES; +} + +#pragma mark - SPUserManagerDataSource + +- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView +{ + return [schemas count]; +} + +- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex +{ + NSString *databaseName = [schemas objectAtIndex:rowIndex]; + if ([databaseName isEqualToString:@""]) { + databaseName = NSLocalizedString(@"All Databases", @"All databases placeholder"); + } else if ([databaseName isEqualToString:@"%"]) { + databaseName = NSLocalizedString(@"All Databases (%)", @"All databases (%) placeholder"); + } + return databaseName; +} + #pragma mark - - (void)dealloc diff --git a/Source/SPUserManagerDataSource.h b/Source/SPUserManagerDataSource.h deleted file mode 100644 index f441c156..00000000 --- a/Source/SPUserManagerDataSource.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// SPUserManagerDataSource.h -// sequel-pro -// -// Created by Rowan Beentje on March 8, 2013. -// Copyright (c) 2013 Rowan Beentje. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// More info at <https://github.com/sequelpro/sequelpro> - -#import "SPUserManager.h" - -@interface SPUserManager (SPUserManagerDataSource) - -@end diff --git a/Source/SPUserManagerDataSource.m b/Source/SPUserManagerDataSource.m deleted file mode 100644 index 95ec6b68..00000000 --- a/Source/SPUserManagerDataSource.m +++ /dev/null @@ -1,51 +0,0 @@ -// -// SPUserManagerDataSource.m -// sequel-pro -// -// Created by Rowan Beentje on March 8, 2013. -// Copyright (c) 2013 Rowan Beentje. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// More info at <https://github.com/sequelpro/sequelpro> - -#import "SPUserManagerDataSource.h" - -@implementation SPUserManager (SPUserManagerDataSource) - -- (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView -{ - return [schemas count]; -} - -- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex -{ - NSString *databaseName = [schemas objectAtIndex:rowIndex]; - if ([databaseName isEqualToString:@""]) { - databaseName = NSLocalizedString(@"All Databases", @"All databases placeholder"); - } else if ([databaseName isEqualToString:@"%"]) { - databaseName = NSLocalizedString(@"All Databases (%)", @"All databases (%) placeholder"); - } - return databaseName; -} - -@end diff --git a/Source/SPUserManagerDelegate.h b/Source/SPUserManagerDelegate.h deleted file mode 100644 index 14581148..00000000 --- a/Source/SPUserManagerDelegate.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// SPUserManagerDelegate.h -// sequel-pro -// -// Created by Mark Townsend on Jan 1, 2009. -// Copyright (c) 2009 Mark Townsend. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// More info at <https://github.com/sequelpro/sequelpro> - -#import "SPUserManager.h" - -@interface SPUserManager (SPUserManagerDelegate) - -@end diff --git a/Source/SPUserManagerDelegate.m b/Source/SPUserManagerDelegate.m deleted file mode 100644 index cefe7f2e..00000000 --- a/Source/SPUserManagerDelegate.m +++ /dev/null @@ -1,335 +0,0 @@ -// -// SPUserManagerDelegate.m -// sequel-pro -// -// Created by Mark Townsend on Jan 1, 2009. -// Copyright (c) 2009 Mark Townsend. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// More info at <https://github.com/sequelpro/sequelpro> - -#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 (DeclaredAPI) - -- (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 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 && [[schemasTableView selectedRowIndexes] count] > 0) { - SPUserMO *user = [[treeController selectedObjects] objectAtIndex:0]; - - // Check to see if the user host node was selected - if ([user valueForKey:@"host"]) { - NSString *selectedSchema = [schemas objectAtIndex:[schemasTableView selectedRow]]; - - 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]; - } -} - -- (void)tableView:(NSTableView *)tableView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)rowIndex -{ - if (tableView == schemasTableView) { - NSString *schemaName = [schemas objectAtIndex:rowIndex]; - - // Gray out the "all database" entries - if ([schemaName isEqualToString:@""] || [schemaName isEqualToString:@"%"]) { - [cell setTextColor:[NSColor lightGrayColor]]; - } else { - [cell setTextColor:[NSColor blackColor]]; - } - - // If the schema has permissions set, highlight with a yellow background - BOOL enabledPermissions = NO; - SPUserMO *user = [[treeController selectedObjects] objectAtIndex:0]; - NSArray *results = [self _fetchPrivsWithUser:[[user parent] valueForKey:@"user"] - schema:[schemaName stringByReplacingOccurrencesOfString:@"_" withString:@"\\_"] - host:[user valueForKey:@"host"]]; - if ([results count]) { - NSManagedObject *schemaPrivs = [results objectAtIndex:0]; - for (NSString *itemKey in [[[schemaPrivs entity] attributesByName] allKeys]) { - if ([itemKey hasSuffix:@"_priv"] && [[schemaPrivs valueForKey:itemKey] boolValue]) { - enabledPermissions = YES; - break; - } - } - } - - if (enabledPermissions) { - [cell setDrawsBackground:YES]; - [cell setBackgroundColor:[NSColor colorWithDeviceRed:1.f green:1.f blue:0.f alpha:0.2]]; - } else { - [cell setDrawsBackground:NO]; - } - } -} - -#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; - - if (![treeController commitEditing]) { - 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]; - } -} - -#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:[(SPUserMO *)[item representedObject] parent] ? NSImageNameNetwork : NSImageNameUser] retain]; - - [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]; - [schemasTableView setNeedsDisplay:YES]; - [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: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:NSLocalizedString(@"A user with the host '%@' already exists", @"duplicate host informative message"), host]; - - [alert runModal]; - - return NO; - } - } - } - } - - return YES; -} - -@end |