// // FilterManager.m // Cidney // // Created by Chris Karr on 1/12/08. // Copyright 2008 __MyCompanyName__. All rights reserved. // #import "FilterManager.h" #import "Dispatcher.h" #import #import "Caller.h" #define SAVED_FILTERS @"Saved Filters" #define SELECTED_FILTERS @"Selected Filters" @implementation FilterManager @synthesize blacklist; static FilterManager * sharedFilterManager = nil; - (void) broadcastBlacklist:(NSTimer *) theTimer { [[NSNotificationCenter defaultCenter] postNotificationName:BLACKLIST_BROADCAST object:nil userInfo:[NSDictionary dictionaryWithObject:self.blacklist forKey:BLACKLIST]]; [theTimer release]; } - (void) save:(NSNotification *) theNote { NSMutableArray * savedFilters = [NSMutableArray array]; NSMutableArray * selectedFilters = [NSMutableArray array]; for (NSDictionary * filter in [filters arrangedObjects]) { NSMutableDictionary * savedFilter = [NSMutableDictionary dictionaryWithDictionary:filter]; [savedFilter setValue:[[filter valueForKey:@"predicate"] predicateFormat] forKey:@"predicate"]; [savedFilters addObject:savedFilter]; if ([[filters selectedObjects] containsObject:filter]) [selectedFilters addObject:[filter valueForKey:@"name"]]; } [[NSUserDefaults standardUserDefaults] setValue:savedFilters forKey:SAVED_FILTERS]; [[NSUserDefaults standardUserDefaults] setValue:selectedFilters forKey:SELECTED_FILTERS]; [[NSUserDefaults standardUserDefaults] setValue:[self.blacklist allObjects] forKey:BLACKLIST]; [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(broadcastBlacklist:) userInfo:nil repeats:NO] retain]; } - (void) load { NSArray * savedFilters = [[NSUserDefaults standardUserDefaults] valueForKey:SAVED_FILTERS]; NSArray * selectedFilters = [[NSUserDefaults standardUserDefaults] valueForKey:SELECTED_FILTERS]; NSMutableArray * selects = [NSMutableArray array]; if (savedFilters != nil) { for (NSDictionary * savedFilter in savedFilters) { NSMutableDictionary * filter = [NSMutableDictionary dictionaryWithDictionary:savedFilter]; [filter setValue:[NSPredicate predicateWithFormat:[filter valueForKey:@"predicate"]] forKey:@"predicate"]; [filters addObject:filter]; if ([selectedFilters containsObject:[filter valueForKey:@"name"]]) [selects addObject:filter]; } } [filters setSelectedObjects:nil]; [filters setSelectedObjects:selects]; NSArray * savedBlacklist = [[NSUserDefaults standardUserDefaults] valueForKey:BLACKLIST]; if (savedBlacklist == nil) savedBlacklist = [NSArray array]; self.blacklist = [NSMutableSet setWithArray:savedBlacklist]; [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(broadcastBlacklist:) userInfo:nil repeats:NO] retain]; } - (IBAction) addFilter:(id)sender { NSMutableDictionary * filter = [NSMutableDictionary dictionary]; [filter setValue:@"New Filter" forKey:@"name"]; NSPredicate * predicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: [NSPredicate predicateWithFormat:@"(tags contains 'unknown') and (name contains 'Caller')"], nil]]; [filter setValue:predicate forKey:@"predicate"]; [filters addObject:filter]; } - (void) awakeFromNib { sharedFilterManager = self; [filters addObserver:self forKeyPath:@"arrangedObjects" options:0 context:NULL]; [filters addObserver:self forKeyPath:@"selection" options:0 context:NULL]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(save:) name:NSApplicationWillTerminateNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(incoming:) name:INCOMING_CALL object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(blacklist:) name:BLACKLIST_CALL object:nil]; [self load]; } - (void) blacklist: (NSNotification *) msg { NSDictionary * caller = [msg userInfo]; NSDictionary * blacklistedCaller = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[caller valueForKey:NAME_KEY], [caller valueForKey:NUMBER_KEY], nil] forKeys:[NSArray arrayWithObjects:NAME_KEY, NUMBER_KEY, nil]]; [self willChangeValueForKey:@"blacklist"]; [self.blacklist addObject:blacklistedCaller]; [self didChangeValueForKey:@"blacklist"]; [self save:msg]; } - (IBAction) blacklistCall:(id) sender { for (Caller * call in [calls selectedObjects]) { NSString * name = [call valueForKey:@"name"]; NSString * number = [call valueForKey:@"number"]; NSDictionary * blacklistedCaller = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:[call valueForKey:@"name"], [call valueForKey:@"number"], nil] forKeys:[NSArray arrayWithObjects:NAME_KEY, NUMBER_KEY, nil]]; if (![self.blacklist member:blacklistedCaller]) { NSString * msg = [NSString stringWithFormat:@"Should the caller '%@' (%@) be blacklisted?", name, number, nil]; if (NSRunAlertPanel (NSLocalizedString (@"Blacklist Incoming Call", nil), msg, @"No", @"Yes", nil) == NSAlertAlternateReturn) { [self willChangeValueForKey:@"blacklist"]; [self.blacklist addObject:blacklistedCaller]; [self didChangeValueForKey:@"blacklist"]; [self save:nil]; } } } } - (void) incoming: (NSNotification *) msg { NSDictionary * userInfo = [msg userInfo]; ABPerson * person = [userInfo valueForKey:PERSON_KEY]; NSString * number = [userInfo valueForKey:NUMBER_KEY]; NSString * name = [userInfo valueForKey:NAME_KEY]; Caller * call = [Caller dictionary]; [call setValue:[NSDate date] forKey:@"date"]; [call setValue:number forKey:@"number"]; [call setValue:name forKey:@"name"]; [call setValue:person forKey:PERSON_KEY]; BOOL passed = YES; for (NSDictionary * filter in [filters selectedObjects]) { NSPredicate * predicate = [filter valueForKey:@"predicate"]; if (![predicate evaluateWithObject:call]) passed = NO; } NSDictionary * blacklistTest = [NSDictionary dictionaryWithObjectsAndKeys:name, NAME_KEY, number, NUMBER_KEY, nil]; if ([self.blacklist member:blacklistTest]) passed = NO; if (passed) [[NSNotificationCenter defaultCenter] postNotificationName:FILTERED_CALL object:self userInfo:userInfo]; [[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(broadcastBlacklist:) userInfo:nil repeats:NO] retain]; } - (void) selectFilterWithTitle:(NSString *) title { [filters setSelectedObjects:nil]; for (NSDictionary * filter in [filters arrangedObjects]) { if ([[filter valueForKey:@"name"] isEqual:title]) [filters setSelectedObjects:[NSArray arrayWithObject:filter]]; } } - (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([keyPath isEqual:@"arrangedObjects"]) { for (NSMenuItem * item in [filterMenu itemArray]) [filterMenu removeItem:item]; NSMenuItem * none = [filterMenu addItemWithTitle:@"No Filter" action:@selector(switchFilter:) keyEquivalent:@""]; [none setTarget:self]; [filterMenu addItem:[NSMenuItem separatorItem]]; for (NSDictionary * filter in [filters arrangedObjects]) { NSMenuItem * item = [filterMenu addItemWithTitle:[filter valueForKey:@"name"] action:@selector(switchFilter:) keyEquivalent:@""]; [item bind:@"title" toObject:filter withKeyPath:@"name" options:nil]; [item setTarget:self]; } } else if ([keyPath isEqual:@"selection"]) { NSArray * selection = [filters selectedObjects]; NSString * title = @"No Filter"; if ([selection count] > 0) title = [[selection objectAtIndex:0] valueForKey:@"name"]; for (NSMenuItem * item in [filterMenu itemArray]) { [item setState:NSOffState]; if ([[item title] isEqualToString:title]) [item setState:NSOnState]; } } } - (IBAction) switchFilter:(id) sender { for (NSMenuItem * item in [filterMenu itemArray]) { if (item != sender) [item setState:NSOffState]; else { [self selectFilterWithTitle:[item title]]; [item setState:NSOnState]; } } } - (NSArray *) allFilterNames { NSMutableArray * filterNames = [NSMutableArray array]; for (NSDictionary * filter in [filters arrangedObjects]) { NSString * filterName = [filter valueForKey:@"name"]; if (filterName != nil) [filterNames addObject:filterName]; } [filterNames sortUsingSelector:@selector(compare:)]; return filterNames; } + (FilterManager *) sharedFilterManager { return sharedFilterManager; } - (void) doTerminate:(NSNotification *) note; { if(sharedFilterManager) [sharedFilterManager release]; } - (IBAction) resetBlacklist:(id) sender { self.blacklist = [NSMutableSet set]; [self save:nil]; } @end