4444
4545static NSString * const SPTableViewNameColumnID = @" NameColumn" ;
4646
47+ static NSString *SPGeneralTabIdentifier = @" General" ;
48+ static NSString *SPGlobalPrivilegesTabIdentifier = @" Global Privileges" ;
49+ static NSString *SPResourcesTabIdentifier = @" Resources" ;
50+ static NSString *SPSchemaPrivilegesTabIdentifier = @" Schema Privileges" ;
51+
52+
4753@interface SPUserManager ()
4854
4955- (void )_initializeTree : (NSArray *)items ;
@@ -64,6 +70,7 @@ - (void)_initializeAvailablePrivs;
6470- (BOOL )_renameUserFrom : (NSString *)originalUser host : (NSString *)originalHost to : (NSString *)newUser host : (NSString *)newHost ;
6571- (void )sheetDidEnd : (NSWindow *)sheet returnCode : (int )returnCode contextInfo : (void *)context ;
6672- (void )contextWillSave : (NSNotification *)notice ;
73+ - (void )_selectFirstChildOfParentNode ;
6774
6875@end
6976
@@ -1520,6 +1527,306 @@ - (BOOL)_renameUserFrom:(NSString *)originalUser host:(NSString *)originalHost t
15201527 return YES ;
15211528}
15221529
1530+ #pragma mark - SPUserManagerDelegate
1531+
1532+ #pragma mark TableView Delegate Methods
1533+
1534+ - (void )tableViewSelectionDidChange : (NSNotification *)notification
1535+ {
1536+ id object = [notification object ];
1537+
1538+ if (object == schemasTableView) {
1539+ [grantedSchemaPrivs removeAllObjects ];
1540+ [grantedTableView reloadData ];
1541+
1542+ [self _initializeAvailablePrivs ];
1543+
1544+ if ([[treeController selectedObjects ] count ] > 0 && [[schemasTableView selectedRowIndexes ] count ] > 0 ) {
1545+ SPUserMO *user = [[treeController selectedObjects ] objectAtIndex: 0 ];
1546+
1547+ // Check to see if the user host node was selected
1548+ if ([user valueForKey: @" host" ]) {
1549+ NSString *selectedSchema = [schemas objectAtIndex: [schemasTableView selectedRow ]];
1550+
1551+ NSArray *results = [self _fetchPrivsWithUser: [[user parent ] valueForKey: @" user" ]
1552+ schema: [selectedSchema stringByReplacingOccurrencesOfString: @" _" withString: @" \\ _" ]
1553+ host: [user valueForKey: @" host" ]];
1554+
1555+ if ([results count ] > 0 ) {
1556+ NSManagedObject *priv = [results objectAtIndex: 0 ];
1557+
1558+ for (NSPropertyDescription *property in [priv entity ])
1559+ {
1560+ if ([[property name ] hasSuffix: @" _priv" ] && [[priv valueForKey: [property name ]] boolValue ])
1561+ {
1562+ NSString *displayName = [[[property name ] stringByReplacingOccurrencesOfString: @" _priv" withString: @" " ] replaceUnderscoreWithSpace ];
1563+ NSDictionary *newDict = [NSDictionary dictionaryWithObjectsAndKeys: displayName, @" displayName" , [property name ], @" name" , nil ];
1564+ [grantedController addObject: newDict];
1565+
1566+ // Remove items from available so they can't be added twice.
1567+ NSPredicate *predicate = [NSPredicate predicateWithFormat: @" displayName like[cd] %@" , displayName];
1568+ NSArray *previousObjects = [[availableController arrangedObjects ] filteredArrayUsingPredicate: predicate];
1569+
1570+ for (NSDictionary *dict in previousObjects)
1571+ {
1572+ [availableController removeObject: dict];
1573+ }
1574+ }
1575+ }
1576+ }
1577+
1578+ [availableTableView setEnabled: YES ];
1579+ }
1580+ }
1581+ else {
1582+ [availableTableView setEnabled: NO ];
1583+ }
1584+ }
1585+ else if (object == grantedTableView) {
1586+ [removeSchemaPrivButton setEnabled: [[grantedController selectedObjects ] count ] > 0 ];
1587+ }
1588+ else if (object == availableTableView) {
1589+ [addSchemaPrivButton setEnabled: [[availableController selectedObjects ] count ] > 0 ];
1590+ }
1591+ }
1592+
1593+ - (void )tableView : (NSTableView *)tableView willDisplayCell : (id )cell forTableColumn : (NSTableColumn *)tableColumn row : (NSInteger )rowIndex
1594+ {
1595+ if (tableView == schemasTableView) {
1596+ NSString *schemaName = [schemas objectAtIndex: rowIndex];
1597+
1598+ // Gray out the "all database" entries
1599+ if ([schemaName isEqualToString: @" " ] || [schemaName isEqualToString: @" %" ]) {
1600+ [cell setTextColor: [NSColor lightGrayColor ]];
1601+ } else {
1602+ [cell setTextColor: [NSColor blackColor ]];
1603+ }
1604+
1605+ // If the schema has permissions set, highlight with a yellow background
1606+ BOOL enabledPermissions = NO ;
1607+ SPUserMO *user = [[treeController selectedObjects ] objectAtIndex: 0 ];
1608+ NSArray *results = [self _fetchPrivsWithUser: [[user parent ] valueForKey: @" user" ]
1609+ schema: [schemaName stringByReplacingOccurrencesOfString: @" _" withString: @" \\ _" ]
1610+ host: [user valueForKey: @" host" ]];
1611+ if ([results count ]) {
1612+ NSManagedObject *schemaPrivs = [results objectAtIndex: 0 ];
1613+ for (NSString *itemKey in [[[schemaPrivs entity ] attributesByName ] allKeys ]) {
1614+ if ([itemKey hasSuffix: @" _priv" ] && [[schemaPrivs valueForKey: itemKey] boolValue ]) {
1615+ enabledPermissions = YES ;
1616+ break ;
1617+ }
1618+ }
1619+ }
1620+
1621+ if (enabledPermissions) {
1622+ [cell setDrawsBackground: YES ];
1623+ [cell setBackgroundColor: [NSColor colorWithDeviceRed: 1 .f green: 1 .f blue: 0 .f alpha: 0.2 ]];
1624+ } else {
1625+ [cell setDrawsBackground: NO ];
1626+ }
1627+ }
1628+ }
1629+
1630+ #pragma mark -
1631+ #pragma mark Tab View Delegate methods
1632+
1633+ - (BOOL )tabView : (NSTabView *)tabView shouldSelectTabViewItem : (NSTabViewItem *)tabViewItem
1634+ {
1635+ BOOL retVal = YES ;
1636+
1637+ if ([[treeController selectedObjects ] count ] == 0 ) return NO ;
1638+
1639+ if (![treeController commitEditing ]) {
1640+ return NO ;
1641+ }
1642+
1643+ // Currently selected object in tree
1644+ id selectedObject = [[treeController selectedObjects ] objectAtIndex: 0 ];
1645+
1646+ // If we are selecting a tab view that requires there be a child,
1647+ // make sure there is a child to select. If not, don't allow it.
1648+ if ([[tabViewItem identifier ] isEqualToString: SPGlobalPrivilegesTabIdentifier] ||
1649+ [[tabViewItem identifier ] isEqualToString: SPResourcesTabIdentifier] ||
1650+ [[tabViewItem identifier ] isEqualToString: SPSchemaPrivilegesTabIdentifier]) {
1651+
1652+ id parent = [selectedObject parent ];
1653+
1654+ retVal = parent ? ([[parent children ] count ] > 0 ) : ([[selectedObject children ] count ] > 0 );
1655+
1656+ if (!retVal) {
1657+ NSAlert *alert = [NSAlert alertWithMessageText: NSLocalizedString(@" User has no hosts" , @" user has no hosts message" )
1658+ defaultButton: NSLocalizedString(@" Add Host" , @" Add Host" )
1659+ alternateButton: NSLocalizedString(@" Cancel" , @" cancel button" )
1660+ otherButton: nil
1661+ 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" )];
1662+
1663+ if ([alert runModal ] == NSAlertDefaultReturn ) {
1664+ [self addHost: nil ];
1665+ }
1666+ }
1667+
1668+ // If this is the resources tab, enable or disable the controls based on the server's support for them
1669+ if ([[tabViewItem identifier ] isEqualToString: SPResourcesTabIdentifier]) {
1670+
1671+ BOOL serverSupportsUserMaxVars = [serverSupport supportsUserMaxVars ];
1672+
1673+ // Disable the fields according to the version
1674+ [maxUpdatesTextField setEnabled: serverSupportsUserMaxVars];
1675+ [maxConnectionsTextField setEnabled: serverSupportsUserMaxVars];
1676+ [maxQuestionsTextField setEnabled: serverSupportsUserMaxVars];
1677+ }
1678+ }
1679+
1680+ return retVal;
1681+ }
1682+
1683+ - (void )tabView : (NSTabView *)tabView didSelectTabViewItem : (NSTabViewItem *)tabViewItem
1684+ {
1685+ if ([[treeController selectedObjects ] count ] == 0 ) return ;
1686+
1687+ id selectedObject = [[treeController selectedObjects ] objectAtIndex: 0 ];
1688+
1689+ // If the selected tab is General and a child is selected, select the
1690+ // parent (user info).
1691+ if ([[tabViewItem identifier ] isEqualToString: SPGeneralTabIdentifier]) {
1692+ if ([selectedObject parent ]) {
1693+ [self _selectParentFromSelection ];
1694+ }
1695+ }
1696+ else if ([[tabViewItem identifier ] isEqualToString: SPGlobalPrivilegesTabIdentifier] ||
1697+ [[tabViewItem identifier ] isEqualToString: SPResourcesTabIdentifier] ||
1698+ [[tabViewItem identifier ] isEqualToString: SPSchemaPrivilegesTabIdentifier]) {
1699+ // If the tab is either Global Privs or Resources and we have a user
1700+ // selected, then open tree and select first child node.
1701+ [self _selectFirstChildOfParentNode ];
1702+ }
1703+ }
1704+
1705+ #pragma mark -
1706+ #pragma mark Outline view Delegate Methods
1707+
1708+ - (void )outlineView : (NSOutlineView *)olv willDisplayCell : (NSCell *)cell forTableColumn : (NSTableColumn *)tableColumn item : (id )item
1709+ {
1710+ if ([cell isKindOfClass: [ImageAndTextCell class ]])
1711+ {
1712+ // Determines which Image to display depending on parent or child object
1713+ NSImage *image = [[NSImage imageNamed: [(SPUserMO *)[item representedObject ] parent ] ? NSImageNameNetwork : NSImageNameUser ] retain ];
1714+
1715+ [image setSize: (NSSize ){16 , 16 }];
1716+ [(ImageAndTextCell *)cell setImage: image];
1717+ [image release ];
1718+ }
1719+ }
1720+
1721+ - (BOOL )outlineView : (NSOutlineView *)olv isGroupItem : (id )item
1722+ {
1723+ return NO ;
1724+ }
1725+
1726+ - (BOOL )outlineView : (NSOutlineView *)olv shouldSelectItem : (id )item
1727+ {
1728+ return YES ;
1729+ }
1730+
1731+ - (BOOL )outlineView : (NSOutlineView *)olv shouldEditTableColumn : (NSTableColumn *)tableColumn item : (id )item
1732+ {
1733+ return ([[[item representedObject ] children ] count ] == 0 );
1734+ }
1735+
1736+ - (void )outlineViewSelectionDidChange : (NSNotification *)notification
1737+ {
1738+ if ([[treeController selectedObjects ] count ] == 0 ) return ;
1739+
1740+ id selectedObject = [[treeController selectedObjects ] objectAtIndex: 0 ];
1741+
1742+ if ([selectedObject parent ] == nil && !([[[tabView selectedTabViewItem ] identifier ] isEqualToString: @" General" ])) {
1743+ [tabView selectTabViewItemWithIdentifier: SPGeneralTabIdentifier];
1744+ }
1745+ else {
1746+ if ([selectedObject parent ] != nil && [[[tabView selectedTabViewItem ] identifier ] isEqualToString: @" General" ]) {
1747+ [tabView selectTabViewItemWithIdentifier: SPGlobalPrivilegesTabIdentifier];
1748+ }
1749+ }
1750+
1751+ if ([selectedObject parent ] != nil && [selectedObject host ] == nil )
1752+ {
1753+ [selectedObject setValue: @" %" forKey: @" host" ];
1754+ [outlineView reloadItem: selectedObject];
1755+ }
1756+
1757+ [schemasTableView deselectAll: nil ];
1758+ [schemasTableView setNeedsDisplay: YES ];
1759+ [grantedTableView deselectAll: nil ];
1760+ [availableTableView deselectAll: nil ];
1761+ }
1762+
1763+ - (BOOL )selectionShouldChangeInOutlineView : (NSOutlineView *)olv
1764+ {
1765+ if ([[treeController selectedObjects ] count ] > 0 )
1766+ {
1767+ id selectedObject = [[treeController selectedObjects ] objectAtIndex: 0 ];
1768+
1769+ // Check parents
1770+ if ([selectedObject valueForKey: @" parent" ] == nil )
1771+ {
1772+ NSString *name = [selectedObject valueForKey: @" user" ];
1773+ NSArray *results = [self _fetchUserWithUserName: name];
1774+
1775+ if ([results count ] > 1 ) {
1776+ NSAlert *alert = [NSAlert alertWithMessageText: NSLocalizedString(@" Duplicate User" , @" duplicate user message" )
1777+ defaultButton: NSLocalizedString(@" OK" , @" OK button" )
1778+ alternateButton: nil
1779+ otherButton: nil
1780+ informativeTextWithFormat: NSLocalizedString(@" A user with the name '%@ ' already exists" , @" duplicate user informative message" ), name];
1781+ [alert runModal ];
1782+
1783+ return NO ;
1784+ }
1785+ }
1786+ else
1787+ {
1788+ NSArray *children = [selectedObject valueForKeyPath: @" parent.children" ];
1789+ NSString *host = [selectedObject valueForKey: @" host" ];
1790+
1791+ for (NSManagedObject *child in children)
1792+ {
1793+ if (![selectedObject isEqual: child] && [[child valueForKey: @" host" ] isEqualToString: host])
1794+ {
1795+ NSAlert *alert = [NSAlert alertWithMessageText: NSLocalizedString(@" Duplicate Host" , @" duplicate host message" )
1796+ defaultButton: NSLocalizedString(@" OK" , @" OK button" )
1797+ alternateButton: nil
1798+ otherButton: nil
1799+ informativeTextWithFormat: NSLocalizedString(@" A user with the host '%@ ' already exists" , @" duplicate host informative message" ), host];
1800+
1801+ [alert runModal ];
1802+
1803+ return NO ;
1804+ }
1805+ }
1806+ }
1807+ }
1808+
1809+ return YES ;
1810+ }
1811+
1812+ #pragma mark - SPUserManagerDataSource
1813+
1814+ - (NSInteger )numberOfRowsInTableView : (NSTableView *)aTableView
1815+ {
1816+ return [schemas count ];
1817+ }
1818+
1819+ - (id )tableView : (NSTableView *)aTableView objectValueForTableColumn : (NSTableColumn *)aTableColumn row : (NSInteger )rowIndex
1820+ {
1821+ NSString *databaseName = [schemas objectAtIndex: rowIndex];
1822+ if ([databaseName isEqualToString: @" " ]) {
1823+ databaseName = NSLocalizedString(@" All Databases" , @" All databases placeholder" );
1824+ } else if ([databaseName isEqualToString: @" %" ]) {
1825+ databaseName = NSLocalizedString(@" All Databases (%)" , @" All databases (%) placeholder" );
1826+ }
1827+ return databaseName;
1828+ }
1829+
15231830#pragma mark -
15241831
15251832- (void )dealloc
0 commit comments