1 | //
|
---|
2 | // NJRTableDelegate.m
|
---|
3 | // Pester
|
---|
4 | //
|
---|
5 | // Created by Nicholas Riley on Sun Oct 27 2002.
|
---|
6 | // Copyright (c) 2002 __MyCompanyName__. All rights reserved.
|
---|
7 | //
|
---|
8 |
|
---|
9 | #import "NJRTableDelegate.h"
|
---|
10 | #import "NSTableView-NJRExtensions.h"
|
---|
11 |
|
---|
12 | #pragma mark sorting support
|
---|
13 |
|
---|
14 | typedef struct { NSString *key; BOOL descending; } SortContext;
|
---|
15 |
|
---|
16 | // Sort array of itemNums, by looking up the itemNum in the dictionary of dictionaries.
|
---|
17 | // based on code of Ondra Cada <ocs@ocs.cz> on cocoa-dev list
|
---|
18 |
|
---|
19 | int ORDER_BY_CONTEXT(id left, id right, void *ctxt) {
|
---|
20 | SortContext *context = (SortContext *)ctxt;
|
---|
21 | int order = 0;
|
---|
22 | id key = context->key;
|
---|
23 | if (0 != key) {
|
---|
24 | id first, second; // the actual objects to compare
|
---|
25 |
|
---|
26 | if (context->descending) {
|
---|
27 | first = [right objectForKey: key];
|
---|
28 | second = [left objectForKey: key];
|
---|
29 | } else {
|
---|
30 | first = [left objectForKey: key];
|
---|
31 | second = [right objectForKey: key];
|
---|
32 | }
|
---|
33 |
|
---|
34 | if ([first respondsToSelector: @selector(caseInsensitiveCompare:)]) {
|
---|
35 | order = [first caseInsensitiveCompare:second];
|
---|
36 | } else { // sort numbers or dates
|
---|
37 | order = [(NSNumber *)first compare:second];
|
---|
38 | }
|
---|
39 | }
|
---|
40 | return order;
|
---|
41 | }
|
---|
42 |
|
---|
43 | @implementation NJRTableDelegate
|
---|
44 |
|
---|
45 | #pragma mark initialize-release
|
---|
46 |
|
---|
47 | - (void)dealloc
|
---|
48 | {
|
---|
49 | [sortingColumn release];
|
---|
50 | [sortingKey release];
|
---|
51 | [super dealloc];
|
---|
52 | }
|
---|
53 |
|
---|
54 | #pragma mark accessing
|
---|
55 |
|
---|
56 | - (void)setSortingColumn:(NSTableColumn *)inNewValue;
|
---|
57 | {
|
---|
58 | [inNewValue retain];
|
---|
59 | [sortingColumn release];
|
---|
60 | sortingColumn = inNewValue;
|
---|
61 | }
|
---|
62 |
|
---|
63 | - (void)setSortingKey:(NSString *)inNewValue;
|
---|
64 | {
|
---|
65 | [inNewValue retain];
|
---|
66 | [sortingKey release];
|
---|
67 | sortingKey = inNewValue;
|
---|
68 | }
|
---|
69 |
|
---|
70 | #pragma mark saving/restoring selection
|
---|
71 |
|
---|
72 | - (NSSet *)selectedItems;
|
---|
73 | {
|
---|
74 | NSMutableSet *result = [NSMutableSet set];
|
---|
75 | NSEnumerator *e = [tableView selectedRowEnumerator];
|
---|
76 | NSNumber *rowNum;
|
---|
77 |
|
---|
78 | while ( (rowNum = [e nextObject]) != nil) {
|
---|
79 | id item = [oData objectAtIndex: [rowNum intValue]];
|
---|
80 | [result addObject: item];
|
---|
81 | }
|
---|
82 | return result;
|
---|
83 | }
|
---|
84 |
|
---|
85 | - (void)selectItems:(NSSet *)inSelectedItems;
|
---|
86 | {
|
---|
87 | NSEnumerator *e = [inSelectedItems objectEnumerator];
|
---|
88 | id item;
|
---|
89 | int savedLastRow = 0;
|
---|
90 |
|
---|
91 | [tableView deselectAll: nil];
|
---|
92 |
|
---|
93 | while ( (item = [e nextObject]) != nil ) {
|
---|
94 | int row = [oData indexOfObjectIdenticalTo: item];
|
---|
95 | if (row != NSNotFound) {
|
---|
96 | [tableView selectRow: row byExtendingSelection: YES];
|
---|
97 | savedLastRow = row;
|
---|
98 | }
|
---|
99 | }
|
---|
100 | [tableView scrollRowToVisible: savedLastRow];
|
---|
101 | }
|
---|
102 |
|
---|
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.)
|
---|
126 | } 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];
|
---|
164 | if (order != NSOrderedDescending) break;
|
---|
165 | }
|
---|
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 | }
|
---|
174 | }
|
---|
175 |
|
---|
176 | @end
|
---|