source: trunk/macosx/TorrentTableView.m @ 3327

Last change on this file since 3327 was 3327, checked in by livings124, 15 years ago

double click progress string in main window instead of single click to toggle it

  • Property svn:keywords set to Date Rev Author Id
File size: 21.9 KB
Line 
1/******************************************************************************
2 * $Id: TorrentTableView.m 3327 2007-10-08 11:51:58Z livings124 $
3 *
4 * Copyright (c) 2005-2007 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "TorrentTableView.h"
26#import "TorrentCell.h"
27#import "Controller.h"
28#import "Torrent.h"
29#import "NSMenuAdditions.h"
30
31#define PADDING 3.0
32
33#define BUTTON_TO_TOP_REGULAR 33.0
34#define BUTTON_TO_TOP_SMALL 20.0
35
36#define ACTION_BUTTON_TO_TOP 47.0
37
38#define ACTION_MENU_GLOBAL_TAG 101
39#define ACTION_MENU_UNLIMITED_TAG 102
40#define ACTION_MENU_LIMIT_TAG 103
41
42@interface TorrentTableView (Private)
43
44- (NSRect) pauseRectForRow: (int) row;
45- (NSRect) revealRectForRow: (int) row;
46- (NSRect) actionRectForRow: (int) row;
47
48- (BOOL) pointInIconRect: (NSPoint) point;
49- (BOOL) pointInProgressRect: (NSPoint) point;
50- (BOOL) pointInMinimalStatusRect: (NSPoint) point;
51
52- (BOOL) pointInPauseRect: (NSPoint) point;
53- (BOOL) pointInRevealRect: (NSPoint) point;
54- (BOOL) pointInActionRect: (NSPoint) point;
55
56- (void) updateFileMenu: (NSMenu *) menu forFiles: (NSArray *) files;
57
58@end
59
60@implementation TorrentTableView
61
62- (id) initWithCoder: (NSCoder *) decoder
63{
64    if ((self = [super initWithCoder: decoder]))
65    {
66        fResumeOnIcon = [NSImage imageNamed: @"ResumeOn.png"];
67        fResumeOffIcon = [NSImage imageNamed: @"ResumeOff.png"];
68        fPauseOnIcon = [NSImage imageNamed: @"PauseOn.png"];
69        fPauseOffIcon = [NSImage imageNamed: @"PauseOff.png"];
70        fResumeNoWaitOnIcon = [NSImage imageNamed: @"ResumeNoWaitOn.png"];
71        fResumeNoWaitOffIcon = [NSImage imageNamed: @"ResumeNoWaitOff.png"];
72       
73        fRevealOnIcon = [NSImage imageNamed: @"RevealOn.png"];
74        fRevealOffIcon = [NSImage imageNamed: @"RevealOff.png"];
75       
76        fActionOnIcon = [NSImage imageNamed: @"ActionOn.png"];
77        fActionOffIcon = [NSImage imageNamed: @"ActionOff.png"];
78       
79        fClickPoint = NSZeroPoint;
80        fClickIn = NO;
81       
82        fDefaults = [NSUserDefaults standardUserDefaults];
83       
84        [self setDelegate: self];
85    }
86   
87    return self;
88}
89   
90- (void) awakeFromNib
91{
92    [fContextRow setTitle: @"Context"];
93    [fContextNoRow setTitle: @"Context"];
94}
95
96- (void) dealloc
97{
98    [fKeyStrokes release];
99    [fMenuTorrent release];
100   
101    [super dealloc];
102}
103
104- (void) setTorrents: (NSArray *) torrents
105{
106    fTorrents = torrents;
107}
108
109- (void) tableView: (NSTableView *) tableView willDisplayCell: (id) cell
110        forTableColumn: (NSTableColumn *) tableColumn row: (int) row
111{
112    [cell setRepresentedObject: [fTorrents objectAtIndex: row]];
113}
114
115- (void) mouseDown: (NSEvent *) event
116{
117    fClickPoint = [self convertPoint: [event locationInWindow] fromView: nil];
118
119    if ([self pointInActionRect: fClickPoint])
120    {
121        int row = [self rowAtPoint: fClickPoint];
122        [self setNeedsDisplayInRect: [self rectOfRow: row]]; //ensure button is pushed down
123       
124        [self displayTorrentMenuForEvent: event];
125       
126        fClickPoint = NSZeroPoint;
127        [self setNeedsDisplayInRect: [self rectOfRow: row]];
128    }
129    else if ([self pointInPauseRect: fClickPoint] || [self pointInRevealRect: fClickPoint])
130    {
131        fClickIn = YES;
132        [self setNeedsDisplayInRect: [self rectOfRow: [self rowAtPoint: fClickPoint]]];
133    }
134    else
135    {
136        if (/*[event modifierFlags] & NSAlternateKeyMask*/NO)
137        {
138            [fDefaults setBool: ![fDefaults boolForKey: @"UseAdvancedBar"] forKey: @"UseAdvancedBar"];
139            fClickPoint = NSZeroPoint;
140            [self reloadData];
141        }
142        else
143        {
144            if ([self pointInMinimalStatusRect: fClickPoint])
145            {
146                [fDefaults setBool: ![fDefaults boolForKey: @"DisplaySmallStatusRegular"] forKey: @"DisplaySmallStatusRegular"];
147                fClickPoint = NSZeroPoint;
148                [self reloadData];
149            }
150
151            [super mouseDown: event];
152        }
153    }
154}
155
156- (void) mouseUp: (NSEvent *) event
157{
158    NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil];
159    int row = [self rowAtPoint: point], oldRow = [self rowAtPoint: fClickPoint];
160    BOOL sameRow = row == oldRow;
161   
162    if (sameRow && [self pointInPauseRect: point] && [self pointInPauseRect: fClickPoint])
163    {
164        Torrent * torrent = [fTorrents objectAtIndex: row];
165
166        if ([torrent isActive])
167            [fController stopTorrents: [NSArray arrayWithObject: torrent]];
168        else if ([torrent isPaused])
169        {
170            if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)
171                [fController resumeTorrentsNoWait: [NSArray arrayWithObject: torrent]];
172            else if ([torrent waitingToStart])
173                [fController stopTorrents: [NSArray arrayWithObject: torrent]];
174            else
175                [fController resumeTorrents: [NSArray arrayWithObject: torrent]];
176        }
177        else;
178    }
179    else if (sameRow && [self pointInRevealRect: point] && [self pointInRevealRect: fClickPoint])
180        [[fTorrents objectAtIndex: row] revealData];
181    else if ([event clickCount] == 2 && !NSEqualPoints(fClickPoint, NSZeroPoint))
182    {
183        if ([self pointInProgressRect: fClickPoint])
184        {
185            [fDefaults setBool: ![fDefaults boolForKey: @"DisplayStatusProgressSelected"] forKey: @"DisplayStatusProgressSelected"];
186            [self reloadData];
187        }
188        else if ([self pointInIconRect: point])
189            [[fTorrents objectAtIndex: row] revealData];
190        else if (![self pointInActionRect: point])
191            [fController showInfo: nil];
192        else;
193    }
194    else;
195   
196    [super mouseUp: event];
197
198    fClickPoint = NSZeroPoint;
199    fClickIn = NO;
200    [self setNeedsDisplayInRect: [self rectOfRow: oldRow]];
201}
202
203- (void) mouseDragged: (NSEvent *) event
204{
205    if (NSEqualPoints(fClickPoint, NSZeroPoint))
206    {
207        [super mouseDragged: event];
208        return;
209    }
210   
211    NSPoint point = [self convertPoint: [event locationInWindow] fromView: nil];
212    int oldRow = [self rowAtPoint: fClickPoint];
213   
214    BOOL inRect;
215    if ([self pointInRevealRect: fClickPoint])
216        inRect = oldRow == [self rowAtPoint: point] && [self pointInRevealRect: point];
217    else if ([self pointInPauseRect: fClickPoint])
218        inRect = oldRow == [self rowAtPoint: point] && [self pointInPauseRect: point];
219    else
220    {
221        [super mouseDragged: event];
222        return;
223    }
224   
225    if (inRect != fClickIn)
226    {
227        fClickIn = inRect;
228        [self setNeedsDisplayInRect: [self rectOfRow: oldRow]];
229    }
230}
231
232- (NSMenu *) menuForEvent: (NSEvent *) event
233{
234    int row = [self rowAtPoint: [self convertPoint: [event locationInWindow] fromView: nil]];
235   
236    if (row >= 0)
237    {
238        if (![self isRowSelected: row])
239            [self selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO];
240               
241        return fContextRow;
242    }
243    else
244    {
245        [self deselectAll: self];
246        return fContextNoRow;
247    }
248}
249
250- (void) keyDown: (NSEvent *) event
251{
252    if (!fKeyStrokes)
253        fKeyStrokes = [[NSMutableArray alloc] init];
254   
255    unichar newChar = [[event characters] characterAtIndex: 0];
256    if (newChar == ' ' || [[NSCharacterSet alphanumericCharacterSet] characterIsMember: newChar]
257        || [[NSCharacterSet symbolCharacterSet] characterIsMember: newChar]
258        || [[NSCharacterSet punctuationCharacterSet] characterIsMember: newChar])
259    {
260        if ([fKeyStrokes count] > 0 && [event timestamp] - [[fKeyStrokes lastObject] timestamp] > 1.0)
261            [fKeyStrokes removeAllObjects];
262        [fKeyStrokes addObject: event];
263   
264        [self interpretKeyEvents: fKeyStrokes];
265    }
266    else
267    {
268        [fKeyStrokes removeAllObjects];
269        [super keyDown: event];
270    }
271}
272
273- (void) flagsChanged: (NSEvent *) event
274{
275    [self display];
276    [super flagsChanged: event];
277}
278
279- (void) insertText: (NSString *) text
280{
281    //sort torrents by name before finding closest match
282    NSSortDescriptor * nameDescriptor = [[[NSSortDescriptor alloc] initWithKey: @"name" ascending: YES
283                                            selector: @selector(caseInsensitiveCompare:)] autorelease];
284    NSArray * descriptors = [[NSArray alloc] initWithObjects: nameDescriptor, nil];
285
286    NSArray * tempTorrents = [fTorrents sortedArrayUsingDescriptors: descriptors];
287    [descriptors release];
288   
289    //select torrent closest to text that isn't before text alphabetically
290    int row;
291    NSEnumerator * enumerator = [tempTorrents objectEnumerator];
292    Torrent * torrent;
293    while ((torrent = [enumerator nextObject]))
294        if ([[torrent name] caseInsensitiveCompare: text] != NSOrderedAscending)
295        {
296            row = [fTorrents indexOfObject: torrent];
297            break;
298        }
299   
300    //select last torrent alphabetically if no match found
301    if (!torrent)
302        row = [fTorrents indexOfObject: [tempTorrents lastObject]];
303   
304    [self selectRow: row byExtendingSelection: NO];
305    [self scrollRowToVisible: row];
306}
307
308- (void) displayTorrentMenuForEvent: (NSEvent *) event
309{
310    int row = [self rowAtPoint: [self convertPoint: [event locationInWindow] fromView: nil]];
311    if (row < 0)
312        return;
313   
314    //get and update file menu
315    fMenuTorrent = [[fTorrents objectAtIndex: row] retain];
316    NSMenu * fileMenu = [fMenuTorrent fileMenu];
317    [self updateFileMenu: fileMenu forFiles: [fMenuTorrent fileList]];
318   
319    //add file menu items to action menu
320    NSRange range =  NSMakeRange(0, [fileMenu numberOfItems]);
321    [fActionMenu appendItemsFromMenu: fileMenu atIndexes: [NSIndexSet indexSetWithIndexesInRange: range]];
322   
323    //place menu below button
324    NSRect rect = [self actionRectForRow: row];
325    NSPoint location = rect.origin;
326    location.y += rect.size.height + 5.0;
327    location = [self convertPoint: location toView: nil];
328   
329    NSEvent * newEvent = [NSEvent mouseEventWithType: [event type] location: location
330        modifierFlags: [event modifierFlags] timestamp: [event timestamp] windowNumber: [event windowNumber]
331        context: [event context] eventNumber: [event eventNumber] clickCount: [event clickCount] pressure: [event pressure]];
332   
333    [NSMenu popUpContextMenu: fActionMenu withEvent: newEvent forView: self];
334   
335    //move file menu items back to the torrent's file menu
336    range.location = [fActionMenu numberOfItems] - range.length;
337    [fileMenu appendItemsFromMenu: fActionMenu atIndexes: [NSIndexSet indexSetWithIndexesInRange: range]];
338   
339    [fMenuTorrent release];
340    fMenuTorrent = nil;
341}
342
343- (void) menuNeedsUpdate: (NSMenu *) menu
344{
345    //this method seems to be called when it shouldn't be
346    if (!fMenuTorrent || ![menu supermenu])
347        return;
348   
349    if (menu == fUploadMenu || menu == fDownloadMenu)
350    {
351        BOOL upload = menu == fUploadMenu;
352        int mode = [fMenuTorrent speedMode: upload];
353       
354        NSMenuItem * item = [menu itemWithTag: ACTION_MENU_LIMIT_TAG];
355        [item setState: mode == TR_SPEEDLIMIT_SINGLE ? NSOnState : NSOffState];
356        [item setTitle: [NSString stringWithFormat: NSLocalizedString(@"Limit (%d KB/s)",
357                    "torrent action context menu -> upload/download limit"), [fMenuTorrent speedLimit: upload]]];
358       
359        item = [menu itemWithTag: ACTION_MENU_UNLIMITED_TAG];
360        [item setState: mode == TR_SPEEDLIMIT_UNLIMITED ? NSOnState : NSOffState];
361       
362        item = [menu itemWithTag: ACTION_MENU_GLOBAL_TAG];
363        [item setState: mode == TR_SPEEDLIMIT_GLOBAL ? NSOnState : NSOffState];
364    }
365    else if (menu == fRatioMenu)
366    {
367        int mode = [fMenuTorrent ratioSetting];
368       
369        NSMenuItem * item = [menu itemWithTag: ACTION_MENU_LIMIT_TAG];
370        [item setState: mode == NSOnState ? NSOnState : NSOffState];
371        [item setTitle: [NSString stringWithFormat: NSLocalizedString(@"Stop at Ratio (%.2f)",
372                    "torrent action context menu -> ratio stop"), [fMenuTorrent ratioLimit]]];
373       
374        item = [menu itemWithTag: ACTION_MENU_UNLIMITED_TAG];
375        [item setState: mode == NSOffState ? NSOnState : NSOffState];
376       
377        item = [menu itemWithTag: ACTION_MENU_GLOBAL_TAG];
378        [item setState: mode == NSMixedState ? NSOnState : NSOffState];
379    }
380    else if ([menu supermenu]) //assume the menu is part of the file list
381    {
382        NSMenu * supermenu = [menu supermenu];
383        [self updateFileMenu: menu forFiles: [[[supermenu itemAtIndex: [supermenu indexOfItemWithSubmenu: menu]]
384                                                    representedObject] objectForKey: @"Children"]];
385    }
386    else;
387}
388
389- (void) setQuickLimitMode: (id) sender
390{
391    int tag = [sender tag];
392    int mode;
393    if (tag == ACTION_MENU_UNLIMITED_TAG)
394        mode = TR_SPEEDLIMIT_UNLIMITED;
395    else if (tag == ACTION_MENU_LIMIT_TAG)
396        mode = TR_SPEEDLIMIT_SINGLE;
397    else
398        mode = TR_SPEEDLIMIT_GLOBAL;
399   
400    [fMenuTorrent setSpeedMode: mode upload: [sender menu] == fUploadMenu];
401   
402    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
403}
404
405- (void) setQuickLimit: (id) sender
406{
407    BOOL upload = [sender menu] == fUploadMenu;
408    [fMenuTorrent setSpeedMode: TR_SPEEDLIMIT_SINGLE upload: upload];
409    [fMenuTorrent setSpeedLimit: [[sender title] intValue] upload: upload];
410   
411    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
412}
413
414- (void) setQuickRatioMode: (id) sender
415
416{
417    int tag = [sender tag];
418    int mode;
419    if (tag == ACTION_MENU_UNLIMITED_TAG)
420        mode = NSOffState;
421    else if (tag == ACTION_MENU_LIMIT_TAG)
422        mode = NSOnState;
423    else
424        mode = NSMixedState;
425   
426    [fMenuTorrent setRatioSetting: mode];
427   
428    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
429}
430
431- (void) setQuickRatio: (id) sender
432{
433    [fMenuTorrent setRatioSetting: NSOnState];
434    [fMenuTorrent setRatioLimit: [[sender title] floatValue]];
435   
436    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
437}
438
439- (void) checkFile: (id) sender
440{
441    NSIndexSet * indexSet = [[sender representedObject] objectForKey: @"Indexes"];
442    [fMenuTorrent setFileCheckState: [sender state] != NSOnState ? NSOnState : NSOffState forIndexes: indexSet];
443   
444    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateStats" object: nil];
445}
446
447- (void) drawRow: (int) row clipRect: (NSRect) rect
448{
449    [super drawRow: row clipRect: rect];
450   
451    Torrent * torrent = [fTorrents objectAtIndex: row];
452   
453    //pause/resume icon
454    NSImage * pauseImage = nil;
455    NSRect pauseRect  = [self pauseRectForRow: row];
456    if ([torrent isActive])
457        pauseImage = fClickIn && NSPointInRect(fClickPoint, pauseRect) ? fPauseOnIcon : fPauseOffIcon;
458    else if ([torrent isPaused])
459    {
460        BOOL inPauseRect = fClickIn && NSPointInRect(fClickPoint, pauseRect);
461        if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask && [fDefaults boolForKey: @"Queue"])
462            pauseImage = inPauseRect ? fResumeNoWaitOnIcon : fResumeNoWaitOffIcon;
463        else if ([torrent waitingToStart])
464            pauseImage = inPauseRect ? fPauseOnIcon : fPauseOffIcon;
465        else
466            pauseImage = inPauseRect ? fResumeOnIcon : fResumeOffIcon;
467    }
468    else;
469   
470    if (pauseImage)
471        [pauseImage compositeToPoint: NSMakePoint(pauseRect.origin.x, NSMaxY(pauseRect)) operation: NSCompositeSourceOver];
472   
473    //reveal icon
474    NSRect revealRect = [self revealRectForRow: row];
475    NSImage * revealImage = fClickIn && NSPointInRect(fClickPoint, revealRect) ? fRevealOnIcon : fRevealOffIcon;
476    [revealImage compositeToPoint: NSMakePoint(revealRect.origin.x, NSMaxY(revealRect)) operation: NSCompositeSourceOver];
477   
478    //action icon
479    if (![fDefaults boolForKey: @"SmallView"])
480    {
481        NSRect actionRect = [self actionRectForRow: row];
482        NSImage * actionImage = NSPointInRect(fClickPoint, actionRect) ? fActionOnIcon : fActionOffIcon;
483        [actionImage compositeToPoint: NSMakePoint(actionRect.origin.x, NSMaxY(actionRect)) operation: NSCompositeSourceOver];
484    }
485}
486
487@end
488
489@implementation TorrentTableView (Private)
490
491- (NSRect) pauseRectForRow: (int) row
492{
493    if (row < 0)
494        return NSZeroRect;
495   
496    NSRect cellRect = [self frameOfCellAtColumn: 0 row: row];
497   
498    float buttonToTop = [fDefaults boolForKey: @"SmallView"] ? BUTTON_TO_TOP_SMALL : BUTTON_TO_TOP_REGULAR;
499   
500    return NSMakeRect(NSMaxX(cellRect) - PADDING - BUTTON_WIDTH - PADDING - BUTTON_WIDTH,
501                        cellRect.origin.y + buttonToTop, BUTTON_WIDTH, BUTTON_WIDTH);
502}
503
504- (NSRect) revealRectForRow: (int) row
505{
506    if (row < 0)
507        return NSZeroRect;
508   
509    NSRect cellRect = [self frameOfCellAtColumn: 0 row: row];
510   
511    float buttonToTop = [fDefaults boolForKey: @"SmallView"] ? BUTTON_TO_TOP_SMALL : BUTTON_TO_TOP_REGULAR;
512   
513    return NSMakeRect(NSMaxX(cellRect) - PADDING - BUTTON_WIDTH,
514                        cellRect.origin.y + buttonToTop, BUTTON_WIDTH, BUTTON_WIDTH);
515}
516
517- (NSRect) actionRectForRow: (int) row
518{
519    if (row < 0)
520        return NSZeroRect;
521   
522    TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
523    NSRect cellRect = [self frameOfCellAtColumn: 0 row: row],
524            iconRect = [cell iconRectForBounds: cellRect];
525   
526    if ([fDefaults boolForKey: @"SmallView"])
527        return iconRect;
528    else
529        return NSMakeRect(iconRect.origin.x + (iconRect.size.width - ACTION_BUTTON_WIDTH) * 0.5,
530                        cellRect.origin.y + ACTION_BUTTON_TO_TOP, ACTION_BUTTON_WIDTH, ACTION_BUTTON_HEIGHT);
531}
532
533- (BOOL) pointInIconRect: (NSPoint) point
534{
535    int row = [self rowAtPoint: point];
536    if (row < 0)
537        return NO;
538   
539    TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
540    return NSPointInRect(point, [cell iconRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
541}
542
543- (BOOL) pointInProgressRect: (NSPoint) point
544{
545    int row = [self rowAtPoint: point];
546    if (row < 0 || [fDefaults boolForKey: @"SmallView"])
547        return NO;
548   
549    TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
550    [cell setRepresentedObject: [fTorrents objectAtIndex: row]];
551    return NSPointInRect(point, [cell progressRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
552}
553
554- (BOOL) pointInMinimalStatusRect: (NSPoint) point
555{
556    int row = [self rowAtPoint: point];
557    if (row < 0 || ![fDefaults boolForKey: @"SmallView"])
558        return NO;
559   
560    TorrentCell * cell = [[self tableColumnWithIdentifier: @"Torrent"] dataCell];
561    [cell setRepresentedObject: [fTorrents objectAtIndex: row]];
562    return NSPointInRect(point, [cell minimalStatusRectForBounds: [self frameOfCellAtColumn: 0 row: row]]);
563}
564
565- (BOOL) pointInPauseRect: (NSPoint) point
566{
567    int row = [self rowAtPoint: point];
568    if (row < 0)
569        return NO;
570   
571    return NSPointInRect(point, [self pauseRectForRow: row]);
572}
573
574- (BOOL) pointInRevealRect: (NSPoint) point
575{
576    int row = [self rowAtPoint: point];
577    if (row < 0)
578        return NO;
579   
580    return NSPointInRect(point, [self revealRectForRow: row]);
581}
582
583- (BOOL) pointInActionRect: (NSPoint) point
584{
585    int row = [self rowAtPoint: point];
586    if (row < 0)
587        return NO;
588   
589    return NSPointInRect(point, [self actionRectForRow: row]);
590}
591
592- (void) updateFileMenu: (NSMenu *) menu forFiles: (NSArray *) files
593{
594    BOOL create = [menu numberOfItems] <= 0;
595   
596    NSEnumerator * enumerator = [files objectEnumerator];
597    NSDictionary * dict;
598    NSMenuItem * item;
599    while ((dict = [enumerator nextObject]))
600    {
601        NSString * name = [dict objectForKey: @"Name"];
602       
603        if (create)
604        {
605            item = [[NSMenuItem alloc] initWithTitle: name action: NULL keyEquivalent: @""];
606           
607            NSImage * icon;
608            if (![[dict objectForKey: @"IsFolder"] boolValue])
609            {
610                icon = [[dict objectForKey: @"Icon"] copy];
611                [icon setFlipped: NO];
612            }
613            else
614            {
615                NSMenu * itemMenu = [[NSMenu alloc] initWithTitle: name];
616                [itemMenu setAutoenablesItems: NO];
617                [item setSubmenu: itemMenu];
618                [itemMenu setDelegate: self];
619                [itemMenu release];
620               
621                icon = [[[NSWorkspace sharedWorkspace] iconForFileType: NSFileTypeForHFSTypeCode('fldr')] copy];
622            }
623           
624            [item setRepresentedObject: dict];
625           
626            [icon setScalesWhenResized: YES];
627            [icon setSize: NSMakeSize(16.0, 16.0)];
628            [item setImage: icon];
629            [icon release];
630           
631            [item setAction: @selector(checkFile:)];
632           
633            [menu addItem: item];
634            [item release];
635        }
636        else
637            item = [menu itemWithTitle: name];
638       
639        NSIndexSet * indexSet = [dict objectForKey: @"Indexes"];
640        [item setState: [fMenuTorrent checkForFiles: indexSet]];
641        [item setEnabled: [fMenuTorrent canChangeDownloadCheckForFiles: indexSet]];
642    }
643}
644
645@end
Note: See TracBrowser for help on using the repository browser.