From b5934d004ce7e73e45da1b4de823e8092843ef9b Mon Sep 17 00:00:00 2001 From: rowanbeentje Date: Sun, 3 Jun 2012 18:45:48 +0000 Subject: - Remove delayed favourite selection call on tab setup. This fixes detail reset issues causing Issue #1362 and Issue #1338, possibly others. - Clean up duplicate code setting and resetting connection interface state, ensuring one code path used by all --- Source/SPConnectionController.m | 94 +++++++++++++++------------------ Source/SPConnectionControllerDelegate.m | 12 ++--- Source/SPDatabaseDocument.m | 31 ++--------- 3 files changed, 50 insertions(+), 87 deletions(-) diff --git a/Source/SPConnectionController.m b/Source/SPConnectionController.m index e57399bb..337fed11 100644 --- a/Source/SPConnectionController.m +++ b/Source/SPConnectionController.m @@ -62,6 +62,7 @@ static NSString *SPExportFavoritesFilename = @"SequelProFavorites.plist"; - (void)_sortTreeNode:(SPTreeNode *)node usingKey:(NSString *)key; - (void)_favoriteTypeDidChange; - (void)_reloadFavoritesViewData; +- (void)_updateFavoriteFirstResponder; - (void)_restoreConnectionInterface; - (void)_selectNode:(SPTreeNode *)node; - (void)_scrollToSelectedNode; @@ -72,7 +73,6 @@ static NSString *SPExportFavoritesFilename = @"SequelProFavorites.plist"; - (NSString *)_stripInvalidCharactersFromString:(NSString *)subject; - (void)_updateFavoritePasswordsFromField:(NSControl *)control; -- (void)_resetConnectionDetailsInputInterface; static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, void *key); @@ -476,6 +476,7 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, if (connectionSSHKeychainItemAccount) [connectionSSHKeychainItemAccount release], connectionSSHKeychainItemAccount = nil; SPTreeNode *node = [self selectedFavoriteNode]; + if ([node isGroup]) node = nil; // Update key-value properties from the selected favourite, using empty strings where not found NSDictionary *fav = [[node representedObject] nodeFavorite]; @@ -545,18 +546,7 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, [prefs setInteger:[[fav objectForKey:SPFavoriteIDKey] integerValue] forKey:SPLastFavoriteID]; // Set first responder to password field if it is empty - switch ([self type]) - { - case SPTCPIPConnection: - if (![[standardPasswordField stringValue] length]) [[dbDocument parentWindow] makeFirstResponder:standardPasswordField]; - break; - case SPSocketConnection: - if (![[socketPasswordField stringValue] length]) [[dbDocument parentWindow] makeFirstResponder:socketPasswordField]; - break; - case SPSSHTunnelConnection: - if (![[sshPasswordField stringValue] length]) [[dbDocument parentWindow] makeFirstResponder:sshPasswordField]; - break; - } + [self performSelector:@selector(_updateFavoriteFirstResponder) withObject:nil afterDelay:0.0]; } /** @@ -959,12 +949,15 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, * This method is called as part of Key Value Observing. */ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context -{ +{ + NSMutableDictionary *selectedFavorite = [self selectedFavorite]; + if (!selectedFavorite) return; + id oldObject = [change objectForKey:NSKeyValueChangeOldKey]; id newObject = [change objectForKey:NSKeyValueChangeNewKey]; - + if (oldObject != newObject) { - [[self selectedFavorite] setObject:![newObject isNSNull] ? newObject : @"" forKey:keyPath]; + [selectedFavorite setObject:![newObject isNSNull] ? newObject : @"" forKey:keyPath]; // Save the new data to disk [favoritesController saveFavorites]; @@ -1214,7 +1207,7 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, */ - (void)_favoriteTypeDidChange { - NSDictionary *favorite = [[[self selectedFavoriteNode] representedObject] nodeFavorite]; + NSDictionary *favorite = [self selectedFavorite]; // If either socket or host is localhost, clear. if ((previousType != SPSocketConnection) && [[favorite objectForKey:SPFavoriteHostKey] isEqualToString:@"localhost"]) { @@ -1241,6 +1234,36 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, [self _scrollToSelectedNode]; } +/** + * Update the first responder status on password fields if they are empty and + * some host details are set, usually as a response to favourite selection changes. + */ +- (void)_updateFavoriteFirstResponder +{ + + // Skip auto-selection changes if there is no user set + if (![[self user] length]) return; + + switch ([self type]) + { + case SPTCPIPConnection: + if (![[standardPasswordField stringValue] length]) { + [[dbDocument parentWindow] makeFirstResponder:standardPasswordField]; + } + break; + case SPSocketConnection: + if (![[socketPasswordField stringValue] length]) { + [[dbDocument parentWindow] makeFirstResponder:socketPasswordField]; + } + break; + case SPSSHTunnelConnection: + if (![[sshPasswordField stringValue] length]) { + [[dbDocument parentWindow] makeFirstResponder:sshPasswordField]; + } + break; + } +} + /** * Restores the connection interface to its original state. */ @@ -1339,11 +1362,11 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, [favoritesController removeFavoriteNode:node]; - [self _resetConnectionDetailsInputInterface]; [self _reloadFavoritesViewData]; - // Clear the selection + // Clear the selection and update the interface to match [favoritesOutlineView selectRowIndexes:nil byExtendingSelection:NO]; + [self updateFavoriteSelection:self]; [connectionResizeContainer setHidden:NO]; [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Enter connection details below, or choose a favorite", @"enter connection details label")]; @@ -1488,39 +1511,6 @@ static NSComparisonResult _compareFavoritesUsingKey(id favorite1, id favorite2, } } -/** - * Resets the connection details input interface to an empty state. - */ -- (void)_resetConnectionDetailsInputInterface -{ - if (currentFavorite) [currentFavorite release], currentFavorite = nil; - - [self setName:@""]; - [self setHost:@""]; - [self setSocket:@""]; - [self setUser:@""]; - [self setPort:@""]; - [self setDatabase:@""]; - [self setPassword:@""]; - - // SSL details - [self setUseSSL:NSOffState]; - [self setSslKeyFileLocationEnabled:NSOffState]; - [self setSslKeyFileLocation:@""]; - [self setSslCertificateFileLocationEnabled:NSOffState]; - [self setSslCertificateFileLocation:@""]; - [self setSslCACertFileLocationEnabled:NSOffState]; - [self setSslCACertFileLocation:@""]; - - // SSH details - [self setSshHost:@""]; - [self setSshUser:@""]; - [self setSshPassword:@""]; - [self setSshKeyLocationEnabled:NSOffState]; - [self setSshKeyLocation:@""]; - [self setSshPort:@""]; -} - #pragma mark - - (void)dealloc diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index bbdf7624..567f8e87 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -45,7 +45,6 @@ static NSString *SPDatabaseImage = @"database-small"; - (NSString *)_stripInvalidCharactersFromString:(NSString *)subject; -- (void)_resetConnectionDetailsInputInterface; - (void)_setNodeIsExpanded:(BOOL)expanded fromNotification:(NSNotification *)notification; @end @@ -85,17 +84,15 @@ static NSString *SPDatabaseImage = @"database-small"; SPTreeNode *node = [self selectedFavoriteNode]; - if (![node isGroup]) { - [self updateFavoriteSelection:self]; - + [self updateFavoriteSelection:self]; + + if (![node isGroup]) { [addToFavoritesButton setEnabled:NO]; - + favoriteNameFieldWasTouched = YES; } else { [addToFavoritesButton setEnabled:YES]; - - [self _resetConnectionDetailsInputInterface]; } [connectionResizeContainer setHidden:NO]; @@ -415,6 +412,7 @@ static NSString *SPDatabaseImage = @"database-small"; */ - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { + // Request a password refresh to keep keychain references in sync with favorites, but only if a favorite // is selected, meaning we're editing an existing one, not a new one. if (((id)control != (id)favoritesOutlineView) && ([self selectedFavoriteNode])) { diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m index 90f9985a..f09a97da 100644 --- a/Source/SPDatabaseDocument.m +++ b/Source/SPDatabaseDocument.m @@ -4109,7 +4109,7 @@ static NSString *SPRenameDatabaseAction = @"SPRenameDatabase"; #ifndef SP_REFACTOR [aWindow makeFirstResponder:(NSResponder *)[connectionController favoritesOutlineView]]; #endif - [connectionController performSelector:@selector(updateFavoriteSelection:) withObject:self afterDelay:0.0]; + [connectionController updateFavoriteSelection:self]; } parentWindow = aWindow; @@ -4393,7 +4393,8 @@ static NSString *SPRenameDatabaseAction = @"SPRenameDatabase"; [self updateWindowTitle:self]; - // Deselect all favorites on the connection controller + // Deselect all favorites on the connection controller. This will automatically + // clear and reset the connection state. [[connectionController favoritesOutlineView] deselectAll:connectionController]; // Suppress the possibility to choose an other connection from the favorites @@ -4401,32 +4402,6 @@ static NSString *SPRenameDatabaseAction = @"SPRenameDatabase"; // that the SPF file runs out of sync. [[connectionController favoritesOutlineView] setEnabled:NO]; - // Ensure the connection controller is set to a blank slate - [connectionController setName:@""]; - [connectionController setUser:@""]; - [connectionController setHost:@""]; - [connectionController setPort:@""]; - [connectionController setSocket:@""]; - [connectionController setUseSSL:NSOffState]; - [connectionController setSslKeyFileLocationEnabled:NSOffState]; - [connectionController setSslKeyFileLocation:nil]; - [connectionController setSslCertificateFileLocationEnabled:NSOffState]; - [connectionController setSslCertificateFileLocation:nil]; - [connectionController setSslCACertFileLocationEnabled:NSOffState]; - [connectionController setSslCACertFileLocation:nil]; - [connectionController setSshHost:@""]; - [connectionController setSshUser:@""]; - [connectionController setSshKeyLocationEnabled:NSOffState]; - [connectionController setSshKeyLocation:nil]; - [connectionController setSshPort:@""]; - [connectionController setDatabase:@""]; - [connectionController setPassword:nil]; - [connectionController setConnectionKeychainItemName:nil]; - [connectionController setConnectionKeychainItemAccount:nil]; - [connectionController setSshPassword:nil]; - [connectionController setConnectionSSHKeychainItemName:nil]; - [connectionController setConnectionSSHKeychainItemAccount:nil]; - // Set the correct connection type if ([connection objectForKey:@"type"]) { if ([[connection objectForKey:@"type"] isEqualToString:@"SPTCPIPConnection"]) -- cgit v1.2.3