From cf243d99127441ce2fd3b4641427cb49ab155402 Mon Sep 17 00:00:00 2001 From: Bibiko Date: Thu, 1 Oct 2009 16:35:44 +0000 Subject: =?UTF-8?q?=E2=80=A2=20first=20implementation=20of=20a=20Content?= =?UTF-8?q?=20Filter=20Editor=20-=20user-defined=20content=20filter=20can?= =?UTF-8?q?=20be=20saved=20globally=20(Prefs)=20or=20in=20SPF=20files=20-?= =?UTF-8?q?=20BETA=20-=20further=20tests=20are=20needed=20due=20to=20compl?= =?UTF-8?q?exity=20-=20SPQueryController=20now=20handles=20the=20local=20u?= =?UTF-8?q?ser-defined=20content=20filters=20-=20tooltips=20are=20now=20ge?= =?UTF-8?q?nerated=20automatically=20if=20not=20defined=20explicitly=20(in?= =?UTF-8?q?cl.=20if=20$BINARY=20placeholder=20was=20used)=20=E2=80=A2=20if?= =?UTF-8?q?=20user=20added=20local=20query=20favorites=20or=20content=20fi?= =?UTF-8?q?lters=20to=20an=20Untitled=20document=20and=20s/he=20wants=20to?= =?UTF-8?q?=20close=20it=20the=20standard=20sheet=20will=20be=20displayed?= =?UTF-8?q?=20(Don't=20Save=20-=20Cancel=20-=20Save)=20-=20due=20to=20that?= =?UTF-8?q?=20changed=20old=20[TableDocument=20displayName]=20to=20'displa?= =?UTF-8?q?ySPName'=20to=20be=20conform=20with=20Cocoa=20=E2=80=A2=20chang?= =?UTF-8?q?ed=20behavior=20while=20importing=20query=20favorites=20-=20now?= =?UTF-8?q?=20they=20will=20append=20at=20the=20list=20(not=20inserted=20a?= =?UTF-8?q?fter=20selected=20row=20-=20makes=20more=20sense)=20=E2=80=A2?= =?UTF-8?q?=20introduced=20to=20history=20filter=20dict=20the=20key=20'men?= =?UTF-8?q?uLabel'=20which=20will=20be=20set=20to=20[TableContent=20tableF?= =?UTF-8?q?ilterString]=20for=20displaying=20the=20history=20menu=20title?= =?UTF-8?q?=20and=20simplified=20the=20SPHistoryController=20logic=20for?= =?UTF-8?q?=20that=20=E2=80=A2=20minor=20code=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Source/SPContentFilterManager.h | 2 +- Source/SPContentFilterManager.m | 78 ++++++++++++------------- Source/SPHistoryController.m | 23 +------- Source/SPQueryController.h | 4 ++ Source/SPQueryController.m | 40 +++++++++++++ Source/SPQueryFavoriteManager.m | 22 +++---- Source/TableContent.m | 23 +++++--- Source/TableDocument.h | 1 + Source/TableDocument.m | 125 +++++++++++++++++++++++----------------- Source/TablesList.m | 10 ++-- 10 files changed, 189 insertions(+), 139 deletions(-) (limited to 'Source') diff --git a/Source/SPContentFilterManager.h b/Source/SPContentFilterManager.h index 50cdb95a..c6942ba5 100644 --- a/Source/SPContentFilterManager.h +++ b/Source/SPContentFilterManager.h @@ -49,7 +49,7 @@ IBOutlet id insertPlaceholderButton; IBOutlet id contentFilterArrayController; - + NSMutableArray *contentFilters; BOOL isTableCellEditing; diff --git a/Source/SPContentFilterManager.m b/Source/SPContentFilterManager.m index 4d15823b..79c629bc 100644 --- a/Source/SPContentFilterManager.m +++ b/Source/SPContentFilterManager.m @@ -27,6 +27,7 @@ #import "ImageAndTextCell.h" #import "RegexKitLite.h" #import "SPQueryController.h" +#import "TableContent.h" #define DEFAULT_SEQUELPRO_FILE_EXTENSION @"spf" @@ -58,6 +59,7 @@ return nil; } delegatesFileURL = [[managerDelegate valueForKeyPath:@"tableDocumentInstance"] fileURL]; + filterType = [NSString stringWithString:compareType]; } @@ -96,7 +98,7 @@ @"", @"ConjunctionLabel", nil]]; - // Build data source for global queryFavorites (as mutable copy! otherwise each + // Build data source for global content filter (as mutable copy! otherwise each // change will be stored in the prefs at once) if([[prefs objectForKey:@"ContentFilters"] objectForKey:filterType]) { for(id fav in [[prefs objectForKey:@"ContentFilters"] objectForKey:filterType]) { @@ -107,16 +109,18 @@ } } + // Build doc-based filters [contentFilters addObject:[NSDictionary dictionaryWithObjectsAndKeys: [[[delegatesFileURL absoluteString] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] lastPathComponent], @"MenuLabel", [delegatesFileURL absoluteString], @"headerOfFileURL", @"", @"Clause", nil]]; - - // if([[SPQueryController sharedQueryController] favoritesForFileURL:delegatesFileURL]) { - // for(id fav in [[SPQueryController sharedQueryController] favoritesForFileURL:delegatesFileURL]) - // [contentFilters addObject:[[fav mutableCopy] autorelease]]; - // } + if([[SPQueryController sharedQueryController] contentFilterForFileURL:delegatesFileURL]) { + id filters = [[SPQueryController sharedQueryController] contentFilterForFileURL:delegatesFileURL]; + if([filters objectForKey:filterType]) + for(id fav in [filters objectForKey:filterType]) + [contentFilters addObject:[[fav mutableCopy] autorelease]]; + } // Select the first query if any @@ -351,23 +355,23 @@ // Ensure that last changes will be written back // if only one filter is selected; otherwise unstable state - if ([contentFilterTableView numberOfSelectedRows] == 1) { + if ([contentFilterTableView numberOfSelectedRows] == 1) [[self window] makeFirstResponder:contentFilterTableView]; - } - + // Update current document's content filters in the SPQueryController - // [[SPQueryController sharedQueryController] replaceFavoritesByArray: - // [self contentFilterForFileURL:delegatesFileURL] forFileURL:delegatesFileURL]; - // + [[SPQueryController sharedQueryController] replaceContentFilterByArray: + [self contentFilterForFileURL:delegatesFileURL] ofType:filterType forFileURL:delegatesFileURL]; + // Update global preferences' list id cf = [[prefs objectForKey:@"ContentFilters"] mutableCopy]; [cf setObject:[self contentFilterForFileURL:nil] forKey:filterType]; [prefs setObject:cf forKey:@"ContentFilters"]; - - // // Inform all opened documents to update the query favorites list - // for(id doc in [[NSDocumentController sharedDocumentController] documents]) - // if([[doc valueForKeyPath:@"customQueryInstance"] respondsToSelector:@selector(queryFavoritesHaveBeenUpdated:)]) - // [[doc valueForKeyPath:@"customQueryInstance"] queryFavoritesHaveBeenUpdated:self]; + [cf release]; + + // Inform all opened documents to update the query favorites list + for(id doc in [[NSDocumentController sharedDocumentController] documents]) + if([[doc valueForKeyPath:@"tableContentInstance"] respondsToSelector:@selector(setCompareTypes:)]) + [[doc valueForKeyPath:@"tableContentInstance"] setCompareTypes:nil]; } @@ -762,17 +766,17 @@ } if([[spf objectForKey:@"ContentFilters"] objectForKey:filterType] && [[[spf objectForKey:@"ContentFilters"] objectForKey:filterType] count]) { - if([contentFilterTableView numberOfSelectedRows] > 0) { - // Insert imported filters after the last selected filter - NSUInteger insertIndex = [[contentFilterTableView selectedRowIndexes] lastIndex] + 1; - NSUInteger i; - for(i=0; i<[[[spf objectForKey:@"ContentFilters"] objectForKey:filterType] count]; i++) { - [contentFilters insertObject:[[spf objectForKey:@"queryFavorites"] objectAtIndex:i] atIndex:insertIndex+i]; - } - } else { - // If no selection add them - [contentFilters addObjectsFromArray:[[spf objectForKey:@"ContentFilters"] objectForKey:filterType]]; - } + // if([contentFilterTableView numberOfSelectedRows] > 0) { + // // Insert imported filters after the last selected filter + // NSUInteger insertIndex = [[contentFilterTableView selectedRowIndexes] lastIndex] + 1; + // NSUInteger i; + // for(i=0; i<[[[spf objectForKey:@"ContentFilters"] objectForKey:filterType] count]; i++) { + // [contentFilters insertObject:[[spf objectForKey:@"queryFavorites"] objectAtIndex:i] atIndex:insertIndex+i]; + // } + // } else { + // // If no selection add them + [contentFilters addObjectsFromArray:[[spf objectForKey:@"ContentFilters"] objectForKey:filterType]]; + // } [contentFilterArrayController rearrangeObjects]; [contentFilterTableView reloadData]; } else { @@ -797,23 +801,12 @@ - (void)savePanelDidEnd:(NSSavePanel *)panel returnCode:(int)returnCode contextInfo:(NSString *)contextInfo { - if([contextInfo isEqualToString:@"saveQuery"]) { - if (returnCode == NSOKButton) { - NSError *error = nil; - - [prefs setInteger:[[encodingPopUp selectedItem] tag] forKey:@"lastSqlFileEncoding"]; - [prefs synchronize]; - - [[contentFilterTextView string] writeToFile:[panel filename] atomically:YES encoding:[[encodingPopUp selectedItem] tag] error:&error]; - - if (error) [[NSAlert alertWithError:error] runModal]; - } - } - else if([contextInfo isEqualToString:@"exportFavorites"]) { + if([contextInfo isEqualToString:@"exportFilter"]) { if (returnCode == NSOKButton) { // Build a SPF with format = "content filters" NSMutableDictionary *spfdata = [NSMutableDictionary dictionary]; + NSMutableDictionary *cfdata = [NSMutableDictionary dictionary]; NSMutableArray *filterData = [NSMutableArray array]; @@ -829,7 +822,8 @@ if([indexes containsIndex:i]) [filterData addObject:[contentFilters objectAtIndex:i]]; - [spfdata setObject:filterData forKey:@"ContentFilter"]; + [cfdata setObject:filterData forKey:filterType]; + [spfdata setObject:cfdata forKey:@"ContentFilters"]; NSString *err = nil; NSData *plist = [NSPropertyListSerialization dataFromPropertyList:spfdata diff --git a/Source/SPHistoryController.m b/Source/SPHistoryController.m index 9277a64b..8dc716fc 100644 --- a/Source/SPHistoryController.m +++ b/Source/SPHistoryController.m @@ -396,26 +396,9 @@ NSDictionary *filterSettings = [theEntry objectForKey:@"contentFilter"]; if (![filterSettings objectForKey:@"filterField"]) return theName; - if ([[filterSettings objectForKey:@"filterComparison"] isEqualToString:@"IS NULL"] - || [[filterSettings objectForKey:@"filterComparison"] isEqualToString:@"IS NOT NULL"]) - { - [theName appendFormat:@" (%@ %@ %@)", NSLocalizedString(@"Filtered by", @"History item filtered by label"), - [filterSettings objectForKey:@"filterField"], [filterSettings objectForKey:@"filterComparison"]]; - } else if ([[filterSettings objectForKey:@"filterComparison"] isEqualToString:@"BETWEEN"] - && [filterSettings objectForKey:@"firstBetweenField"] - && [[filterSettings objectForKey:@"secondBetweenField"] length] - && [filterSettings objectForKey:@"firstBetweenField"] - && [[filterSettings objectForKey:@"secondBetweenField"] length]) - { - [theName appendFormat:NSLocalizedString(@" (Filtered by %@ between %@ and %@)", @"History item filtered between values label"), - [filterSettings objectForKey:@"filterField"], - [filterSettings objectForKey:@"firstBetweenField"], - [filterSettings objectForKey:@"secondBetweenField"]]; - } else if ([filterSettings objectForKey:@"filterValue"] && [[filterSettings objectForKey:@"filterValue"] length]) { - [theName appendFormat:@" (%@ %@ %@ %@)", NSLocalizedString(@"Filtered by", @"History item filtered by label"), - [filterSettings objectForKey:@"filterField"], [filterSettings objectForKey:@"filterComparison"], - [filterSettings objectForKey:@"filterValue"]]; - } + if([filterSettings objectForKey:@"menuLabel"]) + return [NSString stringWithFormat:NSLocalizedString(@"%@ (Filtered by %@)", @"History item filtered by values label"), + theName, [filterSettings objectForKey:@"menuLabel"]]; return theName; } diff --git a/Source/SPQueryController.h b/Source/SPQueryController.h index 2a15ba45..f1cc84e7 100644 --- a/Source/SPQueryController.h +++ b/Source/SPQueryController.h @@ -49,6 +49,7 @@ NSUInteger untitledDocumentCounter; NSMutableDictionary *favoritesContainer; NSMutableDictionary *historyContainer; + NSMutableDictionary *contentFilterContainer; NSUInteger numberOfMaxAllowedHistory; NSUserDefaults *prefs; @@ -90,8 +91,11 @@ - (void)addHistory:(NSString *)history forFileURL:(NSURL *)fileURL; - (void)replaceHistoryByArray:(NSArray *)historyArray forFileURL:(NSURL *)fileURL; +- (void)replaceContentFilterByArray:(NSArray *)contentFilterArray ofType:(NSString *)filterType forFileURL:(NSURL *)fileURL; + - (NSMutableArray *)favoritesForFileURL:(NSURL *)fileURL; - (NSMutableArray *)historyForFileURL:(NSURL *)fileURL; +- (NSMutableDictionary *)contentFilterForFileURL:(NSURL *)fileURL; - (NSArray *)queryFavoritesForFileURL:(NSURL *)fileURL andTabTrigger:(NSString *)tabTrigger includeGlobals:(BOOL)includeGlobals; diff --git a/Source/SPQueryController.m b/Source/SPQueryController.m index a08a0906..86fa9908 100644 --- a/Source/SPQueryController.m +++ b/Source/SPQueryController.m @@ -101,6 +101,7 @@ static SPQueryController *sharedQueryController = nil; favoritesContainer = [[NSMutableDictionary alloc] init]; historyContainer = [[NSMutableDictionary alloc] init]; + contentFilterContainer = [[NSMutableDictionary alloc] init]; } @@ -151,6 +152,7 @@ static SPQueryController *sharedQueryController = nil; [favoritesContainer release]; [historyContainer release]; + [contentFilterContainer release]; [super dealloc]; } @@ -437,6 +439,11 @@ static SPQueryController *sharedQueryController = nil; } } + // Set the doc-based content filters + if(![contentFilterContainer objectForKey:[new absoluteString]]) { + [contentFilterContainer setObject:[NSMutableDictionary dictionary] forKey:[new absoluteString]]; + } + return new; } @@ -467,6 +474,15 @@ static SPQueryController *sharedQueryController = nil; [arr release]; } } + if(![contentFilterContainer objectForKey:[fileURL absoluteString]]) { + if(contextInfo != nil && [contextInfo objectForKey:@"ContentFilters"]) { + [contentFilterContainer setObject:[contextInfo objectForKey:@"ContentFilters"] forKey:[fileURL absoluteString]]; + } else { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + [contentFilterContainer setObject:dict forKey:[fileURL absoluteString]]; + [dict release]; + } + } return fileURL; @@ -490,6 +506,21 @@ static SPQueryController *sharedQueryController = nil; [favoritesContainer removeObjectForKey:[fileURL absoluteString]]; if([historyContainer objectForKey:[fileURL absoluteString]]) [historyContainer removeObjectForKey:[fileURL absoluteString]]; + if([contentFilterContainer objectForKey:[fileURL absoluteString]]) + [contentFilterContainer removeObjectForKey:[fileURL absoluteString]]; + +} + +- (void)replaceContentFilterByArray:(NSArray *)contentFilterArray ofType:(NSString *)filterType forFileURL:(NSURL *)fileURL +{ + + if([contentFilterContainer objectForKey:[fileURL absoluteString]]) { + NSMutableDictionary *c = [[NSMutableDictionary alloc] init]; + [c setDictionary:[contentFilterContainer objectForKey:[fileURL absoluteString]]]; + [c setObject:contentFilterArray forKey:filterType]; + [contentFilterContainer setObject:c forKey:[fileURL absoluteString]]; + [c release]; + } } @@ -569,6 +600,15 @@ static SPQueryController *sharedQueryController = nil; } +- (NSMutableDictionary *)contentFilterForFileURL:(NSURL *)fileURL +{ + if([contentFilterContainer objectForKey:[fileURL absoluteString]]) + return [contentFilterContainer objectForKey:[fileURL absoluteString]]; + + return [NSMutableDictionary dictionary]; + +} + - (NSArray *)queryFavoritesForFileURL:(NSURL *)fileURL andTabTrigger:(NSString *)tabTrigger includeGlobals:(BOOL)includeGlobals { diff --git a/Source/SPQueryFavoriteManager.m b/Source/SPQueryFavoriteManager.m index 590bf3c9..eb409500 100644 --- a/Source/SPQueryFavoriteManager.m +++ b/Source/SPQueryFavoriteManager.m @@ -731,17 +731,17 @@ } if([spf objectForKey:@"queryFavorites"] && [[spf objectForKey:@"queryFavorites"] count]) { - if([favoritesTableView numberOfSelectedRows] > 0) { - // Insert imported queries after the last selected favorite - NSUInteger insertIndex = [[favoritesTableView selectedRowIndexes] lastIndex] + 1; - NSUInteger i; - for(i=0; i<[[spf objectForKey:@"queryFavorites"] count]; i++) { - [favorites insertObject:[[spf objectForKey:@"queryFavorites"] objectAtIndex:i] atIndex:insertIndex+i]; - } - } else { - // If no selection add them - [favorites addObjectsFromArray:[spf objectForKey:@"queryFavorites"]]; - } + // if([favoritesTableView numberOfSelectedRows] > 0) { + // // Insert imported queries after the last selected favorite + // NSUInteger insertIndex = [[favoritesTableView selectedRowIndexes] lastIndex] + 1; + // NSUInteger i; + // for(i=0; i<[[spf objectForKey:@"queryFavorites"] count]; i++) { + // [favorites insertObject:[[spf objectForKey:@"queryFavorites"] objectAtIndex:i] atIndex:insertIndex+i]; + // } + // } else { + // // If no selection add them + [favorites addObjectsFromArray:[spf objectForKey:@"queryFavorites"]]; + // } [favoritesArrayController rearrangeObjects]; [favoritesTableView reloadData]; } else { diff --git a/Source/TableContent.m b/Source/TableContent.m index 369cfaec..f5b0fa47 100644 --- a/Source/TableContent.m +++ b/Source/TableContent.m @@ -774,7 +774,7 @@ - (IBAction)toggleFilterField:(id)sender { - // Check if user called "Edit filter…" + // Check if user called "Edit Filter…" if([[compareField selectedItem] tag] == [[contentFilters objectForKey:compareType] count]) { [self openContentFilterManager]; return; @@ -784,10 +784,11 @@ lastSelectedContentFilterIndex = [[compareField selectedItem] tag]; NSDictionary *filter = [[contentFilters objectForKey:compareType] objectAtIndex:lastSelectedContentFilterIndex]; + NSUInteger numOfArgs = [[filter objectForKey:@"NumberOfArguments"] intValue]; if ([[filter objectForKey:@"NumberOfArguments"] intValue] == 2) { [argumentField setHidden:YES]; - if([filter objectForKey:@"ConjunctionLabels"] && [[filter objectForKey:@"ConjunctionLabels"] count] == 1) + if(numOfArgs == 1) [betweenTextField setStringValue:[[filter objectForKey:@"ConjunctionLabels"] objectAtIndex:0]]; [betweenTextField setHidden:NO]; [firstBetweenField setHidden:NO]; @@ -797,7 +798,7 @@ [secondBetweenField setEnabled:YES]; [firstBetweenField selectText:self]; } - else if ([[filter objectForKey:@"NumberOfArguments"] intValue] == 1){ + else if (numOfArgs == 1){ [argumentField setHidden:NO]; [argumentField setEnabled:YES]; [argumentField selectText:self]; @@ -815,7 +816,8 @@ [secondBetweenField setHidden:YES]; // Start search if no argument is required - [self filterTable:self]; + if(numOfArgs == 0) + [self filterTable:self]; } } @@ -1200,7 +1202,7 @@ } } - // Load user-defined content filters + // Load global user-defined content filters if([prefs objectForKey:@"ContentFilters"] && [contentFilters objectForKey:compareType] && [[prefs objectForKey:@"ContentFilters"] objectForKey:compareType]) @@ -1208,6 +1210,13 @@ [[contentFilters objectForKey:compareType] addObjectsFromArray:[[prefs objectForKey:@"ContentFilters"] objectForKey:compareType]]; } + // Load doc-based user-defined content filters + if([[SPQueryController sharedQueryController] contentFilterForFileURL:[tableDocumentInstance fileURL]]) { + id filters = [[SPQueryController sharedQueryController] contentFilterForFileURL:[tableDocumentInstance fileURL]]; + if([filters objectForKey:compareType]) + [[contentFilters objectForKey:compareType] addObjectsFromArray:[filters objectForKey:compareType]]; + } + // Rebuild operator popup menu NSUInteger i = 0; NSMenu *menu = [compareField menu]; @@ -1255,9 +1264,6 @@ { [compareField selectItemWithTag:lastSelectedContentFilterIndex]; - [SPTooltip showWithObject:@"

  Please be patient. Under constructions.   

" atLocation:[NSEvent mouseLocation] ofType:@"html"]; - return; - // init query favorites controller [prefs synchronize]; if(contentFilterManager) [contentFilterManager release]; @@ -1858,6 +1864,7 @@ if (![fieldField isEnabled]) return nil; theDictionary = [NSDictionary dictionaryWithObjectsAndKeys: + [self tableFilterString], @"menuLabel", [[fieldField selectedItem] title], @"filterField", [[compareField selectedItem] title], @"filterComparison", [NSNumber numberWithInt:[[compareField selectedItem] tag]], @"filterComparisonTag", diff --git a/Source/TableDocument.h b/Source/TableDocument.h index 2741ca7d..87daf69a 100644 --- a/Source/TableDocument.h +++ b/Source/TableDocument.h @@ -215,6 +215,7 @@ enum sp_current_query_mode - (NSString *)table; - (NSString *)mySQLVersion; - (NSString *)user; +- (NSString *)displaySPName; // Notification center methods - (void)willPerformQuery:(NSNotification *)notification; diff --git a/Source/TableDocument.m b/Source/TableDocument.m index be05b720..0eb24ece 100644 --- a/Source/TableDocument.m +++ b/Source/TableDocument.m @@ -89,7 +89,7 @@ spfSession = nil; spfPreferences = [[NSMutableDictionary alloc] init]; spfDocData = [[NSMutableDictionary alloc] init]; - + } return self; @@ -174,7 +174,7 @@ av.size.width, av.size.height); [titleAccessoryView setFrame:initialAccessoryViewFrame]; - [windowFrame addSubview:titleAccessoryView]; + [windowFrame addSubview:titleAccessoryView]; // Bind the background color of the create syntax text view to the users preference [createTableSyntaxTextView setAllowsDocumentBackgroundColorChange:YES]; @@ -191,7 +191,7 @@ // Load additional nibs if (![NSBundle loadNibNamed:@"ConnectionErrorDialog" owner:self]) { NSLog(@"Connection error dialog could not be loaded; connection failure handling will not function correctly."); - } + } } - (void)initWithConnectionFile:(NSString *)path @@ -209,7 +209,7 @@ int connectionType; // Inform about the data source in the window title bar - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; // Clean fields [connectionController setName:@""]; @@ -417,14 +417,6 @@ [spfDocData setObject:[NSNumber numberWithBool:YES] forKey:@"include_session"]; } - [spfDocData setObject:[NSNumber numberWithBool:YES] forKey:@"save_password"]; - if(![connection objectForKey:@"password"]) { - // TODO How to set the focus to standardPasswordField in the connection nib? - // [[connectionController valueForKeyPath:@"standardPasswordField"] selectText:connectionController]; - [spfDocData setObject:[NSNumber numberWithBool:NO] forKey:@"save_password"]; - return; - } - [self setFileURL:[NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[NSURL URLWithString:[path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; @@ -432,6 +424,16 @@ [spfPreferences setObject:[spf objectForKey:@"queryFavorites"] forKey:@"queryFavorites"]; if([spf objectForKey:@"queryHistory"]) [spfPreferences setObject:[spf objectForKey:@"queryHistory"] forKey:@"queryHistory"]; + if([spf objectForKey:@"ContentFilters"]) + [spfPreferences setObject:[spf objectForKey:@"ContentFilters"] forKey:@"ContentFilters"]; + + [spfDocData setObject:[NSNumber numberWithBool:YES] forKey:@"save_password"]; + if(![connection objectForKey:@"password"]) { + // TODO How to set the focus to standardPasswordField in the connection nib? + // [[connectionController valueForKeyPath:@"standardPasswordField"] selectText:connectionController]; + [spfDocData setObject:[NSNumber numberWithBool:NO] forKey:@"save_password"]; + return; + } [spfDocData setObject:[NSNumber numberWithBool:NO] forKey:@"auto_connect"]; if([spf objectForKey:@"auto_connect"] && [[spf valueForKey:@"auto_connect"] boolValue]) { @@ -492,7 +494,7 @@ [[tablesListInstance valueForKeyPath:@"tablesListView"] scrollRowToVisible:[tables indexOfObject:[spfSession objectForKey:@"selectedTable"]]]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; // dealloc spfSession data [spfSession release]; @@ -600,7 +602,7 @@ // Set the cutom query editor's MySQL version [customQueryInstance setMySQLversion:mySQLVersion]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; [self viewStructure:self]; // Connected Growl notification @@ -867,7 +869,7 @@ [tablesListInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; // Add a history entry if (!historyStateChanging) { @@ -950,7 +952,7 @@ [tablesListInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; } /** @@ -1026,7 +1028,7 @@ [tablesListInstance setConnection:mySQLConnection]; [tableDumpInstance setConnection:mySQLConnection]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; } } @@ -1066,12 +1068,12 @@ if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil; selectedDatabase = [[NSString alloc] initWithString:dbName]; [chooseDatabaseButton selectItemWithTitle:selectedDatabase]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; } } else { if (selectedDatabase) [selectedDatabase release], selectedDatabase = nil; [chooseDatabaseButton selectItemAtIndex:0]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; } } @@ -1724,7 +1726,7 @@ beginSheetModalForWindow:tableWindow modalDelegate:self didEndSelector:NULL - contextInfo:NULL]; + contextInfo:NULL]; } /** @@ -1749,17 +1751,17 @@ - (IBAction)copyCreateTableSyntaxFromSheet:(id)sender { NSString *createSyntax = [createTableSyntaxTextView string]; - + if ([createSyntax length] > 0) { // Copy to the clipboard NSPasteboard *pb = [NSPasteboard generalPasteboard]; - + [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self]; [pb setString:createSyntax forType:NSStringPboardType]; - + // Table syntax copied Growl notification [[SPGrowlController sharedGrowlController] notifyWithTitle:@"Syntax Copied" - description:[NSString stringWithFormat:NSLocalizedString(@"Syntax for %@ table copied", @"description for table syntax copied growl notification"), [self table]] + description:[NSString stringWithFormat:NSLocalizedString(@"Syntax for %@ table copied", @"description for table syntax copied growl notification"), [self table]] notificationName:@"Syntax Copied"]; } } @@ -2022,6 +2024,7 @@ /** * Saves SP session or if Custom Query tab is active the editor's content as SQL file + * If sender == nil then the call came from [self writeSafelyToURL:ofType:forSaveOperation:error] */ - (IBAction)saveConnectionSheet:(id)sender { @@ -2034,7 +2037,7 @@ [panel setCanSelectHiddenExtension:YES]; // Save Query… - if( [sender tag] == 1006 ) { + if( sender != nil && [sender tag] == 1006 ) { // Save the editor's content as SQL file [panel setAccessoryView:[SPEncodingPopupAccessory encodingAccessory:[prefs integerForKey:@"lastSqlFileEncoding"] @@ -2058,11 +2061,11 @@ [encodingPopUp setEnabled:YES]; // Save As… or Save - } else if([sender tag] == 1005 || [sender tag] == 1004) { + } else if(sender == nil || [sender tag] == 1005 || [sender tag] == 1004) { // If Save was invoked check for fileURL and Untitled docs and save the spf file without save panel // otherwise ask for file name - if([sender tag] == 1004 && [[[self fileURL] absoluteString] length] && [[[self fileURL] absoluteString] hasPrefix:@"/"]) { + if(sender != nil && [sender tag] == 1004 && [[[self fileURL] absoluteString] length] && [[[self fileURL] absoluteString] hasPrefix:@"/"]) { [self saveDocumentWithFilePath:nil inBackground:YES onlyPreferences:NO]; return; } @@ -2104,7 +2107,10 @@ else filename = [NSString stringWithFormat:@"%@", [self name]]; - contextInfo = @"saveSPFfile"; + if(sender == nil) + contextInfo = @"saveSPFfileAndClose"; + else + contextInfo = @"saveSPFfile"; } else { return; @@ -2171,12 +2177,14 @@ } // Save connection and session as SPF file - else if(contextInfo == @"saveSPFfile") { + else if(contextInfo == @"saveSPFfile" || contextInfo == @"saveSPFfileAndClose") { // Save changes of saveConnectionEncryptString [[saveConnectionEncryptString window] makeFirstResponder:[[saveConnectionEncryptString window] initialFirstResponder]]; [self saveDocumentWithFilePath:fileName inBackground:NO onlyPreferences:NO]; + if(contextInfo == @"saveSPFfileAndClose") + [self close]; } } } @@ -2251,6 +2259,7 @@ // Update the keys [spf setObject:[[SPQueryController sharedQueryController] favoritesForFileURL:[self fileURL]] forKey:@"queryFavorites"]; [spf setObject:[[SPQueryController sharedQueryController] historyForFileURL:[self fileURL]] forKey:@"queryHistory"]; + [spf setObject:[[SPQueryController sharedQueryController] contentFilterForFileURL:[self fileURL]] forKey:@"ContentFilters"]; // Save it again NSString *err = nil; @@ -2301,7 +2310,8 @@ // Store the preferences - take them from the current document URL to catch renaming [spfdata setObject:[[SPQueryController sharedQueryController] favoritesForFileURL:[self fileURL]] forKey:@"queryFavorites"]; [spfdata setObject:[[SPQueryController sharedQueryController] historyForFileURL:[self fileURL]] forKey:@"queryHistory"]; - + [spfdata setObject:[[SPQueryController sharedQueryController] contentFilterForFileURL:[self fileURL]] forKey:@"ContentFilters"]; + [spfdata setObject:[spfDocData_temp objectForKey:@"encrypted"] forKey:@"encrypted"]; if([[spfDocData_temp objectForKey:@"save_password"] boolValue]) @@ -2446,15 +2456,16 @@ return NO; } - // Register and update query favorites and history for the (new) file URL + // Register and update query favorites, content filter, and history for the (new) file URL NSMutableDictionary *preferences = [[NSMutableDictionary alloc] init]; [preferences setObject:[spfdata objectForKey:@"queryHistory"] forKey:@"queryHistory"]; [preferences setObject:[spfdata objectForKey:@"queryFavorites"] forKey:@"queryFavorites"]; + [preferences setObject:[spfdata objectForKey:@"ContentFilters"] forKey:@"ContentFilters"]; [[SPQueryController sharedQueryController] registerDocumentWithFileURL:[NSURL URLWithString:[fileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] andContextInfo:preferences]; [self setFileURL:[NSURL URLWithString:[fileName stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]]; - [tableWindow setTitle:[self displayName]]; + [tableWindow setTitle:[self displaySPName]]; // Store doc data permanently [spfDocData removeAllObjects]; @@ -3093,40 +3104,42 @@ if(isSaved) [[SPQueryController sharedQueryController] removeRegisteredDocumentWithFileURL:[self fileURL]]; return isSaved; - - // Before removing an Untitled doc check if it contains any defined query favorites. - // If so save them globally. TODO: How to do it better ? - } else if([self fileURL] && [[[self fileURL] absoluteString] length] && ![[[self fileURL] absoluteString] hasPrefix:@"/"]) { - if([[[SPQueryController sharedQueryController] favoritesForFileURL:[self fileURL]] count]) { - - NSMutableArray *favs = [[[NSMutableArray alloc] init] autorelease]; - [favs addObjectsFromArray:[prefs objectForKey:@"queryFavorites"]]; - [favs addObjectsFromArray:[[SPQueryController sharedQueryController] favoritesForFileURL:[self fileURL]]]; - [prefs setObject:favs forKey:@"queryFavorites"]; - - if(![prefs synchronize]) - NSLog(@"Sorry, couldn't backup query favorites from Untitled document."); - } - [[SPQueryController sharedQueryController] removeRegisteredDocumentWithFileURL:[self fileURL]]; - return YES; } } return YES; } +/* + * Invoked if user chose "Save" from 'Do you want save changes you made...' sheet + * which is called automatically if [self isDocumentEdited] == YES and user wanted to close an Untitled doc. + */ +- (BOOL)writeSafelyToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError +{ + if(saveOperation == NSSaveOperation) { + // Dummy error to avoid crashes after Canceling the Save Panel + *outError = [NSError errorWithDomain:@"SP_DOMAIN" code:1000 userInfo:nil]; + [self saveConnectionSheet:nil]; + return NO; + } + return YES; +} + /** - * Don't show the document "changed" dot in the close button, or show a - * "save?" dialog when closing the document. + * Shows "save?" dialog when closing the document if the an Untitled doc has doc-based query favorites or content filters. */ - (BOOL)isDocumentEdited { - return NO; + return ([self fileURL] && [[[self fileURL] absoluteString] length] && ![[[self fileURL] absoluteString] hasPrefix:@"/"] && ([[[SPQueryController sharedQueryController] favoritesForFileURL:[self fileURL]] count] + || [[[[SPQueryController sharedQueryController] contentFilterForFileURL:[self fileURL]] objectForKey:@"number"] count] + || [[[[SPQueryController sharedQueryController] contentFilterForFileURL:[self fileURL]] objectForKey:@"date"] count] + || [[[[SPQueryController sharedQueryController] contentFilterForFileURL:[self fileURL]] objectForKey:@"string"] count]) + ); } /** * The window title for this document. */ -- (NSString *)displayName +- (NSString *)displaySPName { if (!_isConnected) return [NSString stringWithFormat:@"%@%@", ([[[self fileURL] absoluteString] length]) ? [NSString stringWithFormat:@"%@ — ",[[[[self fileURL] absoluteString] lastPathComponent] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]] : @"", @@ -3139,6 +3152,14 @@ ([self database]?[NSString stringWithFormat:@"/%@",[self database]]:@""), ([[self table] length]?[NSString stringWithFormat:@"/%@",[self table]]:@"")]; } +/** + * The window title for this document. + */ +- (NSString *)displayName +{ + if(!_isConnected) return [self displaySPName]; + return [[[[self fileURL] absoluteString] lastPathComponent] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; +} #pragma mark - diff --git a/Source/TablesList.m b/Source/TablesList.m index 3cd4a8a2..546fe2e0 100644 --- a/Source/TablesList.m +++ b/Source/TablesList.m @@ -795,7 +795,7 @@ } // set window title - [tableWindow setTitle:[tableDocumentInstance displayName]]; + [tableWindow setTitle:[tableDocumentInstance displaySPName]]; // Update the "Show Create Syntax" window if it's already opened // according to the selected table/view/proc/func @@ -884,7 +884,7 @@ [separatorTableContextMenuItem setHidden:YES]; // set window title - [tableWindow setTitle:[tableDocumentInstance displayName]]; + [tableWindow setTitle:[tableDocumentInstance displaySPName]]; } @@ -1217,7 +1217,7 @@ } // Set window title - [tableWindow setTitle:[tableDocumentInstance displayName]]; + [tableWindow setTitle:[tableDocumentInstance displaySPName]]; } else { @@ -1696,7 +1696,7 @@ [tablesListView reloadData]; // set window title - [tableWindow setTitle:[tableDocumentInstance displayName]]; + [tableWindow setTitle:[tableDocumentInstance displaySPName]]; [tablesListView deselectAll:self]; } @@ -2055,7 +2055,7 @@ } // Set window title - [tableWindow setTitle:[tableDocumentInstance displayName]]; + [tableWindow setTitle:[tableDocumentInstance displaySPName]]; } /* -- cgit v1.2.3