aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPAppController.m
diff options
context:
space:
mode:
authorstuconnolly <stuart02@gmail.com>2009-08-08 01:19:48 +0000
committerstuconnolly <stuart02@gmail.com>2009-08-08 01:19:48 +0000
commit313d135b383a3023f1d6e51d7c69368d98733cd1 (patch)
treeae00e7847f99386613d72753b3a23ddf0bfb4537 /Source/SPAppController.m
parent4e86aae1cd84904e40f3cd7dab3c4cc72bab77dc (diff)
downloadsequelpro-313d135b383a3023f1d6e51d7c69368d98733cd1.tar.gz
sequelpro-313d135b383a3023f1d6e51d7c69368d98733cd1.tar.bz2
sequelpro-313d135b383a3023f1d6e51d7c69368d98733cd1.zip
Rename MainController to SPAppController.
Diffstat (limited to 'Source/SPAppController.m')
-rw-r--r--Source/SPAppController.m352
1 files changed, 352 insertions, 0 deletions
diff --git a/Source/SPAppController.m b/Source/SPAppController.m
new file mode 100644
index 00000000..9b0bce1d
--- /dev/null
+++ b/Source/SPAppController.m
@@ -0,0 +1,352 @@
+//
+// $Id$
+//
+// SPAppController.m
+// sequel-pro
+//
+// Created by lorenz textor (lorenz@textor.ch) on Wed May 01 2002.
+// Copyright (c) 2002-2003 Lorenz Textor. 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 "SPKeychain.h"
+#import "SPAppController.h"
+#import "TableDocument.h"
+#import "SPPreferenceController.h"
+
+#import <Sparkle/Sparkle.h>
+
+#define SEQUEL_PRO_HOME_PAGE_URL @"http://www.sequelpro.com/"
+#define SEQUEL_PRO_DONATIONS_URL @"http://www.sequelpro.com/donate.html"
+#define SEQUEL_PRO_FAQ_URL @"http://www.sequelpro.com/frequently-asked-questions.html"
+#define SEQUEL_PRO_DOCS_URL @"http://www.sequelpro.com/docs"
+
+@implementation SPAppController
+
+
+- (id) init
+{
+ if ((self = [super init])) {
+ [NSApp setDelegate: self];
+ }
+
+ return self;
+}
+
+/**
+ * Called if user drag and drops files on Sequel Pro's dock item or double-clicked
+ * at files *.spf or *.sql
+ */
+- (void)application:(NSApplication *)app openFiles:(NSArray *)filenames
+{
+
+ for( NSString* filename in filenames ) {
+
+ // Opens a sql file and insert its content into the Custom Query editor
+ if([[[filename pathExtension] lowercaseString] isEqualToString:@"sql"]) {
+
+ // Check if at least one document exists
+ if (![[[NSDocumentController sharedDocumentController] documents] count]) {
+ // TODO : maybe open a connection first
+ // return;
+ TableDocument *firstTableDocument;
+
+ // Manually open a new document, setting SPAppController as sender to trigger autoconnection
+ if (firstTableDocument = [[NSDocumentController sharedDocumentController] makeUntitledDocumentOfType:@"DocumentType" error:nil]) {
+ [firstTableDocument setShouldAutomaticallyConnect:NO];
+ [firstTableDocument initQueryEditorWithString:[self contentOfFile:filename]];
+ [[NSDocumentController sharedDocumentController] addDocument:firstTableDocument];
+ [firstTableDocument makeWindowControllers];
+ [firstTableDocument showWindows];
+ }
+ } else {
+ // Pass query to the Query editor of the current document
+ [[[NSDocumentController sharedDocumentController] currentDocument] doPerformLoadQueryService:[self contentOfFile:filename]];
+ }
+
+ break; // open only the first SQL file
+
+ }
+ else if([[[filename pathExtension] lowercaseString] isEqualToString:@"spf"]) {
+ NSLog(@"open connection %@", filename);
+ }
+ else {
+ NSLog(@"Only files with the extensions ‘spf’ or ‘sql’ are allowed.");
+ }
+ }
+
+}
+
+/**
+ * Called even before init so we can register our preference defaults
+ */
++ (void)initialize
+{
+ // Register application defaults
+ [[NSUserDefaults standardUserDefaults] registerDefaults:[NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"PreferenceDefaults" ofType:@"plist"]]];
+}
+
+/**
+ * Initialisation stuff upon nib awakening
+ */
+- (void)awakeFromNib
+{
+ // Set Sparkle delegate
+ [[SUUpdater sharedUpdater] setDelegate:self];
+
+ prefsController = [[SPPreferenceController alloc] init];
+
+ // Register SPAppController as services provider
+ [NSApp setServicesProvider:self];
+
+ // Register SPAppController for AppleScript events
+ [[NSScriptExecutionContext sharedScriptExecutionContext] setTopLevelObject:self];
+
+ isNewFavorite = NO;
+}
+
+#pragma mark -
+#pragma mark IBAction methods
+
+/**
+ * Opens the preferences window
+ */
+- (IBAction)openPreferences:(id)sender
+{
+ [prefsController showWindow:self];
+}
+
+#pragma mark -
+#pragma mark Getters
+
+/**
+ * Provide a method to retrieve the prefs controller
+ */
+- (SPPreferenceController *)preferenceController
+{
+ return prefsController;
+}
+
+
+#pragma mark -
+#pragma mark Services menu methods
+
+/**
+ * Passes the query to the last created document
+ */
+- (void)doPerformQueryService:(NSPasteboard *)pboard userData:(NSString *)data error:(NSString **)error
+{
+ NSString *pboardString;
+
+ NSArray *types = [pboard types];
+
+ if ((![types containsObject:NSStringPboardType]) || (!(pboardString = [pboard stringForType:NSStringPboardType]))) {
+ *error = @"Pasteboard couldn't give string.";
+
+ return;
+ }
+
+ // Check if at least one document exists
+ if (![[[NSDocumentController sharedDocumentController] documents] count]) {
+ *error = @"No Documents open!";
+
+ return;
+ }
+
+ // Pass query to last created document
+ [[[[NSDocumentController sharedDocumentController] documents] objectAtIndex:([[[NSDocumentController sharedDocumentController] documents] count] - 1)] doPerformQueryService:pboardString];
+
+ return;
+}
+
+#pragma mark -
+#pragma mark Sequel Pro menu methods
+
+/**
+ * Opens donate link in default browser
+ */
+- (IBAction)donate:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_DONATIONS_URL]];
+}
+
+/**
+ * Opens website link in default browser
+ */
+- (IBAction)visitWebsite:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_HOME_PAGE_URL]];
+}
+
+/**
+ * Opens help link in default browser
+ */
+- (IBAction)visitHelpWebsite:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_DOCS_URL]];
+}
+
+/**
+ * Opens FAQ help link in default browser
+ */
+- (IBAction)visitFAQWebsite:(id)sender
+{
+ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:SEQUEL_PRO_FAQ_URL]];
+}
+
+#pragma mark -
+#pragma mark Other methods
+
+/**
+ * Override the default open-blank-document methods to automatically connect
+ * automatically opened windows.
+ */
+- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender
+{
+ TableDocument *firstTableDocument;
+
+ // Manually open a new document, setting SPAppController as sender to trigger autoconnection
+ if (firstTableDocument = [[NSDocumentController sharedDocumentController] makeUntitledDocumentOfType:@"DocumentType" error:nil]) {
+ if ([[NSUserDefaults standardUserDefaults] boolForKey:@"AutoConnectToDefault"]) {
+ [firstTableDocument setShouldAutomaticallyConnect:YES];
+ }
+ [[NSDocumentController sharedDocumentController] addDocument:firstTableDocument];
+ [firstTableDocument makeWindowControllers];
+ [firstTableDocument showWindows];
+ }
+
+ // Return NO to the automatic opening
+ return NO;
+}
+
+/*
+ * Insert content of a plain text file for a given path.
+ * In addition it tries to figure out the file's text encoding heuristically.
+ */
+- (NSString *)contentOfFile:(NSString *)aPath
+{
+
+ NSError *err = nil;
+ NSStringEncoding enc;
+ NSString *content = nil;
+
+ // Make usage of the UNIX command "file" to get an info
+ // about file type and encoding.
+ NSTask *task=[[NSTask alloc] init];
+ NSPipe *pipe=[[NSPipe alloc] init];
+ NSFileHandle *handle;
+ NSString *result;
+ [task setLaunchPath:@"/usr/bin/file"];
+ [task setArguments:[NSArray arrayWithObjects:aPath, @"-Ib", nil]];
+ [task setStandardOutput:pipe];
+ handle=[pipe fileHandleForReading];
+ [task launch];
+ result=[[NSString alloc] initWithData:[handle readDataToEndOfFile]
+ encoding:NSASCIIStringEncoding];
+
+ [pipe release];
+ [task release];
+
+ // UTF16/32 files are detected as application/octet-stream resp. audio/mpeg
+ if( [result hasPrefix:@"text/plain"]
+ || [[[aPath pathExtension] lowercaseString] isEqualToString:@"sql"]
+ || [[[aPath pathExtension] lowercaseString] isEqualToString:@"txt"]
+ || [result hasPrefix:@"audio/mpeg"]
+ || [result hasPrefix:@"application/octet-stream"]
+ )
+ {
+ // if UTF16/32 cocoa will try to find the correct encoding
+ if([result hasPrefix:@"application/octet-stream"] || [result hasPrefix:@"audio/mpeg"] || [result rangeOfString:@"utf-16"].length)
+ enc = 0;
+ else if([result rangeOfString:@"utf-8"].length)
+ enc = NSUTF8StringEncoding;
+ else if([result rangeOfString:@"iso-8859-1"].length)
+ enc = NSISOLatin1StringEncoding;
+ else if([result rangeOfString:@"us-ascii"].length)
+ enc = NSASCIIStringEncoding;
+ else
+ enc = 0;
+
+ if(enc == 0) // cocoa tries to detect the encoding
+ content = [NSString stringWithContentsOfFile:aPath usedEncoding:&enc error:&err];
+ else
+ content = [NSString stringWithContentsOfFile:aPath encoding:enc error:&err];
+
+ if(content)
+ {
+ [result release];
+ return content;
+ }
+ // If UNIX "file" failed try cocoa's encoding detection
+ content = [NSString stringWithContentsOfFile:aPath encoding:enc error:&err];
+ if(content)
+ {
+ [result release];
+ return content;
+ }
+ }
+
+ [result release];
+
+ NSLog(@"%@ ‘%@’.", NSLocalizedString(@"Couldn't read the file content of", @"Couldn't read the file content of"), aPath);
+
+ return @"";
+}
+
+
+/**
+ * What exactly is this for?
+ */
+- (id)handleQuitScriptCommand:(NSScriptCommand *)command
+{
+ [NSApp terminate:self];
+
+ // Suppress warning
+ return nil;
+}
+
+/**
+ * Sparkle updater delegate method. Called just before the updater relaunches Sequel Pro and we need to make
+ * sure that no sheets are currently open, which will prevent the app from being quit.
+ */
+- (void)updaterWillRelaunchApplication:(SUUpdater *)updater
+{
+ // Get all the currently open windows and their attached sheets if any
+ NSArray *windows = [NSApp windows];
+
+ for (NSWindow *window in windows)
+ {
+ NSWindow *attachedSheet = [window attachedSheet];
+
+ if (attachedSheet) {
+ [NSApp endSheet:attachedSheet returnCode:0];
+ [attachedSheet orderOut:nil];
+ }
+ }
+}
+
+/**
+ * Deallocate prefs controller
+ */
+- (void)dealloc
+{
+ [prefsController release], prefsController = nil;
+
+ [super dealloc];
+}
+
+@end