aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPConnectionControllerDelegate.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPConnectionControllerDelegate.m')
-rw-r--r--Source/SPConnectionControllerDelegate.m589
1 files changed, 471 insertions, 118 deletions
diff --git a/Source/SPConnectionControllerDelegate.m b/Source/SPConnectionControllerDelegate.m
index 85ddedab..352836e3 100644
--- a/Source/SPConnectionControllerDelegate.m
+++ b/Source/SPConnectionControllerDelegate.m
@@ -24,89 +24,32 @@
// More info at <http://code.google.com/p/sequel-pro/>
#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"
-@implementation SPConnectionController (SPConnectionControllerDelegate)
+#define CELL(cell) (SPTableTextFieldCell *)cell
+
+static NSString *SPDatabaseImage = @"database-small";
+
+@interface SPConnectionController ()
+
+- (void)_checkHost;
+- (void)_sortFavorites;
+- (void)_favoriteTypeDidChange;
+- (void)_reloadFavoritesViewData;
+- (void)_updateFavoritePasswordsFromField:(NSControl *)control;
+
+- (NSString *)_stripInvalidCharactersFromString:(NSString *)subject;
-/*#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 <NSDraggingInfo>)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 <NSDraggingInfo>)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;
- }*/
+@end
+
+@implementation SPConnectionController (SPConnectionControllerDelegate)
#pragma mark -
#pragma mark SplitView delegate methods
@@ -118,92 +61,502 @@
/**
* When the split view is resized, trigger a resize in the hidden table
- * width as well, to keep the connection view and connected view in synch.
+ * width as well, to keep the connection view and connected view in sync.
*/
-- (void)splitViewDidResizeSubviews:(NSNotification *)aNotification
+- (void)splitViewDidResizeSubviews:(NSNotification *)notification
{
[databaseConnectionView setPosition:[[[connectionSplitView subviews] objectAtIndex:0] frame].size.width ofDividerAtIndex:0];
}
#pragma mark -
-#pragma mark Outline view datasource methods
+#pragma mark Outline view delegate methods
-- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
-{
- SPFavoriteNode *node = (item == nil ? favoritesRoot : (SPFavoriteNode *)item);
+- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
+{
+ return ([[(SPTreeNode *)item parentNode] parentNode] == nil);
+}
+
+- (void)outlineViewSelectionDidChange:(NSNotification *)notification
+{
+ NSInteger selected = [favoritesOutlineView numberOfSelectedRows];
- return [[node nodeChildren] count];
+ if (selected == 1) {
+
+ SPTreeNode *node = [self selectedFavoriteNode];
+
+ if (![node isGroup]) {
+ [self updateFavoriteSelection:self];
+
+ [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 if (selected > 1) {
+ [connectionResizeContainer setHidden:YES];
+ [connectionInstructionsTextField setStringValue:NSLocalizedString(@"Please choose a favorite", @"please choose a favorite connection view label")];
+ }
}
-- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)anIndex ofItem:(id)item
+- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
{
- SPFavoriteNode *node = (item == nil ? favoritesRoot : (SPFavoriteNode *)item);
+ SPTreeNode *node = (SPTreeNode *)item;
+
+ [CELL(cell) setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
- return NSArrayObjectAtIndex([node nodeChildren], anIndex);
+ [CELL(cell) setTextColor:([favoritesOutlineView isEnabled]) ? [NSColor blackColor] : [NSColor grayColor]];
+
+ if (![[node parentNode] parentNode]) {
+ [CELL(cell) setImage:nil];
+ }
+ else {
+ [CELL(cell) setImage:(![node isGroup]) ? [NSImage imageNamed:SPDatabaseImage] : folderImage];
+ }
}
-- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
-{
- return [(SPFavoriteNode *)item nodeIsGroup];
+- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
+{
+ return ([[item parentNode] parentNode]) ? 17 : 22;
}
-- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
+- (NSString *)outlineView:(NSOutlineView *)outlineView toolTipForCell:(NSCell *)cell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)tableColumn item:(id)item mouseLocation:(NSPoint)mouseLocation
{
- SPFavoriteNode *node = (SPFavoriteNode *)item;
+ NSString *toolTip = nil;
+
+ SPTreeNode *node = (SPTreeNode *)item;
+
+ if (![node isGroup]) {
+
+ 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]) {
+ NSUInteger favCount = [[node childNodes] count];
+
+ toolTip = [NSString stringWithFormat:@"%@ - %d %@", [[node representedObject] nodeName], favCount, (favCount == 1) ? NSLocalizedString(@"favorite", @"favorite singular label") : NSLocalizedString(@"favorites", @"favorites plural label")];
+ }
- return ([node nodeIsGroup]) ? [node nodeName] : [[node nodeFavorite] objectForKey:SPFavoriteNameKey];
+ return toolTip;
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
+{
+ return ([[item parentNode] parentNode] != nil);
}
#pragma mark -
-#pragma mark Outline view delegate methods
+#pragma mark Outline view drag & drop
-- (BOOL)outlineView:(NSOutlineView *)outlineView isGroupItem:(id)item
+- (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];
+
+ BOOL result = [pboard setData:[NSData data] forType:SPFavoritesPasteboardDragType];
+
+ draggedNodes = items;
+
+ return result;
+}
+
+- (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(NSInteger)index
{
- return [(SPFavoriteNode *)item nodeIsGroup];
+ 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];
+
+ result = NSDragOperationMove;
+ }
+
+ return result;
}
-- (void)outlineViewSelectionDidChange:(NSNotification *)notification
+- (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(NSInteger)index
{
- if ([favoritesTable numberOfSelectedRows] == 1) {
- [self updateFavoriteSelection:self];
+ BOOL acceptedDrop = NO;
+
+ if ((!item) || ([info draggingSource] != outlineView)) return acceptedDrop;
+
+ SPTreeNode *node = item ? item : [[[[favoritesRoot childNodes] objectAtIndex:0] childNodes] objectAtIndex:0];
- [addToFavoritesButton setEnabled:NO];
- }
+ // Disable all automatic sorting
+ currentSortItem = -1;
+ reverseFavoritesSort = NO;
+
+ [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 = draggedNodes;
+
+ if (![nodes count]) return acceptedDrop;
+
+ if ([node isGroup]) {
+ if (index == NSOutlineViewDropOnItemIndex) {
+ index = 0;
+ }
+ }
else {
- [addToFavoritesButton setEnabled:YES];
+ if (index == NSOutlineViewDropOnItemIndex) {
+ index = 0;
+ }
}
+
+ if (![[node representedObject] nodeName]) {
+ node = [[favoritesRoot childNodes] objectAtIndex: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++;
+ }
+
+ [favoritesController saveFavorites];
+
+ [self _reloadFavoritesViewData];
+
+ [[[[NSApp delegate] preferenceController] generalPreferencePane] updateDefaultFavoritePopup];
+
+ acceptedDrop = YES;
+
+ return acceptedDrop;
}
-- (void)outlineView:(NSOutlineView *)outlineView willDisplayCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item
+#pragma mark -
+#pragma mark Textfield delegate methods
+
+/**
+ * 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.
+ */
+- (void)controlTextDidChange:(NSNotification *)notification
{
- [(SPTableTextFieldCell *)cell setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
+ id field = [notification object];
- if ([favoritesTable isEnabled]) {
- [(SPTableTextFieldCell *)cell setTextColor:[NSColor blackColor]];
+ if (((field == standardNameField) || (field == socketNameField) || (field == sshNameField)) && [self selectedFavoriteNode]) {
+
+ [field setStringValue:[self _stripInvalidCharactersFromString:[field stringValue]]];
+
+ favoriteNameFieldWasTouched = YES;
+
+ BOOL nameFieldIsEmpty = [[field stringValue] 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;
+ }
}
- else {
- [(SPTableTextFieldCell *)cell setTextColor:[NSColor grayColor]];
+}
+
+/**
+ * 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
+{
+ // 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])) {
+ [self _updateFavoritePasswordsFromField:control];
}
- [(SPTableTextFieldCell *)cell setImage:([(SPFavoriteNode *)item nodeIsGroup]) ? nil : [NSImage imageNamed:@"database-small"]];
+ // Proceed with editing
+ return YES;
}
-- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
+#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;
+
+ // Enable the add to favorites button
+ [addToFavoritesButton setEnabled:YES];
+
+ [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
{
- return ([item nodeIsGroup]) ? 22 : 17;
+ 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];
+ }
}
-- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
+#pragma mark -
+#pragma mark Menu Validation
+
+/**
+ * Menu item validation.
+ */
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
- return (![item nodeIsGroup]);
+ SEL action = [menuItem action];
+
+ SPTreeNode *node = [self selectedFavoriteNode];
+
+ if ((action == @selector(sortFavorites:)) || (action == @selector(reverseSortFavorites:))) {
+
+ // 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:)) {
+ 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);
+ }
+
+ // 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;
}
+#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 *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];
+ }
+}
/**
- * Prevent editing of outline view rows
+ * Called by the favorites importer when the imported data is available.
*/
-- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item
+- (void)favoritesImportData:(NSArray *)data
{
- return NO;
+ // 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];
+}
+
+/**
+ * Called by the favorites importer when the import completes.
+ */
+- (void)favoritesImportCompletedWithError:(NSError *)error
+{
+ if (error) {
+ 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];
+ }
}
+
@end