aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/SPUserManager.m307
-rw-r--r--Source/SPUserManagerDataSource.h35
-rw-r--r--Source/SPUserManagerDataSource.m51
-rw-r--r--Source/SPUserManagerDelegate.h35
-rw-r--r--Source/SPUserManagerDelegate.m335
-rw-r--r--sequel-pro.xcodeproj/project.pbxproj12
6 files changed, 307 insertions, 468 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
diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj
index 9f8f46b2..5bc97dc1 100644
--- a/sequel-pro.xcodeproj/project.pbxproj
+++ b/sequel-pro.xcodeproj/project.pbxproj
@@ -37,7 +37,6 @@
172A65110F7BED7A001E861A /* SPConsoleMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 172A65100F7BED7A001E861A /* SPConsoleMessage.m */; };
173284EA1088FEDE0062E892 /* SPConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 173284E91088FEDE0062E892 /* SPConstants.m */; };
1734696B11C1167000AB3D16 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A7FEA54F5311CA2CBB /* Cocoa.framework */; };
- 17381856151FB34E0078FFE2 /* SPUserManagerDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17381855151FB34E0078FFE2 /* SPUserManagerDelegate.m */; };
173C4362104455CA001F3A30 /* QueryFavoriteManager.xib in Resources */ = {isa = PBXBuildFile; fileRef = 173C4360104455CA001F3A30 /* QueryFavoriteManager.xib */; };
173C4366104455E0001F3A30 /* SPQueryFavoriteManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 173C4365104455E0001F3A30 /* SPQueryFavoriteManager.m */; };
173C44D81044A6B0001F3A30 /* SPOutlineView.m in Sources */ = {isa = PBXBuildFile; fileRef = 173C44D71044A6B0001F3A30 /* SPOutlineView.m */; };
@@ -384,7 +383,6 @@
58CDB3400FCE13EF00F8ACA3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5EAC0FC0EC87FF900CC579C /* Security.framework */; };
58CDB3410FCE141900F8ACA3 /* SequelProTunnelAssistant.m in Sources */ = {isa = PBXBuildFile; fileRef = 58CDB3310FCE139C00F8ACA3 /* SequelProTunnelAssistant.m */; };
58CDB3420FCE142500F8ACA3 /* SPKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E641740EF01F80001BC333 /* SPKeychain.m */; };
- 58D29FE016E96306002EB401 /* SPUserManagerDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D29FDF16E96306002EB401 /* SPUserManagerDataSource.m */; };
58D2A6A716FBDEFF002EB401 /* SPComboPopupButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D2A6A616FBDEFF002EB401 /* SPComboPopupButton.m */; };
58D2E229101222670063EF1D /* SPTextAndLinkCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 58D2E227101222670063EF1D /* SPTextAndLinkCell.m */; };
58D2E22E101222870063EF1D /* link-arrow-clicked.png in Resources */ = {isa = PBXBuildFile; fileRef = 58D2E22B101222870063EF1D /* link-arrow-clicked.png */; };
@@ -661,8 +659,6 @@
172A65100F7BED7A001E861A /* SPConsoleMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPConsoleMessage.m; sourceTree = "<group>"; };
173284E81088FEDE0062E892 /* SPConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPConstants.h; sourceTree = "<group>"; };
173284E91088FEDE0062E892 /* SPConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPConstants.m; sourceTree = "<group>"; };
- 17381854151FB34E0078FFE2 /* SPUserManagerDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPUserManagerDelegate.h; sourceTree = "<group>"; };
- 17381855151FB34E0078FFE2 /* SPUserManagerDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPUserManagerDelegate.m; sourceTree = "<group>"; };
173C4361104455CA001F3A30 /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/QueryFavoriteManager.xib; sourceTree = "<group>"; };
173C4364104455E0001F3A30 /* SPQueryFavoriteManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPQueryFavoriteManager.h; sourceTree = "<group>"; };
173C4365104455E0001F3A30 /* SPQueryFavoriteManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPQueryFavoriteManager.m; sourceTree = "<group>"; };
@@ -1144,8 +1140,6 @@
58CDB32F0FCE138D00F8ACA3 /* SPSSHTunnel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPSSHTunnel.m; sourceTree = "<group>"; };
58CDB3310FCE139C00F8ACA3 /* SequelProTunnelAssistant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SequelProTunnelAssistant.m; sourceTree = "<group>"; };
58CDB3360FCE13C900F8ACA3 /* SequelProTunnelAssistant */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = SequelProTunnelAssistant; sourceTree = BUILT_PRODUCTS_DIR; };
- 58D29FDE16E96306002EB401 /* SPUserManagerDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPUserManagerDataSource.h; sourceTree = "<group>"; };
- 58D29FDF16E96306002EB401 /* SPUserManagerDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPUserManagerDataSource.m; sourceTree = "<group>"; };
58D2A6A516FBDEFF002EB401 /* SPComboPopupButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPComboPopupButton.h; sourceTree = "<group>"; };
58D2A6A616FBDEFF002EB401 /* SPComboPopupButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPComboPopupButton.m; sourceTree = "<group>"; };
58D2E227101222670063EF1D /* SPTextAndLinkCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPTextAndLinkCell.m; sourceTree = "<group>"; };
@@ -1499,10 +1493,6 @@
children = (
4D90B798101E0CDF00D116A1 /* SPUserManager.h */,
4D90B799101E0CDF00D116A1 /* SPUserManager.m */,
- 17381854151FB34E0078FFE2 /* SPUserManagerDelegate.h */,
- 17381855151FB34E0078FFE2 /* SPUserManagerDelegate.m */,
- 58D29FDE16E96306002EB401 /* SPUserManagerDataSource.h */,
- 58D29FDF16E96306002EB401 /* SPUserManagerDataSource.m */,
);
name = "User Manager";
sourceTree = "<group>";
@@ -3352,7 +3342,6 @@
584D87921514101E00F24774 /* SPDatabaseStructure.m in Sources */,
584D88A91515034200F24774 /* NSNotificationCenterThreadingAdditions.m in Sources */,
584D899D15162CBE00F24774 /* SPDataBase64EncodingAdditions.m in Sources */,
- 17381856151FB34E0078FFE2 /* SPUserManagerDelegate.m in Sources */,
17BA2A3215275D8600389803 /* SPExportInterfaceController.m in Sources */,
1798F1871550175B004B0AB8 /* SPFavoritesExporter.m in Sources */,
1798F1881550175B004B0AB8 /* SPFavoritesImporter.m in Sources */,
@@ -3366,7 +3355,6 @@
58DF9F7315AB8509003B4330 /* SPSplitView.m in Sources */,
58DFC91615CB3501003B4330 /* BGHUDButtonCell.m in Sources */,
5843E247162B555B00EAA6D1 /* SPThreadAdditions.m in Sources */,
- 58D29FE016E96306002EB401 /* SPUserManagerDataSource.m in Sources */,
58D2A6A716FBDEFF002EB401 /* SPComboPopupButton.m in Sources */,
17846BA4170C962E00414499 /* SPProcessListControllerDataSource.m in Sources */,
501B1D181728A3DA0017C92E /* SPCharsetCollationHelper.m in Sources */,