aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/NoodleLineNumberView.m141
-rw-r--r--Source/SPAppController.m54
-rw-r--r--Source/SPBundleCommandTextView.m20
-rw-r--r--Source/SPDatabaseDocument.m38
-rw-r--r--Source/SPTableData.m2
-rw-r--r--Source/SPTextViewAdditions.m4
-rw-r--r--Source/SPXMLExporter.m4
7 files changed, 149 insertions, 114 deletions
diff --git a/Source/NoodleLineNumberView.m b/Source/NoodleLineNumberView.m
index 0bb9b25e..9e0d284a 100644
--- a/Source/NoodleLineNumberView.m
+++ b/Source/NoodleLineNumberView.m
@@ -353,7 +353,7 @@
- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect
{
- id view;
+ id view;
NSRect bounds;
bounds = [self bounds];
@@ -362,87 +362,88 @@
{
[backgroundColor set];
NSRectFill(bounds);
-
+
[[NSColor colorWithCalibratedWhite:0.58 alpha:1.0] set];
- [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(bounds) - 0/5, NSMinY(bounds)) toPoint:NSMakePoint(NSMaxX(bounds) - 0.5, NSMaxY(bounds))];
+ [NSBezierPath strokeLineFromPoint:NSMakePoint(NSMaxX(bounds) - 0.5, NSMinY(bounds)) toPoint:NSMakePoint(NSMaxX(bounds) - 0.5, NSMaxY(bounds))];
}
-
- view = [self clientView];
-
- if ([view isKindOfClass:[NSTextView class]])
- {
- NSLayoutManager *layoutManager;
- NSTextContainer *container;
- NSRect visibleRect;
- NSRange range, glyphRange, nullRange;
- NSString *text, *labelText;
- NSUInteger rectCount, index, line, count;
- NSRectArray rects;
- CGFloat ypos, yinset;
- NSDictionary *textAttributes, *currentTextAttributes;
- NSSize stringSize;
+
+ view = [self clientView];
+
+ if ([view isKindOfClass:[NSTextView class]])
+ {
+ NSLayoutManager *layoutManager;
+ NSTextContainer *container;
+ NSRect visibleRect;
+ NSRange range, glyphRange, nullRange;
+ NSString *text, *labelText;
+ NSUInteger rectCount, index, line, count;
+ NSRectArray rects;
+ CGFloat ypos, yinset;
+ NSDictionary *textAttributes;
+ NSSize stringSize;
NSMutableArray *lines;
- layoutManager = [view layoutManager];
- container = [view textContainer];
- text = [view string];
- nullRange = NSMakeRange(NSNotFound, 0);
-
+ layoutManager = [view layoutManager];
+ container = [view textContainer];
+ text = [view string];
+ nullRange = NSMakeRange(NSNotFound, 0);
+
yinset = [view textContainerInset].height;
- visibleRect = [[[self scrollView] contentView] bounds];
+ visibleRect = [[[self scrollView] contentView] bounds];
+
+ textAttributes = [self textAttributes];
- textAttributes = [self textAttributes];
-
lines = [self lineIndices];
- // Find the characters that are currently visible
- glyphRange = [layoutManager glyphRangeForBoundingRect:visibleRect inTextContainer:container];
- range = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
-
- // Fudge the range a tad in case there is an extra new line at end.
- // It doesn't show up in the glyphs so would not be accounted for.
- range.length++;
-
- count = [lines count];
-
- for (line = [self lineNumberForCharacterIndex:range.location inText:text]; line < count; line++)
- {
- index = [NSArrayObjectAtIndex(lines, line) unsignedIntegerValue];
-
- if (NSLocationInRange(index, range))
- {
- rects = [layoutManager rectArrayForCharacterRange:NSMakeRange(index, 0)
- withinSelectedCharacterRange:nullRange
- inTextContainer:container
- rectCount:&rectCount];
-
- if (rectCount > 0)
- {
- // Note that the ruler view is only as tall as the visible
- // portion. Need to compensate for the clipview's coordinates.
- ypos = yinset + NSMinY(rects[0]) - NSMinY(visibleRect);
-
- // Line numbers are internally stored starting at 0
- labelText = [NSString stringWithFormat:@"%lu", (unsigned long)(line + 1)];
-
- stringSize = [labelText sizeWithAttributes:textAttributes];
-
- currentTextAttributes = textAttributes;
-
- // Draw string flush right, centered vertically within the line
- [labelText drawInRect:
- NSMakeRect(NSWidth(bounds) - stringSize.width - RULER_MARGIN,
- ypos + (NSHeight(rects[0]) - stringSize.height) / 2.0,
- NSWidth(bounds) - RULER_MARGIN * 2.0, NSHeight(rects[0]))
- withAttributes:currentTextAttributes];
- }
- }
+ // Find the characters that are currently visible
+ glyphRange = [layoutManager glyphRangeForBoundingRect:visibleRect inTextContainer:container];
+ range = [layoutManager characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
+
+ // Fudge the range a tad in case there is an extra new line at end.
+ // It doesn't show up in the glyphs so would not be accounted for.
+ range.length++;
+
+ count = [lines count];
+
+ CGFloat boundsRULERMargin2 = NSWidth(bounds) - RULER_MARGIN * 2.0;
+ CGFloat boundsWidthRULER = NSWidth(bounds) - RULER_MARGIN;
+ CGFloat yinsetMinY = yinset - NSMinY(visibleRect);
+
+ for (line = [self lineNumberForCharacterIndex:range.location inText:text]; line < count; line++)
+ {
+ index = [NSArrayObjectAtIndex(lines, line) unsignedIntegerValue];
+
+ if (NSLocationInRange(index, range))
+ {
+ rects = [layoutManager rectArrayForCharacterRange:NSMakeRange(index, 0)
+ withinSelectedCharacterRange:nullRange
+ inTextContainer:container
+ rectCount:&rectCount];
+
+ if (rectCount > 0)
+ {
+ // Note that the ruler view is only as tall as the visible
+ // portion. Need to compensate for the clipview's coordinates.
+
+ // Line numbers are internally stored starting at 0
+ labelText = [NSString stringWithFormat:@"%lu", (NSUInteger)(line + 1)];
+
+ stringSize = [labelText sizeWithAttributes:textAttributes];
+
+ // Draw string flush right, centered vertically within the line
+ [labelText drawInRect:
+ NSMakeRect(boundsWidthRULER - stringSize.width,
+ yinsetMinY + NSMinY(rects[0]) + ((NSHeight(rects[0]) - stringSize.height) / 2.0),
+ boundsRULERMargin2, NSHeight(rects[0]))
+ withAttributes:textAttributes];
+ }
+ }
if (index > NSMaxRange(range))
{
break;
}
- }
- }
+ }
+ }
}
- (void)mouseDown:(NSEvent *)theEvent
diff --git a/Source/SPAppController.m b/Source/SPAppController.m
index e5b47c80..2117a3ac 100644
--- a/Source/SPAppController.m
+++ b/Source/SPAppController.m
@@ -544,16 +544,16 @@
defaultButton:NSLocalizedString(@"Update", @"Update button")
alternateButton:NSLocalizedString(@"Cancel", @"Cancel button")
otherButton:nil
- informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"A bundle ‘%@’ is already installed. Do you want to update it?", @"a bundle ‘%@’ is already installed. do you want to update it?"), [installedBundleUUIDs objectForKey:[cmdData objectForKey:SPBundleFileUUIDKey]]]];
+ informativeTextWithFormat:[NSString stringWithFormat:NSLocalizedString(@"A bundle ‘%@’ is already installed. Do you want to update it?", @"a bundle ‘%@’ is already installed. do you want to update it?"), [[installedBundleUUIDs objectForKey:[cmdData objectForKey:SPBundleFileUUIDKey]] objectForKey:@"name"]]];
[alert setAlertStyle:NSCriticalAlertStyle];
NSInteger answer = [alert runModal];
if(answer == NSAlertDefaultReturn) {
NSError *error = nil;
- NSString *moveToTrashCommand = [NSString stringWithFormat:@"osascript -e 'tell application \"Finder\" to move (POSIX file \"%@\") to the trash'", newPath];
+ NSString *moveToTrashCommand = [NSString stringWithFormat:@"osascript -e 'tell application \"Finder\" to move (POSIX file \"%@\") to the trash'", infoPath];
[moveToTrashCommand runBashCommandWithEnvironment:nil atCurrentDirectoryPath:nil error:&error];
if(error != nil) {
- NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Error while moving “%@” to Trash.", @"error while moving “%@” to trash"), newPath]
+ NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Error while moving “%@” to Trash.", @"error while moving “%@” to trash"), [[installedBundleUUIDs objectForKey:[cmdData objectForKey:SPBundleFileUUIDKey]] objectForKey:@"path"]]
defaultButton:NSLocalizedString(@"OK", @"OK button")
alternateButton:nil
otherButton:nil
@@ -661,28 +661,28 @@
BOOL userTerminated = NO;
- while(1) {
- NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:NSDefaultRunLoopMode
- dequeue:YES];
-
- if ([event type] == NSKeyDown) {
- unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
- if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
- userTerminated = YES;
- break;
- }
- }
- [NSApp sendEvent:event];
- if(![processDocument isWorking]) break;
- usleep(1000);
- }
-
- if(userTerminated) {
- NSBeep();
- return;
- }
+ // while(1) {
+ // NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
+ // untilDate:[NSDate distantPast]
+ // inMode:NSDefaultRunLoopMode
+ // dequeue:YES];
+ //
+ // if ([event type] == NSKeyDown) {
+ // unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
+ // if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
+ // userTerminated = YES;
+ // break;
+ // }
+ // }
+ // [NSApp sendEvent:event];
+ // if(![processDocument isWorking]) break;
+ // usleep(1000);
+ // }
+ //
+ // if(userTerminated) {
+ // NSBeep();
+ // return;
+ // }
if(processDocument && command) {
if([command isEqualToString:@"passToDoc"]) {
@@ -1421,7 +1421,9 @@
}
if([cmdData objectForKey:SPBundleFileUUIDKey] && [[cmdData objectForKey:SPBundleFileUUIDKey] length])
- [installedBundleUUIDs setObject:[NSString stringWithFormat:@"%@ (%@)", bundle, [cmdData objectForKey:SPBundleFileNameKey]] forKey:[cmdData objectForKey:SPBundleFileUUIDKey]];
+ [installedBundleUUIDs setObject:[NSDictionary dictionaryWithObjectsAndKeys:
+ [NSString stringWithFormat:@"%@ (%@)", bundle, [cmdData objectForKey:SPBundleFileNameKey]], @"name",
+ infoPath, @"path", nil] forKey:[cmdData objectForKey:SPBundleFileUUIDKey]];
if([cmdData objectForKey:SPBundleFileTooltipKey] && [[cmdData objectForKey:SPBundleFileTooltipKey] length])
[aDict setObject:[cmdData objectForKey:SPBundleFileTooltipKey] forKey:SPBundleFileTooltipKey];
diff --git a/Source/SPBundleCommandTextView.m b/Source/SPBundleCommandTextView.m
index 8a5bf620..6411ccfd 100644
--- a/Source/SPBundleCommandTextView.m
+++ b/Source/SPBundleCommandTextView.m
@@ -29,25 +29,15 @@
@implementation SPBundleCommandTextView
-- (id)init
-{
- if(self = [super init])
- {
- ;
- }
- return self;
-}
-
- (void)dealloc
{
-
- [[NSNotificationCenter defaultCenter] removeObserver:self];
[prefs removeObserver:self forKeyPath:SPCustomQueryEditorTabStopWidth];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
[prefs release];
[lineNumberView release];
}
-- (void) awakeFromNib
+- (void)awakeFromNib
{
prefs = [[NSUserDefaults standardUserDefaults] retain];
@@ -68,6 +58,12 @@
// Re-define tab stops for a better editing
[self setTabStops];
+ // add NSViewBoundsDidChangeNotification to scrollView
+ [[commandScrollView contentView] setPostsBoundsChangedNotifications:YES];
+
+ // disabled to get the current text range in textView safer
+ [[self layoutManager] setBackgroundLayoutEnabled:NO];
+
}
- (void)drawRect:(NSRect)rect
diff --git a/Source/SPDatabaseDocument.m b/Source/SPDatabaseDocument.m
index 44d3965c..86588f88 100644
--- a/Source/SPDatabaseDocument.m
+++ b/Source/SPDatabaseDocument.m
@@ -55,6 +55,7 @@
#import "SPTableCopy.h"
#import "SPDatabaseRename.h"
#import "SPServerSupport.h"
+#import "SPTooltip.h"
@interface SPDatabaseDocument (PrivateAPI)
@@ -4553,7 +4554,10 @@
if(!docProcessID) docProcessID = @"";
// Authenticate command
- if(![docProcessID isEqualToString:[commandDict objectForKey:@"id"]]) return;
+ if(![docProcessID isEqualToString:[commandDict objectForKey:@"id"]]) {
+ [SPTooltip showWithObject:NSLocalizedString(@"URL scheme command couldn't authenticated", @"URL scheme command couldn't authenticated") atLocation:[NSApp mouseLocation]];
+ return;
+ }
if([command isEqualToString:@"SelectDocumentView"]) {
if([params count] == 2) {
@@ -4645,7 +4649,8 @@
if([command isEqualToString:@"ExecuteQuery"]) {
// Bail if document is busy
- if (_isWorkingLevel) return;
+ if (_isWorkingLevel)
+ [SPTooltip showWithObject:NSLocalizedString(@"Connection window is busy. URL scheme command bailed", @"Connection window is busy. URL scheme command bailed") atLocation:[NSApp mouseLocation]];
NSString *outputFormat = @"tab";
if([params count] == 2)
@@ -4660,6 +4665,7 @@
NSFileManager *fm = [NSFileManager defaultManager];
NSString *status = @"0";
BOOL isDir;
+ BOOL userTerminated = NO;
if([fm fileExistsAtPath:queryFileName isDirectory:&isDir] && !isDir) {
NSError *inError = nil;
@@ -4717,12 +4723,21 @@
NSInteger i, j;
NSArray *theRow;
NSMutableString *result = [NSMutableString string];
-
if(writeAsCsv) {
for ( i = 0 ; i < [theResult numOfRows] ; i++ ) {
[result setString:@""];
theRow = [theResult fetchNextRowAsArray];
for( j = 0 ; j < [theRow count] ; j++ ) {
+
+ NSEvent* event = [NSApp currentEvent];
+ if ([event type] == NSKeyDown) {
+ unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
+ if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
+ userTerminated = YES;
+ break;
+ }
+ }
+
if([result length]) [result appendString:@","];
id cell = NSArrayObjectAtIndex(theRow, j);
if([cell isKindOfClass:[NSNull class]])
@@ -4742,6 +4757,7 @@
else
[result appendFormat:@"\"%@\"", [[cell description] stringByReplacingOccurrencesOfString:@"\"" withString:@"\"\""]];
}
+ if(userTerminated) break;
[result appendString:@"\n"];
[fh writeData:[result dataUsingEncoding:NSUTF8StringEncoding]];
}
@@ -4751,6 +4767,16 @@
[result setString:@""];
theRow = [theResult fetchNextRowAsArray];
for( j = 0 ; j < [theRow count] ; j++ ) {
+
+ NSEvent* event = [NSApp currentEvent];
+ if ([event type] == NSKeyDown) {
+ unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
+ if (([event modifierFlags] & NSCommandKeyMask) && key == '.') {
+ userTerminated = YES;
+ break;
+ }
+ }
+
if([result length]) [result appendString:@"\t"];
id cell = NSArrayObjectAtIndex(theRow, j);
if([cell isKindOfClass:[NSNull class]])
@@ -4770,6 +4796,7 @@
else
[result appendString:[[[cell description] stringByReplacingOccurrencesOfString:@"\n" withString:@"↵"] stringByReplacingOccurrencesOfString:@"\t" withString:@"⇥"]];
}
+ if(userTerminated) break;
[result appendString:@"\n"];
[fh writeData:[result dataUsingEncoding:NSUTF8StringEncoding]];
}
@@ -4779,6 +4806,11 @@
}
}
+ if(userTerminated) {
+ [SPTooltip showWithObject:NSLocalizedString(@"URL scheme command was terminated by user", @"URL scheme command was terminated by user") atLocation:[NSApp mouseLocation]];
+ status = @"1";
+ }
+
// write status file as notification that query was finished
BOOL succeed = [status writeToFile:statusFileName atomically:YES encoding:NSUTF8StringEncoding error:nil];
if(!succeed) {
diff --git a/Source/SPTableData.m b/Source/SPTableData.m
index 404395b9..28717864 100644
--- a/Source/SPTableData.m
+++ b/Source/SPTableData.m
@@ -944,6 +944,7 @@
// Run the status query and retrieve as a dictionary.
NSMutableString *escapedTableName = [NSMutableString stringWithString:[tableListInstance tableName]];
+ [escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])];
[escapedTableName replaceOccurrencesOfString:@"'" withString:@"\\\'" options:0 range:NSMakeRange(0, [escapedTableName length])];
MCPResult *tableStatusResult = nil;
@@ -964,6 +965,7 @@
tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SELECT * FROM information_schema.VIEWS AS r WHERE r.TABLE_NAME = '%@' AND r.TABLE_SCHEMA = '%@'", escapedTableName, escapedDatabaseName]];
}
else if ([tableListInstance tableType] == SPTableTypeTable) {
+ [escapedTableName replaceOccurrencesOfRegex:@"\\\\(?=\\Z|[^\'])" withString:@"\\\\\\\\"];
tableStatusResult = [mySQLConnection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE '%@'", escapedTableName ]];
[tableStatusResult setReturnDataAsStrings:YES];
}
diff --git a/Source/SPTextViewAdditions.m b/Source/SPTextViewAdditions.m
index 11defa20..f04c6684 100644
--- a/Source/SPTextViewAdditions.m
+++ b/Source/SPTextViewAdditions.m
@@ -534,7 +534,7 @@
[[NSFileManager defaultManager] removeItemAtPath:bundleInputFilePath error:nil];
- BOOL selfIsQueryEditor = ([[[self class] description] isEqualToString:@"SPTextView"]) ;
+ BOOL selfIsQueryEditor = ([[[self class] description] isEqualToString:@"SPTextView"] && [self respondsToSelector:@selector(currentQueryRange)]) ;
if([cmdData objectForKey:SPBundleFileInputSourceKey])
inputAction = [[cmdData objectForKey:SPBundleFileInputSourceKey] lowercaseString];
@@ -553,7 +553,7 @@
if(!currentQueryRange.length)
currentQueryRange = currentSelectionRange;
- NSRange replaceRange = NSMakeRange(currentSelectionRange.location, 0);
+ NSRange replaceRange = currentSelectionRange;
if([inputAction isEqualToString:SPBundleInputSourceSelectedText]) {
if(!currentSelectionRange.length) {
if([inputFallBackAction isEqualToString:SPBundleInputSourceCurrentWord])
diff --git a/Source/SPXMLExporter.m b/Source/SPXMLExporter.m
index 962d5a53..57977be0 100644
--- a/Source/SPXMLExporter.m
+++ b/Source/SPXMLExporter.m
@@ -113,7 +113,9 @@
if (([self xmlFormat] == SPXMLExportMySQLFormat) && [self xmlOutputIncludeStructure]) {
structureResult = [connection queryString:[NSString stringWithFormat:@"SHOW COLUMNS FROM %@", [[self xmlTableName] backtickQuotedString]]];
- statusResult = [connection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE %@", [[self xmlTableName] tickQuotedString]]];
+ NSMutableString *escapedTableName = [NSMutableString stringWithString:[[self xmlTableName] tickQuotedString]];
+ [escapedTableName replaceOccurrencesOfString:@"\\" withString:@"\\\\\\\\" options:0 range:NSMakeRange(0, [escapedTableName length])];
+ statusResult = [connection queryString:[NSString stringWithFormat:@"SHOW TABLE STATUS LIKE %@", escapedTableName]];
if ([structureResult numOfRows] && [statusResult numOfRows]) {