From 967136fd591a7f13185a0b353827bf8946883fc8 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Mon, 11 Jan 2010 17:48:49 +0000 Subject: =?UTF-8?q?=E2=80=A2=20further=20preparations=20to=20F5=20completi?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: not yet active - only querying the data in background will be performed for testing --- Source/CMTextView.m | 121 ++++++++++++++++++++++++------------ Source/SPNarrowDownCompletion.m | 132 ++++++++++++++++++++++++---------------- Source/TableDocument.h | 2 + Source/TableDocument.m | 20 ++++-- Source/TablesList.h | 1 + Source/TablesList.m | 10 ++- 6 files changed, 190 insertions(+), 96 deletions(-) (limited to 'Source') diff --git a/Source/CMTextView.m b/Source/CMTextView.m index bebea5c0..e05ceefb 100644 --- a/Source/CMTextView.m +++ b/Source/CMTextView.m @@ -124,7 +124,7 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) * NSDic key "display" := the displayed and to be inserted word * NSDic key "image" := an image to be shown left from "display" (optional) * - * [NSDictionary dictionaryWithObjectsAndKeys:@"foo", @"display", @"`foo`", @"insert", @"func-small", @"image", nil] + * [NSDictionary dictionaryWithObjectsAndKeys:@"foo", @"display", @"`foo`", @"match", @"func-small", @"image", nil] */ - (NSArray *)suggestionsForSQLCompletionWith:(NSString *)currentWord dictMode:(BOOL)isDictMode { @@ -140,42 +140,6 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) NSMutableArray *possibleCompletions = [[NSMutableArray alloc] initWithCapacity:32]; - if([mySQLConnection isConnected]) - { - - // NSLog(@"struct:\n %@", [mySQLConnection getDbStructure]); - - // Add table names to completions list - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allTableNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"table-small-square", @"image", nil]]; - - // Add view names to completions list - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allViewNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"table-view-small-square", @"image", nil]]; - - // Add field names to completions list for currently selected table - if ([[[self window] delegate] table] != nil) - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tableDataInstance"] valueForKey:@"columnNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"dummy-small", @"image", nil]]; - - - // Add all database names to completions list - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allDatabaseNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"database-small", @"image", nil]]; - - // Add proc/func only for MySQL version 5 or higher - if(mySQLmajorVersion > 4) { - // Add all procedures to completions list for currently selected table - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allProcedureNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"proc-small", @"image", nil]]; - - // Add all function to completions list for currently selected table - for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allFunctionNames"]) - [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"func-small", @"image", nil]]; - } - - } - // If caret is not inside backticks add keywords and all words coming from the view. if([[self string] length] && ![[[self textStorage] attribute:kBTQuote atIndex:[self selectedRange].location-1 effectiveRange:nil] isEqualToString:kBTQuoteValue] ) { @@ -209,9 +173,90 @@ NSInteger alphabeticSort(id string1, id string2, void *reverse) } + if([mySQLConnection isConnected]) + { + // Add structural db/table/field data to completions list or fallback to gathering TablesList data + NSDictionary *dbs = [NSDictionary dictionaryWithDictionary:[mySQLConnection getDbStructure]]; + if(dbs != nil && [dbs count]) { + NSArray *allDbs = [dbs allKeys]; + NSSortDescriptor *desc = [[NSSortDescriptor alloc] initWithKey:nil ascending:YES selector:@selector(localizedCompare:)]; + NSArray *sortedDbs = [allDbs sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; + for(id db in sortedDbs) { + NSArray *allTables = [[dbs objectForKey:db] allKeys]; + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:db, @"display", @"database-small", @"image", nil]]; + NSArray *sortedTables = [allTables sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; + for(id table in sortedTables) { + NSDictionary * theTable = [[dbs objectForKey:db] objectForKey:table]; + NSArray *allFields = [theTable allKeys]; + NSInteger structtype = [[theTable objectForKey:@" struct_type "] intValue]; + BOOL breakFlag = NO; + switch(structtype) { + case 0: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-small-square", @"image", db, @"path", nil]]; + break; + case 1: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"table-view-small-square", @"image", db, @"path", nil]]; + break; + case 2: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"proc-small", @"image", db, @"path", nil]]; + breakFlag = YES; + break; + case 3: + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:table, @"display", @"func-small", @"image", db, @"path", nil]]; + breakFlag = YES; + break; + } + if(!breakFlag) { + NSArray *sortedFields = [allFields sortedArrayUsingDescriptors:[NSArray arrayWithObject:desc]]; + for(id field in sortedFields) { + if(![field hasPrefix:@" "]) { + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:field, @"display", @"field-small-square", @"image", [NSString stringWithFormat:@"%@⇠%@",table,db], @"path", [theTable objectForKey:field], @"type", nil]]; + } + } + } + } + } + } else { + // [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:NSLocalizedString(@"updating data…", @"updating table data for completion in progress message"), @"path", nil]]; + + // Add all database names to completions list + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allDatabaseNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"database-small", @"image", nil]]; + + // Add all system database names to completions list + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allSystemDatabaseNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"database-small", @"image", nil]]; + + // Add table names to completions list + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allTableNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"table-small-square", @"image", nil]]; + + // Add view names to completions list + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allViewNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"table-view-small-square", @"image", nil]]; + + // Add field names to completions list for currently selected table + if ([[[self window] delegate] table] != nil) + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tableDataInstance"] valueForKey:@"columnNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"field-small-square", @"image", nil]]; + + // Add proc/func only for MySQL version 5 or higher + if(mySQLmajorVersion > 4) { + // Add all procedures to completions list for currently selected table + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allProcedureNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"proc-small", @"image", nil]]; + + // Add all function to completions list for currently selected table + for (id obj in [[[[self window] delegate] valueForKeyPath:@"tablesListInstance"] valueForKey:@"allFunctionNames"]) + [possibleCompletions addObject:[NSDictionary dictionaryWithObjectsAndKeys:obj, @"display", @"func-small", @"image", nil]]; + } + } + } + // Make suggestions unique + BOOL avoidUnique = ([currentWord isEqualToString:@"`"]) ? YES :NO; for(id suggestion in possibleCompletions) - if(![compl containsObject:suggestion]) + if(avoidUnique || ![compl containsObject:suggestion]) [compl addObject:suggestion]; [possibleCompletions release]; diff --git a/Source/SPNarrowDownCompletion.m b/Source/SPNarrowDownCompletion.m index 090319dc..0724d722 100644 --- a/Source/SPNarrowDownCompletion.m +++ b/Source/SPNarrowDownCompletion.m @@ -98,7 +98,7 @@ // ============================= - (id)init { - if(self = [super initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]) + if(self = [super initWithContentRect:NSMakeRect(0,0,450,0) styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO]) { mutablePrefix = [NSMutableString new]; textualInputCharacters = [[NSMutableCharacterSet alphanumericCharacterSet] retain]; @@ -193,24 +193,44 @@ [self setLevel:NSStatusWindowLevel]; [self setHidesOnDeactivate:YES]; [self setHasShadow:YES]; + [self setAlphaValue:0.9]; NSScrollView* scrollView = [[[NSScrollView alloc] initWithFrame:NSZeroRect] autorelease]; - [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + // [scrollView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [scrollView setAutohidesScrollers:YES]; [scrollView setHasVerticalScroller:YES]; + [scrollView setHasHorizontalScroller:NO]; [[scrollView verticalScroller] setControlSize:NSSmallControlSize]; + [[scrollView horizontalScroller] setControlSize:NSSmallControlSize]; theTableView = [[[NSTableView alloc] initWithFrame:NSZeroRect] autorelease]; [theTableView setFocusRingType:NSFocusRingTypeNone]; [theTableView setAllowsEmptySelection:NO]; [theTableView setHeaderView:nil]; - - NSTableColumn *column = [[[NSTableColumn alloc] initWithIdentifier:@"foo"] autorelease]; - // - [column setDataCell:[[ImageAndTextCell new] autorelease]]; - [column setEditable:NO]; - [theTableView addTableColumn:column]; - [column setWidth:[theTableView bounds].size.width]; + // [theTableView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleSourceList]; + + NSTableColumn *column0 = [[[NSTableColumn alloc] initWithIdentifier:@"image"] autorelease]; + [column0 setDataCell:[[ImageAndTextCell new] autorelease]]; + [column0 setEditable:NO]; + [theTableView addTableColumn:column0]; + [column0 setWidth:20]; + NSTableColumn *column1 = [[[NSTableColumn alloc] initWithIdentifier:@"name"] autorelease]; + [column1 setEditable:NO]; + // [[column1 dataCell] setFont:[NSFont systemFontOfSize:12]]; + [theTableView addTableColumn:column1]; + [column1 setWidth:180]; + NSTableColumn *column2 = [[[NSTableColumn alloc] initWithIdentifier:@"type"] autorelease]; + [column2 setEditable:NO]; + // [[column2 dataCell] setFont:[NSFont systemFontOfSize:11]]; + [[column2 dataCell] setTextColor:[NSColor grayColor]]; + [theTableView addTableColumn:column2]; + [column2 setWidth:120]; + NSTableColumn *column3 = [[[NSTableColumn alloc] initWithIdentifier:@"path"] autorelease]; + [column3 setEditable:NO]; + // [[column3 dataCell] setFont:[NSFont systemFontOfSize:11]]; + [[column3 dataCell] setTextColor:[NSColor grayColor]]; + [theTableView addTableColumn:column3]; + [column3 setWidth:130]; [theTableView setDataSource:self]; [scrollView setDocumentView:theTableView]; @@ -230,15 +250,22 @@ { NSImage* image = nil; NSString* imageName = nil; - if(!dictMode) { - imageName = [[filtered objectAtIndex:rowIndex] objectForKey:@"image"]; - if(imageName) - image = [NSImage imageNamed:imageName]; - [[aTableColumn dataCell] setImage:image]; + if([[aTableColumn identifier] isEqualToString:@"image"]) { + if(!dictMode) { + imageName = [[filtered objectAtIndex:rowIndex] objectForKey:@"image"]; + if(imageName) + image = [NSImage imageNamed:imageName]; + [[aTableColumn dataCell] setImage:image]; + return @""; + } + } else if([[aTableColumn identifier] isEqualToString:@"name"]) { return [[filtered objectAtIndex:rowIndex] objectForKey:@"display"]; + } else if([[aTableColumn identifier] isEqualToString:@"type"]) { + return ([[filtered objectAtIndex:rowIndex] objectForKey:@"type"])?[[filtered objectAtIndex:rowIndex] objectForKey:@"type"]:@""; + } else if ([[aTableColumn identifier] isEqualToString:@"path"]) { + return ([[filtered objectAtIndex:rowIndex] objectForKey:@"path"])?[[filtered objectAtIndex:rowIndex] objectForKey:@"path"]:@""; } return [filtered objectAtIndex:rowIndex]; - } // ==================== @@ -246,7 +273,7 @@ // ==================== - (void)filter { - NSRect mainScreen = [self rectOfMainScreen]; + // NSRect mainScreen = [self rectOfMainScreen]; NSArray* newFiltered; if([mutablePrefix length] > 0) @@ -274,46 +301,47 @@ NSInteger displayedRows = [newFiltered count] < SP_NARROWDOWNLIST_MAX_ROWS ? [newFiltered count] : SP_NARROWDOWNLIST_MAX_ROWS; CGFloat newHeight = ([theTableView rowHeight] + [theTableView intercellSpacing].height) * displayedRows; - CGFloat maxLen = 1; - NSString* item; - NSInteger i; - BOOL spaceInSuggestion = NO; - [textualInputCharacters removeCharactersInString:@" "]; - CGFloat maxWidth = [self frame].size.width; - if([newFiltered count]>0) - { - for(i=0; i<[newFiltered count]; i++) - { - if(dictMode) - item = NSArrayObjectAtIndex(newFiltered, i); - else - item = [NSArrayObjectAtIndex(newFiltered, i) objectForKey:@"display"]; - // If space in suggestion add space to allowed input chars - if(!spaceInSuggestion && [item rangeOfString:@" "].length) { - [textualInputCharacters addCharactersInString:@" "]; - spaceInSuggestion = YES; - } - - if([item length]>maxLen) - maxLen = [item length]; - } - maxWidth = maxLen*16; - maxWidth = (maxWidth>340) ? 340 : maxWidth; - } - if(caretPos.y>=0 && (isAbove || caretPos.y0) + // { + // for(i=0; i<[newFiltered count]; i++) + // { + // if(dictMode) + // item = NSArrayObjectAtIndex(newFiltered, i); + // else + // item = [NSArrayObjectAtIndex(newFiltered, i) objectForKey:@"display"]; + // // If space in suggestion add space to allowed input chars + // if(!spaceInSuggestion && [item rangeOfString:@" "].length) { + // [textualInputCharacters addCharactersInString:@" "]; + // spaceInSuggestion = YES; + // } + // + // if([item length]>maxLen) + // maxLen = [item length]; + // } + // maxWidth = maxLen*16; + // maxWidth = (maxWidth>340) ? 340 : maxWidth; + // maxWidth = (maxWidth<20) ? 20 : maxWidth; + // } + // if(caretPos.y>=0 && (isAbove || caretPos.y 0) { + if ([allSystemDatabases count] > 0) { [[chooseDatabaseButton menu] addItem:[NSMenuItem separatorItem]]; } @@ -1114,6 +1115,14 @@ return allDatabases; } +/** + * Returns an array of all available system database names + */ +- (NSArray *)allSystemDatabaseNames +{ + return allSystemDatabases; +} + /** * Alert sheet method. Invoked when an alert sheet is dismissed. * @@ -3599,6 +3608,7 @@ { [_encoding release]; [allDatabases release]; + [allSystemDatabases release]; [printWebView release]; if (connectionController) [connectionController release]; diff --git a/Source/TablesList.h b/Source/TablesList.h index b9a3d0c2..911945eb 100644 --- a/Source/TablesList.h +++ b/Source/TablesList.h @@ -139,6 +139,7 @@ enum sp_table_types - (NSArray *)allFunctionNames; - (NSArray *)allProcedureNames; - (NSArray *)allDatabaseNames; +- (NSArray *)allSystemDatabaseNames; - (BOOL)structureLoaded; - (BOOL)contentLoaded; - (BOOL)statusLoaded; diff --git a/Source/TablesList.m b/Source/TablesList.m index b5dbc110..b5490e7a 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -87,7 +87,7 @@ [[NSNotificationCenter defaultCenter] postNotificationName:@"SMySQLQueryWillBePerformed" object:tableDocumentInstance]; // Query the structure of all databases in the background (mainly for completion) - [mySQLConnection performSelector:@selector(queryDbStructure) withObject:nil afterDelay:0.1]; + [mySQLConnection performSelector:@selector(queryDbStructure) withObject:nil afterDelay:0.5]; // Select the table list for the current database. On MySQL versions after 5 this will include // views; on MySQL versions >= 5.0.02 select the "full" list to also select the table type column. @@ -1064,6 +1064,14 @@ return [tableDocumentInstance allDatabaseNames]; } +/** + * Returns an array of all available database names + */ +- (NSArray *)allSystemDatabaseNames +{ + return [tableDocumentInstance allSystemDatabaseNames]; +} + /** * Database table types accessor */ -- cgit v1.2.3