aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2009-08-26 02:21:53 +0000
committerstuconnolly <stuart02@gmail.com>2009-08-26 02:21:53 +0000
commit86085ceb7de7772dd3f85fb61f397e240b4a0e66 (patch)
tree5351e3d467288fd056a191db11c645606f2052a1 /Source
parent7de1a9a8517c2004e6a97543fbb1462d9c32f4d1 (diff)
downloadsequelpro-86085ceb7de7772dd3f85fb61f397e240b4a0e66.tar.gz
sequelpro-86085ceb7de7772dd3f85fb61f397e240b4a0e66.tar.bz2
sequelpro-86085ceb7de7772dd3f85fb61f397e240b4a0e66.zip
Completely redesigned query favorite manager, including:
- The ability to name query favorites - The ability to edit query favorites using the same editor in the cutom query view - The ability to save your query favorites to a file Note that any already saved query favorites will be upgraded to accommodate the new format, that is including a name associated with the query. The default name is the first 32 chars of the query with '...' appended. Also, added menu item validation to the 'Save Query to Favorites' menu item.
Diffstat (limited to 'Source')
-rw-r--r--Source/CustomQuery.h25
-rw-r--r--Source/CustomQuery.m374
-rw-r--r--Source/SPPreferenceController.m22
-rw-r--r--Source/SPQueryFavoriteManager.h74
-rw-r--r--Source/SPQueryFavoriteManager.m415
5 files changed, 636 insertions, 274 deletions
diff --git a/Source/CustomQuery.h b/Source/CustomQuery.h
index 2987efed..eae2de5c 100644
--- a/Source/CustomQuery.h
+++ b/Source/CustomQuery.h
@@ -33,8 +33,10 @@
#define SP_HELP_TOC_SEARCH_STRING @"contents"
+@class SPQueryFavoriteManager;
+
@interface CustomQuery : NSObject
-{
+{
IBOutlet id tableDocumentInstance;
IBOutlet id tableWindow;
IBOutlet id queryFavoritesButton;
@@ -45,10 +47,6 @@
IBOutlet id affectedRowsText;
IBOutlet id valueSheet;
IBOutlet id valueTextField;
- IBOutlet id queryFavoritesSheet;
- IBOutlet id queryFavoritesView;
- IBOutlet id removeQueryFavoriteButton;
- IBOutlet id copyQueryFavoriteButton;
IBOutlet id runSelectionButton;
IBOutlet id runAllButton;
IBOutlet id multipleLineEditingButton;
@@ -66,17 +64,20 @@
IBOutlet NSMenuItem *commentCurrentQueryMenuItem;
IBOutlet NSMenuItem *commentLineOrSelectionMenuItem;
+ IBOutlet NSWindow *queryFavoritesSheet;
+ IBOutlet NSButton *saveQueryFavoriteButton;
+ IBOutlet NSTextField *queryFavoriteNameTextField;
+
IBOutlet NSWindow *helpWebViewWindow;
IBOutlet WebView *helpWebView;
IBOutlet NSSearchField *helpSearchField;
IBOutlet NSSearchFieldCell *helpSearchFieldCell;
IBOutlet NSSegmentedControl *helpNavigator;
IBOutlet NSSegmentedControl *helpTargetSelector;
-
+
+ SPQueryFavoriteManager *favoritesManager;
NSUserDefaults *prefs;
- NSMutableArray *queryFavorites;
-
MCPConnection *mySQLConnection;
NSString *usedQuery;
@@ -103,7 +104,6 @@
NSString *fieldIDQueryString;
unsigned int numberOfQueries;
-
}
// IBAction methods
@@ -123,12 +123,6 @@
- (IBAction)helpSelectHelpTargetPage:(id)sender;
- (IBAction)helpSelectHelpTargetWeb:(id)sender;
-// queryFavoritesSheet methods
-- (IBAction)addQueryFavorite:(id)sender;
-- (IBAction)removeQueryFavorite:(id)sender;
-- (IBAction)copyQueryFavorite:(id)sender;
-- (IBAction)closeQueryFavoritesSheet:(id)sender;
-
// Query actions
- (void)performQueries:(NSArray *)queries;
- (NSString *)queryAtPosition:(long)position lookBehind:(BOOL *)doLookBehind;
@@ -149,7 +143,6 @@
// Other
- (void)setConnection:(MCPConnection *)theConnection;
-- (void)setFavorites;
- (void)doPerformQueryService:(NSString *)query;
- (void)doPerformLoadQueryService:(NSString *)query;
- (void)selectCurrentQuery;
diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m
index daa09cf6..c8ded233 100644
--- a/Source/CustomQuery.m
+++ b/Source/CustomQuery.m
@@ -37,6 +37,7 @@
#import "SPFieldEditorController.h"
#import "SPTextAndLinkCell.h"
#import "SPTooltip.h"
+#import "SPQueryFavoriteManager.h"
#define SP_MYSQL_DEV_SEARCH_URL @"http://search.mysql.com/search?q=%@&site=refman-%@"
#define SP_HELP_SEARCH_IN_MYSQL 0
@@ -89,10 +90,6 @@
[textView setSelectedRange:NSMakeRange(oldRange.location,0)];
[textView insertText:@""];
[textView setSelectedRange:oldRange];
-
-
- // Select the text of the query textView for re-editing
- //[textView selectAll:self];
}
/*
@@ -127,7 +124,7 @@
// Invoke textStorageDidProcessEditing: for syntax highlighting and auto-uppercase
// and preserve the selection
- [textView setSelectedRange:NSMakeRange(selectedRange.location,0)];
+ [textView setSelectedRange:NSMakeRange(selectedRange.location, 0)];
[textView insertText:@""];
[textView setSelectedRange:selectedRange];
@@ -142,43 +139,32 @@
- (IBAction)chooseQueryFavorite:(id)sender
{
if ([queryFavoritesButton indexOfSelectedItem] == 1) {
- // Save query to favorites
- // Check if favorite doesn't exist
- NSEnumerator *enumerator = [queryFavorites objectEnumerator];
- id favorite;
-
- while ((favorite = [enumerator nextObject]))
- {
- if ([favorite isEqualToString:[textView string]]) {
- NSBeginAlertSheet(NSLocalizedString(@"Query already exists", @"query already exists message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
- NSLocalizedString(@"The query you are adding to your favorites already exists.", @"query already exists informative message"));
- return;
- }
- }
+ // This should never evaluate to true as we are now performing menu validation, meaning the 'Save Query to Favorites' menu item will
+ // only be enabled if the query text view has at least one character present.
if ([[textView string] isEqualToString:@""]) {
- NSBeginAlertSheet(NSLocalizedString(@"Empty query", @"empty query message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
- NSLocalizedString(@"Cannot save an empty query.", @"empty query informative message"));
- return;
+ NSBeginAlertSheet(NSLocalizedString(@"Empty query", @"empty query message"), NSLocalizedString(@"OK", @"OK button"), nil, nil, tableWindow, self, nil, nil, nil,
+ NSLocalizedString(@"Cannot save an empty query.", @"empty query informative message"));
+ return;
}
- [queryFavorites addObject:[NSString stringWithString:[textView string]]];
- [queryFavoritesView reloadData];
- [prefs setObject:queryFavorites forKey:@"queryFavorites"];
- [self setFavorites];
-
+ [NSApp beginSheet:queryFavoritesSheet
+ modalForWindow:tableWindow
+ modalDelegate:self
+ didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:)
+ contextInfo:@"addNewQueryFavorite"];
}
- else if ([queryFavoritesButton indexOfSelectedItem] == 2) {
- // Edit favorites
- [NSApp beginSheet:queryFavoritesSheet
+ else if ([queryFavoritesButton indexOfSelectedItem] == 2) {
+ // Open query favorite manager
+ [NSApp beginSheet:[favoritesManager window]
modalForWindow:tableWindow
- modalDelegate:self
+ modalDelegate:favoritesManager
didEndSelector:nil
contextInfo:nil];
}
- else if ([queryFavoritesButton indexOfSelectedItem] != 3) {
+ else if ([queryFavoritesButton indexOfSelectedItem] > 3) {
// Choose favorite
- [textView insertText:[queryFavoritesButton titleOfSelectedItem]];
+ [textView insertText:[[[prefs objectForKey:@"queryFavorites"] objectAtIndex:([queryFavoritesButton indexOfSelectedItem] - 4)] objectForKey:@"query"]];
}
}
@@ -195,7 +181,8 @@
*/
- (IBAction)closeSheet:(id)sender
{
- [NSApp stopModal];
+ [NSApp endSheet:[sender window] returnCode:[sender tag]];
+ [[sender window] orderOut:self];
}
/*
@@ -292,108 +279,6 @@
return (NSFontPanelAllModesMask ^ NSFontPanelAllEffectsModeMask);
}
-
-#pragma mark -
-#pragma mark queryFavoritesSheet methods
-
-/**
- * Adds a query favorite
- */
-- (IBAction)addQueryFavorite:(id)sender
-{
- int row = [queryFavoritesView editedRow];
- int column = [queryFavoritesView editedColumn];
- NSTableColumn *tableColumn;
- NSCell *cell;
-
- // End editing
- if ( row != -1 ) {
- tableColumn = [[queryFavoritesView tableColumns] objectAtIndex:column];
- cell = [tableColumn dataCellForRow:row];
- [cell endEditing:[queryFavoritesView currentEditor]];
- }
-
- [queryFavorites addObject:[NSString string]];
- [queryFavoritesView reloadData];
- [queryFavoritesView selectRow:[queryFavoritesView numberOfRows]-1 byExtendingSelection:NO];
- [queryFavoritesView editColumn:0 row:[queryFavoritesView numberOfRows]-1 withEvent:nil select:YES];
-}
-
-/**
- * Removes a query favorite
- */
-- (IBAction)removeQueryFavorite:(id)sender
-{
- int row = [queryFavoritesView editedRow];
- int column = [queryFavoritesView editedColumn];
- NSTableColumn *tableColumn;
- NSCell *cell;
-
- // End editing
- if ( row != -1 ) {
- tableColumn = [[queryFavoritesView tableColumns] objectAtIndex:column];
- cell = [tableColumn dataCellForRow:row];
- [cell endEditing:[queryFavoritesView currentEditor]];
- }
-
- if ( [queryFavoritesView numberOfSelectedRows] > 0 ) {
- [queryFavorites removeObjectAtIndex:[queryFavoritesView selectedRow]];
- [queryFavoritesView reloadData];
- }
-}
-
-/**
- * Copies a query favorite
- */
-- (IBAction)copyQueryFavorite:(id)sender
-{
- int row = [queryFavoritesView editedRow];
- int column = [queryFavoritesView editedColumn];
- NSTableColumn *tableColumn;
- NSCell *cell;
-
- // End editing
- if ( row != -1 ) {
- tableColumn = [[queryFavoritesView tableColumns] objectAtIndex:column];
- cell = [tableColumn dataCellForRow:row];
- [cell endEditing:[queryFavoritesView currentEditor]];
- }
-
- if ( [queryFavoritesView numberOfSelectedRows] > 0 ) {
- [queryFavorites insertObject:
- [NSString stringWithString:[queryFavorites objectAtIndex:[queryFavoritesView selectedRow]]]
- atIndex:[queryFavoritesView selectedRow]+1];
- [queryFavoritesView reloadData];
- [queryFavoritesView selectRow:[queryFavoritesView selectedRow]+1 byExtendingSelection:NO];
- [queryFavoritesView editColumn:0 row:[queryFavoritesView selectedRow] withEvent:nil select:YES];
- }
-}
-
-/**
- * Closes queryFavoritesSheet and saves favorites to preferences
- */
-- (IBAction)closeQueryFavoritesSheet:(id)sender
-{
- [NSApp endSheet:queryFavoritesSheet returnCode:0];
- [queryFavoritesSheet orderOut:self];
-
- int row = [queryFavoritesView editedRow];
- int column = [queryFavoritesView editedColumn];
- NSTableColumn *tableColumn;
- NSCell *cell;
-
- // End editing
- if (row != -1) {
- tableColumn = [[queryFavoritesView tableColumns] objectAtIndex:column];
- cell = [tableColumn dataCellForRow:row];
- [cell endEditing:[queryFavoritesView currentEditor]];
- }
-
- [prefs setObject:queryFavorites forKey:@"queryFavorites"];
- [self setFavorites];
-}
-
-
#pragma mark -
#pragma mark Query actions
@@ -403,7 +288,6 @@
*/
- (void)performQueries:(NSArray *)queries;
{
-
NSArray *theColumns;
NSTableColumn *theCol;
MCPStreamingResult *streamingResult = nil;
@@ -1129,21 +1013,9 @@
*/
- (void)setConnection:(MCPConnection *)theConnection
{
- NSArray *tableColumns = [queryFavoritesView tableColumns];
- NSEnumerator *enumerator = [tableColumns objectEnumerator];
- id column;
-
mySQLConnection = theConnection;
-
- prefs = [NSUserDefaults standardUserDefaults];
currentQueryRanges = nil;
- if ( [prefs objectForKey:@"queryFavorites"] ) {
- queryFavorites = [[NSMutableArray alloc] initWithArray:[prefs objectForKey:@"queryFavorites"]];
- } else {
- queryFavorites = [[NSMutableArray array] retain];
- }
-
hasBackgroundAttribute = NO;
// Set up the interface
@@ -1172,39 +1044,14 @@
[textView setAutohelp:[prefs boolForKey:@"CustomQueryUpdateAutoHelp"]];
[autouppercaseKeywordsMenuItem setState:([prefs boolForKey:@"CustomQueryAutoUppercaseKeywords"]?NSOnState:NSOffState)];
[textView setAutouppercaseKeywords:[prefs boolForKey:@"CustomQueryAutoUppercaseKeywords"]];
- [queryFavoritesView registerForDraggedTypes:[NSArray arrayWithObjects:@"SequelProPasteboard", nil]];
- while ( (column = [enumerator nextObject]) )
- {
- if ( [prefs boolForKey:@"UseMonospacedFonts"] ) {
- [[column dataCell] setFont:[NSFont fontWithName:@"Monaco" size:10]];
- } else {
- [[column dataCell] setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
- }
- }
if ( [prefs objectForKey:@"queryHistory"] )
{
[queryHistoryButton addItemsWithTitles:[prefs objectForKey:@"queryHistory"]];
}
- [self setFavorites];
// Disable runSelectionMenuItem in the gear menu
[runSelectionMenuItem setEnabled:NO];
-
-}
-
-/*
- * Set up the favorites popUpButton
- */
-- (void)setFavorites
-{
- int i;
-
-//remove all menuItems and add favorites from preferences
- for ( i = 4 ; i < [queryFavoritesButton numberOfItems] ; i++ ) {
- [queryFavoritesButton removeItemAtIndex:i];
- }
- [queryFavoritesButton addItemsWithTitles:queryFavorites];
}
/*
@@ -1226,7 +1073,7 @@
return usedQuery;
}
-#pragma mark
+#pragma mark -
#pragma mark Field Editing
/*
@@ -1313,8 +1160,6 @@
} else {
return [fullResult count];
}
- } else if ( aTableView == queryFavoritesView ) {
- return [queryFavorites count];
} else {
return 0;
}
@@ -1359,11 +1204,6 @@
return theValue;
}
-
- else if ( aTableView == queryFavoritesView ) {
- return [queryFavorites objectAtIndex:rowIndex];
- }
-
else {
return @"";
}
@@ -1372,37 +1212,7 @@
- (void)tableView:(NSTableView *)aTableView setObjectValue:(id)anObject
forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
- if ( aTableView == queryFavoritesView ) {
- NSEnumerator *enumerator = [queryFavorites objectEnumerator];
- id favorite;
- int i = 0;
-
- if ( [anObject isEqualToString:@""] ) {
- [queryFavoritesView deselectAll:self];
- [queryFavorites removeObjectAtIndex:rowIndex];
- [queryFavoritesView reloadData];
- return;
- }
-
- while ( (favorite = [enumerator nextObject]) ) {
- if ( [favorite isEqualToString:anObject] && i != rowIndex) {
- NSRunAlertPanel(@"Query already exists", @"The query you are adding to your favorites already exists.", @"OK", nil, nil);
-
- //remove row if it was a (blank) new row or a copied row
- if ( [NSArrayObjectAtIndex(queryFavorites, rowIndex) isEqualToString:@""] ||
- [NSArrayObjectAtIndex(queryFavorites, rowIndex) isEqualToString:anObject] ) {
- [queryFavoritesView deselectAll:self];
- [queryFavorites removeObjectAtIndex:rowIndex];
- [queryFavoritesView reloadData];
- }
- return;
- }
- i++;
- }
- [queryFavorites replaceObjectAtIndex:rowIndex withObject:anObject];
- [queryFavoritesView reloadData];
- }
- else if ( aTableView == customQueryView ) {
+ if ( aTableView == customQueryView ) {
// Field editing
@@ -1608,26 +1418,7 @@
- (BOOL)tableView:(NSTableView *)aTableView writeRows:(NSArray*)rows toPasteboard:(NSPasteboard*)pboard
{
- int originalRow;
- NSArray *pboardTypes;
-
- if ( aTableView == queryFavoritesView )
- {
- if ( [rows count] == 1 )
- {
- pboardTypes = [NSArray arrayWithObjects:@"SequelProPasteboard", nil];
- originalRow = [[rows objectAtIndex:0] intValue];
-
- [pboard declareTypes:pboardTypes owner:nil];
- [pboard setString:[[NSNumber numberWithInt:originalRow] stringValue] forType:@"SequelProPasteboard"];
-
- return YES;
- }
- else
- {
- return NO;
- }
- } else if ( aTableView == customQueryView ) {
+ if ( aTableView == customQueryView ) {
NSString *tmp = [customQueryView draggedRowsAsTabString:rows];
if ( nil != tmp )
{
@@ -1644,7 +1435,7 @@
}
}
-- (NSDragOperation)tableView:(NSTableView*)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row
+/*- (NSDragOperation)tableView:(NSTableView*)aTableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row
proposedDropOperation:(NSTableViewDropOperation)operation
{
NSArray *pboardTypes = [[info draggingPasteboard] types];
@@ -1693,8 +1484,7 @@
} else {
return NO;
}
-}
-
+}*/
#pragma mark -
#pragma mark TableView delegate methods
@@ -1836,19 +1626,6 @@
#pragma mark -
#pragma mark TableView notifications
-/*
- * Updates various interface elements based on the current table view selection.
- */
-- (void)tableViewSelectionDidChange:(NSNotification *)notification
-{
- if ([notification object] == queryFavoritesView) {
-
- // Enable/disable buttons
- [removeQueryFavoriteButton setEnabled:([queryFavoritesView numberOfSelectedRows] == 1)];
- [copyQueryFavoriteButton setEnabled:([queryFavoritesView numberOfSelectedRows] == 1)];
- }
-}
-
/**
* Saves the new column size in the preferences for columns which map to fields
*/
@@ -2016,7 +1793,6 @@
[runSelectionMenuItem setEnabled:YES];
[commentLineOrSelectionMenuItem setTitle:NSLocalizedString(@"Comment Selection", @"Title of action menu item to comment selection")];
}
-
}
/*
@@ -2025,10 +1801,21 @@
- (void)textViewDidChangeTypingAttributes:(NSNotification *)aNotification
{
// Only save the font if prefs have been loaded, ensuring the saved font has been applied once.
- if (prefs)
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[textView font]] forKey:@"CustomQueryEditorFont"];
+ if (prefs) [prefs setObject:[NSArchiver archivedDataWithRootObject:[textView font]] forKey:@"CustomQueryEditorFont"];
}
+#pragma mark -
+#pragma mark TextField delegate methods
+
+/**
+ * Called whenever the user changes the name of the new query favorite.
+ */
+- (void)controlTextDidChange:(NSNotification *)notification
+{
+ if ([notification object] == queryFavoriteNameTextField) {
+ [saveQueryFavoriteButton setEnabled:[[queryFavoriteNameTextField stringValue] length]];
+ }
+}
#pragma mark -
#pragma mark SplitView delegate methods
@@ -2541,14 +2328,39 @@
}
return webViewMenuItems;
+}
+
+#pragma mark -
+#pragma mark Query favorites manager delegate methods
+/**
+ * Called by the query favorites manager whenever the query favorites have been updated.
+ */
+- (void)queryFavoritesHaveBeenUpdated:(id)manager
+{
+ NSInteger i;
+ NSMutableArray *favorites = ([favoritesManager queryFavorites]) ? [favoritesManager queryFavorites] : [prefs objectForKey:@"queryFavorites"];
+
+ // Remove all favorites
+ for (i = 4; i < [queryFavoritesButton numberOfItems]; i++)
+ {
+ [queryFavoritesButton removeItemAtIndex:i];
+ }
+
+ // Re-add favorites
+ for (NSDictionary *favorite in favorites)
+ {
+ [queryFavoritesButton addItemWithTitle:[favorite objectForKey:@"name"]];
+ }
}
#pragma mark -
#pragma mark Other
-
-- (unsigned int)numberOfQueries
+/**
+ * Returns the number of queries.
+ */
+- (NSUInteger)numberOfQueries
{
return numberOfQueries;
}
@@ -2563,10 +2375,48 @@
}
}
+/**
+ * Called when the save query favorite sheet is dismissed.
+ */
+- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo
+{
+ if ([contextInfo isEqualToString:@"addNewQueryFavorite"]) {
+ if (returnCode == NSOKButton) {
+
+ // Add the new query favorite directly the user's preferences here instead of asking the manager to do it
+ // as it may not have been fully initialized yet.
+ NSMutableArray *favorites = [NSMutableArray arrayWithArray:[prefs objectForKey:@"queryFavorites"]];
+
+ [favorites addObject:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[queryFavoriteNameTextField stringValue], [textView string], nil] forKeys:[NSArray arrayWithObjects:@"name", @"query", nil]]];
+
+ [prefs setObject:favorites forKey:@"queryFavorites"];
+ [prefs synchronize];
+
+ [self queryFavoritesHaveBeenUpdated:nil];
+ }
+ }
+
+ [queryFavoriteNameTextField setStringValue:@""];
+}
+
+/**
+ * Menu item validation.
+ */
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+ // Use the menu item's title instead of its action as all menu items in the drop down have the same action
+ if ([[menuItem title] isEqualToString:@"Save Query to Favorites"]) {
+ return ([[textView string] length] > 0);
+ }
+
+ return YES;
+}
+
+
#pragma mark -
// Last but not least
-- (id)init;
+- (id)init
{
if ((self = [super init])) {
@@ -2595,7 +2445,11 @@
// init tableView's data source
fullResult = [[NSMutableArray alloc] init];
-
+
+ // init query favorites controller
+ favoritesManager = [[SPQueryFavoriteManager alloc] initWithDelegate:self];
+
+ prefs = [NSUserDefaults standardUserDefaults];
}
return self;
@@ -2605,14 +2459,22 @@
{
// Set the structure and index view's vertical gridlines if required
[customQueryView setGridStyleMask:([prefs boolForKey:@"DisplayTableViewVerticalGridlines"]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
+
+ // Populate the query favorites popup button
+ for (NSDictionary *favorite in [prefs objectForKey:@"queryFavorites"])
+ {
+ [queryFavoritesButton addItemWithTitle:[favorite objectForKey:@"name"]];
+ }
}
- (void)dealloc
{
- [queryFavorites release];
[usedQuery release];
[fullResult release];
+ [favoritesManager release];
+
if (sortField) [sortField release];
+
[super dealloc];
}
diff --git a/Source/SPPreferenceController.m b/Source/SPPreferenceController.m
index f9618249..d27234d7 100644
--- a/Source/SPPreferenceController.m
+++ b/Source/SPPreferenceController.m
@@ -111,6 +111,7 @@
// -------------------------------------------------------------------------------
- (void)applyRevisionChanges
{
+ int i;
int currentVersionNumber, recordedVersionNumber = 0;
// Get the current bundle version number (the SVN build number) for per-version upgrades
@@ -202,7 +203,6 @@
// For versions prior to r567 (0.9.5), add a timestamp-based identifier to favorites and keychain entries
if (recordedVersionNumber < 567 && [prefs objectForKey:@"favorites"]) {
- int i;
NSMutableArray *favoritesArray = [NSMutableArray arrayWithArray:[prefs objectForKey:@"favorites"]];
NSMutableDictionary *favorite;
NSString *password, *keychainName, *keychainAccount;
@@ -231,7 +231,6 @@
// For versions prior to r981 (~0.9.6), upgrade the favourites to include a connection type for each
if (recordedVersionNumber < 981 && [prefs objectForKey:@"favorites"]) {
- int i;
NSMutableArray *favoritesArray = [NSMutableArray arrayWithArray:[prefs objectForKey:@"favorites"]];
NSMutableDictionary *favorite;
@@ -269,6 +268,25 @@
[toolbarDict removeObjectForKey:@"TB Item Identifiers"];
[prefs setObject:[NSDictionary dictionaryWithDictionary:toolbarDict] forKey:@"NSToolbar Configuration TableWindowToolbar"];
}
+
+ // For versions prior to r1263 (~0.9.7), convert the query favorites array to an array of dictionaries
+ if (recordedVersionNumber < 1263 && [prefs objectForKey:@"queryFavorites"]) {
+ NSMutableArray *queryFavoritesArray = [NSMutableArray arrayWithArray:[prefs objectForKey:@"queryFavorites"]];
+
+ for (i = 0; i < [queryFavoritesArray count]; i++)
+ {
+ id favorite = [queryFavoritesArray objectAtIndex:i];
+
+ if (([favorite isKindOfClass:[NSDictionary class]]) && ([favorite objectForKey:@"name"]) && ([favorite objectForKey:@"query"])) continue;
+
+ // By default make the query's name the first 32 characters of the query with '...' appended
+ NSString *favoriteName = [[[favorite stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]] substringToIndex:32] stringByAppendingString:@"..."];
+
+ [queryFavoritesArray replaceObjectAtIndex:i withObject:[NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:favoriteName, favorite, nil] forKeys:[NSArray arrayWithObjects:@"name", @"query", nil]]];
+ }
+
+ [prefs setObject:queryFavoritesArray forKey:@"queryFavorites"];
+ }
// Update the prefs revision
[prefs setObject:[NSNumber numberWithInt:currentVersionNumber] forKey:@"LastUsedVersion"];
diff --git a/Source/SPQueryFavoriteManager.h b/Source/SPQueryFavoriteManager.h
new file mode 100644
index 00000000..bc0d7e2d
--- /dev/null
+++ b/Source/SPQueryFavoriteManager.h
@@ -0,0 +1,74 @@
+//
+// $Id$
+//
+// SPQueryFavoriteManager.h
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on Aug 23, 2009
+// Copyright (c) 2009 Stuart Connolly. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import <Cocoa/Cocoa.h>
+
+// Query favorite addition constants
+typedef enum {
+ SPQueryFavoriteAdded = 0,
+ SPQueryFavoriteIsBlank = 1,
+ SPQueryFavoriteExists = 2
+} SPQueryFavoriteAddition;
+
+@interface NSObject (SPQueryFavoriteManagerDelegate)
+
+- (void)queryFavoritesHaveBeenUpdated:(id)manager;
+
+@end
+
+@interface SPQueryFavoriteManager : NSWindowController
+{
+ id delegate;
+
+ NSUserDefaults *prefs;
+
+ BOOL delegateRespondsToFavoriteUpdates;
+
+ IBOutlet NSPopUpButton *encodingPopUp;
+ IBOutlet NSTableView *favoritesTableView;
+ IBOutlet NSTextField *favoriteNameTextField;
+ IBOutlet NSTextView *favoriteQueryTextView;
+ IBOutlet NSArrayController *queryFavoritesController;
+}
+
+- (id)initWithDelegate:(id)managerDelegate;
+
+// Accessors
+- (NSMutableArray *)queryFavorites;
+- (id)customQueryInstance;
+
+// IBAction methods
+- (IBAction)addQueryFavorite:(id)sender;
+- (IBAction)removeQueryFavorite:(id)sender;
+- (IBAction)removeAllQueryFavorites:(id)sender;
+- (IBAction)copyQueryFavorite:(id)sender;
+- (IBAction)saveFavoriteToFile:(id)sender;
+- (IBAction)closeQueryManagerSheet:(id)sender;
+
+// Favorite methods
+- (NSString *)queryFavoriteAtIndex:(NSInteger)index;
+- (SPQueryFavoriteAddition)addQueryToFavorites:(NSString *)query;
+
+@end
diff --git a/Source/SPQueryFavoriteManager.m b/Source/SPQueryFavoriteManager.m
new file mode 100644
index 00000000..ee4f8c56
--- /dev/null
+++ b/Source/SPQueryFavoriteManager.m
@@ -0,0 +1,415 @@
+//
+// $Id$
+//
+// SPQueryFavoriteManager.m
+// sequel-pro
+//
+// Created by Stuart Connolly (stuconnolly.com) on Aug 23, 2009
+// Copyright (c) 2009 Stuart Connolly. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// More info at <http://code.google.com/p/sequel-pro/>
+
+#import "SPQueryFavoriteManager.h"
+#import "SPEncodingPopupAccessory.h"
+
+#define DEFAULT_QUERY_FAVORITE_FILE_EXTENSION @"sql"
+#define QUERY_FAVORITES_PB_DRAG_TYPE @"SequelProQueryFavoritesPasteboard"
+
+@implementation SPQueryFavoriteManager
+
+/**
+ * Initialize the manager with the supplied delegate
+ */
+- (id)initWithDelegate:(id)managerDelegate
+{
+ if ((self = [super initWithWindowNibName:@"QueryFavoriteManager"])) {
+ delegate = managerDelegate;
+
+ prefs = [NSUserDefaults standardUserDefaults];
+
+ delegateRespondsToFavoriteUpdates = [delegate respondsToSelector:@selector(queryFavoritesHaveBeenUpdated:)];
+ }
+
+ return self;
+}
+
+/**
+ * Upon awakening bind the query text view's background colour.
+ */
+- (void)awakeFromNib
+{
+ [favoriteQueryTextView setAllowsDocumentBackgroundColorChange:YES];
+
+ NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionary];
+
+ [bindingOptions setObject:NSUnarchiveFromDataTransformerName forKey:@"NSValueTransformerName"];
+
+ [favoriteQueryTextView bind:@"backgroundColor"
+ toObject:[NSUserDefaultsController sharedUserDefaultsController]
+ withKeyPath:@"values.CustomQueryEditorBackgroundColor"
+ options:bindingOptions];
+
+ // Select the first query
+ [queryFavoritesController setSelectionIndex:0];
+
+ // Register drag types
+ [favoritesTableView registerForDraggedTypes:[NSArray arrayWithObject:QUERY_FAVORITES_PB_DRAG_TYPE]];
+}
+
+#pragma mark -
+#pragma mark Accessor methods
+
+/**
+ * Returns the query favorites array.
+ */
+- (NSMutableArray *)queryFavorites
+{
+ return [queryFavoritesController arrangedObjects];
+}
+
+/**
+ * This method is only implemented to be compatible with CMTextView.
+ */
+- (id)customQueryInstance
+{
+ return [[[NSApp mainWindow] delegate] valueForKey:@"customQueryInstance"];
+}
+
+#pragma mark -
+#pragma mark IBAction methods
+
+/**
+ * Adds a query favorite
+ */
+- (IBAction)addQueryFavorite:(id)sender
+{
+ NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"New Favorite", @"", nil] forKeys:[NSArray arrayWithObjects:@"name", @"query", nil]];
+
+ [queryFavoritesController addObject:favorite];
+ [queryFavoritesController setSelectionIndex:([[queryFavoritesController arrangedObjects] count] - 1)];
+
+ [favoritesTableView reloadData];
+ [favoritesTableView scrollRowToVisible:[favoritesTableView selectedRow]];
+
+ // Inform the delegate that the query favorites have been updated
+ if (delegateRespondsToFavoriteUpdates) {
+ [delegate queryFavoritesHaveBeenUpdated:self];
+ }
+}
+
+/**
+ * Removes a query favorite
+ */
+- (IBAction)removeQueryFavorite:(id)sender
+{
+ if ([favoritesTableView numberOfSelectedRows] == 1) {
+ [queryFavoritesController removeObjectAtArrangedObjectIndex:[favoritesTableView selectedRow]];
+
+ [favoritesTableView reloadData];
+
+ // Inform the delegate that the query favorites have been updated
+ if (delegateRespondsToFavoriteUpdates) {
+ [delegate queryFavoritesHaveBeenUpdated:self];
+ }
+ }
+}
+
+/**
+ * Removes all query favorites
+ */
+- (IBAction)removeAllQueryFavorites:(id)sender
+{
+ NSAlert *alert = [NSAlert alertWithMessageText:NSLocalizedString(@"Remove all query favorites?", @"remove all query favorites message")
+ defaultButton:NSLocalizedString(@"Cancel", @"cancel button")
+ alternateButton:NSLocalizedString(@"Remove All", @"remove all button")
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"Are you sure you want to remove all of your saved query favorites? This action cannot be undone.", @"remove all query favorites informative message")];
+
+ [alert setAlertStyle:NSCriticalAlertStyle];
+
+ NSArray *buttons = [alert buttons];
+
+ // Change the alert's cancel button to have the key equivalent of return
+ [[buttons objectAtIndex:0] setKeyEquivalent:@"\r"];
+ [[buttons objectAtIndex:1] setKeyEquivalent:@""];
+
+ [alert beginSheetModalForWindow:[self window] modalDelegate:self didEndSelector:@selector(sheetDidEnd:returnCode:contextInfo:) contextInfo:@"removeAllFavorites"];
+}
+
+/**
+ * Copies a query favorite
+ */
+- (IBAction)copyQueryFavorite:(id)sender
+{
+ if ([favoritesTableView numberOfSelectedRows] == 1) {
+ NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[[favoriteNameTextField stringValue] stringByAppendingFormat:@" Copy"], [favoriteQueryTextView string], nil] forKeys:[NSArray arrayWithObjects:@"name", @"query", nil]];
+
+ [queryFavoritesController addObject:favorite];
+ [queryFavoritesController setSelectionIndex:([[queryFavoritesController arrangedObjects] count] - 1)];
+
+ [favoritesTableView reloadData];
+ [favoritesTableView scrollRowToVisible:[favoritesTableView selectedRow]];
+
+ // Inform the delegate that the query favorites have been updated
+ if (delegateRespondsToFavoriteUpdates) {
+ [delegate queryFavoritesHaveBeenUpdated:self];
+ }
+ }
+}
+
+/**
+ * Saves the currently selected query favorite to a user specified file.
+ */
+- (IBAction)saveFavoriteToFile:(id)sender
+{
+ NSSavePanel *panel = [NSSavePanel savePanel];
+
+ [panel setRequiredFileType:DEFAULT_QUERY_FAVORITE_FILE_EXTENSION];
+
+ [panel setExtensionHidden:NO];
+ [panel setAllowsOtherFileTypes:YES];
+ [panel setCanSelectHiddenExtension:YES];
+
+ [panel setAccessoryView:[SPEncodingPopupAccessory encodingAccessory:[prefs integerForKey:@"lastSqlFileEncoding"] includeDefaultEntry:NO encodingPopUp:&encodingPopUp]];
+
+ [encodingPopUp setEnabled:YES];
+
+ [panel beginSheetForDirectory:nil file:[favoriteNameTextField stringValue] modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
+}
+
+/**
+ * Closes the query favorite manager
+ */
+- (IBAction)closeQueryManagerSheet:(id)sender
+{
+ [NSApp endSheet:[self window] returnCode:0];
+ [[self window] orderOut:self];
+}
+
+#pragma mark -
+#pragma mark Favorite methods
+
+/**
+ * Returns the query favorite at the supplied index.
+ */
+- (NSString *)queryFavoriteAtIndex:(NSInteger)index
+{
+ return [[[queryFavoritesController arrangedObjects] objectAtIndex:index] objectForKey:@"query"];
+}
+
+/**
+ * Adds the supplied query the user's favorites.
+ */
+- (SPQueryFavoriteAddition)addQueryToFavorites:(NSString *)query
+{
+ if ([query isEqualToString:@""]) return SPQueryFavoriteIsBlank;
+
+ // Check that the favorite doesn't already exist
+ for (NSDictionary *favorite in [queryFavoritesController arrangedObjects])
+ {
+ if ([[favorite objectForKey:@"query"] isEqualToString:query]) {
+ return SPQueryFavoriteExists;
+ }
+ }
+
+ NSMutableDictionary *favorite = [NSMutableDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"test", query, nil] forKeys:[NSArray arrayWithObjects:@"name", @"query", nil]];
+
+ [queryFavoritesController addObject:favorite];
+ [queryFavoritesController setSelectionIndex:([[queryFavoritesController arrangedObjects] count] - 1)];
+
+ [favoritesTableView reloadData];
+ [favoritesTableView scrollRowToVisible:[favoritesTableView selectedRow]];
+
+ // Inform the delegate that the query favorites have been updated
+ if (delegateRespondsToFavoriteUpdates) {
+ [delegate queryFavoritesHaveBeenUpdated:self];
+ }
+
+ return SPQueryFavoriteAdded;
+}
+
+#pragma mark -
+#pragma mark SplitView delegate methods
+
+/**
+ * Return the maximum possible size of the splitview.
+ */
+- (float)splitView:(NSSplitView *)sender constrainMaxCoordinate:(float)proposedMax ofSubviewAt:(int)offset
+{
+ return (proposedMax - 220);
+}
+
+/**
+ * Return the minimum possible size of the splitview.
+ */
+- (float)splitView:(NSSplitView *)sender constrainMinCoordinate:(float)proposedMin ofSubviewAt:(int)offset
+{
+ return (proposedMin + 120);
+}
+
+#pragma mark -
+#pragma mark TableView datasource methods
+
+/**
+ * Returns the number of query favorites.
+ */
+- (int)numberOfRowsInTableView:(NSTableView *)aTableView
+{
+ return [[queryFavoritesController arrangedObjects] count];
+}
+
+/**
+ * Returns the value for the requested table column and row index.
+ */
+- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
+{
+ return [[[queryFavoritesController arrangedObjects] objectAtIndex:rowIndex] objectForKey:[aTableColumn identifier]];
+}
+
+#pragma mark -
+#pragma mark TableView delegate methods
+
+/**
+ * Called whenever the user's changes the currently selected favorite.
+ */
+/*- (void)tableViewSelectionDidChange:(NSNotification *)notification
+{
+ [favoriteQueryTextView setString:@""];
+
+ if ([favoritesTableView numberOfSelectedRows] == 1) {
+ [favoriteQueryTextView setString:[[[queryFavoritesController arrangedObjects] objectAtIndex:[favoritesTableView selectedRow]] objectForKey:@"query"]];
+ }
+}*/
+
+#pragma mark -
+#pragma mark Menu validation
+
+/**
+ * Menu item validation.
+ */
+- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
+{
+ SEL action = [menuItem action];
+
+ if ((action == @selector(removeQueryFavorite:)) ||
+ (action == @selector(copyQueryFavorite:)) ||
+ (action == @selector(saveFavoriteToFile:)))
+ {
+ return ([favoritesTableView numberOfSelectedRows] == 1);
+ }
+ else if (action == @selector(removeAllQueryFavorites:)) {
+ return ([[queryFavoritesController arrangedObjects] count] > 0);
+ }
+
+ return YES;
+}
+
+#pragma mark -
+#pragma mark TableView drag & drop delegate methods
+
+/**
+ * Return whether or not the supplied rows can be written.
+ */
+- (BOOL)tableView:(NSTableView *)tableView writeRows:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard
+{
+ if ([rows count] == 1) {
+ NSArray *pboardTypes = [NSArray arrayWithObject:QUERY_FAVORITES_PB_DRAG_TYPE];
+ NSInteger originalRow = [[rows objectAtIndex:0] intValue];
+
+ [pboard declareTypes:pboardTypes owner:nil];
+ [pboard setString:[[NSNumber numberWithInt:originalRow] stringValue] forType:QUERY_FAVORITES_PB_DRAG_TYPE];
+
+ return YES;
+ }
+
+ return NO;
+}
+
+/**
+ * Validate the proposed drop of the supplied rows.
+ */
+- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id <NSDraggingInfo>)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)operation
+{
+ NSArray *pboardTypes = [[info draggingPasteboard] types];
+
+ if (([pboardTypes count] > 1) && (row != -1)) {
+ if (([pboardTypes containsObject:QUERY_FAVORITES_PB_DRAG_TYPE]) && (operation == NSTableViewDropAbove)) {
+ NSInteger originalRow = [[[info draggingPasteboard] stringForType:QUERY_FAVORITES_PB_DRAG_TYPE] intValue];
+
+ if ((row != originalRow) && (row != (originalRow + 1))) {
+ return NSDragOperationMove;
+ }
+ }
+ }
+
+ return NSDragOperationNone;
+}
+
+/**
+ * Return whether or not to accept the drop of the supplied rows.
+ */
+- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id <NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)operation
+{
+ NSInteger originalRow = [[[info draggingPasteboard] stringForType:QUERY_FAVORITES_PB_DRAG_TYPE] intValue];
+ NSInteger destinationRow = row;
+
+ if (destinationRow > originalRow) destinationRow--;
+
+ NSMutableDictionary *draggedRow = [NSMutableDictionary dictionaryWithDictionary:[[queryFavoritesController arrangedObjects] objectAtIndex:originalRow]];
+
+ [queryFavoritesController removeObjectAtArrangedObjectIndex:originalRow];
+ [queryFavoritesController insertObject:draggedRow atArrangedObjectIndex:destinationRow];
+
+ [favoritesTableView reloadData];
+ [favoritesTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:destinationRow] byExtendingSelection:NO];
+
+ return YES;
+}
+
+#pragma mark -
+#pragma mark Other
+
+/**
+ * Sheet did end method
+ */
+- (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(NSString *)contextInfo
+{
+ if ([contextInfo isEqualToString:@"removeAllFavorites"]) {
+ if (returnCode == NSAlertAlternateReturn) {
+ [queryFavoritesController removeObjects:[queryFavoritesController arrangedObjects]];
+ }
+ }
+}
+
+/**
+ * Save panel did end method.
+ */
+- (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(int)returnCode contextInfo:(NSString *)contextInfo
+{
+ if (returnCode == NSOKButton) {
+ NSError *error = nil;
+
+ [prefs setInteger:[[encodingPopUp selectedItem] tag] forKey:@"lastSqlFileEncoding"];
+ [prefs synchronize];
+
+ [[favoriteQueryTextView string] writeToFile:[panel filename] atomically:YES encoding:[[encodingPopUp selectedItem] tag] error:&error];
+
+ if (error) [[NSAlert alertWithError:error] runModal];
+ }
+}
+
+@end