From 4e87089af2ce50364a3e6fcfdf8a3c31e172d8aa Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 5 Dec 2010 15:03:28 +0000 Subject: Apply new favorites outline view patch. --- Source/SPConnectionControllerDelegate.m | 495 +++++++++++++++++++++++++------- 1 file changed, 392 insertions(+), 103 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index a2653c5a..f6923ec2 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -25,88 +25,11 @@ #import "SPConnectionControllerDelegate.h" #import "SPTableTextFieldCell.h" +#import "SPFavoriteNode.h" +#import "SPGroupNode.h" @implementation SPConnectionController (SPConnectionControllerDelegate) -/*#pragma mark - - #pragma mark TableView drag & drop delegate methods - - - (BOOL)tableView:(NSTableView *)aTableView writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard *)pboard - { - NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes]; - [pboard declareTypes:[NSArray arrayWithObject:favoritesPBoardType] owner:self]; - [pboard setData:archivedData forType:favoritesPBoardType]; - return YES; - } - - - (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id )info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation - { - if (row == 0) return NSDragOperationNone; - if ([info draggingSource] == aTableView) - { - [aTableView setDropRow:row dropOperation:NSTableViewDropAbove]; - return NSDragOperationMove; - } - return NSDragOperationNone; - } - - - (BOOL)tableView:(NSTableView *)aTableView acceptDrop:(id )info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation - { - BOOL acceptedDrop = NO; - - if ((row == 0) || ([info draggingSource] != aTableView)) return acceptedDrop; - - // Disable all automatic sorting - currentSortItem = -1; - reverseFavoritesSort = NO; - - [prefs setInteger:currentSortItem forKey:SPFavoritesSortedBy]; - [prefs setBool:NO forKey:SPFavoritesSortedInReverse]; - - // Remove sort descriptors - [favorites sortUsingDescriptors:[NSArray array]]; - - // Uncheck sort by menu items - for (NSMenuItem *menuItem in [[favoritesSortByMenuItem submenu] itemArray]) - { - [menuItem setState:NSOffState]; - } - - NSPasteboard* pboard = [info draggingPasteboard]; - NSData* rowData = [pboard dataForType:favoritesPBoardType]; - NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData:rowData]; - NSInteger dragRow = [rowIndexes firstIndex]; - NSInteger defaultConnectionRow = [prefs integerForKey:SPLastFavoriteIndex]; - if (defaultConnectionRow == dragRow) - { - [prefs setInteger:row forKey:SPLastFavoriteIndex]; - } - NSMutableDictionary *draggedFavorite = [favorites objectAtIndex:dragRow]; - [favorites removeObjectAtIndex:dragRow]; - if (row > dragRow) - { - row--; - } - [favorites insertObject:draggedFavorite atIndex:row]; - [aTableView reloadData]; - - // reset the prefs with the new order - NSMutableArray *reorderedFavorites = [[NSMutableArray alloc] initWithArray:favorites]; - [reorderedFavorites removeObjectAtIndex:0]; - [prefs setObject:reorderedFavorites forKey:SPFavorites]; - - [[[[NSApp delegate] preferenceController] generalPreferencePane] updateDefaultFavoritePopup]; - - [reorderedFavorites release]; - - [self updateFavorites]; - [aTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO]; - - acceptedDrop = YES; - - return acceptedDrop; - }*/ - #pragma mark - #pragma mark SplitView delegate methods @@ -144,28 +67,57 @@ - (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item { - SPFavoriteNode *node = (item == nil ? favoritesRoot : (SPFavoriteNode *)item); + SPTreeNode *node = (item == nil ? favoritesRoot : (SPTreeNode *)item); - return [[node nodeChildren] count]; + return [[node childNodes] count]; } - (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item { - SPFavoriteNode *node = (item == nil ? favoritesRoot : (SPFavoriteNode *)item); + SPTreeNode *node = (item == nil ? favoritesRoot : (SPTreeNode *)item); - return NSArrayObjectAtIndex([node nodeChildren], index); + return NSArrayObjectAtIndex([node childNodes], index); } - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item { - return [(SPFavoriteNode *)item nodeIsGroup]; + return [(SPTreeNode *)item isGroup]; } - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item { - SPFavoriteNode *node = (SPFavoriteNode *)item; + SPTreeNode *node = (SPTreeNode *)item; + + return (![node isGroup]) ? [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey] : [[node representedObject] nodeName]; +} + +- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item +{ + // Trim whitespace + NSString *newName = [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - return ([node nodeIsGroup]) ? [node nodeName] : [[node nodeFavorite] objectForKey:SPFavoriteNameKey]; + if ([newName length]) { + + // Get the node that was renamed + SPTreeNode *node = [self selectedFavoriteNode]; + + if (![node isGroup]) { + //[[[node representedObject] nodeFavorite] setObject:newName forKey:SPFavoriteNameKey]; + + // Updating the name triggers a KVO update + [self setName:newName]; + + // Update associated Keychain items + [self _updateFavoritePasswordsFromField:nil]; + } + else { + [[node representedObject] setNodeName:newName]; + + [favoritesController saveFavorites]; + + [self _reloadFavoritesViewData]; + } + } } #pragma mark - @@ -173,15 +125,22 @@ - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item { - return [(SPFavoriteNode *)item nodeIsGroup]; + return ([[(SPTreeNode *)item parentNode] parentNode] == nil); } - (void)outlineViewSelectionDidChange:(NSNotification *)notification -{ - if ([favoritesTable numberOfSelectedRows] == 1) { - [self updateFavoriteSelection:self]; +{ + if ([favoritesOutlineView numberOfSelectedRows] == 1) { + + SPTreeNode *node = [self selectedFavoriteNode]; - [addToFavoritesButton setEnabled:NO]; + if (![node isGroup]) { + [self updateFavoriteSelection:self]; + + [addToFavoritesButton setEnabled:NO]; + + favoriteNameFieldWasTouched = YES; + } } else { [addToFavoritesButton setEnabled:YES]; @@ -190,35 +149,365 @@ - (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item { + SPTreeNode *node = (SPTreeNode *)item; + [(SPTableTextFieldCell *)cell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]]; - if ([favoritesTable isEnabled]) { - [(SPTableTextFieldCell *)cell setTextColor:[NSColor blackColor]]; + [(SPTableTextFieldCell *)cell setTextColor:([favoritesOutlineView isEnabled]) ? [NSColor blackColor] : [NSColor grayColor]]; + + if (![[node parentNode] parentNode]) { + [(SPTableTextFieldCell *)cell setImage:nil]; } else { - [(SPTableTextFieldCell *)cell setTextColor:[NSColor grayColor]]; - } - - [(SPTableTextFieldCell *)cell setImage:([(SPFavoriteNode *)item nodeIsGroup]) ? nil : [NSImage imageNamed:@"database-small"]]; + [(SPTableTextFieldCell *)cell setImage:(![node isGroup]) ? [NSImage imageNamed:@"database-small"] : folderImage]; + } } - (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item { - return ([item nodeIsGroup]) ? 22 : 17; + return ((SPTreeNode *)[[item parentNode] parentNode] == nil) ? 22 : 17; +} + +- (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation +{ + SPTreeNode *node = (SPTreeNode *)item; + + if (![node isGroup]) { + return [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey]; + } + else { + NSUInteger favCount = [[node childNodes] count]; + + return [NSString stringWithFormat:@"%@ - %d %@", [[node representedObject] nodeName], favCount, (favCount == 1) ? NSLocalizedString(@"favorite", @"favorite singular label") : NSLocalizedString(@"favorites", @"favorites plural label")]; + } } - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item +{ + return ([[item parentNode] parentNode] != nil); +} + +#pragma mark - +#pragma mark Outline view drag & drop + +/*- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard +{ + [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; + [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; + + return YES; +} + +- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index { - return (![item nodeIsGroup]); + NSDragOperation result = NSDragOperationNone; + + if ([info draggingSource] == outlineView) { + [outlineView setDropItem:item dropChildIndex:index]; + + result = NSDragOperationMove; + } + + return result; } +- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id )info item:(id)item childIndex:(NSInteger)index +{ + BOOL acceptedDrop = NO; + + if ((!item) || ([info draggingSource] != outlineView)) return acceptedDrop; + + SPTreeNode *node = (item) ? item : favoritesRoot; + + // Disable all automatic sorting + //currentSortItem = -1; + //reverseFavoritesSort = NO; + + //[prefs setInteger:currentSortItem forKey:SPFavoritesSortedBy]; + //[prefs setBool:NO forKey:SPFavoritesSortedInReverse]; + + // Remove sort descriptors + //[favorites sortUsingDescriptors:[NSArray array]]; + + // Uncheck sort by menu items + for (NSMenuItem *menuItem in [[favoritesSortByMenuItem submenu] itemArray]) + { + [menuItem setState:NSOffState]; + } + + NSArray *nodes = [self selectedFavoriteNodes]; + + if ([node isGroup]) { + if (index == NSOutlineViewDropOnItemIndex) { + index = 0; + } + else { + SPTreeNode *oldNode = node; + + node = [node parentNode]; + index = ([[node childNodes] indexOfObject:oldNode] + 1); + } + } + else { + if (index == NSOutlineViewDropOnItemIndex) { + index = 0; + } + } + + NSMutableArray *childNodeArray = [node mutableChildNodes]; + + for (SPTreeNode *treeNode in nodes) + { + // Remove the node from its old location + NSInteger oldIndex = [childNodeArray indexOfObject:treeNode]; + NSInteger newIndex = index; + + if (oldIndex != NSNotFound) { + + [childNodeArray removeObjectAtIndex:oldIndex]; + + if (index > oldIndex) { + newIndex--; + } + } + else { + [[[treeNode parentNode] mutableChildNodes] removeObject:treeNode]; + } + + [childNodeArray insertObject:treeNode atIndex:newIndex]; + + newIndex++; + } + + [self _reloadFavoritesViewData]; + + [[[[NSApp delegate] preferenceController] generalPreferencePane] updateDefaultFavoritePopup]; + + acceptedDrop = YES; + + return acceptedDrop; +}*/ + +#pragma mark - +#pragma mark Textfield delegate methods /** - * Double-Click opens the connection. + * Trap and control the 'name' field of the selected favorite. If the user pressed + * 'Add Favorite' the 'name' field is set to 'New Favorite'. If the user did not + * change the 'name' field or delete that field it will be set to user@host automatically. */ -- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item +- (void)controlTextDidChange:(NSNotification *)notification { - [self initiateConnection:self]; - return NO; + id field = [notification object]; + + NSMutableDictionary *favorite = [self selectedFavorite]; + + BOOL nameFieldIsEmpty = [[favorite objectForKey:SPFavoriteNameKey] isEqualToString:@""]; + + switch (previousType) + { + case SPTCPIPConnection: + + nameFieldIsEmpty = (nameFieldIsEmpty || [[standardNameField stringValue] isEqualToString:@""]); + + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == standardUserField || field == standardSQLHostField))) { + [standardNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [standardUserField stringValue], [standardSQLHostField stringValue]]]; + + // Trigger KVO update + [self setName:[standardNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } + + break; + case SPSocketConnection: + + nameFieldIsEmpty = (nameFieldIsEmpty || [[socketNameField stringValue] isEqualToString:@""]); + + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && field == socketUserField)) { + [socketNameField setStringValue:[NSString stringWithFormat:@"%@@localhost", [socketUserField stringValue]]]; + + // Trigger KVO update + [self setName:[socketNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } + + break; + case SPSSHTunnelConnection: + + nameFieldIsEmpty = (nameFieldIsEmpty || [[sshNameField stringValue] isEqualToString:@""]); + + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == sshUserField || field == sshSQLHostField))) { + [sshNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [sshUserField stringValue], [sshSQLHostField stringValue]]]; + + // Trigger KVO update + [self setName:[sshNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } + + break; + default: + break; + } + + if ((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) favoriteNameFieldWasTouched = YES; } + +/** + * When a host field finishes editing, ensure that it hasn't been set to "localhost" + * to ensure that socket connections don't inadvertently occur. + */ +- (void)controlTextDidEndEditing:(NSNotification *)notification +{ + if ([notification object] == standardSQLHostField || [notification object] == sshSQLHostField) { + [self _checkHost]; + } +} + +/** + * Trap editing end notifications and use them to update the keychain password + * appropriately when name, host, user, password or database changes. + */ +- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor +{ + if (control != favoritesOutlineView) { + // Request a password refresh to keep keychain references in synch with favorites + [self _updateFavoritePasswordsFromField:control]; + } + + // Proceed with editing + return YES; +} + +#pragma mark - +#pragma mark Tab bar delegate methods + +/** + * Trigger a resize action whenever the tab view changes. The connection + * detail forms are held within container views, which are of a fixed width; + * the tabview and buttons are contained within a resizable view which + * is set to dimensions based on the container views, allowing the view + * to be sized according to the detail type. + */ +- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem +{ + NSInteger selectedTabView = [tabView indexOfTabViewItem:tabViewItem]; + + // Deselect any selected favorite for manual changes + if (!automaticFavoriteSelection) [favoritesOutlineView deselectAll:self]; + automaticFavoriteSelection = NO; + + if (selectedTabView == previousType) return; + + [self resizeTabViewToConnectionType:selectedTabView animating:YES]; + + // Update the host as appropriate + if ((selectedTabView != SPSocketConnection) && [[self host] isEqualToString:@"localhost"]) { + [self setHost:@""]; + } + + previousType = selectedTabView; + + [self _favoriteTypeDidChange]; +} + +#pragma mark - +#pragma mark Scroll view notifications + +/** + * As the scrollview resizes, keep the details centered within it if + * the detail frame is larger than the scrollview size; otherwise, pin + * the detail frame to the top of the scrollview. + */ +- (void)scrollViewFrameChanged:(NSNotification *)aNotification +{ + NSRect scrollViewFrame = [connectionDetailsScrollView frame]; + NSRect scrollDocumentFrame = [[connectionDetailsScrollView documentView] frame]; + NSRect connectionDetailsFrame = [connectionResizeContainer frame]; + + // Scroll view is smaller than contents - keep positioned at top. + if (scrollViewFrame.size.height < connectionDetailsFrame.size.height + 10) { + if (connectionDetailsFrame.origin.y != 0) { + connectionDetailsFrame.origin.y = 0; + [connectionResizeContainer setFrame:connectionDetailsFrame]; + scrollDocumentFrame.size.height = connectionDetailsFrame.size.height + 10; + [[connectionDetailsScrollView documentView] setFrame:scrollDocumentFrame]; + } + } + // Otherwise, center + else { + connectionDetailsFrame.origin.y = (scrollViewFrame.size.height - connectionDetailsFrame.size.height)/3; + [connectionResizeContainer setFrame:connectionDetailsFrame]; + scrollDocumentFrame.size.height = scrollViewFrame.size.height; + [[connectionDetailsScrollView documentView] setFrame:scrollDocumentFrame]; + } +} + +#pragma mark - +#pragma mark Menu Validation + +/** + * Menu item validation. + */ +- (BOOL)validateMenuItem:(NSMenuItem *)menuItem +{ + SEL action = [menuItem action]; + + SPTreeNode *node = [self selectedFavoriteNode]; + + if ((action == @selector(sortFavorites:)) || (action == @selector(reverseSortFavorites:))) { + + // TODO: Fix me, disabled because of new outline view + return NO; + + // Loop all the items in the sort by menu only checking the currently selected one + for (NSMenuItem *item in [[menuItem menu] itemArray]) + { + [item setState:([[menuItem menu] indexOfItem:item] == currentSortItem) ? NSOnState : NSOffState]; + } + + // Check or uncheck the reverse sort item + if (action == @selector(reverseSortFavorites:)) { + [menuItem setState:reverseFavoritesSort]; + } + } + + // Remove the selected favorite + if (action == @selector(removeNode:)) { + return ([favoritesOutlineView numberOfSelectedRows] == 1); + } + + // Duplicate and make the selected favorite the default + if ((action == @selector(duplicateFavorite:)) || (action == @selector(makeSelectedFavoriteDefault:))) { + return (([favoritesOutlineView numberOfSelectedRows] == 1) && (![node isGroup])); + } + + // Rename selected favorite/group + if (action == @selector(renameFavorite:)) { + return ([favoritesOutlineView numberOfSelectedRows] == 1); + } + + // Favorites export + if (action == @selector(exportFavorites:)) { + + NSInteger rows = [favoritesOutlineView numberOfSelectedRows]; + + if (rows > 1) { + [menuItem setTitle:NSLocalizedString(@"Export Selected...", @"export selected favorites menu item")]; + } + else if (rows == 1) { + return (![[self selectedFavoriteNode] isGroup]); + } + + return YES; + } + + return YES; +} + @end -- cgit v1.2.3 From e945be72f8e476d84c19f712dd79e51a4a3f1e80 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 5 Dec 2010 15:37:40 +0000 Subject: Improve menu item validation with regard to making the selected favorite the default. --- Source/SPConnectionControllerDelegate.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index f6923ec2..da16fd57 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -483,10 +483,17 @@ } // Duplicate and make the selected favorite the default - if ((action == @selector(duplicateFavorite:)) || (action == @selector(makeSelectedFavoriteDefault:))) { + if (action == @selector(duplicateFavorite:)) { return (([favoritesOutlineView numberOfSelectedRows] == 1) && (![node isGroup])); } + // Make selected favorite the default + if (action == @selector(makeSelectedFavoriteDefault:)) { + NSInteger favoriteID = [[[self selectedFavorite] objectForKey:SPFavoriteIDKey] integerValue]; + + return (([favoritesOutlineView numberOfSelectedRows] == 1) && (![node isGroup]) && (favoriteID != [prefs integerForKey:SPDefaultFavorite])); + } + // Rename selected favorite/group if (action == @selector(renameFavorite:)) { return ([favoritesOutlineView numberOfSelectedRows] == 1); -- cgit v1.2.3 From e1abafb0d9401c3b62c762921362effabe14f844 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 5 Dec 2010 19:00:55 +0000 Subject: Add description methods to tree node classes to aid debugging. --- Source/SPConnectionControllerDelegate.m | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 8e2e03b2..9094c6cc 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -101,9 +101,7 @@ // Get the node that was renamed SPTreeNode *node = [self selectedFavoriteNode]; - if (![node isGroup]) { - //[[[node representedObject] nodeFavorite] setObject:newName forKey:SPFavoriteNameKey]; - + if (![node isGroup]) { // Updating the name triggers a KVO update [self setName:newName]; @@ -124,9 +122,7 @@ #pragma mark Outline view delegate methods - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item -{ - NSLog(@"%@", [(SPTreeNode *)item representedObject]); - +{ return ([[(SPTreeNode *)item parentNode] parentNode] == nil); } @@ -192,7 +188,7 @@ #pragma mark - #pragma mark Outline view drag & drop -- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard +/*- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard { [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; @@ -220,7 +216,7 @@ if ((!item) || ([info draggingSource] != outlineView)) return acceptedDrop; SPTreeNode *node = (item) ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0]; - + // TODO: Fix me, disable automatic sorting // Disable all automatic sorting @@ -234,10 +230,10 @@ //[favorites sortUsingDescriptors:[NSArray array]]; // Uncheck sort by menu items - /*for (NSMenuItem *menuItem in [[favoritesSortByMenuItem submenu] itemArray]) + for (NSMenuItem *menuItem in [[favoritesSortByMenuItem submenu] itemArray]) { [menuItem setState:NSOffState]; - }*/ + } NSArray *nodes = [self selectedFavoriteNodes]; @@ -292,7 +288,7 @@ acceptedDrop = YES; return acceptedDrop; -} +}*/ #pragma mark - #pragma mark Textfield delegate methods -- cgit v1.2.3 From fa8ef20485323e394af10cd3a9937b634d47b436 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Mon, 6 Dec 2010 21:30:46 +0000 Subject: When either more than one favorite or a favorite group is selected in the connection view, hide the connection details form. --- Source/SPConnectionControllerDelegate.m | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 9094c6cc..65804eff 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -127,9 +127,9 @@ } - (void)outlineViewSelectionDidChange:(NSNotification *)notification -{ +{ if ([favoritesOutlineView numberOfSelectedRows] == 1) { - + SPTreeNode *node = [self selectedFavoriteNode]; if (![node isGroup]) { @@ -138,10 +138,18 @@ [addToFavoritesButton setEnabled:NO]; favoriteNameFieldWasTouched = YES; + + [connectionResizeContainer setHidden:NO]; + [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Enter connection details below, or choose a favorite", @"enter connection details label")]; } - } + else { + [connectionResizeContainer setHidden:YES]; + [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Please choose a favorite", @"please choose a favorite connection view label")]; + } + } else { - [addToFavoritesButton setEnabled:YES]; + [connectionResizeContainer setHidden:YES]; + [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Please choose a favorite", @"please choose a favorite connection view label")]; } } -- cgit v1.2.3 From 04beef3900cfdb023257ebfeadb48a9949e9ea5f Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Wed, 8 Dec 2010 19:29:10 +0000 Subject: When changing the type of an already existing favorite, don't hide connection details form view. --- Source/SPConnectionControllerDelegate.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 65804eff..4af4eeda 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -128,7 +128,9 @@ - (void)outlineViewSelectionDidChange:(NSNotification *)notification { - if ([favoritesOutlineView numberOfSelectedRows] == 1) { + NSInteger selected = [favoritesOutlineView numberOfSelectedRows]; + + if (selected == 1) { SPTreeNode *node = [self selectedFavoriteNode]; @@ -147,7 +149,7 @@ [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Please choose a favorite", @"please choose a favorite connection view label")]; } } - else { + else if (selected > 1) { [connectionResizeContainer setHidden:YES]; [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Please choose a favorite", @"please choose a favorite connection view label")]; } -- cgit v1.2.3 From 05f91b6778fecc28add3cc2218867cf9134599e7 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Wed, 8 Dec 2010 19:46:16 +0000 Subject: Enable the 'add to favorites' button when the user manually changes a connection's type. --- Source/SPConnectionControllerDelegate.m | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 4af4eeda..ee218ba3 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -409,7 +409,7 @@ - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem { NSInteger selectedTabView = [tabView indexOfTabViewItem:tabViewItem]; - + // Deselect any selected favorite for manual changes if (!automaticFavoriteSelection) [favoritesOutlineView deselectAll:self]; automaticFavoriteSelection = NO; @@ -425,6 +425,9 @@ previousType = selectedTabView; + // Enable the add to favorites button + [addToFavoritesButton setEnabled:YES]; + [self _favoriteTypeDidChange]; } -- cgit v1.2.3 From cecdee329489a304d94630662a24a6d0145eaa1a Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Wed, 8 Dec 2010 20:58:57 +0000 Subject: Update a connection favorite's name accordingly if it's type is changed. --- Source/SPConnectionControllerDelegate.m | 108 ++++++++++++++++---------------- 1 file changed, 55 insertions(+), 53 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index ee218ba3..922d2405 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -311,63 +311,64 @@ - (void)controlTextDidChange:(NSNotification *)notification { id field = [notification object]; - - NSMutableDictionary *favorite = [self selectedFavorite]; - - BOOL nameFieldIsEmpty = [[favorite objectForKey:SPFavoriteNameKey] isEqualToString:@""]; - - switch (previousType) - { - case SPTCPIPConnection: - - nameFieldIsEmpty = (nameFieldIsEmpty || [[standardNameField stringValue] isEqualToString:@""]); - - if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == standardUserField || field == standardSQLHostField))) { - [standardNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [standardUserField stringValue], [standardSQLHostField stringValue]]]; - // Trigger KVO update - [self setName:[standardNameField stringValue]]; - - // If name field is empty enable user@host update - if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; - } - - break; - case SPSocketConnection: - - nameFieldIsEmpty = (nameFieldIsEmpty || [[socketNameField stringValue] isEqualToString:@""]); - - if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && field == socketUserField)) { - [socketNameField setStringValue:[NSString stringWithFormat:@"%@@localhost", [socketUserField stringValue]]]; + if ([self selectedFavoriteNode]) { + + BOOL nameFieldIsEmpty = [[field stringValue] isEqualToString:@""]; + + switch (previousType) + { + case SPTCPIPConnection: - // Trigger KVO update - [self setName:[socketNameField stringValue]]; + nameFieldIsEmpty = (nameFieldIsEmpty || [[standardNameField stringValue] isEqualToString:@""]); - // If name field is empty enable user@host update - if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; - } - - break; - case SPSSHTunnelConnection: - - nameFieldIsEmpty = (nameFieldIsEmpty || [[sshNameField stringValue] isEqualToString:@""]); - - if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == sshUserField || field == sshSQLHostField))) { - [sshNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [sshUserField stringValue], [sshSQLHostField stringValue]]]; + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == standardUserField || field == standardSQLHostField))) { + [standardNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [standardUserField stringValue], [standardSQLHostField stringValue]]]; + + // Trigger KVO update + [self setName:[standardNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } - // Trigger KVO update - [self setName:[sshNameField stringValue]]; + break; + case SPSocketConnection: - // If name field is empty enable user@host update - if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; - } - - break; - default: - break; + nameFieldIsEmpty = (nameFieldIsEmpty || [[socketNameField stringValue] isEqualToString:@""]); + + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && field == socketUserField)) { + [socketNameField setStringValue:[NSString stringWithFormat:@"%@@localhost", [socketUserField stringValue]]]; + + // Trigger KVO update + [self setName:[socketNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } + + break; + case SPSSHTunnelConnection: + + nameFieldIsEmpty = (nameFieldIsEmpty || [[sshNameField stringValue] isEqualToString:@""]); + + if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && (field == sshUserField || field == sshSQLHostField))) { + [sshNameField setStringValue:[NSString stringWithFormat:@"%@@%@", [sshUserField stringValue], [sshSQLHostField stringValue]]]; + + // Trigger KVO update + [self setName:[sshNameField stringValue]]; + + // If name field is empty enable user@host update + if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; + } + + break; + default: + break; + } + + if ((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) favoriteNameFieldWasTouched = YES; } - - if ((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) favoriteNameFieldWasTouched = YES; } /** @@ -387,8 +388,9 @@ */ - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { - if (control != favoritesOutlineView) { - // Request a password refresh to keep keychain references in synch with favorites + // Request a password refresh to keep keychain references in synch with favorites, but only if a favorite + // is selected, meaning we're editing an existing one, not a new one. + if ((control != favoritesOutlineView) && ([self selectedFavoriteNode])) { [self _updateFavoritePasswordsFromField:control]; } -- cgit v1.2.3 From 66f0041a06b8710cd3ed3b5ff2c8cbb54004efba Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sat, 11 Dec 2010 21:48:37 +0000 Subject: Tidy up. --- Source/SPConnectionControllerDelegate.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 922d2405..6ad83963 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -227,7 +227,7 @@ SPTreeNode *node = (item) ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0]; - // TODO: Fix me, disable automatic sorting + // TODO: Fix me // Disable all automatic sorting //currentSortItem = -1; @@ -479,7 +479,7 @@ if ((action == @selector(sortFavorites:)) || (action == @selector(reverseSortFavorites:))) { - // TODO: Fix me, disabled because of new outline view + // TODO: Fix me return NO; // Loop all the items in the sort by menu only checking the currently selected one -- cgit v1.2.3 From cacea8262fa8a696fbdf132874383d3bafb2ef93 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Fri, 17 Dec 2010 21:50:37 +0000 Subject: Improve favorite tooltips. --- Source/SPConnectionControllerDelegate.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 9e63a547..c0b86c0f 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -183,7 +183,7 @@ SPTreeNode *node = (SPTreeNode *)item; if (![node isGroup]) { - return [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey]; + return [NSString stringWithFormat:@"%@ (%@)", [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey], [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteHostKey]]; } else { NSUInteger favCount = [[node childNodes] count]; -- cgit v1.2.3 From fa7cff57548edc51420693e6909fe2adb3c18951 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Wed, 26 Jan 2011 21:44:29 +0000 Subject: Fix and enable drag and drop in the connection favorites outline view. --- Source/SPConnectionControllerDelegate.m | 49 ++++++++++++++------------------- 1 file changed, 21 insertions(+), 28 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 449a2cb2..3318958e 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -109,7 +109,7 @@ #pragma mark Outline view delegate methods - (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item -{ +{ return ([[(SPTreeNode *)item parentNode] parentNode] == nil); } @@ -160,7 +160,7 @@ - (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item { - return ((SPTreeNode *)[[item parentNode] parentNode] == nil) ? 22 : 17; + return (![[item parentNode] parentNode]) ? 22 : 17; } - (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation @@ -185,7 +185,7 @@ #pragma mark - #pragma mark Outline view drag & drop -/*- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard +- (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard { [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; @@ -197,6 +197,9 @@ { NSDragOperation result = NSDragOperationNone; + // Prevent dropping favorites on other favorites (non-groups) + if ((index == NSOutlineViewDropOnItemIndex) && (![item isGroup])) return result; + if ([info draggingSource] == outlineView) { [outlineView setDropItem:item dropChildIndex:index]; @@ -211,46 +214,39 @@ BOOL acceptedDrop = NO; if ((!item) || ([info draggingSource] != outlineView)) return acceptedDrop; - + SPTreeNode *node = (item) ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0]; - - // TODO: Fix me - + // Disable all automatic sorting - //currentSortItem = -1; - //reverseFavoritesSort = NO; - - //[prefs setInteger:currentSortItem forKey:SPFavoritesSortedBy]; - //[prefs setBool:NO forKey:SPFavoritesSortedInReverse]; + currentSortItem = -1; + reverseFavoritesSort = NO; - // Remove sort descriptors - //[favorites sortUsingDescriptors:[NSArray array]]; + [prefs setInteger:currentSortItem forKey:SPFavoritesSortedBy]; + [prefs setBool:NO forKey:SPFavoritesSortedInReverse]; // Uncheck sort by menu items for (NSMenuItem *menuItem in [[favoritesSortByMenuItem submenu] itemArray]) { [menuItem setState:NSOffState]; } - + NSArray *nodes = [self selectedFavoriteNodes]; if ([node isGroup]) { if (index == NSOutlineViewDropOnItemIndex) { index = 0; } - else { - SPTreeNode *oldNode = node; - - node = [node parentNode]; - index = ([[node childNodes] indexOfObject:oldNode] + 1); - } } else { if (index == NSOutlineViewDropOnItemIndex) { index = 0; } } - + + if (![[node representedObject] nodeName]) { + node = [[favoritesRoot childNodes] objectAtIndex:0]; + } + NSMutableArray *childNodeArray = [node mutableChildNodes]; for (SPTreeNode *treeNode in nodes) @@ -270,12 +266,12 @@ else { [[[treeNode parentNode] mutableChildNodes] removeObject:treeNode]; } - + [childNodeArray insertObject:treeNode atIndex:newIndex]; newIndex++; } - + [favoritesController saveFavorites]; [self _reloadFavoritesViewData]; @@ -285,7 +281,7 @@ acceptedDrop = YES; return acceptedDrop; -}*/ +} #pragma mark - #pragma mark Textfield delegate methods @@ -466,9 +462,6 @@ if ((action == @selector(sortFavorites:)) || (action == @selector(reverseSortFavorites:))) { - // TODO: Fix me - return NO; - // Loop all the items in the sort by menu only checking the currently selected one for (NSMenuItem *item in [[menuItem menu] itemArray]) { -- cgit v1.2.3 From 32b7c4df28e2eb3a4a8bcb71b3faae4f173f016c Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sat, 5 Mar 2011 00:14:43 +0000 Subject: Add support for auto saving expanded items. --- Source/SPConnectionControllerDelegate.m | 56 --------------------------------- 1 file changed, 56 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 3318958e..3aeb2da6 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -49,62 +49,6 @@ [databaseConnectionView setPosition:[[[connectionSplitView subviews] objectAtIndex:0] frame].size.width ofDividerAtIndex:0]; } -#pragma mark - -#pragma mark Outline view datasource methods - -- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item -{ - SPTreeNode *node = (item == nil ? favoritesRoot : (SPTreeNode *)item); - - return [[node childNodes] count]; -} - -- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item -{ - SPTreeNode *node = (item == nil ? favoritesRoot : (SPTreeNode *)item); - - return NSArrayObjectAtIndex([node childNodes], index); -} - -- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item -{ - return [(SPTreeNode *)item isGroup]; -} - -- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item -{ - SPTreeNode *node = (SPTreeNode *)item; - - return (![node isGroup]) ? [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey] : [[node representedObject] nodeName]; -} - -- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item -{ - // Trim whitespace - NSString *newName = [object stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; - - if ([newName length]) { - - // Get the node that was renamed - SPTreeNode *node = [self selectedFavoriteNode]; - - if (![node isGroup]) { - // Updating the name triggers a KVO update - [self setName:newName]; - - // Update associated Keychain items - [self _updateFavoritePasswordsFromField:nil]; - } - else { - [[node representedObject] setNodeName:newName]; - - [favoritesController saveFavorites]; - - [self _reloadFavoritesViewData]; - } - } -} - #pragma mark - #pragma mark Outline view delegate methods -- cgit v1.2.3 From bb425dd261f7dd5accb3882f7dfdbf1eac298d7e Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sat, 5 Mar 2011 15:28:26 +0000 Subject: Only update a favourite's name if it was the name field that was actually changed. --- Source/SPConnectionControllerDelegate.m | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 3aeb2da6..f055fdc6 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -239,7 +239,9 @@ { id field = [notification object]; - if ([self selectedFavoriteNode]) { + if ([self selectedFavoriteNode] && ((field == standardNameField) || (field == socketNameField) || (field == sshNameField))) { + + favoriteNameFieldWasTouched = YES; BOOL nameFieldIsEmpty = [[field stringValue] isEqualToString:@""]; @@ -289,12 +291,8 @@ if (nameFieldIsEmpty) favoriteNameFieldWasTouched = NO; } - break; - default: break; } - - if ((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) favoriteNameFieldWasTouched = YES; } } -- cgit v1.2.3 From 2b65cd016551fa211409bcde6278f5593afd34e2 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sat, 5 Mar 2011 16:08:32 +0000 Subject: ToolTip fixes for root node. --- Source/SPConnectionControllerDelegate.m | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index f055fdc6..76a4c35e 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -104,21 +104,26 @@ - (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item { - return (![[item parentNode] parentNode]) ? 22 : 17; + return ([[item parentNode] parentNode]) ? 17 : 22; } - (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation { + NSString *toolTip = nil; + SPTreeNode *node = (SPTreeNode *)item; if (![node isGroup]) { - return [NSString stringWithFormat:@"%@ (%@)", [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey], [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteHostKey]]; + toolTip = [NSString stringWithFormat:@"%@ (%@)", [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey], [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteHostKey]]; } - else { + // Only display a tooltip for group nodes that are a child of the root node + else if ([[node parentNode] parentNode]) { NSUInteger favCount = [[node childNodes] count]; - return [NSString stringWithFormat:@"%@ - %d %@", [[node representedObject] nodeName], favCount, (favCount == 1) ? NSLocalizedString(@"favorite", @"favorite singular label") : NSLocalizedString(@"favorites", @"favorites plural label")]; + toolTip = [NSString stringWithFormat:@"%@ - %d %@", [[node representedObject] nodeName], favCount, (favCount == 1) ? NSLocalizedString(@"favorite", @"favorite singular label") : NSLocalizedString(@"favorites", @"favorites plural label")]; } + + return toolTip; } - (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item @@ -239,7 +244,7 @@ { id field = [notification object]; - if ([self selectedFavoriteNode] && ((field == standardNameField) || (field == socketNameField) || (field == sshNameField))) { + if (((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) && [self selectedFavoriteNode]) { favoriteNameFieldWasTouched = YES; @@ -313,7 +318,7 @@ */ - (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor { - // Request a password refresh to keep keychain references in synch with favorites, but only if a favorite + // 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 ((control != favoritesOutlineView) && ([self selectedFavoriteNode])) { [self _updateFavoritePasswordsFromField:control]; -- cgit v1.2.3 From 755287031cdc15298155a5dbffe43476801d97b3 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 6 Mar 2011 14:14:24 +0000 Subject: Fix tooltips for favorite nodes that don't yet have a hostname. --- Source/SPConnectionControllerDelegate.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 76a4c35e..897c86ff 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -114,7 +114,11 @@ SPTreeNode *node = (SPTreeNode *)item; if (![node isGroup]) { - toolTip = [NSString stringWithFormat:@"%@ (%@)", [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey], [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteHostKey]]; + + NSString *favoriteName = [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteNameKey]; + NSString *favoriteHostname = [[[node representedObject] nodeFavorite] objectForKey:SPFavoriteHostKey]; + + toolTip = ([favoriteHostname length]) ? [NSString stringWithFormat:@"%@ (%@)", favoriteName, favoriteHostname] : favoriteName; } // Only display a tooltip for group nodes that are a child of the root node else if ([[node parentNode] parentNode]) { -- cgit v1.2.3 From 915a3831525bf3a9350648d82f86dd54ae366292 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 6 Mar 2011 15:37:06 +0000 Subject: Comments. --- Source/SPConnectionControllerDelegate.m | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 897c86ff..4bff297a 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -30,6 +30,8 @@ #define CELL(cell) (SPTableTextFieldCell *)cell +static const NSString *SPDatabaseImage = @"database-small"; + @implementation SPConnectionController (SPConnectionControllerDelegate) #pragma mark - @@ -98,7 +100,7 @@ [CELL(cell) setImage:nil]; } else { - [CELL(cell) setImage:(![node isGroup]) ? [NSImage imageNamed:@"database-small"] : folderImage]; + [CELL(cell) setImage:(![node isGroup]) ? [NSImage imageNamed:SPDatabaseImage] : folderImage]; } } @@ -277,7 +279,7 @@ if (nameFieldIsEmpty || (!favoriteNameFieldWasTouched && field == socketUserField)) { [socketNameField setStringValue:[NSString stringWithFormat:@"%@@localhost", [socketUserField stringValue]]]; - + // Trigger KVO update [self setName:[socketNameField stringValue]]; -- cgit v1.2.3 From 1e5288e9840e201a00bcb5ca3035d7aa807f1f8d Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Mon, 7 Mar 2011 20:12:52 +0000 Subject: Bring outline view branch up to date with trunk (r3203:r3224). --- Source/SPConnectionControllerDelegate.m | 1 + 1 file changed, 1 insertion(+) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 4bff297a..31ec4099 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -27,6 +27,7 @@ #import "SPTableTextFieldCell.h" #import "SPFavoriteNode.h" #import "SPGroupNode.h" +#import "SPTreeNode.h" #define CELL(cell) (SPTableTextFieldCell *)cell -- cgit v1.2.3 From 1632c45fdd9d0b8fe1e0aef3e891e8bd5704df29 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 13 Mar 2011 18:50:40 +0000 Subject: Fix issue related to dragging a node to a group node that is being renamed as well as fix all warnings related to the connection outlinew view. --- Source/SPConnectionControllerDelegate.m | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 31ec4099..b86e716f 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -24,14 +24,27 @@ // More info at #import "SPConnectionControllerDelegate.h" +#import "SPFavoritesController.h" #import "SPTableTextFieldCell.h" +#import "SPPreferenceController.h" +#import "SPGeneralPreferencePane.h" +#import "SPAppController.h" #import "SPFavoriteNode.h" #import "SPGroupNode.h" #import "SPTreeNode.h" #define CELL(cell) (SPTableTextFieldCell *)cell -static const NSString *SPDatabaseImage = @"database-small"; +static NSString *SPDatabaseImage = @"database-small"; + +@interface SPConnectionController (PrivateAPI) + +- (void)_checkHost; +- (void)_favoriteTypeDidChange; +- (void)_reloadFavoritesViewData; +- (void)_updateFavoritePasswordsFromField:(NSControl *)control; + +@end @implementation SPConnectionController (SPConnectionControllerDelegate) @@ -143,6 +156,17 @@ static const NSString *SPDatabaseImage = @"database-small"; - (BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard { + // If the user is in the process of changing a node's name, trigger a save and prevent dragging. + if (isEditing) { + [favoritesController saveFavorites]; + + [self _reloadFavoritesViewData]; + + isEditing = NO; + + return NO; + } + [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; @@ -327,7 +351,7 @@ static const NSString *SPDatabaseImage = @"database-small"; { // 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 ((control != favoritesOutlineView) && ([self selectedFavoriteNode])) { + if (((id)control != (id)favoritesOutlineView) && ([self selectedFavoriteNode])) { [self _updateFavoritePasswordsFromField:control]; } -- cgit v1.2.3 From f3e65efba3f76cb2149fd8427af9463032d3c45d Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 12 Jun 2011 13:56:11 +0000 Subject: Add the ability to export favorites. --- Source/SPConnectionControllerDelegate.m | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index b86e716f..03dbd930 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -492,4 +492,20 @@ static NSString *SPDatabaseImage = @"database-small"; return YES; } +#pragma mark - +#pragma mark Favorites import/export delegate methods + +/** + * Called by the favorites exporter when the export completes. + */ +- (void)favoritesExportCompletedWithError:(NSError *)error +{ + if (error) { + [[NSAlert alertWithError:error] beginSheetModalForWindow:[dbDocument parentWindow] + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; + } +} + @end -- cgit v1.2.3 From e70486eb1503cad882a0d5e452fef3b2fecf6629 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Mon, 1 Aug 2011 21:54:27 +0000 Subject: Work on importing favorites. --- Source/SPConnectionControllerDelegate.m | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 03dbd930..63f58ace 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -37,7 +37,7 @@ static NSString *SPDatabaseImage = @"database-small"; -@interface SPConnectionController (PrivateAPI) +@interface SPConnectionController () - (void)_checkHost; - (void)_favoriteTypeDidChange; @@ -508,4 +508,17 @@ static NSString *SPDatabaseImage = @"database-small"; } } +/** + * Called by the favorites importer when the import completes. + */ +- (void)favoritesImportCompletedWithError:(NSError *)error +{ + if (error) { + [[NSAlert alertWithError:error] beginSheetModalForWindow:[dbDocument parentWindow] + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; + } +} + @end -- cgit v1.2.3 From d01474532b11014019d4d5a1197a8f8f7d683c0b Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 7 Aug 2011 18:42:51 +0000 Subject: Don't allow newlines in the connection view input fields. Fixes issue #1008. --- Source/SPConnectionControllerDelegate.m | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 63f58ace..7d461233 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -44,6 +44,8 @@ static NSString *SPDatabaseImage = @"database-small"; - (void)_reloadFavoritesViewData; - (void)_updateFavoritePasswordsFromField:(NSControl *)control; +- (NSString *)_stripInvalidCharactersFromString:(NSString *)subject; + @end @implementation SPConnectionController (SPConnectionControllerDelegate) @@ -274,7 +276,9 @@ static NSString *SPDatabaseImage = @"database-small"; - (void)controlTextDidChange:(NSNotification *)notification { id field = [notification object]; - + + [field setStringValue:[self _stripInvalidCharactersFromString:[field stringValue]]]; + if (((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) && [self selectedFavoriteNode]) { favoriteNameFieldWasTouched = YES; -- cgit v1.2.3 From e23ba5155a53c43a106ac9646f51321ccc7d86f4 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 2 Oct 2011 11:25:26 +0000 Subject: Favorites import progress. --- Source/SPConnectionControllerDelegate.m | 39 ++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 7d461233..26101071 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -489,8 +489,6 @@ static NSString *SPDatabaseImage = @"database-small"; else if (rows == 1) { return (![[self selectedFavoriteNode] isGroup]); } - - return YES; } return YES; @@ -505,23 +503,44 @@ static NSString *SPDatabaseImage = @"database-small"; - (void)favoritesExportCompletedWithError:(NSError *)error { if (error) { - [[NSAlert alertWithError:error] beginSheetModalForWindow:[dbDocument parentWindow] - modalDelegate:self - didEndSelector:NULL - contextInfo:NULL]; + + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Favorites export error", @"favorites export error message") + defaultButton:NSLocalizedString(@"OK", @"OK") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"The following error occurred during the export process:\n\n%@", @"favorites export error informative message"), [error localizedDescription]]]; + + [alert beginSheetModalForWindow:[dbDocument parentWindow] + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; } } +/** + * Called by the favorites importer when the imported data is available. + */ +- (void)favoritesImportData:(NSDictionary *)data +{ + +} + /** * Called by the favorites importer when the import completes. */ - (void)favoritesImportCompletedWithError:(NSError *)error { if (error) { - [[NSAlert alertWithError:error] beginSheetModalForWindow:[dbDocument parentWindow] - modalDelegate:self - didEndSelector:NULL - contextInfo:NULL]; + NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Favorites import error", @"favorites import error message") + defaultButton:NSLocalizedString(@"OK", @"OK") + alternateButton:nil + otherButton:nil + informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"The following error occurred during the import process:\n\n%@", @"favorites import error informative message"), [error localizedDescription]]]; + + [alert beginSheetModalForWindow:[dbDocument parentWindow] + modalDelegate:self + didEndSelector:NULL + contextInfo:NULL]; } } -- cgit v1.2.3 From 816c870b93ad7bd3078d8b7a700e24354adfe4af Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Tue, 24 Jan 2012 23:19:17 +0000 Subject: Tidy up. --- Source/SPConnectionControllerDelegate.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 26101071..11d092f4 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -503,7 +503,6 @@ static NSString *SPDatabaseImage = @"database-small"; - (void)favoritesExportCompletedWithError:(NSError *)error { if (error) { - NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Favorites export error", @"favorites export error message") defaultButton:NSLocalizedString(@"OK", @"OK") alternateButton:nil @@ -522,7 +521,7 @@ static NSString *SPDatabaseImage = @"database-small"; */ - (void)favoritesImportData:(NSDictionary *)data { - + // TODO: do something with the data } /** -- cgit v1.2.3 From c9ac1028d6b430de61b376257beee1d5747c7783 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 4 Mar 2012 19:07:52 +0000 Subject: Fix exception caused by adding a nil representation of a tree node. --- Source/SPConnectionControllerDelegate.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 11d092f4..12a364f0 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -170,7 +170,7 @@ static NSString *SPDatabaseImage = @"database-small"; } [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; - [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; + [pboard setData:[NSKeyedArchiver archivedDataWithRootObject:items] forType:SPFavoritesPasteboardDragType]; return YES; } @@ -196,8 +196,8 @@ static NSString *SPDatabaseImage = @"database-small"; BOOL acceptedDrop = NO; if ((!item) || ([info draggingSource] != outlineView)) return acceptedDrop; - - SPTreeNode *node = (item) ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0]; + + SPTreeNode *node = item ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0]; // Disable all automatic sorting currentSortItem = -1; @@ -212,8 +212,10 @@ static NSString *SPDatabaseImage = @"database-small"; [menuItem setState:NSOffState]; } - NSArray *nodes = [self selectedFavoriteNodes]; - + NSArray *nodes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:SPFavoritesPasteboardDragType]]; + + if (![nodes count]) return acceptedDrop; + if ([node isGroup]) { if (index == NSOutlineViewDropOnItemIndex) { index = 0; -- cgit v1.2.3 From e2fbd102c251671d42c33c5e748ceb06c4926ceb Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 4 Mar 2012 19:11:12 +0000 Subject: Would help if I committed the right file. --- Source/SPConnectionControllerDelegate.m | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 12a364f0..5230ff5a 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -170,7 +170,8 @@ static NSString *SPDatabaseImage = @"database-small"; } [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; - [pboard setData:[NSKeyedArchiver archivedDataWithRootObject:items] forType:SPFavoritesPasteboardDragType]; + //[pboard setData:[NSKeyedArchiver archivedDataWithRootObject:items] forType:SPFavoritesPasteboardDragType]; + [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; return YES; } @@ -211,10 +212,12 @@ static NSString *SPDatabaseImage = @"database-small"; { [menuItem setState:NSOffState]; } + + NSArray *nodes = [self selectedFavoriteNodes]; - NSArray *nodes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:SPFavoritesPasteboardDragType]]; + //NSArray *nodes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:SPFavoritesPasteboardDragType]]; - if (![nodes count]) return acceptedDrop; + //if (![nodes count]) return acceptedDrop; if ([node isGroup]) { if (index == NSOutlineViewDropOnItemIndex) { -- cgit v1.2.3 From be3263f8158cb6f3dfa1005f49beefa7e494b852 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sat, 17 Mar 2012 23:03:25 +0000 Subject: Fix drag and drop of items that aren't selected. --- Source/SPConnectionControllerDelegate.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index 5230ff5a..c0bdf5d8 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -168,12 +168,14 @@ static NSString *SPDatabaseImage = @"database-small"; return NO; } - + [pboard declareTypes:[NSArray arrayWithObject:SPFavoritesPasteboardDragType] owner:self]; - //[pboard setData:[NSKeyedArchiver archivedDataWithRootObject:items] forType:SPFavoritesPasteboardDragType]; - [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; + + BOOL result = [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType]; - return YES; + draggedNodes = items; + + return result; } - (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id )info proposedItem:(id)item proposedChildIndex:(NSInteger)index @@ -213,11 +215,9 @@ static NSString *SPDatabaseImage = @"database-small"; [menuItem setState:NSOffState]; } - NSArray *nodes = [self selectedFavoriteNodes]; - - //NSArray *nodes = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType:SPFavoritesPasteboardDragType]]; + NSArray *nodes = draggedNodes; - //if (![nodes count]) return acceptedDrop; + if (![nodes count]) return acceptedDrop; if ([node isGroup]) { if (index == NSOutlineViewDropOnItemIndex) { -- cgit v1.2.3 From 37b58a7b37cabc7409be30f57671d7af05961436 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 29 Apr 2012 11:13:35 +0000 Subject: Pass the array of imported favorites instead of the whole dictionary to the delegate and improve error handling. --- Source/SPConnectionControllerDelegate.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index c0bdf5d8..dc429faf 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -524,9 +524,8 @@ static NSString *SPDatabaseImage = @"database-small"; /** * Called by the favorites importer when the imported data is available. */ -- (void)favoritesImportData:(NSDictionary *)data +- (void)favoritesImportData:(NSArray *)data { - // TODO: do something with the data } /** -- cgit v1.2.3 From 27614654120c64c4d708e299b3ec8f01cd837415 Mon Sep 17 00:00:00 2001 From: stuconnolly Date: Sun, 29 Apr 2012 11:30:51 +0000 Subject: Add imported favorites to the root node and preserve sorting if enabled. --- Source/SPConnectionControllerDelegate.m | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'Source/SPConnectionControllerDelegate.m') diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m index dc429faf..e2557601 100644 --- a/Source/SPConnectionControllerDelegate.m +++ b/Source/SPConnectionControllerDelegate.m @@ -40,6 +40,7 @@ static NSString *SPDatabaseImage = @"database-small"; @interface SPConnectionController () - (void)_checkHost; +- (void)_sortFavorites; - (void)_favoriteTypeDidChange; - (void)_reloadFavoritesViewData; - (void)_updateFavoritePasswordsFromField:(NSControl *)control; @@ -526,6 +527,17 @@ static NSString *SPDatabaseImage = @"database-small"; */ - (void)favoritesImportData:(NSArray *)data { + // Add each of the imported favorites to the root node + for (NSMutableDictionary *favorite in data) + { + [favoritesController addFavoriteNodeWithData:favorite asChildOfNode:nil]; + } + + if (currentSortItem > SPFavoritesSortUnsorted) { + [self _sortFavorites]; + } + + [self _reloadFavoritesViewData]; } /** -- cgit v1.2.3