diff options
-rw-r--r-- | Resources/English.lproj/sequel-pro-print-template.html | 57 | ||||
-rw-r--r-- | Resources/sequel-pro-mysql-help-template.html | 61 | ||||
-rw-r--r-- | Source/CustomQuery.m | 4 | ||||
-rw-r--r-- | Source/SPConstants.h | 4 | ||||
-rw-r--r-- | Source/SPConstants.m | 4 | ||||
-rw-r--r-- | Source/SPPrintController.h | 33 | ||||
-rw-r--r-- | Source/SPPrintController.m | 256 | ||||
-rw-r--r-- | Source/SPTableRelations.h | 4 | ||||
-rw-r--r-- | Source/SPTableRelations.m | 44 | ||||
-rw-r--r-- | Source/TableDocument.h | 27 | ||||
-rw-r--r-- | Source/TableDocument.m | 168 | ||||
-rw-r--r-- | Source/TableSource.h | 2 | ||||
-rw-r--r-- | Source/TableSource.m | 56 | ||||
-rw-r--r-- | sequel-pro.xcodeproj/project.pbxproj | 6 |
14 files changed, 488 insertions, 238 deletions
diff --git a/Resources/English.lproj/sequel-pro-print-template.html b/Resources/English.lproj/sequel-pro-print-template.html index 9fe2fe29..6265a3f8 100644 --- a/Resources/English.lproj/sequel-pro-print-template.html +++ b/Resources/English.lproj/sequel-pro-print-template.html @@ -24,14 +24,22 @@ color: #000000; } + h1 { + font-size: 14px; + } + + h2 { + font-size: 11px; + } + table, th, td { border: 0.1em solid #000000; } table { + width: 100%; border-collapse: collapse; border-spacing: 0; - width: 100%; } th, td { @@ -39,8 +47,13 @@ } th { - background-color: #E5E5E5; + text-align: left; font-weight: bold; + background-color: #E5E5E5; + } + + td { + font-family: {{font}}; } tr > td { @@ -54,19 +67,26 @@ tr.odd > td { background-color: #FFFFFF; } + + code { + font-family: Monaco; + } </style> </head> <body> + <h1>{{c.table}}</h1> + <p> - {% if c.table %}<b>Table:</b> {{c.table}}<br>{% /if %} - <b>Connection:</b> {{c.username}}{% if c.username %}@{% /if %}{{c.hostname}}{% if c.port %}:{% /if %}{{c.port}}/{{c.database}}<br> - <b>Generated on:</b> {% now | date_format: "dd MMM yyyy 'at' HH:mm:ss" %} by {{c.version}}<br> - {% if c.query %}<b>SQL query:</b> {{c.query}}{% /if %} - <br> + <strong>Connection:</strong> {{c.username}}{% if c.username %}@{% /if %}{{c.hostname}}{% if c.port %}:{% /if %}{{c.port}}/{{c.database}}<br /> + <strong>Generated on:</strong> {% now | date_format: "dd MMM yyyy 'at' HH:mm:ss" %} by {{c.version}}<br /> + {% if c.query %}<br /><strong>SQL query:</strong> <code>{{c.query}}</code>{% /if %} + <br /> </p> - <table id="table_results" class="data"> + <h2>{{title}}</h2> + + <table class="data"> <thead> <tr> {% for column in columns %}<th>{{ column }}</th>{% /for %} @@ -80,7 +100,26 @@ </tr> {% /for %} </tbody> -</table> + </table><br /> + + {% if indexes %} + <h2>Table Indexes</h2><br /> + + <table class="data"> + <thead> + <tr> + {% for indexColumn in indexColumns %}<th>{{ indexColumn }}</th>{% /for %} + </tr> + </thead> + <tbody> + {% for index in indexes %} + <tr {% cycle 'class="odd" ' 'class="even" ' %}> + {% for cell in index %}<td>{{ cell }}</td>{% /for %} + </tr> + {% /for %} + </tbody> + </table> + {% /if %} </body> </html> diff --git a/Resources/sequel-pro-mysql-help-template.html b/Resources/sequel-pro-mysql-help-template.html index 13f14e3d..214c2623 100644 --- a/Resources/sequel-pro-mysql-help-template.html +++ b/Resources/sequel-pro-mysql-help-template.html @@ -1,34 +1,39 @@ <!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html dir="ltr" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> -<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> -<style type="text/css" media="all"> - body { - margin: 2px; - padding: 10px; - font-family:'Helvetica'; - font-size:9pt; - } - h2 { - } - ul { - } - li { - } - .internallink { - color:#6A81DD; - text-decoration:none; - } - .description { - font-family:Monaco; - } - .example { - font-family:Courier; - } - .header { - padding-bottom:5px; - } -</style> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + + <style type="text/css" media="all"> + body { + margin: 2px; + padding: 10px; + font-family:'Helvetica'; + font-size:9pt; + } + + h2 {} + + ul {} + + li {} + + .internallink { + color: #6A81DD; + text-decoration: none; + } + + .description { + font-family: Monaco; + } + + .example { + font-family: Courier; + } + + .header { + padding-bottom: 5px; + } + </style> </head> <body> %@ diff --git a/Source/CustomQuery.m b/Source/CustomQuery.m index 33285910..370db2bc 100644 --- a/Source/CustomQuery.m +++ b/Source/CustomQuery.m @@ -3077,13 +3077,13 @@ NSError *error; helpHTMLTemplate = [[NSString alloc] - initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"sequel-pro-mysql-help-template" ofType:@"html"] + initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:SPHTMLHelpTemplate ofType:@"html"] encoding:NSUTF8StringEncoding error:&error]; // an error occurred while reading if (helpHTMLTemplate == nil) { - NSLog(@"%@", [NSString stringWithFormat:@"Error reading “sequel-pro-mysql-help-template.html”!<br>%@", [error localizedFailureReason]]); + NSLog(@"%@", [NSString stringWithFormat:@"Error reading “%@.html”!<br>%@", SPHTMLHelpTemplate, [error localizedFailureReason]]); NSBeep(); } diff --git a/Source/SPConstants.h b/Source/SPConstants.h index fd20509b..c8342a5f 100644 --- a/Source/SPConstants.h +++ b/Source/SPConstants.h @@ -71,6 +71,10 @@ extern NSString *SPQueryFavortiesPasteboardDragType; extern NSString *SPFileExtensionDefault; extern NSString *SPFileExtensionSQL; +// Filenames +extern NSString *SPHTMLPrintTemplate; +extern NSString *SPHTMLHelpTemplate; + // Preference key constants // General Prefpane diff --git a/Source/SPConstants.m b/Source/SPConstants.m index 23f1278f..a395e11a 100644 --- a/Source/SPConstants.m +++ b/Source/SPConstants.m @@ -40,6 +40,10 @@ NSString *SPContentFilterPasteboardDragType = @"SPContentFilterPasteboard"; NSString *SPFileExtensionDefault = @"spf"; NSString *SPFileExtensionSQL = @"sql"; +// Filenames +NSString *SPHTMLPrintTemplate = @"sequel-pro-print-template"; +NSString *SPHTMLHelpTemplate = @"sequel-pro-mysql-help-template"; + // Preference key constants // General Prefpane NSString *SPDefaultFavorite = @"DefaultFavorite"; diff --git a/Source/SPPrintController.h b/Source/SPPrintController.h new file mode 100644 index 00000000..8fd1acf8 --- /dev/null +++ b/Source/SPPrintController.h @@ -0,0 +1,33 @@ +// +// $Id$ +// +// SPPrintController.h +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on March 11, 2010 +// Copyright (c) 2010 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 "TableDocument.h" + +@interface TableDocument (SPPrintController) + +- (NSString *)generateHTMLforPrinting; +- (NSArray *)columnNames; + +@end diff --git a/Source/SPPrintController.m b/Source/SPPrintController.m new file mode 100644 index 00000000..718a203b --- /dev/null +++ b/Source/SPPrintController.m @@ -0,0 +1,256 @@ +// +// $Id$ +// +// SPPrintController.m +// sequel-pro +// +// Created by Stuart Connolly (stuconnolly.com) on March 11, 2010 +// Copyright (c) 2010 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 "SPPrintController.h" +#import "TableContent.h" +#import "TableSource.h" +#import "CustomQuery.h" +#import "SPConstants.h" +#import "SPTableRelations.h" +#import "SPPrintAccessory.h" +#import "MGTemplateEngine.h" +#import "ICUTemplateMatcher.h" +#import "SPConnectionController.h" + +@implementation TableDocument (SPPrintController) + +/** + * WebView delegate method. + */ +- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame +{ + // Because we need the webFrame loaded (for preview), we've moved the actual printing here + NSPrintInfo *printInfo = [self printInfo]; + + [printInfo setHorizontalPagination:NSFitPagination]; + [printInfo setVerticalPagination:NSAutoPagination]; + [printInfo setVerticallyCentered:NO]; + [printInfo setTopMargin:30]; + [printInfo setBottomMargin:30]; + [printInfo setLeftMargin:10]; + [printInfo setRightMargin:10]; + + NSPrintOperation *op = [NSPrintOperation printOperationWithView:[[[printWebView mainFrame] frameView] documentView] printInfo:printInfo]; + + // Add the ability to select the orientation to print panel + NSPrintPanel *printPanel = [op printPanel]; + + [printPanel setOptions:[printPanel options] + NSPrintPanelShowsOrientation + NSPrintPanelShowsScaling + NSPrintPanelShowsPaperSize]; + + SPPrintAccessory *printAccessory = [[SPPrintAccessory alloc] initWithNibName:@"PrintAccessory" bundle:nil]; + + [printAccessory setPrintView:printWebView]; + [printPanel addAccessoryController:printAccessory]; + + [[NSPageLayout pageLayout] addAccessoryController:printAccessory]; + [printAccessory release]; + + [op setPrintPanel:printPanel]; + + [op runOperationModalForWindow:tableWindow + delegate:self + didRunSelector:nil + contextInfo:nil]; + +} + +/** + * Loads the print document interface. The actual printing is done in the doneLoading delegate. + */ +- (IBAction)printDocument:(id)sender +{ + [[printWebView mainFrame] loadHTMLString:[self generateHTMLforPrinting] baseURL:nil]; +} + + +/** + * Generates the HTML for the current view that is being printed. + */ +- (NSString *)generateHTMLforPrinting +{ + // Set up template engine with your chosen matcher + MGTemplateEngine *engine = [MGTemplateEngine templateEngine]; + + [engine setMatcher:[ICUTemplateMatcher matcherWithTemplateEngine:engine]]; + + NSString *versionForPrint = [NSString stringWithFormat:@"%@ %@ (build %@)", + [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"], + [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], + [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] + ]; + + NSMutableDictionary *connection = [[NSMutableDictionary alloc] init]; + + if ([[self user] length]) { + [connection setValue:[self user] forKey:@"username"]; + } + + if ([[self table] length]) { + [connection setValue:[self table] forKey:@"table"]; + } + + + if ([connectionController port] && [[connectionController port] length]) { + [connection setValue:[connectionController port] forKey:@"port"]; + } + + [connection setValue:[self host] forKey:@"hostname"]; + [connection setValue:selectedDatabase forKey:@"database"]; + [connection setValue:versionForPrint forKey:@"version"]; + + NSString *title = @""; + NSArray *rows, *indexes, *indexColumns = nil; + NSArray *columns = [self columnNames]; + + NSMutableDictionary *printData = [NSMutableDictionary dictionary]; + + // Table source view + if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 0) { + + NSDictionary *tableSource = [tableSourceInstance tableSourceForPrinting]; + + if ([[tableSource objectForKey:@"structure"] count] > 1) { + + title = @"Table Structure"; + + rows = [[NSArray alloc] initWithArray: + [[tableSource objectForKey:@"structure"] objectsAtIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[tableSource objectForKey:@"structure"] count] - 1)] + ] + ]; + + indexes = [[NSArray alloc] initWithArray: + [[tableSource objectForKey:@"indexes"] objectsAtIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[tableSource objectForKey:@"indexes"] count] - 1)] + ] + ]; + + indexColumns = [[tableSource objectForKey:@"indexes"] objectAtIndex:0]; + + [printData setObject:indexes forKey:@"indexes"]; + [printData setObject:indexColumns forKey:@"indexColumns"]; + } + } + // Table content view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 1) { + if ([[tableContentInstance currentResult] count] > 1) { + + title = @"Table Content"; + + rows = [[NSArray alloc] initWithArray: + [[tableContentInstance currentDataResult] objectsAtIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[tableContentInstance currentResult] count] - 1)] + ] + ]; + + [connection setValue:[tableContentInstance usedQuery] forKey:@"query"]; + } + } + // Custom query view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 2) { + if ([[customQueryInstance currentResult] count] > 1) { + + title = @"Query Result"; + + rows = [[NSArray alloc] initWithArray: + [[customQueryInstance currentResult] objectsAtIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[customQueryInstance currentResult] count] - 1)] + ] + ]; + + [connection setValue:[customQueryInstance usedQuery] forKey:@"query"]; + } + } + // Table relations view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 4) { + if ([[tableRelationsInstance relationDataForPrinting] count] > 1) { + + title = @"Table Relations"; + + NSArray *data = [tableRelationsInstance relationDataForPrinting]; + + rows = [[NSArray alloc] initWithArray: + [data objectsAtIndexes: + [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, ([data count] - 1))] + ] + ]; + } + } + + [engine setObject:connection forKey:@"c"]; + + [printData setObject:title forKey:@"title"]; + [printData setObject:columns forKey:@"columns"]; + [printData setObject:rows forKey:@"rows"]; + [printData setObject:([prefs boolForKey:SPUseMonospacedFonts]) ? SPDefaultMonospacedFontName : @"Lucida Grande" forKey:@"font"]; + + [connection release]; + + if (rows) [rows release]; + + // Process the template and display the results. + NSString *result = [engine processTemplateInFileAtPath:[[NSBundle mainBundle] pathForResource:SPHTMLPrintTemplate ofType:@"html"] withVariables:printData]; + + return result; +} + +/** + * Returns an array of columns for whichever view is being printed. + */ +- (NSArray *)columnNames +{ + NSArray *columns = nil; + + // Table source view + if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 0 + && [[tableSourceInstance tableSourceForPrinting] count] > 0 ) { + + columns = [[NSArray alloc] initWithArray:[[[tableSourceInstance tableSourceForPrinting] objectForKey:@"structure"] objectAtIndex:0] copyItems:YES]; + } + // Table content view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 1 + && [[tableContentInstance currentResult] count] > 0 ) { + + columns = [[NSArray alloc] initWithArray:[[tableContentInstance currentResult] objectAtIndex:0] copyItems:YES]; + } + // Custom query view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 2 + && [[customQueryInstance currentResult] count] > 0 ) { + + columns = [[NSArray alloc] initWithArray:[[customQueryInstance currentResult] objectAtIndex:0] copyItems:YES]; + } + // Table relations view + else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 4 + && [[tableRelationsInstance relationDataForPrinting] count] > 0 ) { + + columns = [[NSArray alloc] initWithArray:[[tableRelationsInstance relationDataForPrinting] objectAtIndex:0] copyItems:YES]; + } + + if (columns) [columns autorelease]; + + return columns; +} + +@end diff --git a/Source/SPTableRelations.h b/Source/SPTableRelations.h index fb32fd12..5b1db7dd 100644 --- a/Source/SPTableRelations.h +++ b/Source/SPTableRelations.h @@ -55,6 +55,7 @@ NSMutableArray *relationData; } +@property (readonly) NSMutableArray *relationData; @property (readwrite, assign) MCPConnection *connection; // IB action methods @@ -70,4 +71,7 @@ - (void)startDocumentTaskForTab:(NSNotification *)aNotification; - (void)endDocumentTaskForTab:(NSNotification *)aNotification; +// Other +- (NSArray *)relationDataForPrinting; + @end diff --git a/Source/SPTableRelations.m b/Source/SPTableRelations.m index 10780fd1..a88da5e7 100644 --- a/Source/SPTableRelations.m +++ b/Source/SPTableRelations.m @@ -41,6 +41,7 @@ @implementation SPTableRelations @synthesize connection; +@synthesize relationData; /** * init @@ -316,8 +317,7 @@ { // Only proceed if this view is selected. - if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) - return; + if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) return; [addRelationButton setEnabled:NO]; [refreshRelationsButton setEnabled:NO]; @@ -331,13 +331,13 @@ { // Only proceed if this view is selected. - if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) - return; + if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableRelations]) return; if ([relationsTableView isEnabled]) { [addRelationButton setEnabled:YES]; [refreshRelationsButton setEnabled:YES]; } + [removeRelationButton setEnabled:([relationsTableView numberOfSelectedRows] > 0)]; } @@ -345,6 +345,42 @@ #pragma mark Other /** + * Returns an array of relation data to be used for printing purposes. The first element in the array is always + * an array of the columns and each subsequent element is an array of relation data. + */ +- (NSArray *)relationDataForPrinting +{ + NSMutableArray *headings = [NSMutableArray array]; + NSMutableArray *tempData = [NSMutableArray array]; + NSMutableArray *data = [NSMutableArray array]; + + // Get the relations table view's columns + for (NSTableColumn *column in [relationsTableView tableColumns]) + { + [headings addObject:[[column headerCell] stringValue]]; + } + + [data addObject:headings]; + + // Get the relation data + for (NSDictionary *relation in relationData) + { + NSMutableArray *temp = [NSMutableArray array]; + + [temp addObject:[relation objectForKey:@"name"]]; + [temp addObject:[relation objectForKey:@"columns"]]; + [temp addObject:[relation objectForKey:@"fk_table"]]; + [temp addObject:[relation objectForKey:@"fk_columns"]]; + [temp addObject:([relation objectForKey:@"on_update"]) ? [relation objectForKey:@"on_update"] : @""]; + [temp addObject:([relation objectForKey:@"on_delete"]) ? [relation objectForKey:@"on_delete"] : @""]; + + [data addObject:temp]; + } + + return data; +} + +/** * NSAlert didEnd method. */ - (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(NSString *)contextInfo diff --git a/Source/TableDocument.h b/Source/TableDocument.h index 4be47ae1..41bd1186 100644 --- a/Source/TableDocument.h +++ b/Source/TableDocument.h @@ -165,8 +165,6 @@ id statusValues; } -- (NSString *)getHTMLforPrint; - - (BOOL)isUntitled; - (void)initQueryEditorWithString:(NSString *)query; @@ -191,18 +189,18 @@ - (NSArray *)allSystemDatabaseNames; // Task progress and notification methods -- (void) startTaskWithDescription:(NSString *)description; -- (void) showTaskProgressWindow:(NSTimer *)theTimer; -- (void) setTaskDescription:(NSString *)description; -- (void) setTaskPercentage:(CGFloat)taskPercentage; -- (void) setTaskProgressToIndeterminateAfterDelay:(BOOL)afterDelay; -- (void) endTask; -- (void) enableTaskCancellationWithTitle:(NSString *)buttonTitle callbackObject:(id)callbackObject callbackFunction:(SEL)callbackFunction; -- (void) disableTaskCancellation; -- (IBAction) cancelTask:(id)sender; -- (BOOL) isWorking; -- (void) setDatabaseListIsSelectable:(BOOL)isSelectable; -- (void) centerTaskWindow; +- (void)startTaskWithDescription:(NSString *)description; +- (void)showTaskProgressWindow:(NSTimer *)theTimer; +- (void)setTaskDescription:(NSString *)description; +- (void)setTaskPercentage:(CGFloat)taskPercentage; +- (void)setTaskProgressToIndeterminateAfterDelay:(BOOL)afterDelay; +- (void)endTask; +- (void)enableTaskCancellationWithTitle:(NSString *)buttonTitle callbackObject:(id)callbackObject callbackFunction:(SEL)callbackFunction; +- (void)disableTaskCancellation; +- (IBAction)cancelTask:(id)sender; +- (BOOL)isWorking; +- (void)setDatabaseListIsSelectable:(BOOL)isSelectable; +- (void)centerTaskWindow; // Encoding methods - (void)setConnectionEncoding:(NSString *)mysqlEncoding reloadingViews:(BOOL)reloadViews; @@ -259,7 +257,6 @@ - (NSString *)user; - (NSString *)displaySPName; - (NSString *)keyChainID; -- (NSArray *)columnNames; // Notification center methods - (void)willPerformQuery:(NSNotification *)notification; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index 249faee9..6d082a59 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -46,7 +46,6 @@ #import "SPConnectionController.h" #import "SPHistoryController.h" #import "SPPreferenceController.h" -#import "SPPrintAccessory.h" #import "SPUserManager.h" #import "SPEncodingPopupAccessory.h" #import "SPConstants.h" @@ -55,10 +54,6 @@ #import "SPServerVariablesController.h" #import "SPAlertSheets.h" -// Printing -#import "MGTemplateEngine.h" -#import "ICUTemplateMatcher.h" - @interface TableDocument (PrivateAPI) - (void)_addDatabase; @@ -775,136 +770,6 @@ } #pragma mark - -#pragma mark Printing - -- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame -{ - // Because I need the webFrame loaded (for preview), I've moved the actuall printing here. - NSPrintInfo *printInfo = [self printInfo]; - [printInfo setHorizontalPagination:NSFitPagination]; - [printInfo setVerticalPagination:NSAutoPagination]; - [printInfo setVerticallyCentered:NO]; - [printInfo setTopMargin:30]; - [printInfo setBottomMargin:30]; - [printInfo setLeftMargin:10]; - [printInfo setRightMargin:10]; - - NSPrintOperation *op = [NSPrintOperation - printOperationWithView:[[[printWebView mainFrame] frameView] documentView] - printInfo:printInfo]; - - //add ability to select orientation to print panel - NSPrintPanel *printPanel = [op printPanel]; - [printPanel setOptions:[printPanel options] + NSPrintPanelShowsOrientation + NSPrintPanelShowsScaling + NSPrintPanelShowsPaperSize]; - - SPPrintAccessory *printAccessory = [[SPPrintAccessory alloc] initWithNibName:@"PrintAccessory" bundle:nil]; - [printAccessory setPrintView:printWebView]; - [printPanel addAccessoryController:printAccessory]; - - NSPageLayout *pageLayout = [NSPageLayout pageLayout]; - [pageLayout addAccessoryController:printAccessory]; - [printAccessory release]; - - [op setPrintPanel:printPanel]; - - [op runOperationModalForWindow:tableWindow - delegate:self - didRunSelector: - @selector(printOperationDidRun:success:contextInfo:) - contextInfo:NULL]; - -} - -- (IBAction)printDocument:(id)sender -{ - // Here load the printing document. The actual printing is done in the doneLoading delegate. - [[printWebView mainFrame] loadHTMLString:[self getHTMLforPrint] baseURL:nil]; -} - -- (void)printOperationDidRun:(NSPrintOperation *)printOperation success:(BOOL)success contextInfo:(void *)info -{ - // Selector for print... maybe we can get rid of this? -} - -- (NSString *)getHTMLforPrint -{ - // Set up template engine with your chosen matcher. - MGTemplateEngine *engine = [MGTemplateEngine templateEngine]; - - [engine setMatcher:[ICUTemplateMatcher matcherWithTemplateEngine:engine]]; - - NSString *versionForPrint = [NSString stringWithFormat:@"%@ %@ (build %@)", - [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"], - [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], - [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] - ]; - - NSMutableDictionary *connection = [[NSMutableDictionary alloc] init]; - - if ([[self user] length]) { - [connection setValue:[self user] forKey:@"username"]; - } - - if ([[self table] length]) { - [connection setValue:[self table] forKey:@"table"]; - } - - [connection setValue:[self host] forKey:@"hostname"]; - - if ([connectionController port] && [[connectionController port] length]) { - [connection setValue:[connectionController port] forKey:@"port"]; - } - - [connection setValue:selectedDatabase forKey:@"database"]; - [connection setValue:versionForPrint forKey:@"version"]; - - NSArray *rows = nil; - NSArray *columns = [self columnNames]; - - if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 0) { - if ([[tableSourceInstance tableStructureForPrint] count] > 1) - rows = [[NSArray alloc] initWithArray: - [[tableSourceInstance tableStructureForPrint] objectsAtIndexes: - [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[tableSourceInstance tableStructureForPrint] count] - 1)] - ] - ]; - } - else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 1) { - if ([[tableContentInstance currentResult] count] > 1) - rows = [[NSArray alloc] initWithArray: - [[tableContentInstance currentDataResult] objectsAtIndexes: - [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[tableContentInstance currentResult] count] - 1)] - ] - ]; - - [connection setValue:[tableContentInstance usedQuery] forKey:@"query"]; - } - else if ([tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 2) { - if ([[customQueryInstance currentResult] count] > 1) - rows = [[NSArray alloc] initWithArray: - [[customQueryInstance currentResult] objectsAtIndexes: - [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(1, [[customQueryInstance currentResult] count] - 1)] - ] - ]; - - [connection setValue:[customQueryInstance usedQuery] forKey:@"query"]; - } - - [engine setObject:connection forKey:@"c"]; - - NSDictionary *printData = [NSDictionary dictionaryWithObjectsAndKeys:columns, @"columns", rows, @"rows", nil]; - - [connection release]; - - if (rows) [rows release]; - - // Process the template and display the results. - NSString *result = [engine processTemplateInFileAtPath:[[NSBundle mainBundle] pathForResource:@"sequel-pro-print-template" ofType:@"html"] withVariables:printData]; - - return result; -} - -#pragma mark - #pragma mark Database methods /** @@ -1845,28 +1710,6 @@ notificationName:@"Syntax Copied"]; } -- (NSArray *)columnNames -{ - NSArray *columns = nil; - if ( [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 0 - && [[tableSourceInstance tableStructureForPrint] count] > 0 ){ - columns = [[NSArray alloc] initWithArray:[[tableSourceInstance tableStructureForPrint] objectAtIndex:0] copyItems:YES]; - } - else if ( [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 1 - && [[tableContentInstance currentResult] count] > 0 ){ - columns = [[NSArray alloc] initWithArray:[[tableContentInstance currentResult] objectAtIndex:0] copyItems:YES]; - } - else if ( [tableTabView indexOfTabViewItem:[tableTabView selectedTabViewItem]] == 2 - && [[customQueryInstance currentResult] count] > 0 ){ - columns = [[NSArray alloc] initWithArray:[[customQueryInstance currentResult] objectAtIndex:0] copyItems:YES]; - } - - if(columns) { - [columns autorelease]; - } - return columns; -} - /** * Performs a MySQL check table on the selected table and presents the result to the user via an alert sheet. */ @@ -3149,13 +2992,10 @@ return ([self database] != nil && [self table] != nil); } - if ([menuItem action] == @selector(printDocument:)) { - return ( - ( - [self database] != nil - && [[tablesListInstance valueForKeyPath:@"tablesListView"] numberOfSelectedRows] == 1 - ) - || [tableWindow firstResponder] == customQueryInstance); + if ([menuItem action] == @selector(printDocument:)) { + return (((([self database] != nil) && + ([[tablesListInstance valueForKeyPath:@"tablesListView"] numberOfSelectedRows] == 1)) || + ([tableWindow firstResponder] == customQueryInstance))); } if ([menuItem action] == @selector(chooseEncoding:)) { diff --git a/Source/TableSource.h b/Source/TableSource.h index 3650ec14..54a0c492 100644 --- a/Source/TableSource.h +++ b/Source/TableSource.h @@ -100,7 +100,7 @@ - (NSString *)defaultValueForField:(NSString *)field; - (NSArray *)fieldNames; - (NSDictionary *)enumFields; -- (NSArray *)tableStructureForPrint; +- (NSDictionary *)tableSourceForPrinting; // Task interaction - (void)startDocumentTaskForTab:(NSNotification *)aNotification; diff --git a/Source/TableSource.m b/Source/TableSource.m index ed624445..05eb0c53 100644 --- a/Source/TableSource.m +++ b/Source/TableSource.m @@ -1115,22 +1115,50 @@ returns a dictionary containing enum/set field names as key and possible values return [NSDictionary dictionaryWithDictionary:enumFields]; } -- (NSArray *)tableStructureForPrint -{ - MCPResult *queryResult; - NSMutableArray *tempResult = [NSMutableArray array]; +/** + * Returns a dictionary describing the source of the table to be used for printing purposes. The object accessible + * via the key 'structure' is an array of the tables fields, where the first element is always the field names + * and each subsequent element is the field data. This is also true for the table's indexes, which are accessible + * via the key 'indexes'. + */ +- (NSDictionary *)tableSourceForPrinting +{ NSInteger i; + NSMutableArray *tempResult = [NSMutableArray array]; + NSMutableArray *tempResult2 = [NSMutableArray array]; + + MCPResult *structureQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; + MCPResult *indexesQueryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW INDEXES FROM %@", [selectedTable backtickQuotedString]]]; + + [structureQueryResult setReturnDataAsStrings:YES]; + [indexesQueryResult setReturnDataAsStrings:YES]; + + if ([structureQueryResult numOfRows]) [structureQueryResult dataSeek:0]; + if ([indexesQueryResult numOfRows]) [indexesQueryResult dataSeek:0]; + + [tempResult addObject:[structureQueryResult fetchFieldNames]]; + + NSMutableArray *temp = [[[indexesQueryResult fetchFieldNames] mutableCopy] autorelease]; - queryResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [selectedTable backtickQuotedString]]]; - [queryResult setReturnDataAsStrings:YES]; + // Remove the 'table' column + [temp removeObjectAtIndex:0]; - if ([queryResult numOfRows]) [queryResult dataSeek:0]; - [tempResult addObject:[queryResult fetchFieldNames]]; - for ( i = 0 ; i < [queryResult numOfRows] ; i++ ) { - [tempResult addObject:[queryResult fetchRowAsArray]]; + [tempResult2 addObject:temp]; + + for (i = 0 ; i < [structureQueryResult numOfRows]; i++) { + [tempResult addObject:[structureQueryResult fetchRowAsArray]]; } - return tempResult; + for (i = 0 ; i < [indexesQueryResult numOfRows]; i++) { + NSMutableArray *index = [[[indexesQueryResult fetchRowAsArray] mutableCopy] autorelease]; + + // Remove the 'table' column values + [index removeObjectAtIndex:0]; + + [tempResult2 addObject:index]; + } + + return [NSDictionary dictionaryWithObjectsAndKeys:tempResult, @"structure", tempResult2, @"indexes", nil]; } #pragma mark - @@ -1143,8 +1171,7 @@ returns a dictionary containing enum/set field names as key and possible values { // Only proceed if this view is selected. - if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure]) - return; + if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure]) return; [tableSourceView setEnabled:NO]; [addFieldButton setEnabled:NO]; @@ -1166,8 +1193,7 @@ returns a dictionary containing enum/set field names as key and possible values { // Only re-enable elements if the current tab is the structure view - if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure]) - return; + if (![[tableDocumentInstance selectedToolbarItemIdentifier] isEqualToString:SPMainToolbarTableStructure]) return; BOOL editingEnabled = ([tablesListInstance tableType] == SP_TABLETYPE_TABLE); [tableSourceView setEnabled:YES]; diff --git a/sequel-pro.xcodeproj/project.pbxproj b/sequel-pro.xcodeproj/project.pbxproj index 5486bf5d..d159d629 100644 --- a/sequel-pro.xcodeproj/project.pbxproj +++ b/sequel-pro.xcodeproj/project.pbxproj @@ -60,6 +60,7 @@ 17CC97F310B4ABE90034CD7A /* SPAboutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17CC97F210B4ABE90034CD7A /* SPAboutController.m */; }; 17CC97F710B4AC6C0034CD7A /* AboutPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17CC97F510B4AC6C0034CD7A /* AboutPanel.xib */; }; 17CC993B10B4C9C80034CD7A /* License.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 17CC993A10B4C9C80034CD7A /* License.rtf */; }; + 17E090E811498FC9007FC1B4 /* SPPrintController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E090E711498FC9007FC1B4 /* SPPrintController.m */; }; 17E641460EF01EB5001BC333 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E641440EF01EB5001BC333 /* main.m */; }; 17E641560EF01EF6001BC333 /* CustomQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E641490EF01EF6001BC333 /* CustomQuery.m */; }; 17E641570EF01EF6001BC333 /* SPAppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17E6414B0EF01EF6001BC333 /* SPAppController.m */; }; @@ -410,6 +411,8 @@ 17CC97F610B4AC6C0034CD7A /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = Interfaces/English.lproj/AboutPanel.xib; sourceTree = "<group>"; }; 17CC993A10B4C9C80034CD7A /* License.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = License.rtf; sourceTree = "<group>"; }; 17DA04EA0FC1A7DA00D66140 /* Unit Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Unit Tests-Info.plist"; sourceTree = "<group>"; }; + 17E090E611498FC9007FC1B4 /* SPPrintController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPPrintController.h; sourceTree = "<group>"; }; + 17E090E711498FC9007FC1B4 /* SPPrintController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SPPrintController.m; sourceTree = "<group>"; }; 17E641440EF01EB5001BC333 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; 17E641450EF01EB5001BC333 /* sequel-pro_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "sequel-pro_Prefix.pch"; sourceTree = "<group>"; }; 17E641480EF01EF6001BC333 /* CustomQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomQuery.h; sourceTree = "<group>"; }; @@ -944,6 +947,8 @@ 1792C28910AE1C7200ABE758 /* Controller Categories */ = { isa = PBXGroup; children = ( + 17E090E611498FC9007FC1B4 /* SPPrintController.h */, + 17E090E711498FC9007FC1B4 /* SPPrintController.m */, 1792C25F10AE1A2D00ABE758 /* SPConnectionDelegate.h */, 1792C26010AE1A2D00ABE758 /* SPConnectionDelegate.m */, ); @@ -1822,6 +1827,7 @@ 584095191107CB6600260CFD /* SPAlertSheets.m in Sources */, 29FA88231114619E00D1AF3D /* SPTableTriggers.m in Sources */, BCE0025D11173D2A009DA533 /* SPFieldMapperController.m in Sources */, + 17E090E811498FC9007FC1B4 /* SPPrintController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; |