source: trunk/macosx/FileOutlineController.m @ 5383

Last change on this file since 5383 was 5383, checked in by livings124, 14 years ago

update French localization

  • Property svn:keywords set to Date Rev Author Id
File size: 15.9 KB
Line 
1/******************************************************************************
2 * $Id: FileOutlineController.m 5383 2008-03-25 14:10:05Z livings124 $
3 *
4 * Copyright (c) 2008 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 "FileOutlineController.h"
26#import "Torrent.h"
27#import "FileOutlineView.h"
28#import "FilePriorityCell.h"
29#import "NSApplicationAdditions.h"
30
31#define ROW_SMALL_HEIGHT 18.0
32
33typedef enum
34{
35    FILE_CHECK_TAG,
36    FILE_UNCHECK_TAG
37} fileCheckMenuTag;
38
39typedef enum
40{
41    FILE_PRIORITY_HIGH_TAG,
42    FILE_PRIORITY_NORMAL_TAG,
43    FILE_PRIORITY_LOW_TAG
44} filePriorityMenuTag;
45
46@interface FileOutlineController (Private)
47
48- (NSMenu *) menu;
49
50@end
51
52@implementation FileOutlineController
53
54- (void) awakeFromNib
55{
56    [fOutline setDoubleAction: @selector(revealFile:)];
57    [fOutline setTarget: self];
58   
59    //set table header tool tips
60    if ([NSApp isOnLeopardOrBetter])
61    {
62        [[fOutline tableColumnWithIdentifier: @"Check"] setHeaderToolTip: NSLocalizedString(@"Download",
63                                                                            "file table -> header tool tip")];
64        [[fOutline tableColumnWithIdentifier: @"Priority"] setHeaderToolTip: NSLocalizedString(@"Priority",
65                                                                            "file table -> header tool tip")];                                                               
66    }
67   
68    [fOutline setMenu: [self menu]];
69   
70    [self setTorrent: nil];
71}
72
73- (void) setTorrent: (Torrent *) torrent
74{
75    fTorrent = torrent;
76    [fOutline setTorrent: fTorrent];
77   
78    [fOutline deselectAll: nil];
79    [fOutline reloadData];
80}
81
82- (void) reloadData
83{
84    [fTorrent updateFileStat];
85    [fOutline reloadData];
86}
87
88- (int) outlineView: (NSOutlineView *) outlineView numberOfChildrenOfItem: (id) item
89{
90    if (!item)
91        return fTorrent ? [[fTorrent fileList] count] : 0;
92    else
93        return [[item objectForKey: @"IsFolder"] boolValue] ? [[item objectForKey: @"Children"] count] : 0;
94}
95
96- (BOOL) outlineView: (NSOutlineView *) outlineView isItemExpandable: (id) item
97{
98    return [[item objectForKey: @"IsFolder"] boolValue];
99}
100
101- (id) outlineView: (NSOutlineView *) outlineView child: (int) index ofItem: (id) item
102{
103    return [(item ? [item objectForKey: @"Children"] : [fTorrent fileList]) objectAtIndex: index];
104}
105
106- (id) outlineView: (NSOutlineView *) outlineView objectValueForTableColumn: (NSTableColumn *) tableColumn byItem: (id) item
107{
108    if ([[tableColumn identifier] isEqualToString: @"Check"])
109        return [NSNumber numberWithInt: [fTorrent checkForFiles: [item objectForKey: @"Indexes"]]];
110    else
111        return item;
112}
113
114- (void) outlineView: (NSOutlineView *) outlineView willDisplayCell: (id) cell
115            forTableColumn: (NSTableColumn *) tableColumn item: (id) item
116{
117    NSString * identifier = [tableColumn identifier];
118    if ([identifier isEqualToString: @"Check"])
119        [cell setEnabled: [fTorrent canChangeDownloadCheckForFiles: [item objectForKey: @"Indexes"]]];
120    else if ([identifier isEqualToString: @"Priority"])
121    {
122        [cell setRepresentedObject: item];
123       
124        int hoveredRow = [fOutline hoveredRow];
125        [(FilePriorityCell *)cell setHovered: hoveredRow != -1 && hoveredRow == [fOutline rowForItem: item]];
126    }
127    else;
128}
129
130- (void) outlineView: (NSOutlineView *) outlineView setObjectValue: (id) object
131        forTableColumn: (NSTableColumn *) tableColumn byItem: (id) item
132{
133    NSString * identifier = [tableColumn identifier];
134    if ([identifier isEqualToString: @"Check"])
135    {
136        NSIndexSet * indexSet;
137        if ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)
138            indexSet = [NSIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])];
139        else
140            indexSet = [item objectForKey: @"Indexes"];
141       
142        [fTorrent setFileCheckState: [object intValue] != NSOffState ? NSOnState : NSOffState forIndexes: indexSet];
143        [fOutline reloadData];
144       
145        [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil];
146    }
147}
148
149- (NSString *) outlineView: (NSOutlineView *) outlineView typeSelectStringForTableColumn: (NSTableColumn *) tableColumn item: (id) item
150{
151    return [item objectForKey: @"Name"];
152}
153
154- (NSString *) outlineView: (NSOutlineView *) outlineView toolTipForCell: (NSCell *) cell rect: (NSRectPointer) rect
155        tableColumn: (NSTableColumn *) tableColumn item: (id) item mouseLocation: (NSPoint) mouseLocation
156{
157    NSString * ident = [tableColumn identifier];
158    if ([ident isEqualToString: @"Name"])
159        return [[fTorrent downloadFolder] stringByAppendingPathComponent: [item objectForKey: @"Path"]];
160    else if ([ident isEqualToString: @"Check"])
161    {
162        switch ([cell state])
163        {
164            case NSOffState:
165                return NSLocalizedString(@"Don't Download", "files tab -> tooltip");
166            case NSOnState:
167                return NSLocalizedString(@"Download", "files tab -> tooltip");
168            case NSMixedState:
169                return NSLocalizedString(@"Download Some", "files tab -> tooltip");
170        }
171    }
172    else if ([ident isEqualToString: @"Priority"])
173    {
174        NSSet * priorities = [fTorrent filePrioritiesForIndexes: [item objectForKey: @"Indexes"]];
175        switch ([priorities count])
176        {
177            case 0:
178                return NSLocalizedString(@"Priority Not Available", "files tab -> tooltip");
179            case 1:
180                switch ([[priorities anyObject] intValue])
181                {
182                    case TR_PRI_LOW:
183                        return NSLocalizedString(@"Low Priority", "files tab -> tooltip");
184                    case TR_PRI_HIGH:
185                        return NSLocalizedString(@"High Priority", "files tab -> tooltip");
186                    case TR_PRI_NORMAL:
187                        return NSLocalizedString(@"Normal Priority", "files tab -> tooltip");
188                }
189                break;
190            default:
191                return NSLocalizedString(@"Multiple Priorities", "files tab -> tooltip");
192        }
193    }
194    else;
195   
196    return nil;
197}
198
199- (float) outlineView: (NSOutlineView *) outlineView heightOfRowByItem: (id) item
200{
201    if ([[item objectForKey: @"IsFolder"] boolValue])
202        return ROW_SMALL_HEIGHT;
203    else
204        return [outlineView rowHeight];
205}
206
207- (void) setCheck: (id) sender
208{
209    int state = [sender tag] == FILE_UNCHECK_TAG ? NSOffState : NSOnState;
210   
211    NSIndexSet * indexSet = [fOutline selectedRowIndexes];
212    NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
213    int i;
214    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
215        [itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
216   
217    [fTorrent setFileCheckState: state forIndexes: itemIndexes];
218    [fOutline reloadData];
219}
220
221- (void) setOnlySelectedCheck: (id) sender
222{
223    NSIndexSet * indexSet = [fOutline selectedRowIndexes];
224    NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
225    int i;
226    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
227        [itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
228   
229    [fTorrent setFileCheckState: NSOnState forIndexes: itemIndexes];
230   
231    NSMutableIndexSet * remainingItemIndexes = [NSMutableIndexSet indexSetWithIndexesInRange: NSMakeRange(0, [fTorrent fileCount])];
232    [remainingItemIndexes removeIndexes: itemIndexes];
233    [fTorrent setFileCheckState: NSOffState forIndexes: remainingItemIndexes];
234   
235    [fOutline reloadData];
236}
237
238- (void) setPriority: (id) sender
239{
240    int priority;
241    switch ([sender tag])
242    {
243        case FILE_PRIORITY_HIGH_TAG:
244            priority = TR_PRI_HIGH;
245            break;
246        case FILE_PRIORITY_NORMAL_TAG:
247            priority = TR_PRI_NORMAL;
248            break;
249        case FILE_PRIORITY_LOW_TAG:
250            priority = TR_PRI_LOW;
251    }
252   
253    NSIndexSet * indexSet = [fOutline selectedRowIndexes];
254    NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
255    int i;
256    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
257        [itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
258   
259    [fTorrent setFilePriority: priority forIndexes: itemIndexes];
260    [fOutline reloadData];
261}
262
263- (void) revealFile: (id) sender
264{
265    NSString * folder = [fTorrent downloadFolder];
266    NSIndexSet * indexes = [fOutline selectedRowIndexes];
267    int i;
268    for (i = [indexes firstIndex]; i != NSNotFound; i = [indexes indexGreaterThanIndex: i])
269        [[NSWorkspace sharedWorkspace] selectFile: [folder stringByAppendingPathComponent:
270                [[fOutline itemAtRow: i] objectForKey: @"Path"]] inFileViewerRootedAtPath: nil];
271}
272
273#warning make real view controller (Leopard-only) so that Command-R will work
274- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
275{
276    if (!fTorrent)
277        return NO;
278   
279    SEL action = [menuItem action];
280   
281    if (action == @selector(revealFile:))
282    {
283        NSString * downloadFolder = [fTorrent downloadFolder];
284        NSIndexSet * indexSet = [fOutline selectedRowIndexes];
285        int i;
286        for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
287            if ([[NSFileManager defaultManager] fileExistsAtPath:
288                    [downloadFolder stringByAppendingPathComponent: [[[fTorrent fileList] objectAtIndex: i] objectForKey: @"Path"]]])
289                return YES;
290        return NO;
291    }
292   
293    if (action == @selector(setCheck:))
294    {
295        if ([fOutline numberOfSelectedRows] <= 0)
296            return NO;
297       
298        NSIndexSet * indexSet = [fOutline selectedRowIndexes];
299        NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
300        int i, state = ([menuItem tag] == FILE_CHECK_TAG) ? NSOnState : NSOffState;
301        for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
302            [itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
303       
304        return [fTorrent checkForFiles: itemIndexes] != state && [fTorrent canChangeDownloadCheckForFiles: itemIndexes];
305    }
306   
307    if (action == @selector(setOnlySelectedCheck:))
308    {
309        if ([fOutline numberOfSelectedRows] <= 0)
310            return NO;
311       
312        NSIndexSet * indexSet = [fOutline selectedRowIndexes];
313        NSMutableIndexSet * itemIndexes = [NSMutableIndexSet indexSet];
314        int i;
315        for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
316            [itemIndexes addIndexes: [[fOutline itemAtRow: i] objectForKey: @"Indexes"]];
317           
318        return [fTorrent canChangeDownloadCheckForFiles: itemIndexes];
319    }
320   
321    if (action == @selector(setPriority:))
322    {
323        if ([fOutline numberOfSelectedRows] <= 0)
324        {
325            [menuItem setState: NSOffState];
326            return NO;
327        }
328       
329        //determine which priorities are checked
330        NSIndexSet * indexSet = [fOutline selectedRowIndexes];
331        BOOL current = NO, other = NO;
332        int i, priority;
333       
334        switch ([menuItem tag])
335        {
336            case FILE_PRIORITY_HIGH_TAG:
337                priority = TR_PRI_HIGH;
338                break;
339            case FILE_PRIORITY_NORMAL_TAG:
340                priority = TR_PRI_NORMAL;
341                break;
342            case FILE_PRIORITY_LOW_TAG:
343                priority = TR_PRI_LOW;
344        }
345       
346        NSIndexSet * fileIndexSet;
347        for (i = [indexSet firstIndex]; i != NSNotFound && (!current || !other); i = [indexSet indexGreaterThanIndex: i])
348        {
349            fileIndexSet = [[fOutline itemAtRow: i] objectForKey: @"Indexes"];
350            if (![fTorrent canChangeDownloadCheckForFiles: fileIndexSet])
351                continue;
352            else if ([fTorrent hasFilePriority: priority forIndexes: fileIndexSet])
353                current = YES;
354            else
355                other = YES;
356        }
357       
358        [menuItem setState: current ? NSOnState : NSOffState];
359        return current || other;
360    }
361   
362    return YES;
363}
364
365@end
366
367@implementation FileOutlineController (Private)
368
369- (NSMenu *) menu
370{
371    NSMenu * menu = [[NSMenu alloc] initWithTitle: @"File Outline Menu"];
372   
373    //check and uncheck
374    NSMenuItem * item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Check Selected", "File Outline -> Menu")
375                            action: @selector(setCheck:) keyEquivalent: @""];
376    [item setTarget: self];
377    [item setTag: FILE_CHECK_TAG];
378    [menu addItem: item];
379    [item release];
380   
381    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Uncheck Selected", "File Outline -> Menu")
382            action: @selector(setCheck:) keyEquivalent: @""];
383    [item setTarget: self];
384    [item setTag: FILE_UNCHECK_TAG];
385    [menu addItem: item];
386    [item release];
387   
388    //only check selected
389    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Only Check Selected", "File Outline -> Menu")
390            action: @selector(setOnlySelectedCheck:) keyEquivalent: @""];
391    [item setTarget: self];
392    [menu addItem: item];
393    [item release];
394   
395    [menu addItem: [NSMenuItem separatorItem]];
396   
397    //priority
398    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Priority", "File Outline -> Menu") action: NULL keyEquivalent: @""];
399    NSMenu * priorityMenu = [[NSMenu alloc] initWithTitle: @"File Priority Menu"];
400    [item setSubmenu: priorityMenu];
401    [menu addItem: item];
402    [item release];
403   
404    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"High", "File Outline -> Priority Menu")
405            action: @selector(setPriority:) keyEquivalent: @""];
406    [item setTarget: self];
407    [item setTag: FILE_PRIORITY_HIGH_TAG];
408    [item setImage: [NSImage imageNamed: @"PriorityHigh.png"]];
409    [priorityMenu addItem: item];
410    [item release];
411   
412    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Normal", "File Outline -> Priority Menu")
413            action: @selector(setPriority:) keyEquivalent: @""];
414    [item setTarget: self];
415    [item setTag: FILE_PRIORITY_NORMAL_TAG];
416    [item setImage: [NSImage imageNamed: @"PriorityNormal.png"]];
417    [priorityMenu addItem: item];
418    [item release];
419   
420    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Low", "File Outline -> Priority Menu")
421            action: @selector(setPriority:) keyEquivalent: @""];
422    [item setTarget: self];
423    [item setTag: FILE_PRIORITY_LOW_TAG];
424    [item setImage: [NSImage imageNamed: @"PriorityLow.png"]];
425    [priorityMenu addItem: item];
426    [item release];
427   
428    [priorityMenu release];
429   
430    [menu addItem: [NSMenuItem separatorItem]];
431   
432    //reveal in finder
433    item = [[NSMenuItem alloc] initWithTitle: NSLocalizedString(@"Reveal in Finder", "File Outline -> Menu")
434            action: @selector(revealFile:) keyEquivalent: @""];
435    [item setTarget: self];
436    [menu addItem: item];
437    [item release];
438   
439    return [menu autorelease];
440}
441
442@end
Note: See TracBrowser for help on using the repository browser.