Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/Classes/MyTableView.m

Parent Directory Parent Directory | Revision Log Revision Log


Revision 204 - (show annotations) (download)
Sat Jul 23 11:27:57 2022 UTC (20 months, 2 weeks ago) by toshinagata1964
File size: 9424 byte(s)
Row selection is preserved after changing event tick in List window
1 //
2 // MyTableView.m
3 //
4 // Created by Toshi Nagata.
5 /*
6 Copyright (c) 2000-2016 Toshi Nagata. All rights reserved.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 */
17
18 #import "MyTableView.h"
19 #import "ListWindowController.h"
20
21 @implementation MyTableView
22
23 - (id)initWithFrame:(NSRect)frameRect
24 {
25 self = [super initWithFrame:frameRect];
26 if (self) {
27 underlineRow = -1;
28 }
29 return self;
30 }
31
32 - (void)awakeFromNib
33 {
34 underlineRow = -1;
35 }
36
37 - (void)editColumn:(NSInteger)columnIndex row:(NSInteger)rowIndex withEvent:(NSEvent *)theEvent select:(BOOL)flag
38 {
39 // If the delegate implements special editing feature, call it.
40 id delegate = [self delegate];
41 if ([delegate respondsToSelector:@selector(myTableView:shouldEditColumn:row:)]) {
42 if (![(MyTableView *)delegate myTableView:self shouldEditColumn:(int)columnIndex row:(int)rowIndex])
43 return;
44 }
45 // If it does not, then do the usual thing
46 [super editColumn:columnIndex row:rowIndex withEvent:theEvent select:flag];
47 }
48
49 - (void)textDidBeginEditing: (NSNotification *)aNotification
50 {
51 // Make a copy of the original string
52 [originalString release];
53 originalString = [[NSString allocWithZone: [self zone]] initWithString: [[aNotification object] string]];
54 escapeFlag = NO;
55 }
56
57 - (BOOL)textShouldEndEditing: (NSText *)textObject
58 {
59 if (escapeFlag)
60 // Restore the original string
61 [textObject setString: originalString];
62 return [super textShouldEndEditing: textObject];
63 }
64
65 /* Keyboard navigation during editing.
66 * Return: insert a new event in the next line, and continue editing.
67 * Enter: exit editing.
68 * Escape: discard the change in the current cell and exit editing.
69 * Tab/Backtab, arrows, home, end, pageup, pagedown: move the editing cell.
70 */
71 - (BOOL)textView:(NSTextView *)aTextView doCommandBySelector:(SEL)aSelector
72 {
73 int column, row, newRow, oldRow, dColumn, dRow, numRows, pageRows, n;
74 NSRect visibleRect;
75 BOOL endEditing = NO;
76 BOOL insertNewline = NO;
77 BOOL pageScroll = NO;
78 NSEvent *theEvent = [[self window] currentEvent];
79 // unichar charCode;
80 // charCode = [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
81 column = (int)[self editedColumn];
82 row = (int)[self editedRow];
83 dColumn = dRow = 0;
84 numRows = (int)[self numberOfRows];
85 visibleRect = [self visibleRect];
86 pageRows = (int)([self rowsInRect: visibleRect]).length - 1;
87 if (aSelector == @selector(insertNewline:)) {
88 if ([[theEvent charactersIgnoringModifiers] characterAtIndex: 0] == NSEnterCharacter) {
89 endEditing = YES;
90 } else if ([theEvent modifierFlags] & NSShiftKeyMask) {
91 dRow = -1;
92 } else {
93 dRow = 1;
94 }
95 } else if (aSelector == @selector(insertTab:)) {
96 dColumn = 1;
97 } else if (aSelector == @selector(insertBacktab:)) {
98 dColumn = -1;
99 /* } else if (aSelector == @selector(moveLeft:)) {
100 dColumn = -1;
101 } else if (aSelector == @selector(moveRight:)) {
102 dColumn = 1;
103 } else if (aSelector == @selector(moveUp:)) {
104 dRow = -1;
105 } else if (aSelector == @selector(moveDown:)) {
106 dRow = 1; */
107 } else if (aSelector == @selector(scrollToBeginningOfDocument:)) {
108 dRow = -(numRows - 1);
109 } else if (aSelector == @selector(scrollToEndOfDocument:)) {
110 dRow = (numRows - 1);
111 } else if (aSelector == @selector(scrollPageUp:)) {
112 dRow = -pageRows;
113 pageScroll = YES;
114 } else if (aSelector == @selector(scrollPageDown:)) {
115 dRow = pageRows;
116 pageScroll = YES;
117 } else if (aSelector == @selector(cancel:)) {
118 [aTextView setString: originalString];
119 endEditing = YES;
120 } else {
121 // NSLog(@"selector = %@", NSStringFromSelector(aSelector));
122 return NO;
123 }
124
125 /* End edit of the current cell */
126 if (![[self window] makeFirstResponder: self]) {
127 /* Cannot end edit (the value is not valid) */
128 NSBeep();
129 return YES;
130 }
131
132 if (endEditing)
133 return YES;
134
135 /* Continue edit */
136 newRow = (int)[self selectedRow]; /* May have changed during confirmation */
137 oldRow = row;
138
139 /* Adjust the column position */
140 column += dColumn;
141 n = (int)[self numberOfColumns] - 1;
142 if (column > n) {
143 column = 0;
144 dRow = 1;
145 }
146 if (column < 0) {
147 column = n;
148 dRow = -1;
149 }
150
151 /* Adjust the row position */
152 if (newRow != oldRow) {
153 row = newRow;
154 } else {
155 if (dRow != 0) {
156 row += dRow;
157 if (oldRow < newRow && (oldRow < row && row <= newRow))
158 row--;
159 else if (oldRow > newRow && (oldRow > row && row >= newRow))
160 row++;
161 }
162 }
163 if (row < 0)
164 row = 0;
165 else if (row >= (n = (int)[[self dataSource] numberOfRowsInTableView: self]))
166 row = n - 1;
167
168 if (pageScroll) {
169 NSClipView *clipView = (NSClipView *)[self superview];
170 NSPoint newOrigin = [clipView bounds].origin;
171 float amount = [self rectOfRow: row].origin.y - [self rectOfRow: [self selectedRow]].origin.y;
172 // NSLog(@"clipView = %@, origin = (%g, %g) amount = %g", clipView, newOrigin.x, newOrigin.y, amount);
173 newOrigin.y += amount;
174 [clipView scrollToPoint: [clipView constrainScrollPoint: newOrigin]];
175 }
176
177 if (insertNewline) {
178 /* Insert an empty event with the same tick (TODO: or advance the tick by some specified value?) */
179 int32_t position = [(ListWindowController *)[self dataSource] eventPositionForTableRow: row];
180 [(ListWindowController *)[self dataSource] startEditAtColumn: column creatingEventWithTick: kMDNegativeTick atPosition: position + 1];
181 } else {
182 [(ListWindowController *)[self dataSource] startEditAtColumn: column row: row];
183 }
184
185 // if (insertNewline) {
186 // /* Insert empty event and continue */
187 // if (row > numRows - 1)
188 // row = numRows - 1;
189 // [[self dataSource] startEditAtRow: row insertMode: YES];
190 // } else {
191 // if (row > numRows - 2)
192 // row = numRows - 2;
193 // [self selectRow: row byExtendingSelection: NO];
194 // [self editColumn: column row: row withEvent: nil select: YES];
195 // }
196 return YES;
197 }
198
199 /* Keyboard navigation during _not_ editing.
200 * Command+Return: insert a new event after the current event and start editing.
201 * Command+Enter: start editing at the current cell.
202 * Delete, Backspace: delete selected events.
203 */
204 - (void)keyDown:(NSEvent *)theEvent
205 {
206 int row;
207 BOOL insertFlag;
208 unichar charCode = [[theEvent charactersIgnoringModifiers] characterAtIndex: 0];
209 NSUInteger modifierFlags = [theEvent modifierFlags];
210 if ((modifierFlags & NSCommandKeyMask) != 0 && (charCode == NSCarriageReturnCharacter || charCode == NSEnterCharacter)) {
211 /* Enter edit mode */
212 if ([self numberOfSelectedRows] == 1) {
213 int32_t position;
214 row = (int)[self selectedRow];
215 if (charCode == NSCarriageReturnCharacter) {
216 insertFlag = YES;
217 if (row < [self numberOfRows] - 1)
218 row++;
219 } else {
220 insertFlag = NO;
221 }
222 position = [(ListWindowController *)[self dataSource] eventPositionForTableRow: row];
223 [(ListWindowController *)[self dataSource] startEditAtColumn: -1 creatingEventWithTick: kMDNegativeTick atPosition: position + 1];
224 return;
225 }
226 NSBeep();
227 } else if (charCode == NSBackspaceCharacter || charCode == NSDeleteCharacter) {
228 if ([self numberOfSelectedRows] > 0)
229 [(ListWindowController *)[self dataSource] deleteSelectedEvents: self];
230 else NSBeep();
231 } else [super keyDown:theEvent];
232 }
233
234 /* Implement context menu */
235 - (NSMenu *)menuForEvent:(NSEvent *)theEvent
236 {
237 NSPoint pt = [self convertPoint: [theEvent locationInWindow] fromView: nil];
238 int row = (int)[self rowAtPoint: pt];
239 int column = (int)[self columnAtPoint: pt];
240 NSRect cellFrame = [self frameOfCellAtColumn: column row: row];
241 if (cellFrame.size.height > 0 && cellFrame.size.width > 0) {
242 return [[[[self tableColumns] objectAtIndex: column] dataCell] menuForEvent: theEvent inRect: cellFrame ofView: self];
243 } else return nil;
244 /*
245 if (column == 1 && row >= 0 && row < [self numberOfRows] - 1 && [self selectedRow] == row)
246 return [self menu];
247 else return nil; */
248 }
249
250 - (void)setUnderlineRow:(int)row
251 {
252 if (row == underlineRow)
253 return;
254 if (underlineRow >= 0)
255 [self setNeedsDisplayInRect:[self rectOfRow:underlineRow]];
256 underlineRow = row;
257 if (underlineRow >= 0)
258 [self setNeedsDisplayInRect:[self rectOfRow:underlineRow]];
259 }
260
261 - (void)drawRow:(NSInteger)row clipRect:(NSRect)clipRect
262 {
263 [super drawRow:row clipRect:clipRect];
264 if (underlineRow == row) {
265 float y;
266 NSRect rowRect;
267 rowRect = [self rectOfRow:underlineRow];
268 y = rowRect.origin.y + rowRect.size.height - 2;
269 [[NSColor grayColor] set];
270 [NSBezierPath strokeLineFromPoint:NSMakePoint(rowRect.origin.x + 1, y) toPoint:NSMakePoint(rowRect.origin.x + rowRect.size.width - 1, y)];
271 }
272 }
273
274 /*
275 - (void)drawRect: (NSRect)aRect
276 {
277 NSRect rowRect;
278 [super drawRect:aRect];
279 if (underlineRow >= 0) {
280 float y;
281 rowRect = [self rectOfRow:underlineRow];
282 y = rowRect.origin.y + 10;
283 [NSBezierPath strokeLineFromPoint:NSMakePoint(rowRect.origin.x + 1, y) toPoint:NSMakePoint(rowRect.origin.x + rowRect.size.width - 1, y)];
284 }
285 }
286 */
287
288 @end

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26