#import "FiltersController.h" #import "ExtendedTableColumn.h" #import "SwitchTableView.h" @implementation FiltersController - (void) dealloc { RELEASE(categories); [super dealloc]; } - (id) init { if( (self = [super init]) ) { categories = [NSMutableArray new]; return self; } return nil; } - (void) awakeFromNib { [self _setupTable]; [dateFromPopup removeAllItems]; [dateToPopup removeAllItems]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_updateDates:) name: @"Dates Changed" object: nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_updateCategories:) name: @"Categories Changed" object: nil]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_updateSelections:) name: @"Selections Changed" object: nil]; } // Action methods //****************** - (void) includeAll: (id) sender { int i; for( i=0; i < [categories count]; i++ ) { [[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: YES] forKey: @"include"]; } [categoryTable reloadData]; [self _filtersChanged: self]; } - (void) excludeAll: (id) sender { int i; for( i=0; i < [categories count]; i++ ) { [[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: NO] forKey: @"include"]; } [categoryTable reloadData]; [self _filtersChanged: self]; } // NSTableViewDataSource protocol methods //**************************************** - (int) numberOfRowsInTableView: (NSTableView *) view { return [categories count]; } - (id) tableView: (NSTableView *) view objectValueForTableColumn: (NSTableColumn *) column row: (int) row { if( [[column identifier] isEqualToString: @"name"] ) { return [[categories objectAtIndex: row] objectForKey: @"name"]; } return nil; } // SwitchTableViewDataSource protocol methods //******************************************** - (int) tableView: (NSTableView *)aTableView stateForTableColumn: (NSTableColumn *)aTableColumn row: (int)rowIndex { if( [[aTableColumn identifier] isEqualToString: @"include"] ) { return [[[categories objectAtIndex: rowIndex] objectForKey: @"include"] intValue]; } return 0; } - (void) tableView: (NSTableView *)aTableView setState: (int) aState forTableColumn: (NSTableColumn *)aTableColumn row: (int)rowIndex { if( [[aTableColumn identifier] isEqualToString: @"include"] ) { [[categories objectAtIndex: rowIndex] setObject: [NSNumber numberWithInt: aState] forKey: @"include"]; [self _filtersChanged: self]; } } // Private methods and functions //******************************* - (void) _setupTable { ExtendedTableColumn *category, *include; NSButtonCell *cell; category = AUTORELEASE([[NSTableColumn alloc] initWithIdentifier: @"name"]); [category setEditable: NO]; [category setResizable: NO]; [category setWidth: 102]; include = AUTORELEASE([[ExtendedTableColumn alloc] initWithIdentifier: @"include"]); [include setShouldUseAndSetState: YES]; [include setShouldUseMouse: YES]; [include setEditable: NO]; [include setResizable: NO]; [include setWidth: 40]; cell = AUTORELEASE([[NSButtonCell alloc] init]); [cell setButtonType: NSSwitchButton]; [cell setImagePosition: NSImageOnly]; [include setDataCell: cell]; categoryTable = [[SwitchTableView alloc] init]; [categoryTable setDataSource: self]; [categoryTable setDelegate: self]; [categoryTable addTableColumn: category]; [categoryTable addTableColumn: include]; [categoryTable setAllowsMultipleSelection: NO]; [categoryTable setAllowsColumnSelection: NO]; [categoryTable setDrawsGrid: NO]; [categoryTable setRowHeight: [[NSFont systemFontOfSize: [NSFont systemFontSize]] boundingRectForFont].size.height+5]; [categoryTableSV setDocumentView: categoryTable]; [categoryTableSV setHasHorizontalScroller: NO]; [categoryTableSV setHasVerticalScroller: YES]; [categoryTableSV setBorderType: NSBezelBorder]; } - (void) _updateSelections: (NSNotification *) aNotification { NSDictionary *filter = [NSDictionary dictionaryWithDictionary: [aNotification object]]; NSString *category = [NSString string]; int i, k; // should autoenabling take care of this? if( [dateToPopup numberOfItems] > 0 ) { [dateToPopup setEnabled: YES]; [dateFromPopup setEnabled: YES]; } else { [dateToPopup setEnabled: NO]; [dateFromPopup setEnabled: NO]; } if( ![[filter objectForKey: @"item"] isEqualToString: @"NONE"] ) [itemText setStringValue: [filter objectForKey: @"item"]]; if( ![[filter objectForKey: @"dateFrom"] isEqualToString: @"NONE"] ) [dateFromPopup selectItemWithTitle: [filter objectForKey: @"dateFrom"]]; else [dateFromPopup selectItem: [dateFromPopup itemAtIndex: 0]]; if( ![[filter objectForKey: @"dateTo"] isEqualToString: @"NONE"] ) [dateToPopup selectItemWithTitle: [filter objectForKey: @"dateTo"]]; else [dateToPopup selectItem: [dateToPopup lastItem]]; // if the filter is NONE, then select every category if( [[filter objectForKey: @"categories"] isEqual: @"NONE"] ) { for( i = 0; i < [categories count]; i++ ) { [[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: YES] forKey: @"include"]; } } // else, exclude every category else { for( i = 0; i < [categories count]; i++ ) { [[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: NO] forKey: @"include"]; } // then set only the the ones in the filter array to be marked as included for( i = 0; i < [[filter objectForKey: @"categories"] count]; i++ ) { category = [NSString stringWithString: [[filter objectForKey: @"categories"] objectAtIndex: i]]; for( k = 0; k < [categories count]; k++ ) { if( [category isEqualToString: [[categories objectAtIndex: k] objectForKey: @"name"]] ) { [[categories objectAtIndex: k] setObject: [NSNumber numberWithBool: YES] forKey: @"include"]; } } } } [categoryTable reloadData]; } - (void) _updateDates: (NSNotification *) aNotification { int i; NSArray *arr = [NSArray arrayWithArray: [aNotification object]]; [dateFromPopup removeAllItems]; [dateToPopup removeAllItems]; for( i = 0; i < [arr count]; i++ ) { [dateFromPopup addItemWithTitle: [arr objectAtIndex: i]]; [dateToPopup addItemWithTitle: [arr objectAtIndex: i]]; } } - (void) _updateCategories: (NSNotification *) aNotification { int i; NSArray *arr = [NSArray arrayWithArray: [aNotification object]]; [categories removeAllObjects]; for( i = 0; i < [arr count]; i++ ) { [categories addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: [arr objectAtIndex: i], @"name", [NSNumber numberWithBool: YES], @"include", nil]]; } [categoryTable reloadData]; } - (void) _filtersChanged: (id) sender { NSString *dateFrom, *dateTo, *item; NSMutableArray *filteredCategories = [NSMutableArray new]; NSDictionary *filter; int i; dateFrom = [NSString string]; dateTo = [NSString string]; item = [NSString string]; if( [dateFromPopup selectedItem] != nil ) dateFrom = [NSString stringWithString: [[dateFromPopup selectedItem] title]]; else dateFrom = @"NONE"; if( [dateToPopup selectedItem] != nil ) dateTo = [NSString stringWithString: [[dateToPopup selectedItem] title]]; else dateTo = @"NONE"; if( [itemText stringValue] != nil ) item = [NSString stringWithString: [itemText stringValue]]; else item = @"NONE"; for( i=0; i < [categories count]; i++ ) { if( [[[categories objectAtIndex: i] objectForKey: @"include"] boolValue ] ) { [filteredCategories addObject: [[categories objectAtIndex: i] objectForKey: @"name"]]; } } NSLog(@"filteredCategories - %@", [filteredCategories description]); filter = [NSDictionary dictionaryWithObjectsAndKeys: dateFrom, @"dateFrom", dateTo, @"dateTo", item, @"item", filteredCategories, @"categories", nil]; [[NSNotificationCenter defaultCenter] postNotificationName: @"Filters Changed" object: filter]; } @end