aboutsummaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBibiko <bibiko@eva.mpg.de>2010-03-25 15:24:56 +0000
committerBibiko <bibiko@eva.mpg.de>2010-03-25 15:24:56 +0000
commit8d055c6df1d1590f97bd9e7c4834c05c706f27b7 (patch)
treeffbefdfe38f18be63a294465c6a6ca8426c8a76b /Source
parent74cb1152eeb0dcc83f12ea6cf040eacc4e15c551 (diff)
downloadsequelpro-8d055c6df1d1590f97bd9e7c4834c05c706f27b7.tar.gz
sequelpro-8d055c6df1d1590f97bd9e7c4834c05c706f27b7.tar.bz2
sequelpro-8d055c6df1d1590f97bd9e7c4834c05c706f27b7.zip
• Navigator
- first implementation of a search functionality, workable but tiny issues have to be improved - up to now the only search implemented is 'contains', regexp/fuzzy search will come soon - the search is only performed in the main outline view, the upper one is static - for the new search store all available schema paths uniquely in an array which will be set during queryDbStructure (this avoids re-parsing of a dict structure)
Diffstat (limited to 'Source')
-rw-r--r--Source/SPNavigatorController.h4
-rw-r--r--Source/SPNavigatorController.m235
2 files changed, 191 insertions, 48 deletions
diff --git a/Source/SPNavigatorController.h b/Source/SPNavigatorController.h
index 94e8b6a3..fb4c5bc2 100644
--- a/Source/SPNavigatorController.h
+++ b/Source/SPNavigatorController.h
@@ -42,7 +42,8 @@
NSUserDefaults *prefs;
NSMutableDictionary *schemaData;
- NSMutableDictionary *schemaDataUnFiltered;
+ NSMutableDictionary *schemaDataFiltered;
+ NSMutableDictionary *allSchemaKeys;
NSMutableArray *infoArray;
NSMutableDictionary *expandStatus1;
NSMutableDictionary *expandStatus2;
@@ -52,6 +53,7 @@
NSRect selectionViewPort1;
NSRect selectionViewPort2;
BOOL ignoreUpdate;
+ BOOL isFiltered;
}
+ (SPNavigatorController *)sharedNavigatorController;
diff --git a/Source/SPNavigatorController.m b/Source/SPNavigatorController.m
index 64e54053..230d6991 100644
--- a/Source/SPNavigatorController.m
+++ b/Source/SPNavigatorController.m
@@ -24,7 +24,7 @@
#import "SPNavigatorController.h"
#import "RegexKitLite.h"
-#import "SPOutlineView.h"
+#import "SPNavigatorOutlineView.h"
#import "SPConstants.h"
#import "ImageAndTextCell.h"
#import "TableDocument.h"
@@ -64,14 +64,16 @@ static SPNavigatorController *sharedNavigatorController = nil;
{
if((self = [super initWithWindowNibName:@"Navigator"])) {
- schemaData = [[NSMutableDictionary alloc] init];
- schemaDataUnFiltered = [[NSMutableDictionary alloc] init];
- expandStatus1 = [[NSMutableDictionary alloc] init];
- expandStatus2 = [[NSMutableDictionary alloc] init];
- infoArray = [[NSMutableArray alloc] init];
- selectedKey1 = @"";
- selectedKey2 = @"";
- ignoreUpdate = NO;
+ schemaDataFiltered = [[NSMutableDictionary alloc] init];
+ allSchemaKeys = [[NSMutableDictionary alloc] init];
+ schemaData = [[NSMutableDictionary alloc] init];
+ expandStatus1 = [[NSMutableDictionary alloc] init];
+ expandStatus2 = [[NSMutableDictionary alloc] init];
+ infoArray = [[NSMutableArray alloc] init];
+ selectedKey1 = @"";
+ selectedKey2 = @"";
+ ignoreUpdate = NO;
+ isFiltered = NO;
[syncButton setState:NSOffState];
}
@@ -83,8 +85,9 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ if(schemaDataFiltered) [schemaDataFiltered release];
+ if(allSchemaKeys) [allSchemaKeys release];
if(schemaData) [schemaData release];
- if(schemaDataUnFiltered) [schemaDataUnFiltered release];
if(infoArray) [infoArray release];
if(expandStatus1) [expandStatus1 release];
if(expandStatus2) [expandStatus2 release];
@@ -151,22 +154,22 @@ static SPNavigatorController *sharedNavigatorController = nil;
if( [expandStatus1 objectForKey:[parentKeys objectAtIndex:0]] )
[outlineSchema1 expandItem:item];
}
- for( i = 0; i < [outlineSchema2 numberOfRows]; i++ ) {
- id item = [outlineSchema2 itemAtRow:i];
- id parentObject = [outlineSchema2 parentForItem:item] ? [outlineSchema2 parentForItem:item] : schemaData;
- id parentKeys = [parentObject allKeysForObject:item];
- if(parentKeys && [parentKeys count] == 1)
- if( [expandStatus2 objectForKey:[parentKeys objectAtIndex:0]] )
- [outlineSchema2 expandItem:item];
+ if(!isFiltered) {
+ for( i = 0; i < [outlineSchema2 numberOfRows]; i++ ) {
+ id item = [outlineSchema2 itemAtRow:i];
+ id parentObject = [outlineSchema2 parentForItem:item] ? [outlineSchema2 parentForItem:item] : schemaData;
+ id parentKeys = [parentObject allKeysForObject:item];
+ if(parentKeys && [parentKeys count] == 1)
+ if( [expandStatus2 objectForKey:[parentKeys objectAtIndex:0]] )
+ [outlineSchema2 expandItem:item];
+ }
}
}
- (void)saveSelectedItems
{
selectedKey1 = @"";
- selectedKey2 = @"";
selectionViewPort1 = [outlineSchema1 visibleRect];
- selectionViewPort2 = [outlineSchema2 visibleRect];
if(schemaData) {
id selection = nil;
selection = [outlineSchema1 selectedItem];
@@ -176,6 +179,12 @@ static SPNavigatorController *sharedNavigatorController = nil;
if(parentKeys && [parentKeys count] == 1)
selectedKey1 = [[parentKeys objectAtIndex:0] description];
}
+
+ if(isFiltered) return;
+
+ selectedKey2 = @"";
+ selectionViewPort2 = [outlineSchema2 visibleRect];
+
selection = [outlineSchema2 selectedItem];
if(selection) {
id parentObject = [outlineSchema2 parentForItem:selection] ? [outlineSchema2 parentForItem:selection] : schemaData;
@@ -258,7 +267,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
}
}
}
- if(selectedKey2 && [selectedKey2 length]) {
+ if(!isFiltered && selectedKey2 && [selectedKey2 length]) {
id item = schemaData;
NSArray *pathArray = [selectedKey2 componentsSeparatedByString:SPUniqueSchemaDelimiter];
NSMutableString *aKey = [NSMutableString string];
@@ -303,11 +312,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
if(docCounter > 1) return;
+ [schemaDataFiltered removeObjectForKey:connectionID];
[schemaData removeObjectForKey:connectionID];
+ [allSchemaKeys removeObjectForKey:connectionID];
[self saveSelectedItems];
[outlineSchema1 reloadData];
[outlineSchema2 reloadData];
[self restoreSelectedItems];
+ if(isFiltered)
+ [self filterTree:self];
}
}
@@ -369,10 +382,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
[self saveSelectedItems];
[infoArray removeAllObjects];
- if(connectionID)
+ if(connectionID) {
+ [schemaDataFiltered removeObjectForKey:connectionID];
[schemaData removeObjectForKey:connectionID];
- else
+ [allSchemaKeys removeObjectForKey:connectionID];
+ } else {
+ [schemaDataFiltered removeAllObjects];
[schemaData removeAllObjects];
+ [allSchemaKeys removeAllObjects];
+ }
[outlineSchema1 reloadData];
[outlineSchema2 reloadData];
@@ -392,12 +410,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
if([theConnection getDbStructure] && [[theConnection getDbStructure] objectForKey:connectionName]) {
[schemaData setObject:[[theConnection getDbStructure] objectForKey:connectionName] forKey:connectionName];
+ [allSchemaKeys setObject:[theConnection getAllKeysOfDbStructure] forKey:connectionName];
} else {
if([theConnection serverMajorVersion] > 4) {
[schemaData setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"%@&DEL&no data loaded yet", connectionName]];
+ [allSchemaKeys setObject:[NSArray array] forKey:connectionName];
} else {
[schemaData setObject:[NSDictionary dictionary] forKey:[NSString stringWithFormat:@"%@&DEL&no data for this server version", connectionName]];
+ [allSchemaKeys setObject:[NSArray array] forKey:connectionName];
}
}
@@ -413,6 +434,9 @@ static SPNavigatorController *sharedNavigatorController = nil;
[self syncButtonAction:self];
+ if(isFiltered)
+ [self filterTree:self];
+
}
@@ -424,7 +448,10 @@ static SPNavigatorController *sharedNavigatorController = nil;
{
// Reset everything
+ [searchField setStringValue:@""];
+ [schemaDataFiltered removeAllObjects];
[schemaData removeAllObjects];
+ [allSchemaKeys removeAllObjects];
[infoArray removeAllObjects];
[expandStatus1 removeAllObjects];
[expandStatus2 removeAllObjects];
@@ -435,6 +462,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
selectionViewPort1 = NSZeroRect;
selectionViewPort2 = NSZeroRect;
[syncButton setState:NSOffState];
+ isFiltered = NO;
if ([[[NSDocumentController sharedDocumentController] documents] count]) {
for(id doc in [[NSDocumentController sharedDocumentController] documents]) {
@@ -452,7 +480,82 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (IBAction)filterTree:(id)sender
{
- NSString *pattern = [searchField stringValue];
+ NSString *pattern = [[[searchField stringValue] stringByReplacingOccurrencesOfString:@"." withString:SPUniqueSchemaDelimiter] lowercaseString];
+
+ [self saveSelectedItems];
+
+ id currentItem = [outlineSchema2 selectedItem];
+ id parentObject = nil;
+ if(isFiltered)
+ parentObject = [outlineSchema2 parentForItem:currentItem] ? [outlineSchema2 parentForItem:currentItem] : schemaDataFiltered;
+ else
+ parentObject = [outlineSchema2 parentForItem:currentItem] ? [outlineSchema2 parentForItem:currentItem] : schemaData;
+
+ NSString *connectionID = nil;
+ if(parentObject && [[parentObject allKeys] count])
+ connectionID = [[[[parentObject allKeys] objectAtIndex:0] componentsSeparatedByString:SPUniqueSchemaDelimiter] objectAtIndex:0];
+
+ if((pattern && ![pattern length]) || !parentObject || ![[parentObject allKeys] count] || !connectionID || [connectionID length] < 2 || ![allSchemaKeys objectForKey:connectionID]) {
+ isFiltered = NO;
+ [searchField setStringValue:@""];
+ [schemaDataFiltered removeAllObjects];
+ [outlineSchema2 reloadData];
+ [self restoreExpandStatus];
+ [self restoreSelectedItems];
+ return;
+ }
+
+ isFiltered = YES;
+
+ [syncButton setState:NSOffState];
+
+ NSMutableDictionary *structure = [NSMutableDictionary dictionary];
+ [structure setObject:[NSMutableDictionary dictionary] forKey:connectionID];
+
+
+ for(NSString* item in [allSchemaKeys objectForKey:connectionID]) {
+ if([[item lowercaseString] rangeOfString:pattern].length) {
+
+ NSArray *a = [item componentsSeparatedByString:SPUniqueSchemaDelimiter];
+
+ NSString *db_id = [NSString stringWithFormat:@"%@%@%@", connectionID,SPUniqueSchemaDelimiter,[a objectAtIndex:1]];
+
+ if(!a || [a count] < 2) continue;
+
+ if(![[structure valueForKey:connectionID] valueForKey:db_id]) {
+ [[structure valueForKey:connectionID] setObject:[NSMutableDictionary dictionary] forKey:db_id];
+ }
+ if([a count] > 2) {
+
+ NSString *table_id = [NSString stringWithFormat:@"%@%@%@", db_id,SPUniqueSchemaDelimiter,[a objectAtIndex:2]];
+
+ if(![[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id]) {
+ [[[structure valueForKey:connectionID] valueForKey:db_id] setObject:[NSMutableDictionary dictionary] forKey:table_id];
+ }
+
+ if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "])
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
+ [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:@" struct_type "] forKey:@" struct_type "];
+ else
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
+ [NSNumber numberWithInt:0] forKey:@" struct_type "];
+
+ if([a count] > 3) {
+ NSString *field_id = [NSString stringWithFormat:@"%@%@%@", table_id,SPUniqueSchemaDelimiter,[a objectAtIndex:3]];
+ if([[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id])
+ [[[[structure valueForKey:connectionID] valueForKey:db_id] valueForKey:table_id] setObject:
+ [[[[schemaData objectForKey:connectionID] objectForKey:db_id] objectForKey:table_id] objectForKey:field_id] forKey:field_id];
+ }
+ }
+
+ }
+ }
+ [outlineSchema1 reloadData];
+ [schemaDataFiltered removeAllObjects];
+ [outlineSchema2 reloadData];
+ [schemaDataFiltered setDictionary:[structure retain]];
+ [outlineSchema2 reloadData];
+ [outlineSchema2 expandItem:[outlineSchema2 itemAtRow:0] expandChildren:YES];
}
- (IBAction)syncButtonAction:(id)sender
@@ -461,6 +564,14 @@ static SPNavigatorController *sharedNavigatorController = nil;
if(!schemaData) return;
if([syncButton state] == NSOnState) {
+
+ if(isFiltered) {
+ isFiltered = NO;
+ [schemaDataFiltered removeAllObjects];
+ [outlineSchema2 reloadData];
+ [searchField setStringValue:@""];
+ }
+
if ([[[NSDocumentController sharedDocumentController] documents] count]) {
TableDocument *doc = [[NSDocumentController sharedDocumentController] currentDocument];
NSMutableString *key = [NSMutableString string];
@@ -483,10 +594,14 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)outlineViewItemDidExpand:(NSNotification *)notification
{
- SPOutlineView *ov = [notification object];
+ SPNavigatorOutlineView *ov = [notification object];
id item = [[notification userInfo] objectForKey:@"NSObject"];
- id parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaData;
+ id parentObject = nil;
+ if(isFiltered && ov == outlineSchema2)
+ parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaDataFiltered;
+ else
+ parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaData;
if(!parentObject || ![parentObject allKeysForObject:item] || ![[parentObject allKeysForObject:item] count]) return;
@@ -494,7 +609,7 @@ static SPNavigatorController *sharedNavigatorController = nil;
{
[expandStatus1 setObject:@"" forKey:[[parentObject allKeysForObject:item] objectAtIndex:0]];
}
- else if(ov == outlineSchema2)
+ else if(ov == outlineSchema2 && !isFiltered)
{
[expandStatus2 setObject:@"" forKey:[[parentObject allKeysForObject:item] objectAtIndex:0]];
}
@@ -502,22 +617,32 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)outlineViewItemDidCollapse:(NSNotification *)notification
{
- SPOutlineView *ov = [notification object];
+ SPNavigatorOutlineView *ov = [notification object];
id item = [[notification userInfo] objectForKey:@"NSObject"];
- id parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaData;
-
+ id parentObject = nil;
+ if(isFiltered && ov == outlineSchema2)
+ parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaDataFiltered;
+ else
+ parentObject = [ov parentForItem:item] ? [ov parentForItem:item] : schemaData;
+
if(!parentObject || ![parentObject allKeysForObject:item] || ![[parentObject allKeysForObject:item] count]) return;
if(ov == outlineSchema1)
[expandStatus1 removeObjectForKey:[[parentObject allKeysForObject:item] objectAtIndex:0]];
- else if(ov == outlineSchema2)
+ else if(ov == outlineSchema2 && !isFiltered)
[expandStatus2 removeObjectForKey:[[parentObject allKeysForObject:item] objectAtIndex:0]];
}
- (id)outlineView:(id)outlineView child:(NSInteger)index ofItem:(id)item
{
- if (item == nil) item = schemaData;
+
+ if (item == nil) {
+ if(isFiltered && outlineView == outlineSchema2)
+ item = schemaDataFiltered;
+ else
+ item = schemaData;
+ }
if ([item isKindOfClass:[NSDictionary class]] && [item allKeys] && [[item allKeys] count]) {
NSSortDescriptor *desc = [[NSSortDescriptor alloc] initWithKey:nil ascending:YES selector:@selector(localizedCompare:)];
@@ -548,10 +673,13 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (NSInteger)outlineView:(id)outlineView numberOfChildrenOfItem:(id)item
{
- if(!schemaData) return 0;
-
- if(item == nil)
- return [schemaData count];
+ if(isFiltered && outlineView == outlineSchema2) {
+ if(item == nil)
+ return [schemaDataFiltered count];
+ } else {
+ if(item == nil)
+ return [schemaData count];
+ }
if([item isKindOfClass:[NSDictionary class]] || [item isKindOfClass:[NSArray class]])
return [item count];
@@ -562,9 +690,12 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (id)outlineView:(id)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
{
- if(!schemaData) return @"";
+ id parentObject = nil;
- id parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
+ if(outlineView == outlineSchema2 && isFiltered)
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaDataFiltered;
+ else
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
if(!parentObject) return @"…";
@@ -673,8 +804,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (CGFloat)outlineView:(NSOutlineView *)outlineView heightOfRowByItem:(id)item
{
- id parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
-
+ id parentObject = nil;
+
+ if(outlineView == outlineSchema2 && isFiltered)
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaDataFiltered;
+ else
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
+
+ if(!parentObject) return 0;
+
// Use " struct_type " as placeholder to increase distance between table and first field name otherwise it looks ugly
if([parentObject allKeysForObject:item] && [[parentObject allKeysForObject:item] count] && [[[parentObject allKeysForObject:item] objectAtIndex:0] hasPrefix:@" "])
return 5.0;
@@ -689,7 +827,15 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldSelectItem:(id)item
{
- id parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
+ id parentObject = nil;
+
+ if(outlineView == outlineSchema2 && isFiltered)
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaDataFiltered;
+ else
+ parentObject = [outlineView parentForItem:item] ? [outlineView parentForItem:item] : schemaData;
+
+ if(!parentObject) return NO;
+
if([parentObject allKeysForObject:item] && [[parentObject allKeysForObject:item] count] && [[[parentObject allKeysForObject:item] objectAtIndex:0] hasPrefix:@" "])
return NO;
return YES;
@@ -705,13 +851,8 @@ static SPNavigatorController *sharedNavigatorController = nil;
- (void)outlineViewSelectionDidChange:(NSNotification *)aNotification
{
- id ov = [aNotification object];
- id selectedItem;
- if(ov == outlineSchema1) {
- selectedItem = [outlineSchema1 selectedItem];
- } else if (ov == outlineSchema2) {
- selectedItem = [outlineSchema2 selectedItem];
- }
+
+ id selectedItem = [[aNotification object] selectedItem];
if(selectedItem) {
[infoArray removeAllObjects];