source: trunk/macosx/TorrentTableView.m @ 3664

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

get reordering of torrent queue working again in trunk (thanks to cocoadev mailing list)

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