Changeset 51 for trunk/Cocoa/Pester/Source/NJRTableDelegate.m
- Timestamp:
- 11/18/02 08:57:41 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Cocoa/Pester/Source/NJRTableDelegate.m
r34 r51 4 4 // 5 5 // Created by Nicholas Riley on Sun Oct 27 2002. 6 // Copyright (c) 2002 __MyCompanyName__. All rights reserved.6 // Copyright (c) 2002 Nicholas Riley. All rights reserved. 7 7 // 8 8 … … 14 14 typedef struct { NSString *key; BOOL descending; } SortContext; 15 15 16 // Sort array of itemNums, by looking up the itemNum in the dictionary of dictionaries.16 // Sort array of itemNums, by looking up the itemNum in the dictionary of objects. 17 17 // based on code of Ondra Cada <ocs@ocs.cz> on cocoa-dev list 18 18 … … 25 25 26 26 if (context->descending) { 27 first = [right objectForKey: key];28 second = [left objectForKey: key];27 first = [right valueForKey: key]; 28 second = [left valueForKey: key]; 29 29 } else { 30 first = [left objectForKey: key];31 second = [right objectForKey: key];30 first = [left valueForKey: key]; 31 second = [right valueForKey: key]; 32 32 } 33 33 … … 41 41 } 42 42 43 @interface NJRTableDelegate (Private) 44 45 - (void)_positionTypeSelectDisplay; 46 - (void)_sortByColumn:(NSTableColumn *)inTableColumn; 47 48 @end 49 43 50 @implementation NJRTableDelegate 44 51 45 52 #pragma mark initialize-release 46 53 54 - (void)awakeFromNib; 55 { 56 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_positionTypeSelectDisplay) name: NSViewFrameDidChangeNotification object: tableView]; 57 } 58 47 59 - (void)dealloc 48 60 { 61 [[NSNotificationCenter defaultCenter] removeObserver: self]; 49 62 [sortingColumn release]; 50 63 [sortingKey release]; 64 [reorderedData release]; 51 65 [super dealloc]; 52 66 } … … 68 82 } 69 83 84 #pragma mark sorting 85 86 - (NSString *)_sortContextDefaultKey; 87 { 88 NSString *autosaveName = [tableView autosaveName]; 89 if (autosaveName != nil) 90 return [NSString stringWithFormat: @"NJRTableDelegate SortContext %@", autosaveName]; 91 else 92 return nil; 93 } 94 95 - (void)_sortData; 96 { 97 SortContext ctxt = { sortingKey, sortDescending }; 98 NSString *sortContextKey = [self _sortContextDefaultKey]; 99 100 if (sortContextKey != nil) { 101 [[NSUserDefaults standardUserDefaults] setObject: 102 [NSDictionary dictionaryWithObjectsAndKeys: sortingKey, @"sortingKey", [NSNumber numberWithBool: sortDescending], @"sortDescending", nil] 103 forKey: [self _sortContextDefaultKey]]; 104 } 105 106 // sort the NSMutableArray 107 [reorderedData sortUsingFunction: ORDER_BY_CONTEXT context: &ctxt]; 108 [tableView reloadData]; 109 } 110 111 - (void)_sortByColumn:(NSTableColumn *)inTableColumn; 112 { 113 NSSet *oldSelection = [self selectedItems]; 114 if (sortingColumn == inTableColumn) { 115 // User clicked same column, change sort order 116 sortDescending = !sortDescending; 117 // Possible optimization: Don't actually re-sort if you just change the sorting direction; instead, just display either the nth item or the (count-1-n)th item depending on ascending/descending.) 118 } else { 119 // User clicked new column, change old/new column headers, save new sorting column, and re-sort the array. 120 if (sortingColumn != nil) { 121 [tableView setIndicatorImage: nil inTableColumn: sortingColumn]; 122 sortDescending = NO; // on initial sort, preserve previous sort order 123 } 124 [self setSortingKey: [inTableColumn identifier]]; 125 [self setSortingColumn: inTableColumn]; 126 [tableView setHighlightedTableColumn: inTableColumn]; 127 } 128 [tableView setIndicatorImage: (sortDescending ? [NSTableView descendingSortIndicator] : [NSTableView ascendingSortIndicator]) inTableColumn: inTableColumn]; 129 [self _positionTypeSelectDisplay]; 130 // Actually sort the data 131 [self _sortData]; 132 [self selectItems: oldSelection]; 133 } 134 135 - (void)_initialSortData; 136 { 137 NSString *sortContextKey = [self _sortContextDefaultKey]; 138 NSDictionary *sortContext; 139 NSString *key; 140 NSTableColumn *column; 141 142 if (sortContextKey == nil) goto noContext; 143 if ( (sortContext = [[NSUserDefaults standardUserDefaults] dictionaryForKey: sortContextKey]) == nil) goto noContext; 144 if ( (key = [sortContext objectForKey: @"sortingKey"]) == nil) goto noContext; 145 if ( (column = [tableView tableColumnWithIdentifier: key]) == nil) goto noContext; 146 sortDescending = [[sortContext objectForKey: @"sortDescending"] boolValue]; 147 [self _sortByColumn: column]; 148 return; 149 150 noContext: 151 sortDescending = NO; 152 [self _sortByColumn: [[tableView tableColumns] objectAtIndex: 0]]; 153 } 154 155 - (NSMutableArray *)reorderedDataForData:(NSArray *)data; 156 { 157 if (reorderedData == nil) { 158 reorderedData = [data mutableCopy]; 159 [self _initialSortData]; 160 } else { 161 NSSet *oldSelection = [self selectedItems]; 162 [reorderedData release]; reorderedData = nil; 163 reorderedData = [data mutableCopy]; 164 [self _sortData]; 165 [self selectItems: oldSelection]; 166 } 167 return reorderedData; 168 } 169 170 #pragma mark type selection 171 172 - (void)_positionTypeSelectDisplay; 173 { 174 [tableView resetTypeSelect]; // avoid extraneous matching 175 if ([tableView typeSelectDisplay] != nil && sortingColumn != nil) { 176 NSControl *typeSelectControl = [tableView typeSelectDisplay]; 177 if ([typeSelectControl isKindOfClass: [NSControl class]]) { 178 NSView *superview = [typeSelectControl superview]; 179 NSRect columnRect = [superview convertRect: [tableView rectOfColumn: [tableView columnWithIdentifier: sortingKey]] fromView: tableView]; 180 // XXX support horizontal scroll bar/clipping (not for Pester, but eventually) 181 NSRect tableScrollFrame = [[tableView enclosingScrollView] frame]; 182 NSRect selectFrame = [typeSelectControl frame]; 183 [superview setNeedsDisplayInRect: selectFrame]; // fix artifacts caused by moving view 184 selectFrame.origin.x = columnRect.origin.x; 185 selectFrame.size.width = columnRect.size.width; 186 [typeSelectControl setAlignment: [[sortingColumn dataCell] alignment]]; 187 [typeSelectControl setFrame: selectFrame]; 188 } 189 } 190 } 191 70 192 #pragma mark saving/restoring selection 71 193 … … 77 199 78 200 while ( (rowNum = [e nextObject]) != nil) { 79 id item = [ oData objectAtIndex: [rowNum intValue]];201 id item = [reorderedData objectAtIndex: [rowNum intValue]]; 80 202 [result addObject: item]; 81 203 } … … 92 214 93 215 while ( (item = [e nextObject]) != nil ) { 94 int row = [ oData indexOfObjectIdenticalTo: item];216 int row = [reorderedData indexOfObjectIdenticalTo: item]; 95 217 if (row != NSNotFound) { 96 218 [tableView selectRow: row byExtendingSelection: YES]; … … 101 223 } 102 224 103 // ---------------------------------------------------------------------------------------- 104 // Sorting 105 // ---------------------------------------------------------------------------------------- 106 107 - (void)sortData 108 { 109 SortContext ctxt = { sortingKey, sortDescending }; 110 NSSet *oldSelection = [self selectedItems]; 111 112 // sort the NSMutableArray 113 [oData sortUsingFunction: ORDER_BY_CONTEXT context: &ctxt]; 114 115 [tableView reloadData]; 116 [self selectItems: oldSelection]; 117 } 118 119 - (void)sortByColumn:(NSTableColumn *)inTableColumn; 120 { 121 if (sortingColumn == inTableColumn) { 122 // User clicked same column, change sort order 123 sortDescending = !sortDescending; 124 // Possible optimization: Don't actually re-sort if you just change the sorting direction; 125 // instead, just display either the nth item or the (count-1-n)th item depending on ascending/descending.) 225 @end 226 227 @implementation NJRTableDelegate (NJRTableViewDelegate) 228 229 - (void)tableView:(NSTableView *)aTableView didClickTableColumn:(NSTableColumn *)inTableColumn 230 { 231 [[tableView window] makeFirstResponder: aTableView]; 232 [self _sortByColumn: inTableColumn]; 233 } 234 235 - (void)tableViewColumnDidResize:(NSNotification *)notification; 236 { 237 [self _positionTypeSelectDisplay]; 238 } 239 240 - (void)tableViewColumnDidMove:(NSNotification *)notification; 241 { 242 [self _positionTypeSelectDisplay]; 243 } 244 245 - (void)tableView:(NSTableView *)aTableView selectRowMatchingString:(NSString *)matchString; 246 { 247 // Look for a highlighted column, presuming we are sorted by that column, and search its values. 248 NSTableColumn *col = [aTableView highlightedTableColumn]; 249 id dataSource = [aTableView dataSource]; 250 int i, rowCount = [reorderedData count]; 251 if (nil == col) return; 252 if (sortDescending) { 253 for ( i = rowCount - 1 ; i >= 0 ; i-- ) { 254 NSComparisonResult order = [matchString caseInsensitiveCompare: 255 [dataSource tableView: aTableView objectValueForTableColumn: col row: i]]; 256 if (order != NSOrderedDescending) break; 257 } 258 if (i < 0) i = 0; 126 259 } else { 127 // User clicked new column, change old/new column headers, 128 // save new sorting column, and re-sort the array. 129 sortDescending = NO; 130 if (nil != sortingColumn) { 131 [tableView setIndicatorImage: nil inTableColumn: sortingColumn]; 132 } 133 [self setSortingKey: [inTableColumn identifier]]; 134 [self setSortingColumn: inTableColumn]; 135 [tableView setHighlightedTableColumn: inTableColumn]; 136 } 137 [tableView setIndicatorImage: (sortDescending ? [NSTableView descendingSortIndicator] : [NSTableView ascendingSortIndicator]) inTableColumn: inTableColumn]; 138 // Actually sort the data 139 [self sortData]; 140 } 141 142 // Sort by whatever column was clicked upon 143 - (void)tableView:(NSTableView*)aTableView didClickTableColumn:(NSTableColumn *)inTableColumn 144 { 145 [[tableView window] makeFirstResponder: aTableView]; // help make this tableView be first responder 146 [self sortByColumn:inTableColumn]; 147 } 148 149 // ---------------------------------------------------------------------------------------- 150 // Alphabetic Type Ahead 151 // ---------------------------------------------------------------------------------------- 152 153 - (void) typeAheadString:(NSString *)inString; 154 { 155 // This general sample looks for a highlighted column, presuming that is that column we are sorted by, and uses that as the lookup key. 156 NSTableColumn *col = [tableView highlightedTableColumn]; 157 if (nil != col) { 158 NSString *key = [col identifier]; 159 int i; 160 for ( i = 0 ; i < [oData count] ; i++ ) { 161 NSDictionary *rowDict = [oData objectAtIndex:i]; 162 NSString *compareTo = [rowDict objectForKey:key]; 163 NSComparisonResult order = [inString caseInsensitiveCompare:compareTo]; 260 for ( i = 0 ; i < rowCount ; i++ ) { 261 NSComparisonResult order = [matchString caseInsensitiveCompare: 262 [dataSource tableView: aTableView objectValueForTableColumn: col row: i]]; 164 263 if (order != NSOrderedDescending) break; 165 264 } 166 // Make sure we're not overflowing the row count. 167 if (i >= [oData count]) { 168 i = [oData count] - 1; 169 } 170 // Now select row i -- either the one we found, or the last row if not found. 171 [tableView selectRow:i byExtendingSelection:NO]; 172 [tableView scrollRowToVisible:i]; 173 } 265 if (i >= rowCount) i = rowCount - 1; 266 } 267 // Now select row i -- either the one we found, or the first/last row if not found. 268 [aTableView selectRow: i byExtendingSelection: NO]; 269 [aTableView scrollRowToVisible: i]; 174 270 } 175 271
Note:
See TracChangeset
for help on using the changeset viewer.