aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorrowanbeentje <rowan@beent.je>2009-11-23 02:15:45 +0000
committerrowanbeentje <rowan@beent.je>2009-11-23 02:15:45 +0000
commit1064dfa5438d493f996d52fd9b1554d121b93214 (patch)
treeb41093f58a98ff63607ea6268e1d8bee13ad07a4 /Source
parent3c52d5ea78847330f86bad7548a8d1a9bd2f0df6 (diff)
downloadsequelpro-1064dfa5438d493f996d52fd9b1554d121b93214.tar.gz
sequelpro-1064dfa5438d493f996d52fd9b1554d121b93214.tar.bz2
sequelpro-1064dfa5438d493f996d52fd9b1554d121b93214.zip
- Replace the LIMIT interface on the content view with a pagination control at the bottom. This addresses the last of Issue #49 and implements Issue #133; jump-to and two prefs affecting loading are available in a popup when clicking the pagination interface.
- Format row counts at the bottom of the content pane - Increase the MCPStreamingResult buffer for a stronger workaround for #463
Diffstat (limited to 'Source')
-rw-r--r--Source/SPHistoryController.m28
-rw-r--r--Source/TableContent.h28
-rw-r--r--Source/TableContent.m292
-rw-r--r--Source/TableDocument.m6
4 files changed, 242 insertions, 112 deletions
diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m
index 6c2683d0..7644f97f 100644
--- a/Source/SPHistoryController.m
+++ b/Source/SPHistoryController.m
@@ -188,7 +188,7 @@
unsigned int theView = [self currentlySelectedView];
NSString *contentSortCol = [tableContentInstance sortColumnName];
BOOL contentSortColIsAsc = [tableContentInstance sortColumnIsAscending];
- unsigned int contentLimitStartPosition = [tableContentInstance limitStart];
+ unsigned int contentPageNumber = [tableContentInstance pageNumber];
NSIndexSet *contentSelectedIndexSet = [tableContentInstance selectedRowIndexes];
NSRect contentViewport = [tableContentInstance viewport];
NSDictionary *contentFilter = [tableContentInstance filterSettings];
@@ -232,7 +232,7 @@
theTable, @"table",
[NSNumber numberWithInt:theView], @"view",
[NSNumber numberWithBool:contentSortColIsAsc], @"contentSortColIsAsc",
- [NSNumber numberWithInt:contentLimitStartPosition], @"contentLimitStartPosition",
+ [NSNumber numberWithInt:contentPageNumber], @"contentPageNumber",
[NSValue valueWithRect:contentViewport], @"contentViewport",
nil];
if (contentSortCol) [newEntry setObject:contentSortCol forKey:@"contentSortCol"];
@@ -288,7 +288,7 @@
// Set table content details for restore
[tableContentInstance setSortColumnNameToRestore:[historyEntry objectForKey:@"contentSortCol"] isAscending:[[historyEntry objectForKey:@"contentSortCol"] boolValue]];
- [tableContentInstance setLimitStartToRestore:[[historyEntry objectForKey:@"contentLimitStartPosition"] intValue]];
+ [tableContentInstance setPageToRestore:[[historyEntry objectForKey:@"contentPageNumber"] intValue]];
[tableContentInstance setSelectedRowIndexesToRestore:[historyEntry objectForKey:@"contentSelectedIndexSet"]];
[tableContentInstance setViewportToRestore:[[historyEntry objectForKey:@"contentViewport"] rectValue]];
[tableContentInstance setFiltersToRestore:[historyEntry objectForKey:@"contentFilter"]];
@@ -415,14 +415,24 @@
if (![theEntry objectForKey:@"table"] || ![[theEntry objectForKey:@"table"] length]) return theName;
[theName appendFormat:@"/%@", [theEntry objectForKey:@"table"]];
- if (![theEntry objectForKey:@"contentFilter"]) return theName;
- NSDictionary *filterSettings = [theEntry objectForKey:@"contentFilter"];
- if (![filterSettings objectForKey:@"filterField"]) return theName;
+ if ([theEntry objectForKey:@"contentFilter"]) {
+ NSDictionary *filterSettings = [theEntry objectForKey:@"contentFilter"];
+ if ([filterSettings objectForKey:@"filterField"]) {
+ if([filterSettings objectForKey:@"menuLabel"]) {
+ theName = [NSString stringWithFormat:NSLocalizedString(@"%@ (Filtered by %@)", @"History item filtered by values label"),
+ theName, [filterSettings objectForKey:@"menuLabel"]];
+ }
+ }
+ }
- if([filterSettings objectForKey:@"menuLabel"])
- return [NSString stringWithFormat:NSLocalizedString(@"%@ (Filtered by %@)", @"History item filtered by values label"),
- theName, [filterSettings objectForKey:@"menuLabel"]];
+ if ([theEntry objectForKey:@"contentPageNumber"]) {
+ NSUInteger pageNumber = [[theEntry objectForKey:@"contentPageNumber"] unsignedIntValue];
+ if (pageNumber > 1) {
+ theName = [NSString stringWithFormat:NSLocalizedString(@"%@ (Page %i)", @"History item with page number label"),
+ theName, pageNumber];
+ }
+ }
return theName;
}
diff --git a/Source/TableContent.h b/Source/TableContent.h
index d0cc0ec3..e3a9bd50 100644
--- a/Source/TableContent.h
+++ b/Source/TableContent.h
@@ -56,9 +56,19 @@
IBOutlet id firstBetweenField;
IBOutlet id secondBetweenField;
IBOutlet id betweenTextField;
+
+ IBOutlet NSButton *paginationPreviousButton;
+ IBOutlet NSButton *paginationButton;
+ IBOutlet NSButton *paginationNextButton;
+ IBOutlet NSView *contentViewPane;
+ IBOutlet NSView *paginationView;
+ IBOutlet NSTextField *paginationPageField;
+ IBOutlet NSStepper *paginationPageStepper;
MCPConnection *mySQLConnection;
-
+
+ BOOL _mainNibLoaded;
+
NSString *selectedTable, *usedQuery;
NSMutableArray *tableValues, *dataColumns, *keys, *oldRow;
NSUInteger tableRowsCount, previousTableRowsCount;
@@ -73,14 +83,17 @@
NSMutableDictionary *numberOfDefaultFilters;
NSUInteger lastSelectedContentFilterIndex;
id contentFilterManager;
+ NSUInteger contentPage;
BOOL sortColumnToRestoreIsAsc;
BOOL tableRowsSelectable;
NSString *sortColumnToRestore;
- unsigned int limitStartPositionToRestore;
+ unsigned int pageToRestore;
NSIndexSet *selectionIndexToRestore;
NSRect selectionViewportToRestore;
NSString *filterFieldToRestore, *filterComparisonToRestore, *filterValueToRestore, *firstBetweenValueToRestore, *secondBetweenValueToRestore;
+
+ int paginationViewHeight;
}
// Table loading methods and information
@@ -98,6 +111,12 @@
- (NSString *) usedQuery;
- (void) setUsedQuery:(NSString *)query;
+// Pagination
+- (IBAction) navigatePaginationFromButton:(id)sender;
+- (IBAction) togglePagination:(id)sender;
+- (void) setPaginationViewVisibility:(BOOL)makeVisible;
+- (void) updatePaginationState;
+
// Edit methods
- (IBAction)addRow:(id)sender;
- (IBAction)copyRow:(id)sender;
@@ -115,7 +134,6 @@
- (void)setConnection:(MCPConnection *)theConnection;
- (void)clickLinkArrow:(SPTextAndLinkCell *)theArrowCell;
- (IBAction)setCompareTypes:(id)sender;
-- (IBAction)stepLimitRows:(id)sender;
- (void)processResultIntoDataStorage:(MCPStreamingResult *)theResult approximateRowCount:(long)targetRowCount;
- (BOOL)addRowToDB;
- (NSString *)argumentForRow:(int)row;
@@ -130,12 +148,12 @@
// Retrieving and setting table state
- (NSString *) sortColumnName;
- (BOOL) sortColumnIsAscending;
-- (unsigned int) limitStart;
+- (unsigned int) pageNumber;
- (NSIndexSet *) selectedRowIndexes;
- (NSRect) viewport;
- (NSDictionary *) filterSettings;
- (void) setSortColumnNameToRestore:(NSString *)theSortColumnName isAscending:(BOOL)isAscending;
-- (void) setLimitStartToRestore:(unsigned int)theLimitStart;
+- (void) setPageToRestore:(unsigned int)thePage;
- (void) setSelectedRowIndexesToRestore:(NSIndexSet *)theIndexSet;
- (void) setViewportToRestore:(NSRect)theViewport;
- (void) setFiltersToRestore:(NSDictionary *)filterSettings;
diff --git a/Source/TableContent.m b/Source/TableContent.m
index 9d5268c8..d3988cef 100644
--- a/Source/TableContent.m
+++ b/Source/TableContent.m
@@ -58,7 +58,8 @@
- (id)init
{
if ((self == [super init])) {
-
+ _mainNibLoaded = NO;
+
tableValues = [[NSMutableArray alloc] init];
tableRowsCount = 0;
previousTableRowsCount = 0;
@@ -71,10 +72,11 @@
keys = nil;
currentlyEditingRow = -1;
+ contentPage = 1;
sortColumnToRestore = nil;
sortColumnToRestoreIsAsc = YES;
- limitStartPositionToRestore = 1;
+ pageToRestore = 1;
selectionIndexToRestore = nil;
selectionViewportToRestore = NSZeroRect;
filterFieldToRestore = nil;
@@ -125,8 +127,24 @@
*/
- (void)awakeFromNib
{
+ if (_mainNibLoaded) return;
+ _mainNibLoaded = YES;
+
// Set the table content view's vertical gridlines if required
[tableContentView setGridStyleMask:([prefs boolForKey:SPDisplayTableViewVerticalGridlines]) ? NSTableViewSolidVerticalGridLineMask : NSTableViewGridNone];
+
+ // Add the pagination view to the content area with ourselves as the owner
+ if (![NSBundle loadNibNamed:@"ContentPaginationView" owner:self]) {
+ NSLog(@"Content pagination nib could not be loaded; pagination will not function correctly.");
+ }
+ NSRect paginationViewFrame = [paginationView frame];
+ NSRect paginationButtonFrame = [paginationButton frame];
+ paginationViewHeight = paginationViewFrame.size.height;
+ paginationViewFrame.origin.x = paginationButtonFrame.origin.x + paginationButtonFrame.size.width - paginationViewFrame.size.width;
+ paginationViewFrame.origin.y = paginationButtonFrame.origin.y + paginationButtonFrame.size.height - 2;
+ paginationViewFrame.size.height = 0;
+ [paginationView setFrame:paginationViewFrame];
+ [contentViewPane addSubview:paginationView];
// Add observers for document task activity
[[NSNotificationCenter defaultCenter] addObserver:self
@@ -154,6 +172,7 @@
NSDictionary *columnDefinition;
NSTableColumn *theCol;
BOOL enableInteraction = ![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT] || ![tableDocumentInstance isWorking];
+ [self performSelectorOnMainThread:@selector(setPaginationViewVisibility:) withObject:nil waitUntilDone:NO];
// Abort the reload if the user is still editing a row
if ( isEditingRow )
@@ -168,6 +187,8 @@
} else {
selectedTable = aTable;
previousTableRowsCount = 0;
+ contentPage = 1;
+ [paginationPageField setStringValue:@"1"];
// Clear the selection
[tableContentView deselectAll:self];
@@ -227,11 +248,11 @@
[secondBetweenField setHidden:YES];
[betweenTextField setHidden:YES];
- // Empty and disable the limit field
- [limitRowsField setStringValue:@""];
- [limitRowsField setEnabled:NO];
- [limitRowsButton setEnabled:NO];
- [limitRowsStepper setEnabled:NO];
+ // Disable pagination
+ [paginationPreviousButton setEnabled:NO];
+ [paginationButton setEnabled:NO];
+ [paginationButton setTitle:@""];
+ [paginationNextButton setEnabled:NO];
// Disable table action buttons
[addButton setEnabled:NO];
@@ -409,27 +430,12 @@
}
}
+ // Restore page number if limiting is set
+ if ([prefs boolForKey:SPLimitResults]) contentPage = pageToRestore;
+
// Restore first responder
[tableWindow performSelectorOnMainThread:@selector(makeFirstResponder:) withObject:currentFirstResponder waitUntilDone:NO];
- // Enable or disable the limit fields according to preference setting
- if ( [prefs boolForKey:SPLimitResults] ) {
-
- // Preserve the limit field - if this is beyond the current number of rows,
- // reloadData will reset as necessary.
- if (limitStartPositionToRestore < 1) limitStartPositionToRestore = 1;
- [limitRowsField setStringValue:[NSString stringWithFormat:@"%u", limitStartPositionToRestore]];
-
- [limitRowsField setEnabled:YES];
- [limitRowsButton setEnabled:YES];
- [limitRowsStepper setEnabled:YES];
- } else {
- [limitRowsField setEnabled:NO];
- [limitRowsButton setEnabled:NO];
- [limitRowsStepper setEnabled:NO];
- [limitRowsField setStringValue:@""];
- }
-
// Set the state of the table buttons
[addButton setEnabled:enableInteraction];
[copyButton setEnabled:NO];
@@ -518,22 +524,23 @@
// Check to see if a limit needs to be applied
if ([prefs boolForKey:SPLimitResults]) {
- // Ensure the limit isn't negative
- if ([limitRowsField intValue] <= 0) {
- [limitRowsField setStringValue:@"1"];
- }
+ // Ensure the page supplied is within the appropriate limits
+ if (contentPage <= 0)
+ contentPage = 1;
+ else if (contentPage > 1 && (contentPage - 1) * [prefs integerForKey:SPLimitResultsValue] >= maxNumRows)
+ contentPage = ceil((float)maxNumRows / [prefs floatForKey:SPLimitResultsValue]);
- // If the result set is being limited, take a copy of the string to allow resetting limit
+ // If the result set is from a late page, take a copy of the string to allow resetting limit
// if no results are found
- if ([limitRowsField intValue] > 1) {
+ if (contentPage > 1) {
queryStringBeforeLimit = [NSString stringWithString:queryString];
}
// Append the limit settings
- [queryString appendFormat:@" LIMIT %d,%d", [limitRowsField intValue]-1, [prefs integerForKey:SPLimitResultsValue]];
+ [queryString appendFormat:@" LIMIT %d,%d", (contentPage-1)*[prefs integerForKey:SPLimitResultsValue], [prefs integerForKey:SPLimitResultsValue]];
// Update the approximate count of the rows to load
- rowsToLoad = rowsToLoad - ([limitRowsField intValue]-1);
+ rowsToLoad = rowsToLoad - (contentPage-1)*[prefs integerForKey:SPLimitResultsValue];
if (rowsToLoad > [prefs integerForKey:SPLimitResultsValue]) rowsToLoad = [prefs integerForKey:SPLimitResultsValue];
}
@@ -547,9 +554,9 @@
[self processResultIntoDataStorage:streamingResult approximateRowCount:rowsToLoad];
[streamingResult release];
- // If the result is empty, and a limit is active, reset the limit
+ // If the result is empty, and a late page is selected, reset the page
if ([prefs boolForKey:SPLimitResults] && queryStringBeforeLimit && !tableRowsCount && ![mySQLConnection queryCancelled]) {
- [limitRowsField setStringValue:@"1"];
+ contentPage = 1;
queryString = [NSMutableString stringWithFormat:@"%@ LIMIT 0,%d", queryStringBeforeLimit, [prefs integerForKey:SPLimitResultsValue]];
[self setUsedQuery:queryString];
streamingResult = [mySQLConnection streamingQueryString:queryString];
@@ -566,7 +573,7 @@
[tableDocumentInstance disableTaskCancellation];
if ([prefs boolForKey:SPLimitResults]
- && ([limitRowsField intValue] > 1
+ && (contentPage > 1
|| tableRowsCount == [prefs integerForKey:SPLimitResultsValue]))
{
isLimited = YES;
@@ -579,7 +586,10 @@
// Set the filter text
[self updateCountText];
-
+
+ // Update pagination
+ [self updatePaginationState];
+
// Notify listenters that the query has finished
[[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryHasBeenPerformed" object:tableDocumentInstance];
}
@@ -836,35 +846,43 @@
{
NSString *rowString;
NSMutableString *countString = [NSMutableString string];
+ NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
+ [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
+
+ // Set up a couple of common strings
+ NSString *tableCountString = [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:tableRowsCount]];
+ NSString *maxRowsString = [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:maxNumRows]];
// If the result is partial due to an error or query cancellation, show a very basic count
if (isInterruptedLoad) {
if (tableRowsCount == 1)
- [countString appendFormat:NSLocalizedString(@"%d row in partial load", @"text showing a single row a partially loaded result"), tableRowsCount];
+ [countString appendFormat:NSLocalizedString(@"%@ row in partial load", @"text showing a single row a partially loaded result"), tableCountString];
else
- [countString appendFormat:NSLocalizedString(@"%d rows in partial load", @"text showing how many rows are in a partially loaded result"), tableRowsCount];
+ [countString appendFormat:NSLocalizedString(@"%@ rows in partial load", @"text showing how many rows are in a partially loaded result"), tableCountString];
// If no filter or limit is active, show just the count of rows in the table
} else if (!isFiltered && !isLimited) {
if (tableRowsCount == 1)
- [countString appendFormat:NSLocalizedString(@"%d row in table", @"text showing a single row in the result"), tableRowsCount];
+ [countString appendFormat:NSLocalizedString(@"%@ row in table", @"text showing a single row in the result"), tableCountString];
else
- [countString appendFormat:NSLocalizedString(@"%d rows in table", @"text showing how many rows are in the result"), tableRowsCount];
+ [countString appendFormat:NSLocalizedString(@"%@ rows in table", @"text showing how many rows are in the result"), tableCountString];
// If a limit is active, display a string suggesting a limit is active
} else if (!isFiltered && isLimited) {
- [countString appendFormat:NSLocalizedString(@"Rows %d-%d of %@%d from table", @"text showing how many rows are in the limited result"), [limitRowsField intValue], [limitRowsField intValue]+tableRowsCount-1, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ NSUInteger limitStart = (contentPage-1)*[prefs integerForKey:SPLimitResultsValue] + 1;
+ [countString appendFormat:NSLocalizedString(@"Rows %@ - %@ of %@%@ from table", @"text showing how many rows are in the limited result"), [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:limitStart]], [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:(limitStart+tableRowsCount-1)]], maxNumRowsIsEstimate?@"~":@"", maxRowsString];
// If just a filter is active, show a count and an indication a filter is active
} else if (isFiltered && !isLimited) {
if (tableRowsCount == 1)
- [countString appendFormat:NSLocalizedString(@"%d row of %@%d matches filter", @"text showing how a single rows matched filter"), tableRowsCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ [countString appendFormat:NSLocalizedString(@"%@ row of %@%@ matches filter", @"text showing how a single rows matched filter"), tableCountString, maxNumRowsIsEstimate?@"~":@"", maxRowsString];
else
- [countString appendFormat:NSLocalizedString(@"%d rows of %@%d match filter", @"text showing how many rows matched filter"), tableRowsCount, maxNumRowsIsEstimate?@"~":@"", maxNumRows];
+ [countString appendFormat:NSLocalizedString(@"%@ rows of %@%@ match filter", @"text showing how many rows matched filter"), tableCountString, maxNumRowsIsEstimate?@"~":@"", maxRowsString];
// If both a filter and limit is active, display full string
} else {
- [countString appendFormat:NSLocalizedString(@"Rows %d-%d from filtered matches", @"text showing how many rows are in the limited filter match"), [limitRowsField intValue], [limitRowsField intValue]+tableRowsCount-1];
+ NSUInteger limitStart = (contentPage-1)*[prefs integerForKey:SPLimitResultsValue] + 1;
+ [countString appendFormat:NSLocalizedString(@"Rows %@ - %@ from filtered matches", @"text showing how many rows are in the limited filter match"), [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:limitStart]], [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:(limitStart+tableRowsCount-1)]]];
}
// If rows are selected, append selection count
@@ -874,7 +892,7 @@
rowString = [NSString stringWithString:NSLocalizedString(@"row", @"singular word for row")];
else
rowString = [NSString stringWithString:NSLocalizedString(@"rows", @"plural word for rows")];
- [countString appendFormat:NSLocalizedString(@"%d %@ selected", @"text showing how many rows are selected"), [tableContentView numberOfSelectedRows], rowString];
+ [countString appendFormat:NSLocalizedString(@"%@ %@ selected", @"text showing how many rows are selected"), [numberFormatter stringFromNumber:[NSNumber numberWithInteger:[tableContentView numberOfSelectedRows]]], rowString];
}
[countText setStringValue:countString];
@@ -927,6 +945,7 @@
- (IBAction)filterTable:(id)sender
{
if ([tableDocumentInstance isWorking]) return;
+ [self setPaginationViewVisibility:FALSE];
[tableDocumentInstance startTaskWithDescription:NSLocalizedString(@"Filtering table...", @"Filtering table task description")];
if ([NSThread isMainThread]) {
[NSThread detachNewThreadSelector:@selector(filterTableTask) toTarget:self withObject:nil];
@@ -944,16 +963,13 @@
// Update history
[spHistoryControllerInstance updateHistoryEntries];
- // Update negative limits
- if ([limitRowsField intValue] <= 0) {
- [limitRowsField setStringValue:@"1"];
- }
-
- // If limitRowsField > number of total table rows show the last limitRowsValue rows
- if ([prefs boolForKey:SPLimitResults] && [limitRowsField intValue] >= maxNumRows) {
- NSUInteger newLimit = maxNumRows - [prefs integerForKey:SPLimitResultsValue];
- [limitRowsField setStringValue:[[NSNumber numberWithInt:(newLimit<1)?1:newLimit] stringValue]];
- }
+ // Select the correct pagination value
+ if (![prefs boolForKey:SPLimitResults] || [paginationPageField integerValue] <= 0)
+ contentPage = 1;
+ else if (([paginationPageField integerValue] - 1) * [prefs integerForKey:SPLimitResultsValue] >= maxNumRows)
+ contentPage = ceil((float)maxNumRows / [prefs floatForKey:SPLimitResultsValue]);
+ else
+ contentPage = [paginationPageField integerValue];
// Reset and reload data using the new filter settings
previousTableRowsCount = 0;
@@ -1032,6 +1048,111 @@
}
#pragma mark -
+#pragma mark Pagination
+
+/**
+ * Move the pagination backwards or forwards one page
+ */
+- (IBAction) navigatePaginationFromButton:(id)sender
+{
+ if (sender == paginationPreviousButton) {
+ if (contentPage <= 1) return;
+ [paginationPageField setIntValue:(contentPage - 1)];
+ [self filterTable:sender];
+ } else if (sender == paginationNextButton) {
+ if (contentPage * [prefs integerForKey:SPLimitResultsValue] >= maxNumRows) return;
+ [paginationPageField setIntValue:(contentPage + 1)];
+ [self filterTable:sender];
+ }
+}
+
+/**
+ * When the Pagination button is pressed, show or hide the pagination
+ * layer depending on the current state.
+ */
+- (IBAction) togglePagination:(id)sender
+{
+ if ([sender state] == NSOnState) [self setPaginationViewVisibility:YES];
+ else [self setPaginationViewVisibility:NO];
+}
+
+/**
+ * Show or hide the pagination layer, also changing the first responder as appropriate.
+ */
+- (void) setPaginationViewVisibility:(BOOL)makeVisible
+{
+ NSRect paginationViewFrame = [paginationView frame];
+
+ if (makeVisible) {
+ if (paginationViewFrame.size.height == paginationViewHeight) return;
+ paginationViewFrame.size.height = paginationViewHeight;
+ [paginationButton setState:NSOnState];
+ [tableWindow makeFirstResponder:paginationPageField];
+ } else {
+ if (paginationViewFrame.size.height == 0) return;
+ paginationViewFrame.size.height = 0;
+ [paginationButton setState:NSOffState];
+ if ([tableWindow firstResponder] == paginationPageField
+ || ([[tableWindow firstResponder] respondsToSelector:@selector(superview)]
+ && [(id)[tableWindow firstResponder] superview]
+ && [[(id)[tableWindow firstResponder] superview] respondsToSelector:@selector(superview)]
+ && [[(id)[tableWindow firstResponder] superview] superview] == paginationPageField))
+ {
+ [tableWindow makeFirstResponder:nil];
+ }
+ }
+
+ [[paginationView animator] setFrame:paginationViewFrame];
+}
+
+/**
+ * Update the state of the pagination buttons and text.
+ */
+- (void) updatePaginationState
+{
+ NSUInteger maxPage = ceil((float)maxNumRows / [prefs floatForKey:SPLimitResultsValue]);
+ if (isFiltered && isLimited && tableRowsCount < [prefs integerForKey:SPLimitResultsValue]) {
+ maxPage = contentPage;
+ }
+ BOOL enabledMode = ![tableDocumentInstance isWorking];
+
+ NSNumberFormatter *numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];
+ [numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
+
+ // Set up the previous page button
+ if ([prefs boolForKey:SPLimitResults] && contentPage > 1)
+ [paginationPreviousButton setEnabled:enabledMode];
+ else
+ [paginationPreviousButton setEnabled:NO];
+
+ // Set up the next page button
+ if ([prefs boolForKey:SPLimitResults] && contentPage < maxPage)
+ [paginationNextButton setEnabled:enabledMode];
+ else
+ [paginationNextButton setEnabled:NO];
+
+ // As long as a table is selected (which it will be if this is called), enable pagination detail button
+ [paginationButton setEnabled:enabledMode];
+
+ // Update the pagination button text
+ if ([prefs boolForKey:SPLimitResults]) {
+ if (isFiltered) {
+ [paginationButton setTitle:[NSString stringWithFormat:NSLocalizedString(@"Page %@", @"Filtered pagination button status text"), [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:contentPage]]]];
+ } else {
+ [paginationButton setTitle:[NSString stringWithFormat:NSLocalizedString(@"Page %@ of %@", @"Pagination button status text"), [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:contentPage]], [numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:maxPage]]]];
+ }
+ } else {
+ [paginationButton setTitle:NSLocalizedString(@"Pagination disabled", @"Pagination text shown when LIMIT is off")];
+ }
+
+ // Set the values and maximums for the text field and associated pager
+ [paginationPageField setStringValue:[numberFormatter stringFromNumber:[NSNumber numberWithUnsignedInteger:contentPage]]];
+ [[paginationPageField formatter] setMaximum:[NSNumber numberWithUnsignedInteger:maxPage]];
+ [paginationPageStepper setIntValue:contentPage];
+ [paginationPageStepper setMaxValue:maxPage];
+}
+
+#pragma mark -
#pragma mark Edit methods
/*
@@ -1281,12 +1402,6 @@
mySQLConnection = theConnection;
[tableContentView setVerticalMotionCanBeginDrag:NO];
-
- [limitRowsStepper setEnabled:NO];
-
- if ( ![prefs boolForKey:SPLimitResults] ) {
- [limitRowsField setStringValue:@""];
- }
}
/**
@@ -1491,25 +1606,6 @@
contextInfo:nil];
}
-- (IBAction)stepLimitRows:(id)sender
-/*
- steps the start row up or down (+/- limitRowsValue)
- */
-{
- if ( [limitRowsStepper intValue] > 0 ) {
- NSInteger newStep = [limitRowsField intValue]+[prefs integerForKey:SPLimitResultsValue];
- // if newStep > the total number of rows in the current table retain the old value
- [limitRowsField setIntValue:(newStep>maxNumRows)?[limitRowsField intValue]:newStep];
- } else {
- if ( ([limitRowsField intValue]-[prefs integerForKey:SPLimitResultsValue]) < 1 ) {
- [limitRowsField setIntValue:1];
- } else {
- [limitRowsField setIntValue:[limitRowsField intValue]-[prefs integerForKey:SPLimitResultsValue]];
- }
- }
- [limitRowsStepper setIntValue:0];
-}
-
/*
* Tries to write a new row to the database.
* Returns YES if row is written to database, otherwise NO; also returns YES if no row
@@ -2163,11 +2259,11 @@
}
/**
- * Provide a getter for the LIMIT position
+ * Provide a getter for the page number
*/
-- (unsigned int) limitStart
+- (unsigned int) pageNumber
{
- return [limitRowsField intValue];
+ return contentPage;
}
/**
@@ -2214,11 +2310,11 @@
}
/**
- * Sets the value for the limit start position to use on next table load
+ * Sets the value for the page number to use on next table load
*/
-- (void) setLimitStartToRestore:(unsigned int)theLimitStart
+- (void) setPageToRestore:(unsigned int)thePage
{
- limitStartPositionToRestore = theLimitStart;
+ pageToRestore = thePage;
}
/**
@@ -2284,7 +2380,7 @@
- (void) storeCurrentDetailsForRestoration
{
[self setSortColumnNameToRestore:[self sortColumnName] isAscending:[self sortColumnIsAscending]];
- [self setLimitStartToRestore:[self limitStart]];
+ [self setPageToRestore:[self pageNumber]];
[self setSelectedRowIndexesToRestore:[self selectedRowIndexes]];
[self setViewportToRestore:[self viewport]];
[self setFiltersToRestore:[self filterSettings]];
@@ -2296,7 +2392,7 @@
- (void) clearDetailsToRestore
{
[self setSortColumnNameToRestore:nil isAscending:YES];
- [self setLimitStartToRestore:1];
+ [self setPageToRestore:1];
[self setSelectedRowIndexesToRestore:nil];
[self setViewportToRestore:NSZeroRect];
[self setFiltersToRestore:nil];
@@ -2352,9 +2448,9 @@
if (checkStatusCount) {
NSInteger foundMaxRows;
if ([prefs boolForKey:SPLimitResults]) {
- foundMaxRows = [limitRowsField intValue] - 1 + tableRowsCount;
+ foundMaxRows = ((contentPage - 1) * [prefs integerForKey:SPLimitResultsValue]) + tableRowsCount;
if (foundMaxRows > maxNumRows) {
- if (foundMaxRows == [limitRowsField intValue] - 1 + [prefs integerForKey:SPLimitResultsValue]) {
+ if (tableRowsCount == [prefs integerForKey:SPLimitResultsValue]) {
maxNumRows = foundMaxRows + 1;
maxNumRowsIsEstimate = YES;
} else {
@@ -2439,7 +2535,7 @@
NSUInteger columnIndex = [[aTableColumn identifier] intValue];
if (rowIndex >= tableRowsCount) return @"...";
NSMutableArray *rowData = NSArrayObjectAtIndex(tableValues, rowIndex);
- if (columnIndex >= [rowData count]) return @"...";
+ if (rowData && columnIndex >= [rowData count]) return @"...";
id theValue = NSArrayObjectAtIndex(rowData, columnIndex);
@@ -2471,7 +2567,7 @@
return;
}
NSMutableArray *rowData = NSArrayObjectAtIndex(tableValues, rowIndex);
- if (columnIndex >= [rowData count]) {
+ if (!rowData || columnIndex >= [rowData count]) {
[cell setTextColor:[NSColor lightGrayColor]];
return;
}
@@ -2801,6 +2897,9 @@
[reloadButton setEnabled:NO];
[filterButton setEnabled:NO];
tableRowsSelectable = NO;
+ [paginationPreviousButton setEnabled:NO];
+ [paginationNextButton setEnabled:NO];
+ [paginationButton setEnabled:NO];
}
/**
@@ -2813,12 +2912,15 @@
if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:MAIN_TOOLBAR_TABLE_CONTENT])
return;
- if ( ![[[tableDataInstance statusValues] objectForKey:@"Rows"] isNSNull] && selectedTable && [selectedTable length] && [tableDataInstance tableEncoding]) [addButton setEnabled:YES];
+ if ( ![[[tableDataInstance statusValues] objectForKey:@"Rows"] isNSNull] && selectedTable && [selectedTable length] && [tableDataInstance tableEncoding]) {
+ [addButton setEnabled:YES];
+ [self updatePaginationState];
+ [reloadButton setEnabled:YES];
+ }
if ([tableContentView numberOfSelectedRows] > 0) {
[removeButton setEnabled:YES];
[copyButton setEnabled:YES];
}
- [reloadButton setEnabled:YES];
[filterButton setEnabled:[fieldField isEnabled]];
tableRowsSelectable = YES;
}
diff --git a/Source/TableDocument.m b/Source/TableDocument.m
index d35e4684..53d4474a 100644
--- a/Source/TableDocument.m
+++ b/Source/TableDocument.m
@@ -551,8 +551,8 @@
// Set table content details for restore
if([spfSession objectForKey:@"contentSortCol"])
[tableContentInstance setSortColumnNameToRestore:[spfSession objectForKey:@"contentSortCol"] isAscending:[[spfSession objectForKey:@"contentSortCol"] boolValue]];
- if([spfSession objectForKey:@"contentLimitStartPosition"])
- [tableContentInstance setLimitStartToRestore:[[spfSession objectForKey:@"contentLimitStartPosition"] intValue]];
+ if([spfSession objectForKey:@"contentPageNumber"])
+ [tableContentInstance setPageToRestore:[[spfSession objectForKey:@"pageNumber"] intValue]];
if([spfSession objectForKey:@"contentViewport"])
[tableContentInstance setViewportToRestore:NSRectFromString([spfSession objectForKey:@"contentViewport"])];
if([spfSession objectForKey:@"contentFilter"])
@@ -2696,7 +2696,7 @@
[session setObject:[self connectionEncoding] forKey:@"connectionEncoding"];
[session setObject:[NSNumber numberWithBool:[tableContentInstance sortColumnIsAscending]] forKey:@"contentSortColIsAsc"];
- [session setObject:[NSNumber numberWithInt:[tableContentInstance limitStart]] forKey:@"contentLimitStartPosition"];
+ [session setObject:[NSNumber numberWithInt:[tableContentInstance pageNumber]] forKey:@"contentPageNumber"];
[session setObject:NSStringFromRect([tableContentInstance viewport]) forKey:@"contentViewport"];
if([tableContentInstance filterSettings])
[session setObject:[tableContentInstance filterSettings] forKey:@"contentFilter"];