aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/SPNarrowDownCompletion.h49
-rw-r--r--Source/SPNarrowDownCompletion.m436
2 files changed, 254 insertions, 231 deletions
diff --git a/Source/SPNarrowDownCompletion.h b/Source/SPNarrowDownCompletion.h
index 670d1a29..153f8b78 100644
--- a/Source/SPNarrowDownCompletion.h
+++ b/Source/SPNarrowDownCompletion.h
@@ -34,12 +34,12 @@
@interface SPNarrowDownCompletion : NSWindow <NSTableViewDelegate, NSTableViewDataSource>
{
- NSArray* suggestions;
- NSMutableString* mutablePrefix;
- NSString* staticPrefix;
- NSString* currentDb;
- NSArray* filtered;
- NSTableView* theTableView;
+ NSArray *suggestions;
+ NSMutableString *mutablePrefix;
+ NSString *staticPrefix;
+ NSString *currentDb;
+ NSArray *filtered;
+ NSTableView *theTableView;
NSPoint caretPos;
BOOL isAbove;
BOOL closeMe;
@@ -70,11 +70,11 @@
NSUInteger timeCounter;
id theView;
-
+
NSInteger maxWindowWidth;
NSInteger spaceCounter;
-
- NSMutableCharacterSet* textualInputCharacters;
+
+ NSMutableCharacterSet *textualInputCharacters;
SPDatabaseStructure *databaseStructureRetrieval;
#ifndef SP_CODA
@@ -82,15 +82,29 @@
#endif
}
-- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix
- additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive
- charRange:(NSRange)initRange parseRange:(NSRange)parseRange inView:(id)aView
- dictMode:(BOOL)mode dbMode:(BOOL)theDbMode tabTriggerMode:(BOOL)tabTriggerMode fuzzySearch:(BOOL)fuzzySearch
- backtickMode:(NSInteger)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName
- selectedDb:(NSString*)selectedDb caretMovedLeft:(BOOL)caretMovedLeft autoComplete:(BOOL)autoComplete oneColumn:(BOOL)oneColumn
- alias:(NSString*)anAlias withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure;
+- (id) initWithItems:(NSArray *)someSuggestions
+ alreadyTyped:(NSString *)aUserString
+ staticPrefix:(NSString *)aStaticPrefix
+ additionalWordCharacters:(NSString *)someAdditionalWordCharacters
+ caseSensitive:(BOOL)isCaseSensitive
+ charRange:(NSRange)initRange
+ parseRange:(NSRange)parseRange
+ inView:(id)aView
+ dictMode:(BOOL)mode
+ dbMode:(BOOL)theDbMode
+ tabTriggerMode:(BOOL)tabTriggerMode
+ fuzzySearch:(BOOL)fuzzySearch
+ backtickMode:(NSInteger)theBackTickMode
+ withDbName:(NSString *)dbName
+ withTableName:(NSString *)tableName
+ selectedDb:(NSString *)selectedDb
+ caretMovedLeft:(BOOL)caretMovedLeft
+ autoComplete:(BOOL)autoComplete
+ oneColumn:(BOOL)oneColumn
+ alias:(NSString *)anAlias
+ withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure;
- (void)setCaretPos:(NSPoint)aPos;
-- (void)insert_text:(NSString* )aString;
+- (void)insert_text:(NSString *)aString;
- (void)insertAutocompletePlaceholder;
- (void)removeAutocompletionPlaceholderUsingFastMethod:(BOOL)useFastMethod;
- (void)adjustWorkingRangeByDelta:(NSInteger)delta;
@@ -98,5 +112,4 @@
- (void)updateSyncArrowStatus;
- (void)reInvokeCompletion;
-
@end
diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m
index af5b2428..f590822a 100644
--- a/Source/SPNarrowDownCompletion.m
+++ b/Source/SPNarrowDownCompletion.m
@@ -67,11 +67,9 @@
- (BOOL)SP_NarrowDownCompletion_canHandleEvent:(NSEvent*)anEvent
{
-
NSInteger visibleRows = (NSInteger)floor(NSHeight([self visibleRect]) / ([self rowHeight]+[self intercellSpacing].height)) - 1;
- struct { unichar key; NSInteger rows; } const key_movements[] =
- {
+ struct { unichar key; NSInteger rows; } const key_movements[] = {
{ NSUpArrowFunctionKey, -1 },
{ NSDownArrowFunctionKey, +1 },
{ NSPageUpFunctionKey, -visibleRows },
@@ -81,19 +79,17 @@
};
unichar keyCode = 0;
- if([anEvent type] == NSKeyDown && [[anEvent characters] length] == 1)
+ if([anEvent type] == NSKeyDown && [[anEvent characters] length] == 1) {
keyCode = [[anEvent characters] characterAtIndex:0];
+ }
-
- for(size_t i = 0; i < (sizeof(key_movements) / sizeof(key_movements[0])); ++i)
- {
- if(keyCode == key_movements[i].key)
- {
+ for(size_t i = 0; i < (sizeof(key_movements) / sizeof(key_movements[0])); ++i) {
+ if(keyCode == key_movements[i].key) {
NSInteger row = MAX(0, MIN([self selectedRow] + key_movements[i].rows, [self numberOfRows]-1));
if(row == 0 && ![[[self delegate] tableView:self selectionIndexesForProposedSelection:[NSIndexSet indexSetWithIndex:row]] containsIndex:0]) {
- if(visibleRows > 1)
- [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO];
- } else {
+ if(visibleRows > 1) [self selectRowIndexes:[NSIndexSet indexSetWithIndex:row+1] byExtendingSelection:NO];
+ }
+ else {
[self selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
}
[self scrollRowToVisible:row];
@@ -103,7 +99,6 @@
}
return NO;
-
}
@end
@@ -114,7 +109,6 @@
// =============================
- (id)init
{
-
maxWindowWidth = 450;
if((self = [super initWithContentRect:NSMakeRect(0,0,maxWindowWidth,0) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:YES]))
@@ -140,15 +134,13 @@
#endif
[self setupInterface];
- syncArrowImages = [[NSArray alloc] initWithObjects:
- [NSImage imageNamed:@"sync_arrows_01"],
- [NSImage imageNamed:@"sync_arrows_02"],
- [NSImage imageNamed:@"sync_arrows_03"],
- [NSImage imageNamed:@"sync_arrows_04"],
- [NSImage imageNamed:@"sync_arrows_05"],
- [NSImage imageNamed:@"sync_arrows_06"],
- nil];
-
+ syncArrowImages = [[NSArray alloc] initWithObjects:[NSImage imageNamed:@"sync_arrows_01"],
+ [NSImage imageNamed:@"sync_arrows_02"],
+ [NSImage imageNamed:@"sync_arrows_03"],
+ [NSImage imageNamed:@"sync_arrows_04"],
+ [NSImage imageNamed:@"sync_arrows_05"],
+ [NSImage imageNamed:@"sync_arrows_06"],
+ nil];
}
return self;
}
@@ -177,7 +169,6 @@
- (void)close
{
-
// Invalidate the timer now to prevent retain cycles preventing deallocation
if (stateTimer != nil) {
[stateTimer invalidate];
@@ -205,7 +196,7 @@
[stateTimer invalidate];
SPClear(stateTimer);
if(syncArrowImages) SPClear(syncArrowImages);
- [self performSelectorOnMainThread:@selector(reInvokeCompletion) withObject:nil waitUntilDone:YES];
+ [[self onMainThread] reInvokeCompletion];
closeMe = YES;
return;
}
@@ -213,7 +204,6 @@
}
[theTableView setNeedsDisplay:YES];
-
}
- (void)reInvokeCompletion
@@ -227,17 +217,30 @@
[theView performSelector:@selector(refreshCompletion) withObject:nil afterDelay:0.0];
}
-- (id)initWithItems:(NSArray*)someSuggestions alreadyTyped:(NSString*)aUserString staticPrefix:(NSString*)aStaticPrefix
- additionalWordCharacters:(NSString*)someAdditionalWordCharacters caseSensitive:(BOOL)isCaseSensitive
- charRange:(NSRange)initRange parseRange:(NSRange)parseRange inView:(id)aView
- dictMode:(BOOL)mode dbMode:(BOOL)theDbMode tabTriggerMode:(BOOL)tabTriggerMode fuzzySearch:(BOOL)fuzzySearch
- backtickMode:(NSInteger)theBackTickMode withDbName:(NSString*)dbName withTableName:(NSString*)tableName
- selectedDb:(NSString*)selectedDb caretMovedLeft:(BOOL)caretMovedLeft autoComplete:(BOOL)autoComplete oneColumn:(BOOL)oneColumn
- alias:(NSString*)anAlias withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure
+- (id) initWithItems:(NSArray *)someSuggestions
+ alreadyTyped:(NSString *)aUserString
+ staticPrefix:(NSString *)aStaticPrefix
+ additionalWordCharacters:(NSString *)someAdditionalWordCharacters
+ caseSensitive:(BOOL)isCaseSensitive
+ charRange:(NSRange)initRange
+ parseRange:(NSRange)parseRange
+ inView:(id)aView
+ dictMode:(BOOL)mode
+ dbMode:(BOOL)theDbMode
+ tabTriggerMode:(BOOL)tabTriggerMode
+ fuzzySearch:(BOOL)fuzzySearch
+ backtickMode:(NSInteger)theBackTickMode
+ withDbName:(NSString *)dbName
+ withTableName:(NSString *)tableName
+ selectedDb:(NSString *)selectedDb
+ caretMovedLeft:(BOOL)caretMovedLeft
+ autoComplete:(BOOL)autoComplete
+ oneColumn:(BOOL)oneColumn
+ alias:(NSString *)anAlias
+ withDBStructureRetriever:(SPDatabaseStructure *)theDatabaseStructure
{
if((self = [self init]))
{
-
// Set filter string
if (aUserString) {
[mutablePrefix appendString:aUserString];
@@ -251,10 +254,8 @@
oneColumnMode = oneColumn;
fuzzyMode = fuzzySearch;
- if(fuzzyMode)
- [theTableView setBackgroundColor:[NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f]];
- else
- [theTableView setBackgroundColor:[NSColor whiteColor]];
+ if(fuzzyMode) [theTableView setBackgroundColor:[NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f]];
+ else [theTableView setBackgroundColor:[NSColor whiteColor]];
dbStructureMode = theDbMode;
cursorMovedLeft = caretMovedLeft;
@@ -262,8 +263,7 @@
commaInsertionMode = NO;
triggerMode = tabTriggerMode;
- if(aStaticPrefix)
- staticPrefix = [aStaticPrefix retain];
+ if(aStaticPrefix) staticPrefix = [aStaticPrefix retain];
caseSensitive = isCaseSensitive;
@@ -288,8 +288,7 @@
if(len>maxLength) maxLength = len;
}
NSMutableString *dummy = [NSMutableString string];
- for(NSUInteger i=0; i<maxLength; i++)
- [dummy appendString:@" "];
+ for(NSUInteger i=0; i<maxLength; i++) [dummy appendString:@" "];
CGFloat w = NSSizeToCGSize([dummy sizeWithAttributes:@{NSFontAttributeName : tableFont}]).width + 26.0f;
maxWindowWidth = (w>maxWindowWidth) ? maxWindowWidth : w;
@@ -303,15 +302,16 @@
theDbName = dbName;
- if(someAdditionalWordCharacters)
- [textualInputCharacters addCharactersInString:someAdditionalWordCharacters];
+ if(someAdditionalWordCharacters) [textualInputCharacters addCharactersInString:someAdditionalWordCharacters];
databaseStructureRetrieval = [theDatabaseStructure retain];
isQueryingDatabaseStructure = [databaseStructureRetrieval isQueryingDatabaseStructure];
- if(isQueryingDatabaseStructure)
+ if(isQueryingDatabaseStructure) {
stateTimer = [[NSTimer scheduledTimerWithTimeInterval:0.07f target:self selector:@selector(updateSyncArrowStatus) userInfo:nil repeats:YES] retain];
+ }
}
+
return self;
}
@@ -323,16 +323,16 @@
NSInteger offx = (caretPos.x/screen.size.width) + 1;
- if((caretPos.x + [self frame].size.width) > (screen.size.width*offx))
+ if((caretPos.x + [self frame].size.width) > (screen.size.width*offx)) {
caretPos.x = (screen.size.width*offx) - [self frame].size.width - 5;
+ }
- if(caretPos.y >= 0 && caretPos.y < [self frame].size.height)
- {
+ if(caretPos.y >= 0 && caretPos.y < [self frame].size.height) {
caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5f);
isAbove = YES;
}
- if(caretPos.y < 0 && (screen.size.height-[self frame].size.height) < (caretPos.y*-1))
- {
+
+ if(caretPos.y < 0 && (screen.size.height-[self frame].size.height) < (caretPos.y*-1)) {
caretPos.y += [self frame].size.height + ([tableFont pointSize]*1.5f);
isAbove = YES;
}
@@ -393,7 +393,6 @@
[scrollView setDocumentView:theTableView];
[self setContentView:scrollView];
-
}
// ========================
@@ -407,40 +406,38 @@
- (NSString *)tableView:(NSTableView *)aTableView toolTipForCell:(id)aCell rect:(NSRectPointer)rect tableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex mouseLocation:(NSPoint)mouseLocation
{
if([[aTableColumn identifier] isEqualToString:@"image"]) {
- if(isQueryingDatabaseStructure && rowIndex == 0)
+ if(isQueryingDatabaseStructure && rowIndex == 0) {
return NSLocalizedString(@"fetching database structure in progress", @"fetching database structure in progress");
+ }
if(!dictMode) {
NSString *imageName = [[filtered objectAtIndex:rowIndex] objectForKey:@"image"];
- if([imageName hasPrefix:@"dummy"])
- return @"";
- if([imageName hasPrefix:@"table-view"])
- return @"view";
- if([imageName hasPrefix:@"table"])
- return @"table";
- if([imageName hasPrefix:@"database"])
- return @"database";
- if([imageName hasPrefix:@"func"])
- return @"function";
- if([imageName hasPrefix:@"proc"])
- return @"procedure";
- if([imageName hasPrefix:@"field"])
- return @"field";
+ if([imageName hasPrefix:@"dummy"]) return @"";
+ if([imageName hasPrefix:@"table-view"]) return @"view";
+ if([imageName hasPrefix:@"table"]) return @"table";
+ if([imageName hasPrefix:@"database"]) return @"database";
+ if([imageName hasPrefix:@"func"]) return @"function";
+ if([imageName hasPrefix:@"proc"]) return @"procedure";
+ if([imageName hasPrefix:@"field"]) return @"field";
}
return @"";
- } else if([[aTableColumn identifier] isEqualToString:@"name"]) {
- if(isQueryingDatabaseStructure && rowIndex == 0)
+ }
+ else if([[aTableColumn identifier] isEqualToString:@"name"]) {
+ if(isQueryingDatabaseStructure && rowIndex == 0) {
return NSLocalizedString(@"fetching database structure in progress", @"fetching database structure in progress");
+ }
return [[filtered objectAtIndex:rowIndex] objectForKey:@"display"];
-
- } else if ([[aTableColumn identifier] isEqualToString:@"list"] || [[aTableColumn identifier] isEqualToString:@"type"]) {
- if(isQueryingDatabaseStructure && rowIndex == 0)
+ }
+ else if ([[aTableColumn identifier] isEqualToString:@"list"] || [[aTableColumn identifier] isEqualToString:@"type"]) {
+ if(isQueryingDatabaseStructure && rowIndex == 0) {
return NSLocalizedString(@"fetching database structure data in progress", @"fetching database structure data in progress");
+ }
if(dictMode) {
return @"";
- } else {
+ }
+ else {
if([[filtered objectAtIndex:rowIndex] objectForKey:@"list"]) {
NSMutableString *tt = [NSMutableString string];
[tt appendStringOrNil:[[filtered objectAtIndex:rowIndex] objectForKey:@"type"]];
@@ -449,19 +446,21 @@
[tt appendString:@"\n"];
[tt appendString:[[filtered objectAtIndex:rowIndex] objectForKey:@"list"]];
return tt;
- } else {
+ }
+ else {
return ([[filtered objectAtIndex:rowIndex] objectForKey:@"type"]) ? [[filtered objectAtIndex:rowIndex] objectForKey:@"type"] : @"";
}
- return @"";
}
-
- } else if ([[aTableColumn identifier] isEqualToString:@"path"]) {
- if(isQueryingDatabaseStructure && rowIndex == 0)
+ }
+ else if ([[aTableColumn identifier] isEqualToString:@"path"]) {
+ if(isQueryingDatabaseStructure && rowIndex == 0) {
return NSLocalizedString(@"fetching database structure in progress", @"fetching database structure in progress");
+ }
if(dictMode) {
return @"";
- } else {
+ }
+ else {
if([[filtered objectAtIndex:rowIndex] objectForKey:@"path"]) {
NSMutableString *tt = [NSMutableString string];
[tt setString:NSLocalizedString(@"Schema path:", @"schema path header for completion tooltip")];
@@ -480,8 +479,9 @@
- (NSIndexSet *)tableView:(NSTableView *)tableView selectionIndexesForProposedSelection:(NSIndexSet *)proposedSelectionIndexes
{
- if(isQueryingDatabaseStructure && [proposedSelectionIndexes containsIndex:0])
+ if(isQueryingDatabaseStructure && [proposedSelectionIndexes containsIndex:0]) {
return [tableView selectedRowIndexes];
+ }
return proposedSelectionIndexes;
}
@@ -495,24 +495,25 @@
if(!dictMode) {
if(isQueryingDatabaseStructure && rowIndex == 0) {
return [syncArrowImages objectAtIndex:currentSyncImage];
- } else {
+ }
+ else {
imageName = [[filtered objectAtIndex:rowIndex] objectForKey:@"image"];
- if(imageName)
- image = [NSImage imageNamed:imageName];
+ if(imageName) image = [NSImage imageNamed:imageName];
return image;
}
}
return @"";
-
- } else if([[aTableColumn identifier] isEqualToString:@"name"]) {
+ }
+ else if([[aTableColumn identifier] isEqualToString:@"name"]) {
[[aTableColumn dataCell] setFont:[NSFont systemFontOfSize:12]];
- if(isQueryingDatabaseStructure && rowIndex == 0)
- return @"fetching structure…";
+ if(isQueryingDatabaseStructure && rowIndex == 0) {
+ return NSLocalizedString(@"fetching database structure in progress", @"fetching database structure in progress");
+ }
return [[filtered objectAtIndex:rowIndex] objectForKey:@"display"];
-
- } else if ([[aTableColumn identifier] isEqualToString:@"list"]) {
+ }
+ else if ([[aTableColumn identifier] isEqualToString:@"list"]) {
if(isQueryingDatabaseStructure && rowIndex == 0) {
NSPopUpButtonCell *b = [[NSPopUpButtonCell new] autorelease];
[b setPullsDown:NO];
@@ -522,10 +523,12 @@
[b setBordered:NO];
[aTableColumn setDataCell:b];
return @"";
- }
+ }
+
if(dictMode) {
return @"";
- } else {
+ }
+ else {
if([[filtered objectAtIndex:rowIndex] objectForKey:@"list"]) {
NSPopUpButtonCell *b = [[NSPopUpButtonCell new] autorelease];
[b setPullsDown:NO];
@@ -543,27 +546,30 @@
[b setFont:[NSFont systemFontOfSize:11]];
[b setBordered:NO];
[aTableColumn setDataCell:b];
- } else {
+ }
+ else {
[aTableColumn setDataCell:[[NSTextFieldCell new] autorelease]];
}
return @"";
}
-
- } else if([[aTableColumn identifier] isEqualToString:@"type"]) {
+ }
+ else if([[aTableColumn identifier] isEqualToString:@"type"]) {
if(isQueryingDatabaseStructure && rowIndex == 0) {
return @"";
- }
+ }
+
if(dictMode) {
return @"";
- } else {
+ }
+ else {
NSTokenFieldCell *b = [[[NSTokenFieldCell alloc] initTextCell:([[filtered objectAtIndex:rowIndex] objectForKey:@"type"]) ? [[filtered objectAtIndex:rowIndex] objectForKey:@"type"] : @""] autorelease];
[b setEditable:NO];
[b setAlignment:NSRightTextAlignment];
[b setFont:[NSFont systemFontOfSize:11]];
return b;
}
-
- } else if ([[aTableColumn identifier] isEqualToString:@"path"]) {
+ }
+ else if ([[aTableColumn identifier] isEqualToString:@"path"]) {
if(isQueryingDatabaseStructure && rowIndex == 0) {
NSPopUpButtonCell *b = [[NSPopUpButtonCell new] autorelease];
[b setPullsDown:NO];
@@ -573,18 +579,21 @@
[b setBordered:NO];
[aTableColumn setDataCell:b];
return @"";
- }
+ }
+
if(dictMode) {
return @"";
- } else {
+ }
+ else {
if([[filtered objectAtIndex:rowIndex] objectForKey:@"path"]) {
NSPopUpButtonCell *b = [[NSPopUpButtonCell new] autorelease];
[b setPullsDown:NO];
[b setAltersStateOfSelectedItem:NO];
[b setControlSize:NSMiniControlSize];
NSMenu *m = [[NSMenu alloc] init];
- for(id p in [[[[[filtered objectAtIndex:rowIndex] objectForKey:@"path"] componentsSeparatedByString:SPUniqueSchemaDelimiter] reverseObjectEnumerator] allObjects])
+ for(id p in [[[[[filtered objectAtIndex:rowIndex] objectForKey:@"path"] componentsSeparatedByString:SPUniqueSchemaDelimiter] reverseObjectEnumerator] allObjects]) {
[m addItemWithTitle:p action:NULL keyEquivalent:@""];
+ }
if([m numberOfItems]>2) {
[m removeItemAtIndex:[m numberOfItems]-1];
[m removeItemAtIndex:0];
@@ -596,7 +605,8 @@
[b setFont:[NSFont systemFontOfSize:11]];
[b setBordered:NO];
[aTableColumn setDataCell:b];
- } else {
+ }
+ else {
[aTableColumn setDataCell:[[NSTextFieldCell new] autorelease]];
}
return @"";
@@ -612,13 +622,14 @@
{
[textualInputCharacters removeCharactersInString:@" "];
if(autoCompletionMode) return;
- if(spaceCounter < 1)
- for(id w in filtered){
+ if(spaceCounter < 1) {
+ for(id w in filtered) {
if([[w objectForKey:@"match"] ?: [w objectForKey:@"display"] rangeOfString:@" "].length && ![w objectForKey:@"noCompletion"]) {
[textualInputCharacters addCharactersInString:@" "];
break;
}
}
+ }
}
// ====================
@@ -626,21 +637,23 @@
// ====================
- (void)filter
{
-
NSMutableArray* newFiltered = [[NSMutableArray alloc] initWithCapacity:5];
- if([mutablePrefix length] > 0)
- {
+ if([mutablePrefix length] > 0) {
if(dictMode) {
NSPredicate* predicate;
- if(caseSensitive)
+ if(caseSensitive) {
predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH %@ OR (match == NULL AND display BEGINSWITH %@)", [self filterString], [self filterString]];
- else
+ }
+ else {
predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH[c] %@ OR (match == NULL AND display BEGINSWITH[c] %@)", [self filterString], [self filterString]];
+ }
[newFiltered addObjectsFromArray:[suggestions filteredArrayUsingPredicate:predicate]];
- for(id w in [[NSSpellChecker sharedSpellChecker] completionsForPartialWordRange:NSMakeRange(0,[[self filterString] length]) inString:[self filterString] language:nil inSpellDocumentWithTag:0])
+ for(id w in [[NSSpellChecker sharedSpellChecker] completionsForPartialWordRange:NSMakeRange(0,[[self filterString] length]) inString:[self filterString] language:nil inSpellDocumentWithTag:0]) {
[newFiltered addObject:[NSDictionary dictionaryWithObjectsAndKeys:w, @"display", nil]];
- } else {
+ }
+ }
+ else {
@try{
if(fuzzyMode) { // eg filter = "inf" this regexp search will be performed: (?i).*?i.*?n.*?f
@@ -648,34 +661,39 @@
NSUInteger i;
unichar c;
- if (!caseSensitive)
- [fuzzyRegexp setString:@"(?i)"];
+ if (!caseSensitive) [fuzzyRegexp setString:@"(?i)"];
for (i=0; i<[[self filterString] length]; i++) {
c = [[self filterString] characterAtIndex:i];
if(c != '`') {
- if(c == '.')
+ if(c == '.') {
[fuzzyRegexp appendFormat:@".*?%@",SPUniqueSchemaDelimiter];
- else if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}')
+ }
+ else if (c == '(' || c == ')' || c == '[' || c == ']' || c == '{' || c == '}') {
[fuzzyRegexp appendFormat:@".*?\\%c",c];
- else
+ }
+ else {
[fuzzyRegexp appendFormat:@".*?%c",c];
+ }
}
}
- for (id s in suggestions)
- if ([[s objectForKey:@"display"] isMatchedByRegex:fuzzyRegexp] || [[s objectForKey:@"path"] isMatchedByRegex:fuzzyRegexp])
+ for (id s in suggestions) {
+ if ([[s objectForKey:@"display"] isMatchedByRegex:fuzzyRegexp] || [[s objectForKey:@"path"] isMatchedByRegex:fuzzyRegexp]) {
[newFiltered addObject:s];
-
+ }
+ }
[fuzzyRegexp release];
-
- } else {
+ }
+ else {
NSPredicate* predicate;
- if(caseSensitive)
+ if(caseSensitive) {
predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH %@ OR (match == NULL AND display BEGINSWITH %@)", [self filterString], [self filterString]];
- else
+ }
+ else {
predicate = [NSPredicate predicateWithFormat:@"match BEGINSWITH[c] %@ OR (match == NULL AND display BEGINSWITH[c] %@)", [self filterString], [self filterString]];
+ }
[newFiltered addObjectsFromArray:[suggestions filteredArrayUsingPredicate:predicate]];
}
}
@@ -685,13 +703,10 @@
closeMe = YES;
return;
}
-
}
}
- else
- {
- if(!dictMode)
- [newFiltered addObjectsFromArray:suggestions];
+ else {
+ if(!dictMode) [newFiltered addObjectsFromArray:suggestions];
}
if(![newFiltered count]) {
@@ -699,7 +714,8 @@
[newFiltered release];
closeMe = YES;
return;
- } else {
+ }
+ else {
if([theView completionWasReinvokedAutomatically]) return;
if([[self filterString] hasSuffix:@"."]) {
[theView setCompletionWasReinvokedAutomatically:YES];
@@ -707,34 +723,35 @@
[newFiltered release];
closeMe = YES;
return;
- } else {
+ }
+ else {
[newFiltered addObject:@{@"display" : NSLocalizedString(@"No item found", @"no item found message"), @"noCompletion" : @""}];
}
}
}
+
if(autoCompletionMode && [newFiltered count] == 1 && [[[self filterString] lowercaseString] isEqualToString:[[[newFiltered objectAtIndex:0] objectForKey:@"display"] lowercaseString]]) {
[newFiltered release];
closeMe = YES;
return;
}
-
// if fetching db structure add dummy row for displaying that info on top of the list
- if(isQueryingDatabaseStructure)
- [newFiltered insertObject:@{@"display" : @"dummy", @"noCompletion" : @""} atIndex:0];
+ if(isQueryingDatabaseStructure) [newFiltered insertObject:@{@"display" : @"dummy", @"noCompletion" : @""} atIndex:0];
NSPoint old = NSMakePoint([self frame].origin.x, [self frame].origin.y + [self frame].size.height);
NSInteger displayedRows = [newFiltered count] < SPNarrowDownCompletionMaxRows ? [newFiltered count] : SPNarrowDownCompletionMaxRows;
- CGFloat newHeight = ([theTableView rowHeight] + [theTableView intercellSpacing].height) * ((displayedRows) ? displayedRows : 1);
+ CGFloat newHeight = ([theTableView rowHeight] + [theTableView intercellSpacing].height) * ((displayedRows) ? displayedRows : 1);
- if(caretPos.y >= 0 && (isAbove || caretPos.y < newHeight))
- {
+ if(caretPos.y >= 0 && (isAbove || caretPos.y < newHeight)) {
isAbove = YES;
old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5f);
}
- if(caretPos.y < 0 && (isAbove || ([self rectOfMainScreen].size.height-newHeight) < (caretPos.y*-1)))
+
+ if(caretPos.y < 0 && (isAbove || ([self rectOfMainScreen].size.height-newHeight) < (caretPos.y*-1))) {
old.y = caretPos.y + newHeight + ([tableFont pointSize]*1.5f);
+ }
// newHeight is currently the new height for theTableView, but we need to resize the whole window
// so here we use the difference in height to find the new height for the window
@@ -743,8 +760,7 @@
if (filtered) [filtered release];
filtered = [newFiltered retain];
[newFiltered release];
- if(!dictMode)
- [self checkSpaceForAllowedCharacter];
+ if(!dictMode) [self checkSpaceForAllowedCharacter];
[theTableView reloadData];
[theTableView selectRowIndexes:[NSIndexSet indexSetWithIndex:(isQueryingDatabaseStructure)?1:0] byExtendingSelection:NO];
}
@@ -761,8 +777,7 @@
{
NSRect screen = [[NSScreen mainScreen] frame];
- for (NSScreen *candidate in [NSScreen screens])
- {
+ for (NSScreen *candidate in [NSScreen screens]) {
if (NSMinX([candidate frame]) == 0.0f && NSMinY([candidate frame]) == 0.0f) {
screen = [candidate frame];
}
@@ -780,7 +795,8 @@
if (!closeMe) {
[super orderFront:sender];
[self performSelector:@selector(watchUserEvents) withObject:nil afterDelay:0.05];
- } else {
+ }
+ else {
[self close];
}
}
@@ -791,33 +807,28 @@
[theView setCompletionIsOpen:YES];
closeMe = NO;
- while(!closeMe)
- {
+ while(!closeMe) {
NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantFuture]
- inMode:NSDefaultRunLoopMode
- dequeue:YES];
+ untilDate:[NSDate distantFuture]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
- if(!event)
- continue;
+ if(!event) continue;
// Exit if closeMe has been set in the meantime
if(closeMe) return;
NSEventType t = [event type];
- if([theTableView SP_NarrowDownCompletion_canHandleEvent:event])
- {
+ if([theTableView SP_NarrowDownCompletion_canHandleEvent:event]) {
// skip the rest
}
- else if(t == NSKeyDown)
- {
+ else if(t == NSKeyDown) {
NSUInteger flags = [event modifierFlags];
unichar key = [[event characters] length] == 1 ? [[event characters] characterAtIndex:0] : 0;
// Check if user pressed ⌥ to allow composing of accented characters.
// e.g. for US keyboard "⌥u a" to insert ä
- if (([event modifierFlags] & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) == NSAlternateKeyMask || [[event characters] length] == 0)
- {
+ if (([event modifierFlags] & (NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask)) == NSAlternateKeyMask || [[event characters] length] == 0) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:YES];
if (autoCompletionMode) {
@@ -829,29 +840,27 @@
[NSApp sendEvent: event];
- if(commaInsertionMode)
- break;
+ if(commaInsertionMode) break;
[mutablePrefix appendString:[event characters]];
theCharRange = NSMakeRange(theCharRange.location, theCharRange.length+[[event characters] length]);
theParseRange = NSMakeRange(theParseRange.location, theParseRange.length+[[event characters] length]);
[self filter];
}
- else if((flags & NSAlternateKeyMask) || (flags & NSCommandKeyMask))
- {
+ else if((flags & NSAlternateKeyMask) || (flags & NSCommandKeyMask)) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:YES];
[theView setCompletionIsOpen:NO];
[self close];
[NSApp sendEvent:event];
break;
}
- else if([event keyCode] == 53) // escape
- {
+ else if([event keyCode] == 53) { // escape
if(flags & NSControlKeyMask) {
fuzzyMode = YES;
[theTableView setBackgroundColor:[NSColor colorWithCalibratedRed:0.9f green:0.9f blue:0.9f alpha:1.0f]];
[self filter];
- } else {
+ }
+ else {
if(autoCompletionMode) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:YES];
[theView setCompletionIsOpen:NO];
@@ -862,12 +871,10 @@
break;
}
}
- else if(key == NSCarriageReturnCharacter || key == NSEnterCharacter || key == NSRightArrowFunctionKey || (key == NSTabCharacter && !triggerMode))
- {
+ else if(key == NSCarriageReturnCharacter || key == NSEnterCharacter || key == NSRightArrowFunctionKey || (key == NSTabCharacter && !triggerMode)) {
[self completeAndInsertSnippet];
}
- else if(key == NSBackspaceCharacter || key == NSDeleteCharacter)
- {
+ else if(key == NSBackspaceCharacter || key == NSDeleteCharacter) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:NO];
if (autoCompletionMode) {
@@ -876,8 +883,7 @@
}
[NSApp sendEvent:event];
- if([mutablePrefix length] == 0 || commaInsertionMode)
- break;
+ if([mutablePrefix length] == 0 || commaInsertionMode) break;
spaceCounter = 0;
[mutablePrefix deleteCharactersInRange:NSMakeRange([mutablePrefix length]-1, 1)];
@@ -886,8 +892,7 @@
theParseRange.length--;
[self filter];
}
- else if([textualInputCharacters characterIsMember:key])
- {
+ else if([textualInputCharacters characterIsMember:key]) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:YES];
if (autoCompletionMode) {
@@ -899,10 +904,8 @@
[NSApp sendEvent:event];
- if(commaInsertionMode)
- break;
- if([event keyCode] == 49) // space
- spaceCounter++;
+ if(commaInsertionMode) break;
+ if([event keyCode] == 49) spaceCounter++; // space
[mutablePrefix appendString:[event characters]];
[originalFilterString appendString:[event characters]];
@@ -910,20 +913,18 @@
theParseRange.length++;
[self filter];
[self insertAutocompletePlaceholder];
-
}
- else
- {
+ else {
[NSApp sendEvent:event];
if(cursorMovedLeft) [theView performSelector:@selector(moveRight:)];
break;
}
}
- else if(t == NSRightMouseDown || t == NSLeftMouseDown)
- {
+ else if(t == NSRightMouseDown || t == NSLeftMouseDown) {
if(([event clickCount] == 2)) {
[self completeAndInsertSnippet];
- } else {
+ }
+ else {
if(!NSPointInRect([NSEvent mouseLocation], [self frame])) {
if (autocompletePlaceholderWasInserted) [self removeAutocompletionPlaceholderUsingFastMethod:YES];
if(cursorMovedLeft) [theView performSelector:@selector(moveRight:)];
@@ -933,8 +934,7 @@
[NSApp sendEvent:event];
}
}
- else
- {
+ else {
[NSApp sendEvent:event];
}
}
@@ -952,8 +952,7 @@
// ==================
- (void)insertAutocompletePlaceholder
{
- if([theTableView selectedRow] == -1 || fuzzyMode)
- return;
+ if([theTableView selectedRow] == -1 || fuzzyMode) return;
// Retrieve the current autocompletion length, if any
NSUInteger currentAutocompleteLength = theCharRange.length - [originalFilterString length];
@@ -1000,8 +999,10 @@
if(backtickMode) {
NSRange r = NSMakeRange(theCharRange.location+1,theCharRange.length);
[theView setSelectedRange:r];
- } else
+ }
+ else {
[theView setSelectedRange:theCharRange];
+ }
[theView insertText:originalFilterString];
} else {
NSRange attributeResultRange = NSMakeRange(0, 0);
@@ -1015,12 +1016,11 @@
// Perform a search for the attribute, capturing the range of the [non]match
if ([[theView textStorage] attribute:kSPAutoCompletePlaceholderName atIndex:scanPosition longestEffectiveRange:&attributeResultRange inRange:NSMakeRange(scanPosition, currentLength-scanPosition)]) {
-
// A match was found - attributeResultRange contains the range of the attributed string
[theView shouldChangeTextInRange:attributeResultRange replacementString:@""];
[[theView textStorage] deleteCharactersInRange:attributeResultRange];
- } else {
-
+ }
+ else {
// No match was found. attributeResultRange contains the range of the no match - this can be
// checked to see whether a match is inside the full range.
if (scanPosition + attributeResultRange.length == currentLength) break;
@@ -1030,7 +1030,7 @@
if ([[theView textStorage] attribute:kSPAutoCompletePlaceholderName atIndex:matchStart longestEffectiveRange:&attributeResultRange inRange:NSMakeRange(matchStart, currentLength - matchStart)]) {
[theView shouldChangeTextInRange:attributeResultRange replacementString:@""];
[[theView textStorage] deleteCharactersInRange:attributeResultRange];
- }
+ }
}
scanPosition = attributeResultRange.location;
}
@@ -1040,49 +1040,54 @@
autocompletePlaceholderWasInserted = NO;
}
-- (void)insert_text:(NSString* )aString
+- (void)insert_text:(NSString *)aString
{
-
// Ensure that theCharRange is valid
- if(NSMaxRange(theCharRange) > [[theView string] length])
+ if(NSMaxRange(theCharRange) > [[theView string] length]) {
theCharRange = NSIntersectionRange(NSMakeRange(0,[[theView string] length]), theCharRange);
+ }
[theView breakUndoCoalescing];
NSRange r = [theView selectedRange];
- if(r.length)
+ if(r.length) {
[theView setSelectedRange:r];
+ }
else {
if(backtickMode == 100) {
NSString *replaceString = [[theView string] substringWithRange:theCharRange];
BOOL nextCharIsBacktick = ([replaceString hasSuffix:@"`"]);
if(theCharRange.length == 1) nextCharIsBacktick = NO;
if(!nextCharIsBacktick) {
- if([replaceString hasPrefix:@"`"])
+ if([replaceString hasPrefix:@"`"]) {
[theView setSelectedRange:NSMakeRange(theCharRange.location, theCharRange.length+2)];
- else
+ }
+ else {
[theView setSelectedRange:theCharRange];
+ }
} else {
[theView setSelectedRange:theCharRange];
}
backtickMode = 0;
- } else
+ }
+ else {
[theView setSelectedRange:theCharRange];
+ }
}
[theView breakUndoCoalescing];
[theView insertText:aString];
-
+
// If completion string contains backticks move caret out of the backticks
- if(backtickMode && !triggerMode)
+ if(backtickMode && !triggerMode) {
[theView performSelector:@selector(moveRight:)];
- // If it's a function or procedure append () and if a argument list can be retieved insert them as snippets
+ }
#ifndef SP_CODA
+ // If it's a function or procedure append () and if a argument list can be retieved insert them as snippets
else if([prefs boolForKey:SPCustomQueryFunctionCompletionInsertsArguments] && ([[[filtered objectAtIndex:[theTableView selectedRow]] objectForKey:@"image"] hasPrefix:@"func"] || [[[filtered objectAtIndex:[theTableView selectedRow]] objectForKey:@"image"] hasPrefix:@"proc"]) && ![aString hasSuffix:@")"]) {
NSString *functionArgumentSnippet = [NSString stringWithFormat:@"(%@)", [[SPQueryController sharedQueryController] argumentSnippetForFunction:aString]];
[theView insertAsSnippet:functionArgumentSnippet atRange:[theView selectedRange]];
- if([functionArgumentSnippet length] == 2)
- [theView performSelector:@selector(moveLeft:)];
+ if([functionArgumentSnippet length] == 2) [theView performSelector:@selector(moveLeft:)];
}
#endif
}
@@ -1098,13 +1103,14 @@
return;
}
- if(dictMode){
+ if(dictMode) {
[self insert_text:[selectedItem objectForKey:@"match"] ?: [selectedItem objectForKey:@"display"]];
- } else {
+ }
+ else {
NSString* candidateMatch = [selectedItem objectForKey:@"match"] ?: [selectedItem objectForKey:@"display"];
if([selectedItem objectForKey:@"isRef"]
- && ([[NSApp currentEvent] modifierFlags] & (NSShiftKeyMask))
- && [(NSString*)[selectedItem objectForKey:@"path"] length] && theAliasName == nil) {
+ && ([[NSApp currentEvent] modifierFlags] & (NSShiftKeyMask))
+ && [(NSString*)[selectedItem objectForKey:@"path"] length] && theAliasName == nil) {
NSString *path = [[[selectedItem objectForKey:@"path"] componentsSeparatedByString:SPUniqueSchemaDelimiter] componentsJoinedByPeriodAndBacktickQuotedAndIgnoreFirst];
// Check if path's db name is the current selected db name
@@ -1116,21 +1122,24 @@
} else {
[self insert_text:path];
}
- } else {
+ }
+ else {
// Is completion string a schema name for current connection
if([selectedItem objectForKey:@"isRef"]) {
backtickMode = 100; // suppress move the caret one step rightwards
- if ([prefs boolForKey:SPCustomQueryEditorCompleteWithBackticks]) {
- [self insert_text:[candidateMatch backtickQuotedString]];
- } else {
- [self insert_text:candidateMatch];
- }
- } else {
+ if ([prefs boolForKey:SPCustomQueryEditorCompleteWithBackticks]) {
+ [self insert_text:[candidateMatch backtickQuotedString]];
+ }
+ else {
+ [self insert_text:candidateMatch];
+ }
+ }
+ else {
[self insert_text:candidateMatch];
}
}
}
-
+
// Pressing CTRL while inserting an item the suggestion list keeps open
// to allow to add more field/table names comma separated
if([selectedItem objectForKey:@"isRef"] && [[NSApp currentEvent] modifierFlags] & (NSControlKeyMask)) {
@@ -1138,7 +1147,8 @@
theCharRange = [theView selectedRange];
theParseRange = [theView selectedRange];
commaInsertionMode = YES;
- } else {
+ }
+ else {
closeMe = YES;
}
}