aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-08-01 19:48:30 +0000
committerrowanbeentje <rowan@beent.je>2009-08-01 19:48:30 +0000
commit8b672753ae94f76308557375ea13f373143d78cd (patch)
treed5b59470f6570fbfd907a9ff214a0e0367578681
parent61c1ffe21ce73752bc195e0312a6a851808601e6 (diff)
downloadsequelpro-8b672753ae94f76308557375ea13f373143d78cd.tar.gz
sequelpro-8b672753ae94f76308557375ea13f373143d78cd.tar.bz2
sequelpro-8b672753ae94f76308557375ea13f373143d78cd.zip
- Fix an errant NSLog in TableSource
- Improve and make consistent state saving in TableContent; now saves filters and scroll position mor reliably on refresh/edit, and supports remembering and restoring which rows were selected - Significantly improve table history - only create entries for tables switches or filters, only remember 50 items, and save view/filters/scroll position/selections in table content view
-rw-r--r--Interfaces/English.lproj/DBView.xib42
-rw-r--r--Source/SPHistoryController.h3
-rw-r--r--Source/SPHistoryController.m92
-rw-r--r--Source/TableContent.h29
-rw-r--r--Source/TableContent.m295
-rw-r--r--Source/TableDocument.m7
-rw-r--r--Source/TableSource.m2
-rw-r--r--Source/TablesList.m3
8 files changed, 360 insertions, 113 deletions
diff --git a/Interfaces/English.lproj/DBView.xib b/Interfaces/English.lproj/DBView.xib
index 092b6a8a..d44e8f93 100644
--- a/Interfaces/English.lproj/DBView.xib
+++ b/Interfaces/English.lproj/DBView.xib
@@ -8,7 +8,6 @@
<string key="IBDocument.HIToolboxVersion">353.00</string>
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool>
- <integer value="27"/>
</object>
<object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -47,7 +46,7 @@
<string key="NSWindowContentMaxSize">{3.40282e+38, 3.40282e+38}</string>
<string key="NSWindowContentMinSize">{780, 480}</string>
<object class="NSView" key="NSWindowView" id="579726586">
- <reference key="NSNextResponder"/>
+ <nil key="NSNextResponder"/>
<int key="NSvFlags">256</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -186,7 +185,6 @@
</object>
<string key="NSFrameSize">{212, 26}</string>
<reference key="NSSuperview" ref="199860064"/>
- <reference key="NSNextKeyView" ref="643201879"/>
<reference key="NSDocView" ref="643201879"/>
<object class="NSColor" key="NSBGColor" id="529261656">
<int key="NSColorSpace">6</int>
@@ -222,7 +220,6 @@
</object>
<string key="NSFrameSize">{212, 26}</string>
<reference key="NSSuperview" ref="801427893"/>
- <reference key="NSNextKeyView" ref="588922296"/>
<int key="NSsFlags">0</int>
<reference key="NSVScroller" ref="540853896"/>
<reference key="NSHScroller" ref="566705316"/>
@@ -337,7 +334,6 @@
</object>
<string key="NSFrameSize">{212, 354}</string>
<reference key="NSSuperview" ref="233472824"/>
- <reference key="NSNextKeyView" ref="251040077"/>
<reference key="NSDocView" ref="251040077"/>
<object class="NSColor" key="NSBGColor" id="1024678221">
<int key="NSColorSpace">6</int>
@@ -369,7 +365,6 @@
</object>
<string key="NSFrameSize">{212, 354}</string>
<reference key="NSSuperview" ref="1017775084"/>
- <reference key="NSNextKeyView" ref="73685676"/>
<int key="NSsFlags">528</int>
<reference key="NSVScroller" ref="693168867"/>
<reference key="NSHScroller" ref="656188692"/>
@@ -494,7 +489,6 @@
</object>
<string key="NSFrameSize">{212, 145}</string>
<reference key="NSSuperview" ref="298226231"/>
- <reference key="NSNextKeyView" ref="347093764"/>
<reference key="NSDocView" ref="347093764"/>
<reference key="NSBGColor" ref="1024678221"/>
<int key="NScvFlags">6</int>
@@ -521,7 +515,6 @@
</object>
<string key="NSFrameSize">{212, 145}</string>
<reference key="NSSuperview" ref="192579410"/>
- <reference key="NSNextKeyView" ref="685057119"/>
<int key="NSsFlags">512</int>
<reference key="NSVScroller" ref="245346414"/>
<reference key="NSHScroller" ref="353686052"/>
@@ -2128,7 +2121,6 @@
</object>
<string key="NSFrame">{{1, 17}, {688, 454}}</string>
<reference key="NSSuperview" ref="33038697"/>
- <reference key="NSNextKeyView" ref="22576329"/>
<reference key="NSDocView" ref="22576329"/>
<reference key="NSBGColor" ref="1024678221"/>
<int key="NScvFlags">2</int>
@@ -2162,7 +2154,6 @@
</object>
<string key="NSFrame">{{1, 0}, {688, 17}}</string>
<reference key="NSSuperview" ref="33038697"/>
- <reference key="NSNextKeyView" ref="457166030"/>
<reference key="NSDocView" ref="457166030"/>
<reference key="NSBGColor" ref="1024678221"/>
<int key="NScvFlags">4</int>
@@ -2171,7 +2162,6 @@
</object>
<string key="NSFrame">{{6, 33}, {690, 472}}</string>
<reference key="NSSuperview" ref="1013108064"/>
- <reference key="NSNextKeyView" ref="545438501"/>
<int key="NSsFlags">562</int>
<reference key="NSVScroller" ref="398797698"/>
<reference key="NSHScroller" ref="178353583"/>
@@ -3101,7 +3091,7 @@
<reference key="NSControlView" ref="363916571"/>
<int key="NSButtonFlags">-2042609409</int>
<int key="NSButtonFlags2">35</int>
- <object class="NSCustomResource" key="NSNormalImage" id="44837094">
+ <object class="NSCustomResource" key="NSNormalImage">
<string key="NSClassName">NSImage</string>
<string key="NSResourceName">button_action</string>
</object>
@@ -3116,7 +3106,10 @@
<string key="NSKeyEquiv"/>
<int key="NSKeyEquivModMask">1048576</int>
<int key="NSMnemonicLoc">2147483647</int>
- <reference key="NSImage" ref="44837094"/>
+ <object class="NSCustomResource" key="NSImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">button_action</string>
+ </object>
<string key="NSAction">_popUpItemAction:</string>
<reference key="NSTarget" ref="984501775"/>
</object>
@@ -4550,7 +4543,6 @@
</object>
</object>
<string key="NSFrameSize">{944, 550}</string>
- <reference key="NSSuperview"/>
</object>
<string key="NSScreenRect">{{0, 0}, {1920, 1178}}</string>
<string key="NSMinSize">{780, 502}</string>
@@ -10914,7 +10906,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<string key="NSExtension">NSResponder</string>
</object>
<object class="NSCustomView" id="884983195">
- <nil key="NSNextResponder"/>
+ <reference key="NSNextResponder"/>
<int key="NSvFlags">301</int>
<object class="NSMutableArray" key="NSSubviews">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -10923,6 +10915,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<int key="NSvFlags">298</int>
<string key="NSFrame">{{0, 3}, {200, 26}}</string>
<reference key="NSSuperview" ref="884983195"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSPopUpButtonCell" key="NSCell" id="931032347">
<int key="NSCellFlags">-2076049856</int>
@@ -11001,6 +10994,7 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<int key="NSvFlags">301</int>
<string key="NSFrame">{{208, 3}, {61, 25}}</string>
<reference key="NSSuperview" ref="884983195"/>
+ <reference key="NSWindow"/>
<bool key="NSEnabled">YES</bool>
<object class="NSSegmentedCell" key="NSCell" id="253177824">
<int key="NSCellFlags">67239424</int>
@@ -11034,6 +11028,8 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
</object>
</object>
<string key="NSFrameSize">{269, 32}</string>
+ <reference key="NSSuperview"/>
+ <reference key="NSWindow"/>
<string key="NSClassName">NSView</string>
</object>
<object class="NSCustomView" id="730777562">
@@ -14616,6 +14612,14 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
</object>
<int key="connectionID">6306</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">spHistoryControllerInstance</string>
+ <reference key="source" ref="392169872"/>
+ <reference key="destination" ref="796834585"/>
+ </object>
+ <int key="connectionID">6316</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -22906,9 +22910,9 @@ IGRvIHlvdSB3YW50IHRvIGFkZCBmb3IgdGhpcyBmaWVsZD8</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<reference ref="9"/>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{252, 100}, {944, 550}}</string>
+ <string>{{60, 100}, {944, 550}}</string>
<boolean value="NO"/>
- <string>{{252, 100}, {944, 550}}</string>
+ <string>{{60, 100}, {944, 550}}</string>
<reference ref="9"/>
<reference ref="9"/>
<string>{{62, 352}, {845, 504}}</string>
@@ -23884,7 +23888,7 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">6315</int>
+ <int key="maxID">6316</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
@@ -24572,6 +24576,7 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
<string>limitRowsText</string>
<string>multipleLineEditingButton</string>
<string>removeButton</string>
+ <string>spHistoryControllerInstance</string>
<string>tableContentView</string>
<string>tableDataInstance</string>
<string>tableDocumentInstance</string>
@@ -24593,6 +24598,7 @@ Y2hhbmdlIHRoZSBvcmRlcg</string>
<string>id</string>
<string>id</string>
<string>id</string>
+ <string>SPHistoryController</string>
<string>CMCopyTable</string>
<string>id</string>
<string>id</string>
diff --git a/Source/SPHistoryController.h b/Source/SPHistoryController.h
index 110ebea3..3e3c5452 100644
--- a/Source/SPHistoryController.h
+++ b/Source/SPHistoryController.h
@@ -24,7 +24,7 @@
#import <Cocoa/Cocoa.h>
-@class TableDocument;
+@class TableDocument, TableContent;
enum sphistory_view_types
{
@@ -39,6 +39,7 @@ enum sphistory_view_types
IBOutlet TableDocument *theDocument;
IBOutlet NSSegmentedControl *historyControl;
+ TableContent *tableContentInstance;
NSMutableArray *history;
unsigned int historyPosition;
BOOL restoringHistoryState;
diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m
index fc6e03b9..acd25ea0 100644
--- a/Source/SPHistoryController.m
+++ b/Source/SPHistoryController.m
@@ -23,6 +23,7 @@
// More info at <http://code.google.com/p/sequel-pro/>
#import "TableDocument.h"
+#import "TableContent.h"
#import "TablesList.h"
#import "SPHistoryController.h"
@@ -44,6 +45,11 @@
return self;
}
+- (void) awakeFromNib
+{
+ tableContentInstance = [theDocument valueForKey:@"tableContentInstance"];
+}
+
- (void) dealloc
{
[history release];
@@ -74,6 +80,7 @@
*/
- (IBAction) historyControlClicked:(NSSegmentedControl *)theControl
{
+
switch ([theControl selectedSegment]) {
// Back button clicked:
@@ -120,6 +127,8 @@
* Call to store or update a history item for the document state. Checks against
* the latest stored details; if they match, a new history item is not created.
* This should therefore be called without worry of duplicates.
+ * Table histories are created per table/filter setting, and while view changes
+ * update the current history entry, they don't replace it.
*/
- (void) updateHistoryEntries
{
@@ -131,30 +140,44 @@
NSString *theDatabase = [theDocument database];
NSString *theTable = [theDocument table];
unsigned int theView = [self currentlySelectedView];
-
- // Check for a duplicate against the current entry
- if (historyPosition != NSNotFound) {
- NSDictionary *currentHistoryItem = [history objectAtIndex:historyPosition];
- if ([[currentHistoryItem objectForKey:@"database"] isEqualToString:theDatabase]
- && [[currentHistoryItem objectForKey:@"table"] isEqualToString:theTable]
- && [[currentHistoryItem objectForKey:@"view"] intValue] == theView)
- {
- return;
- }
- }
+ NSString *contentSortCol = [tableContentInstance sortColumnName];
+ BOOL contentSortColIsAsc = [tableContentInstance sortColumnIsAscending];
+ unsigned int contentLimitStartPosition = [tableContentInstance limitStart];
+ NSIndexSet *contentSelectedIndexSet = [tableContentInstance selectedRowIndexes];
+ NSRect contentViewport = [tableContentInstance viewport];
+ NSDictionary *contentFilter = [tableContentInstance filterSettings];
+ if (!theDatabase) return;
// If there's any items after the current history position, remove them
if (historyPosition != NSNotFound && historyPosition < [history count] - 1) {
[history removeObjectsInRange:NSMakeRange(historyPosition + 1, [history count] - historyPosition - 1)];
- // Special case: if the last history item is currently active, and has no table,
- // but the new selection does - delete the last entry, in order to replace it.
- // This improves history flow.
- } else if (historyPosition != NSNotFound && historyPosition == [history count] - 1
- && [[[history objectAtIndex:historyPosition] objectForKey:@"database"] isEqualToString:theDatabase]
- && ![[history objectAtIndex:historyPosition] objectForKey:@"table"])
- {
- [history removeLastObject];
+ } else if (historyPosition != NSNotFound && historyPosition == [history count] - 1) {
+ NSDictionary *currentHistoryEntry = [history objectAtIndex:historyPosition];
+
+ // If the table is the same, and the filter settings haven't changed, delete the
+ // last entry so it can be replaced. This updates navigation within a table, rather than
+ // creating a new entry every time detail is changed.
+ if ([[currentHistoryEntry objectForKey:@"database"] isEqualToString:theDatabase]
+ && [[currentHistoryEntry objectForKey:@"table"] isEqualToString:theTable]
+ && ([[currentHistoryEntry objectForKey:@"view"] intValue] != theView
+ || ((![currentHistoryEntry objectForKey:@"contentFilter"] && !contentFilter)
+ || (![currentHistoryEntry objectForKey:@"contentFilter"]
+ && ![[contentFilter objectForKey:@"filterValue"] length]
+ && ![[contentFilter objectForKey:@"filterComparison"] isEqualToString:@"IS NULL"]
+ && ![[contentFilter objectForKey:@"filterComparison"] isEqualToString:@"IS NOT NULL"])
+ || [[currentHistoryEntry objectForKey:@"contentFilter"] isEqualToDictionary:contentFilter])))
+ {
+ [history removeLastObject];
+
+ // Special case: if the last history item is currently active, and has no table,
+ // but the new selection does - delete the last entry, in order to replace it.
+ // This improves history flow.
+ } else if ([[currentHistoryEntry objectForKey:@"database"] isEqualToString:theDatabase]
+ && ![currentHistoryEntry objectForKey:@"table"])
+ {
+ [history removeLastObject];
+ }
}
// Construct and add the new history entry
@@ -162,8 +185,19 @@
theDatabase, @"database",
theTable, @"table",
[NSNumber numberWithInt:theView], @"view",
+ [NSNumber numberWithBool:contentSortColIsAsc], @"contentSortColIsAsc",
+ [NSNumber numberWithInt:contentLimitStartPosition], @"contentLimitStartPosition",
+ [NSValue valueWithRect:contentViewport], @"contentViewport",
nil];
+ if (contentSortCol) [newEntry setObject:contentSortCol forKey:@"contentSortCol"];
+ if (contentSelectedIndexSet) [newEntry setObject:contentSelectedIndexSet forKey:@"contentSelectedIndexSet"];
+ if (contentFilter) [newEntry setObject:contentFilter forKey:@"contentFilter"];
+
[history addObject:newEntry];
+
+ // If there are now more than fifty history entries, remove one from the start
+ if ([history count] > 50) [history removeObjectAtIndex:0];
+
historyPosition = [history count] - 1;
[self updateToolbarItem];
}
@@ -189,6 +223,24 @@
historyPosition = position;
NSDictionary *historyEntry = [history objectAtIndex:historyPosition];
+ // Set table content details for restore
+ [tableContentInstance setSortColumnNameToRestore:[historyEntry objectForKey:@"contentSortCol"] isAscending:[[historyEntry objectForKey:@"contentSortCol"] boolValue]];
+ [tableContentInstance setLimitStartToRestore:[[historyEntry objectForKey:@"contentLimitStartPosition"] intValue]];
+ [tableContentInstance setSelectedRowIndexesToRestore:[historyEntry objectForKey:@"contentSelectedIndexSet"]];
+ [tableContentInstance setViewportToRestore:[[historyEntry objectForKey:@"contentViewport"] rectValue]];
+ [tableContentInstance setFiltersToRestore:[historyEntry objectForKey:@"contentFilter"]];
+
+ // If the database, table, and view are the same and content - just trigger a table reload (filters)
+ if ([[theDocument database] isEqualToString:[historyEntry objectForKey:@"database"]]
+ && [historyEntry objectForKey:@"table"] && [[theDocument table] isEqualToString:[historyEntry objectForKey:@"table"]]
+ && [[historyEntry objectForKey:@"view"] intValue] == [self currentlySelectedView] == SP_VIEW_CONTENT)
+ {
+ [tableContentInstance loadTable:[historyEntry objectForKey:@"table"]];
+ restoringHistoryState = NO;
+ [self updateToolbarItem];
+ return;
+ }
+
// Check and set the database
if (![[theDocument database] isEqualToString:[historyEntry objectForKey:@"database"]]) {
NSPopUpButton *chooseDatabaseButton = [theDocument valueForKey:@"chooseDatabaseButton"];
@@ -213,6 +265,8 @@
} else if (![historyEntry objectForKey:@"table"] && [theDocument table]) {
TablesList *tablesListInstance = [theDocument valueForKey:@"tablesListInstance"];
[[tablesListInstance valueForKey:@"tablesListView"] deselectAll:self];
+ } else {
+ [[theDocument valueForKey:@"tablesListInstance"] setContentRequiresReload:YES];
}
// Check and set the view
diff --git a/Source/TableContent.h b/Source/TableContent.h
index 254fe9c9..ba9d9b51 100644
--- a/Source/TableContent.h
+++ b/Source/TableContent.h
@@ -28,13 +28,14 @@
#import <Cocoa/Cocoa.h>
#import <MCPKit/MCPKit.h>
-@class CMCopyTable, SPTextAndLinkCell;
+@class CMCopyTable, SPTextAndLinkCell, SPHistoryController;
@interface TableContent : NSObject
{
IBOutlet id tableDocumentInstance;
IBOutlet id tablesListInstance;
IBOutlet id tableDataInstance;
+ IBOutlet SPHistoryController *spHistoryControllerInstance;
IBOutlet id tableWindow;
IBOutlet CMCopyTable *tableContentView;
@@ -56,14 +57,19 @@
NSString *selectedTable, *usedQuery;
NSMutableArray *fullResult, *filteredResult, *dataColumns, *keys, *oldRow;
- NSString *compareType, *lastField;
- NSString *targetFilterColumn, *targetFilterValue;
+ NSString *compareType;
NSNumber *sortCol;
BOOL isEditingRow, isEditingNewRow, isSavingRow, isDesc, setLimit;
NSUserDefaults *prefs;
int numRows, currentlyEditingRow, maxNumRowsOfCurrentTable;
bool areShowingAllRows;
-
+
+ BOOL sortColumnToRestoreIsAsc;
+ NSString *sortColumnToRestore;
+ unsigned int limitStartPositionToRestore;
+ NSIndexSet *selectionIndexToRestore;
+ NSRect selectionViewportToRestore;
+ NSString *filterFieldToRestore, *filterComparisonToRestore, *filterValueToRestore;
}
//table methods
@@ -101,6 +107,21 @@
- (int)fetchNumberOfRows;
- (BOOL)saveRowOnDeselect;
+// Retrieving and setting table state
+- (NSString *) sortColumnName;
+- (BOOL) sortColumnIsAscending;
+- (unsigned int) limitStart;
+- (NSIndexSet *) selectedRowIndexes;
+- (NSRect) viewport;
+- (NSDictionary *) filterSettings;
+- (void) setSortColumnNameToRestore:(NSString *)theSortColumnName isAscending:(BOOL)isAscending;
+- (void) setLimitStartToRestore:(unsigned int)theLimitStart;
+- (void) setSelectedRowIndexesToRestore:(NSIndexSet *)theIndexSet;
+- (void) setViewportToRestore:(NSRect)theViewport;
+- (void) setFiltersToRestore:(NSDictionary *)filterSettings;
+- (void) storeCurrentDetailsForRestoration;
+- (void) clearDetailsToRestore;
+
//tableView datasource methods
- (int)numberOfRowsInTableView:(NSTableView *)aTableView;
- (id)tableView:(CMCopyTable *)aTableView
diff --git a/Source/TableContent.m b/Source/TableContent.m
index d596eb7b..1e470112 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -59,14 +59,21 @@
selectedTable = nil;
sortCol = nil;
- lastField = nil;
+ isDesc = NO;
// editData = nil;
keys = nil;
- targetFilterColumn = nil;
- targetFilterValue = nil;
areShowingAllRows = false;
currentlyEditingRow = -1;
+
+ sortColumnToRestore = nil;
+ sortColumnToRestoreIsAsc = YES;
+ limitStartPositionToRestore = 1;
+ selectionIndexToRestore = nil;
+ selectionViewportToRestore = NSZeroRect;
+ filterFieldToRestore = nil;
+ filterComparisonToRestore = nil;
+ filterValueToRestore = nil;
prefs = [NSUserDefaults standardUserDefaults];
@@ -89,14 +96,12 @@
- (void)loadTable:(NSString *)aTable
{
int i;
- NSNumber *colWidth, *savedSortCol = nil;
+ NSNumber *colWidth, *sortColumnNumberToRestore = nil;
NSArray *columnNames;
NSDictionary *columnDefinition;
NSTableColumn *theCol;
NSString *query;
MCPResult *queryResult;
- BOOL preserveCurrentView = [aTable isEqualToString:selectedTable];
- NSString *preservedFilterField = nil, *preservedFilterComparison, *preservedFilterValue;
// Clear the selection, and abort the reload if the user is still editing a row
[tableContentView deselectAll:self];
@@ -155,6 +160,9 @@
[copyButton setEnabled:NO];
[removeButton setEnabled:NO];
+ // Clear restoration settings
+ [self clearDetailsToRestore];
+
return;
}
@@ -253,8 +261,8 @@
}
// Set the column to be reselected for sorting if appropriate
- if (lastField && [lastField isEqualToString:[columnDefinition objectForKey:@"name"]])
- savedSortCol = [columnDefinition objectForKey:@"datacolumnindex"];
+ if (sortColumnToRestore && [sortColumnToRestore isEqualToString:[columnDefinition objectForKey:@"name"]])
+ sortColumnNumberToRestore = [columnDefinition objectForKey:@"datacolumnindex"];
// Add the column to the table
[tableContentView addTableColumn:theCol];
@@ -262,11 +270,12 @@
}
// If the table has been reloaded and the previously selected sort column is still present, reselect it.
- if (preserveCurrentView && savedSortCol) {
- theCol = [tableContentView tableColumnWithIdentifier:savedSortCol];
+ if (sortColumnNumberToRestore) {
+ theCol = [tableContentView tableColumnWithIdentifier:sortColumnNumberToRestore];
if (sortCol) [sortCol release];
- sortCol = [savedSortCol copy];
+ sortCol = [sortColumnNumberToRestore copy];
[tableContentView setHighlightedTableColumn:theCol];
+ isDesc = !sortColumnToRestoreIsAsc;
if ( isDesc ) {
[tableContentView setIndicatorImage:[NSImage imageNamed:@"NSDescendingSortIndicator"] inTableColumn:theCol];
} else {
@@ -282,13 +291,9 @@
isDesc = NO;
}
- // Preserve the stored filter settings if appropriate
- if (!targetFilterColumn && preserveCurrentView && [fieldField isEnabled]) {
- preservedFilterField = [NSString stringWithString:[[fieldField selectedItem] title]];
- preservedFilterComparison = [NSString stringWithString:[[compareField selectedItem] title]];
- preservedFilterValue = [NSString stringWithString:[argumentField stringValue]];
- }
-
+ // Store the current first responder so filter field doesn't steal focus
+ id currentFirstResponder = [tableWindow firstResponder];
+
// Enable and initialize filter fields (with tags for position of menu item and field position)
[fieldField setEnabled:YES];
[fieldField removeAllItems];
@@ -302,39 +307,31 @@
[argumentField setStringValue:@""];
[filterButton setEnabled:YES];
- // Select the specified target filter settings if set
- if (targetFilterColumn) {
- [fieldField selectItemWithTitle:targetFilterColumn];
+ // Restore preserved filter settings if appropriate and valid
+ if (filterFieldToRestore) {
+ [fieldField selectItemWithTitle:filterFieldToRestore];
[self setCompareTypes:self];
- if ([targetFilterValue isEqualToString:[prefs objectForKey:@"NullValue"]]) {
- [compareField selectItemWithTitle:@"IS NULL"];
- } else {
- [compareField selectItemAtIndex:0]; // "=", "IS", etc
- [argumentField setStringValue:targetFilterValue];
- }
- areShowingAllRows = NO;
- targetFilterColumn = nil;
- targetFilterValue = nil;
- // Otherwise, restore preserved filter settings if appropriate and valid
- } else if (preserveCurrentView && preservedFilterField != nil && [fieldField itemWithTitle:preservedFilterField]) {
- [fieldField selectItemWithTitle:preservedFilterField];
- [self setCompareTypes:self];
-
- if ([fieldField itemWithTitle:preservedFilterField] && [compareField itemWithTitle:preservedFilterComparison]) {
- [compareField selectItemWithTitle:preservedFilterComparison];
- [argumentField setStringValue:preservedFilterValue];
+ if ([fieldField itemWithTitle:filterFieldToRestore]
+ && ((!filterComparisonToRestore && filterValueToRestore)
+ || [compareField itemWithTitle:filterComparisonToRestore]))
+ {
+ if (filterComparisonToRestore) [compareField selectItemWithTitle:filterComparisonToRestore];
+ if (filterValueToRestore) [argumentField setStringValue:filterValueToRestore];
areShowingAllRows = NO;
}
}
+ // Restore first responder
+ [tableWindow makeFirstResponder:currentFirstResponder];
+
// Enable or disable the limit fields according to preference setting
if ( [prefs boolForKey:@"LimitResults"] ) {
// Attempt to preserve the limit value if it's still valid
- if (!preserveCurrentView || [limitRowsField intValue] < 1 || [limitRowsField intValue] >= numRows) {
- [limitRowsField setStringValue:@"1"];
- }
+ if (limitStartPositionToRestore < 1 || limitStartPositionToRestore >= numRows) limitStartPositionToRestore = 1;
+ [limitRowsField setStringValue:[NSString stringWithFormat:@"%u", limitStartPositionToRestore]];
+
[limitRowsField setEnabled:YES];
[limitRowsButton setEnabled:YES];
[limitRowsStepper setEnabled:YES];
@@ -382,24 +379,28 @@
[fullResult setArray:[self fetchResultAsArray:queryResult]];
- // This to fix an issue where by areShowingAllRows is set to NO above during the restore of the filter options
- // leading the code to believe that the result set is filtered. If the filtered result set count is the same as the
- // maximum rows in the table then filtering is currently not in use and we set areShowingAllRows back to YES.
- if ([filteredResult count] == maxNumRowsOfCurrentTable) {
- areShowingAllRows = YES;
- }
-
// Apply any filtering and update the row count
if (!areShowingAllRows) {
[self filterTable:self];
[countText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%d rows of %d selected", @"text showing how many rows are in the filtered result"), [filteredResult count], numRows]];
- }
+ }
else {
[filteredResult setArray:fullResult];
[countText setStringValue:[NSString stringWithFormat:NSLocalizedString(@"%d rows in table", @"text showing how many rows are in the result"), [fullResult count]]];
}
- // Reload the table data
+ // Restore the view origin if appropriate
+ if (!NSEqualRects(selectionViewportToRestore, NSZeroRect)) {
+ selectionViewportToRestore.size = [tableContentView visibleRect].size;
+ [tableContentView scrollRectToVisible:selectionViewportToRestore];
+ }
+
+ // Restore selection indexes if appropriate
+ if (selectionIndexToRestore) {
+ [tableContentView selectRowIndexes:selectionIndexToRestore byExtendingSelection:NO];
+ }
+
+ // Reload the table data display
[tableContentView reloadData];
// Init copyTable with necessary information for copying selected rows as SQL INSERT
@@ -407,6 +408,9 @@
// Post the notification that the query is finished
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:self];
+
+ // Clear any details to restore now that they have been restored
+ [self clearDetailsToRestore];
}
/*
@@ -417,17 +421,14 @@
// Check whether a save of the current row is required.
if (![self saveRowOnDeselect]) return;
- // Store the current viewport location
- NSRect viewRect = [tableContentView visibleRect];
+ // Save view details to restore safely if possible
+ [self storeCurrentDetailsForRestoration];
// Clear the table data column cache
[tableDataInstance resetColumnData];
// Load the table's data
[self loadTable:selectedTable];
-
- // Restore the viewport
- [tableContentView scrollRectToVisible:viewRect];
}
/*
@@ -441,6 +442,9 @@
//query started
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:self];
+ // Store the current first responder so filter field doesn't steal focus
+ id currentFirstResponder = [tableWindow firstResponder];
+
//enable or disable limit fields
if ( [prefs boolForKey:@"LimitResults"] ) {
[limitRowsField setEnabled:YES];
@@ -455,6 +459,8 @@
[limitRowsText setStringValue:NSLocalizedString(@"No limit", @"text showing that the result isn't limited")];
[limitRowsField setStringValue:@""];
}
+
+ [tableWindow makeFirstResponder:currentFirstResponder];
// queryString = [@"SELECT * FROM " stringByAppendingString:selectedTable];
queryString = [NSString stringWithFormat:@"SELECT %@ FROM %@", [self fieldListForQuery], [selectedTable backtickQuotedString]];
@@ -512,6 +518,9 @@
return;
}
+ // Update history
+ [spHistoryControllerInstance updateHistoryEntries];
+
// Update negative limits
if ( [limitRowsField intValue] <= 0 ) {
[limitRowsField setStringValue:@"1"];
@@ -1037,15 +1046,22 @@
// Check whether a save of the current row is required.
if ( ![self saveRowOnDeselect] ) return;
+ // Save existing scroll position and details
+ [spHistoryControllerInstance updateHistoryEntries];
+
// Store the filter details to use when next loading the table
- targetFilterColumn = [refDictionary objectForKey:@"column"];
- targetFilterValue = [[filteredResult objectAtIndex:[theArrowCell getClickedRow]] objectAtIndex:dataColumnIndex];
+ NSString *targetFilterValue = [[filteredResult objectAtIndex:[theArrowCell getClickedRow]] objectAtIndex:dataColumnIndex];
+ NSDictionary *filterSettings = [NSDictionary dictionaryWithObjectsAndKeys:
+ [refDictionary objectForKey:@"column"], @"filterField",
+ targetFilterValue, @"filterValue",
+ ([targetFilterValue isEqualToString:[prefs objectForKey:@"NullValue"]]?@"IS NULL":nil), @"filterComparison",
+ nil];
+ [self setFiltersToRestore:filterSettings];
// Attempt to switch to the new table
if (![tablesListInstance selectTableOrViewWithName:[refDictionary objectForKey:@"table"]]) {
NSBeep();
- targetFilterColumn = nil;
- targetFilterValue = nil;
+ [self setFiltersToRestore:nil];
}
}
@@ -1303,7 +1319,6 @@
if ( isEditingNewRow ) {
if ( [prefs boolForKey:@"ReloadAfterAddingRow"] ) {
[self reloadTableValues:self];
- [tableContentView deselectAll:self];
[tableWindow endEditingFor:nil];
} else {
@@ -1321,7 +1336,6 @@
} else {
if ( [prefs boolForKey:@"ReloadAfterEditingRow"] ) {
[self reloadTableValues:self];
- [tableContentView deselectAll:self];
[tableWindow endEditingFor:nil];
// TODO: this probably needs looking at... it's reloading it all itself?
@@ -1662,6 +1676,153 @@
[error objectAtIndex:1]);
}
+#pragma mark -
+#pragma mark Retrieving and setting table state
+
+/**
+ * Provide a getter for the table's sort column name
+ */
+- (NSString *) sortColumnName
+{
+ if (!sortCol || !dataColumns) return nil;
+
+ return [[dataColumns objectAtIndex:[sortCol intValue]] objectForKey:@"name"];
+}
+
+/**
+ * Provide a getter for the table current sort order
+ */
+- (BOOL) sortColumnIsAscending
+{
+ return !isDesc;
+}
+
+/**
+ * Provide a getter for the table's selected rows index set
+ */
+- (NSIndexSet *) selectedRowIndexes
+{
+ return [tableContentView selectedRowIndexes];
+}
+
+/**
+ * Provide a getter for the LIMIT position
+ */
+- (unsigned int) limitStart
+{
+ return [limitRowsField intValue];
+}
+
+/**
+ * Provide a getter for the table's current viewport
+ */
+- (NSRect) viewport
+{
+ return [tableContentView visibleRect];
+}
+
+/**
+ * Provide a getter for the current filter details
+ */
+- (NSDictionary *) filterSettings
+{
+ NSDictionary *theDictionary;
+
+ if (![fieldField isEnabled]) return nil;
+
+ theDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
+ [[fieldField selectedItem] title], @"filterField",
+ [[compareField selectedItem] title], @"filterComparison",
+ [argumentField stringValue], @"filterValue",
+ nil];
+
+ return theDictionary;
+}
+
+/**
+ * Set the sort column and sort order to restore on next table load
+ */
+- (void) setSortColumnNameToRestore:(NSString *)theSortColumnName isAscending:(BOOL)isAscending
+{
+ if (sortColumnToRestore) [sortColumnToRestore release], sortColumnToRestore = nil;
+
+ if (theSortColumnName) {
+ sortColumnToRestore = [[NSString alloc] initWithString:theSortColumnName];
+ sortColumnToRestoreIsAsc = isAscending;
+ }
+}
+
+/**
+ * Sets the value for the limit start position to use on next table load
+ */
+- (void) setLimitStartToRestore:(unsigned int)theLimitStart
+{
+ limitStartPositionToRestore = theLimitStart;
+}
+
+/**
+ * Set the selected row indexes to restore on next table load
+ */
+- (void) setSelectedRowIndexesToRestore:(NSIndexSet *)theIndexSet
+{
+ if (selectionIndexToRestore) [selectionIndexToRestore release], selectionIndexToRestore = nil;
+
+ if (theIndexSet) selectionIndexToRestore = [[NSIndexSet alloc] initWithIndexSet:theIndexSet];
+}
+
+/**
+ * Set the viewport to restore on next table load
+ */
+- (void) setViewportToRestore:(NSRect)theViewport
+{
+ selectionViewportToRestore = theViewport;
+}
+
+/**
+ * Set the filter settings to restore (if possible) on next table load
+ */
+- (void) setFiltersToRestore:(NSDictionary *)filterSettings
+{
+ if (filterFieldToRestore) [filterFieldToRestore release], filterFieldToRestore = nil;
+ if (filterComparisonToRestore) [filterComparisonToRestore release], filterComparisonToRestore = nil;
+ if (filterValueToRestore) [filterValueToRestore release], filterValueToRestore = nil;
+
+ if (filterSettings) {
+ if ([filterSettings objectForKey:@"filterField"])
+ filterFieldToRestore = [[NSString alloc] initWithString:[filterSettings objectForKey:@"filterField"]];
+ if ([filterSettings objectForKey:@"filterComparison"])
+ filterComparisonToRestore = [[NSString alloc] initWithString:[filterSettings objectForKey:@"filterComparison"]];
+ if ([filterSettings objectForKey:@"filterValue"])
+ filterValueToRestore = [[NSString alloc] initWithString:[filterSettings objectForKey:@"filterValue"]];
+ }
+}
+
+/**
+ * Convenience method for storing all current settings for restoration
+ */
+- (void) storeCurrentDetailsForRestoration
+{
+ [self setSortColumnNameToRestore:[self sortColumnName] isAscending:[self sortColumnIsAscending]];
+ [self setLimitStartToRestore:[self limitStart]];
+ [self setSelectedRowIndexesToRestore:[self selectedRowIndexes]];
+ [self setViewportToRestore:[self viewport]];
+ [self setFiltersToRestore:[self filterSettings]];
+}
+
+/**
+ * Convenience method for clearing any settings to restore
+ */
+- (void) clearDetailsToRestore
+{
+ [self setSortColumnNameToRestore:nil isAscending:YES];
+ [self setLimitStartToRestore:1];
+ [self setSelectedRowIndexesToRestore:nil];
+ [self setViewportToRestore:NSZeroRect];
+ [self setFiltersToRestore:nil];
+}
+
+#pragma mark -
+#pragma mark Table drawing and editing
/**
* Returns the number of rows in the selected table
@@ -1805,11 +1966,7 @@
}
if (sortCol) [sortCol release];
sortCol = [[NSNumber alloc] initWithInt:[[tableColumn identifier] intValue]];
-
- // Save the sort field name for use when refreshing the table
- if (lastField) [lastField release];
- lastField = [[NSString alloc] initWithString:[[dataColumns objectAtIndex:[[tableColumn identifier] intValue]] objectForKey:@"name"]];
-
+
//make queryString and perform query
queryString = [NSString stringWithFormat:@"SELECT %@ FROM %@ ORDER BY %@", [self fieldListForQuery],
[selectedTable backtickQuotedString], [[[dataColumns objectAtIndex:[sortCol intValue]] objectForKey:@"name"] backtickQuotedString]];
@@ -2161,8 +2318,12 @@
// if (editData) [editData release];
if (keys) [keys release];
if (sortCol) [sortCol release];
- if (lastField) [lastField release];
[usedQuery release];
+ if (sortColumnToRestore) [sortColumnToRestore release];
+ if (selectionIndexToRestore) [selectionIndexToRestore release];
+ if (filterFieldToRestore) filterFieldToRestore = nil;
+ if (filterComparisonToRestore) filterComparisonToRestore = nil;
+ if (filterValueToRestore) filterValueToRestore = nil;
[super dealloc];
}
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index 76e0337b..3a337041 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -402,7 +402,10 @@
}
return;
}
-
+
+ // Save existing scroll position and details
+ [spHistoryControllerInstance updateHistoryEntries];
+
// show error on connection failed
if ( ![mySQLConnection selectDB:[chooseDatabaseButton titleOfSelectedItem]] ) {
if ( [mySQLConnection isConnected] ) {
@@ -1763,7 +1766,7 @@
}
} else if ([itemIdentifier isEqualToString:@"HistoryNavigationToolbarItemIdentifier"]) {
- [toolbarItem setLabel:NSLocalizedString(@"History", @"toolbar item for navigation history")];
+ [toolbarItem setLabel:NSLocalizedString(@"Table History", @"toolbar item for navigation history")];
[toolbarItem setPaletteLabel:[toolbarItem label]];
[toolbarItem setView:historyControl];
diff --git a/Source/TableSource.m b/Source/TableSource.m
index 165d6461..fb7669bd 100644
--- a/Source/TableSource.m
+++ b/Source/TableSource.m
@@ -243,8 +243,6 @@ loads aTable, put it in an array, update the tableViewColumns and reload the tab
//query finished
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:self];
-
- NSLog(@"%@", tableFields);
}
/*
diff --git a/Source/TablesList.m b/Source/TablesList.m
index 6d611306..7986ab3e 100644
--- a/Source/TablesList.m
+++ b/Source/TablesList.m
@@ -1701,6 +1701,9 @@
return;
}
+ // Save existing scroll position and details
+ [spHistoryControllerInstance updateHistoryEntries];
+
[self updateSelection];
}