transmission 2.51 update
[tomato.git] / release / src / router / transmission / macosx / InfoOptionsViewController.m
blobb4c9ecadd26a641735f1905aa79c17e96df7ec9a
1 /******************************************************************************
2  * $Id: InfoOptionsViewController.m 13251 2012-03-13 02:52:11Z livings124 $
3  *
4  * Copyright (c) 2010-2012 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  *****************************************************************************/
25 #import "InfoOptionsViewController.h"
26 #import "NSStringAdditions.h"
27 #import "Torrent.h"
29 #define OPTION_POPUP_GLOBAL 0
30 #define OPTION_POPUP_NO_LIMIT 1
31 #define OPTION_POPUP_LIMIT 2
33 #define OPTION_POPUP_PRIORITY_HIGH 0
34 #define OPTION_POPUP_PRIORITY_NORMAL 1
35 #define OPTION_POPUP_PRIORITY_LOW 2
37 #define INVALID -99
39 @interface InfoOptionsViewController (Private)
41 - (void) setupInfo;
42 - (void) setGlobalLabels;
43 - (void) updateOptionsNotification: (NSNotification *) notification;
45 @end
47 @implementation InfoOptionsViewController
49 - (id) init
51     if ((self = [super initWithNibName: @"InfoOptionsView" bundle: nil]))
52     {
53         [self setTitle: NSLocalizedString(@"Options", "Inspector view -> title")];
54     }
55     
56     return self;
59 - (void) awakeFromNib
61     [self setGlobalLabels];
62     
63     [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(setGlobalLabels) name: @"UpdateGlobalOptions" object: nil];
64     [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateOptionsNotification:) name: @"UpdateOptionsNotification" object: nil];
67 - (void) dealloc
69     [[NSNotificationCenter defaultCenter] removeObserver: self];
70     
71     [fTorrents release];
72     
73     [super dealloc];
76 - (void) setInfoForTorrents: (NSArray *) torrents
78     //don't check if it's the same in case the metadata changed
79     [fTorrents release];
80     fTorrents = [torrents retain];
81     
82     fSet = NO;
85 - (void) updateInfo
87     if (!fSet)
88         [self setupInfo];
89     
90     fSet = YES;
93 - (void) updateOptions
95     if ([fTorrents count] == 0)
96         return;
97     
98     //get bandwidth info
99     NSEnumerator * enumerator = [fTorrents objectEnumerator];
100     Torrent * torrent = [enumerator nextObject]; //first torrent
101     
102     NSInteger uploadUseSpeedLimit = [torrent usesSpeedLimit: YES] ? NSOnState : NSOffState,
103                 uploadSpeedLimit = [torrent speedLimit: YES],
104                 downloadUseSpeedLimit = [torrent usesSpeedLimit: NO] ? NSOnState : NSOffState,
105                 downloadSpeedLimit = [torrent speedLimit: NO],
106                 globalUseSpeedLimit = [torrent usesGlobalSpeedLimit] ? NSOnState : NSOffState;
107     
108     while ((torrent = [enumerator nextObject])
109             && (uploadUseSpeedLimit != NSMixedState || uploadSpeedLimit != INVALID
110                 || downloadUseSpeedLimit != NSMixedState || downloadSpeedLimit != INVALID
111                 || globalUseSpeedLimit != NSMixedState))
112     {
113         if (uploadUseSpeedLimit != NSMixedState && uploadUseSpeedLimit != ([torrent usesSpeedLimit: YES] ? NSOnState : NSOffState))
114             uploadUseSpeedLimit = NSMixedState;
115         
116         if (uploadSpeedLimit != INVALID && uploadSpeedLimit != [torrent speedLimit: YES])
117             uploadSpeedLimit = INVALID;
118         
119         if (downloadUseSpeedLimit != NSMixedState && downloadUseSpeedLimit != ([torrent usesSpeedLimit: NO] ? NSOnState : NSOffState))
120             downloadUseSpeedLimit = NSMixedState;
121         
122         if (downloadSpeedLimit != INVALID && downloadSpeedLimit != [torrent speedLimit: NO])
123             downloadSpeedLimit = INVALID;
124         
125         if (globalUseSpeedLimit != NSMixedState && globalUseSpeedLimit != ([torrent usesGlobalSpeedLimit] ? NSOnState : NSOffState))
126             globalUseSpeedLimit = NSMixedState;
127     }
128     
129     //set upload view
130     [fUploadLimitCheck setState: uploadUseSpeedLimit];
131     [fUploadLimitCheck setEnabled: YES];
132     
133     [fUploadLimitLabel setEnabled: uploadUseSpeedLimit == NSOnState];
134     [fUploadLimitField setEnabled: uploadUseSpeedLimit == NSOnState];
135     if (uploadSpeedLimit != INVALID)
136         [fUploadLimitField setIntValue: uploadSpeedLimit];
137     else
138         [fUploadLimitField setStringValue: @""];
139     
140     //set download view
141     [fDownloadLimitCheck setState: downloadUseSpeedLimit];
142     [fDownloadLimitCheck setEnabled: YES];
143     
144     [fDownloadLimitLabel setEnabled: downloadUseSpeedLimit == NSOnState];
145     [fDownloadLimitField setEnabled: downloadUseSpeedLimit == NSOnState];
146     if (downloadSpeedLimit != INVALID)
147         [fDownloadLimitField setIntValue: downloadSpeedLimit];
148     else
149         [fDownloadLimitField setStringValue: @""];
150     
151     //set global check
152     [fGlobalLimitCheck setState: globalUseSpeedLimit];
153     [fGlobalLimitCheck setEnabled: YES];
154     
155     //get ratio and idle info
156     enumerator = [fTorrents objectEnumerator];
157     torrent = [enumerator nextObject]; //first torrent
158     
159     NSInteger checkRatio = [torrent ratioSetting], checkIdle = [torrent idleSetting];
160     CGFloat ratioLimit = [torrent ratioLimit];
161     NSUInteger idleLimit = [torrent idleLimitMinutes];
162     
163     while ((torrent = [enumerator nextObject])
164             && (checkRatio != INVALID || ratioLimit != INVALID || checkIdle != INVALID || idleLimit != INVALID))
165     {
166         if (checkRatio != INVALID && checkRatio != [torrent ratioSetting])
167             checkRatio = INVALID;
168         
169         if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
170             ratioLimit = INVALID;
171         
172         if (checkIdle != INVALID && checkIdle != [torrent idleSetting])
173             checkIdle = INVALID;
174         
175         if (idleLimit != INVALID && idleLimit != [torrent idleLimitMinutes])
176             idleLimit = INVALID;
177     }
178     
179     //set ratio view
180     NSInteger index;
181     if (checkRatio == TR_RATIOLIMIT_SINGLE)
182         index = OPTION_POPUP_LIMIT;
183     else if (checkRatio == TR_RATIOLIMIT_UNLIMITED)
184         index = OPTION_POPUP_NO_LIMIT;
185     else if (checkRatio == TR_RATIOLIMIT_GLOBAL)
186         index = OPTION_POPUP_GLOBAL;
187     else
188         index = -1;
189     [fRatioPopUp selectItemAtIndex: index];
190     [fRatioPopUp setEnabled: YES];
191     
192     [fRatioLimitField setHidden: checkRatio != TR_RATIOLIMIT_SINGLE];
193     if (ratioLimit != INVALID)
194         [fRatioLimitField setFloatValue: ratioLimit];
195     else
196         [fRatioLimitField setStringValue: @""];
197     
198     [fRatioLimitGlobalLabel setHidden: checkRatio != TR_RATIOLIMIT_GLOBAL];
199     
200     //set idle view
201     if (checkIdle == TR_IDLELIMIT_SINGLE)
202         index = OPTION_POPUP_LIMIT;
203     else if (checkIdle == TR_IDLELIMIT_UNLIMITED)
204         index = OPTION_POPUP_NO_LIMIT;
205     else if (checkIdle == TR_IDLELIMIT_GLOBAL)
206         index = OPTION_POPUP_GLOBAL;
207     else
208         index = -1;
209     [fIdlePopUp selectItemAtIndex: index];
210     [fIdlePopUp setEnabled: YES];
211     
212     [fIdleLimitField setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
213     if (idleLimit != INVALID)
214         [fIdleLimitField setIntegerValue: idleLimit];
215     else
216         [fIdleLimitField setStringValue: @""];
217     [fIdleLimitLabel setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
218     
219     [fIdleLimitGlobalLabel setHidden: checkIdle != TR_IDLELIMIT_GLOBAL];
220     
221     //get priority info
222     enumerator = [fTorrents objectEnumerator];
223     torrent = [enumerator nextObject]; //first torrent
224     
225     NSInteger priority = [torrent priority];
226     
227     while ((torrent = [enumerator nextObject]) && priority != INVALID)
228     {
229         if (priority != INVALID && priority != [torrent priority])
230             priority = INVALID;
231     }
232     
233     //set priority view
234     if (priority == TR_PRI_HIGH)
235         index = OPTION_POPUP_PRIORITY_HIGH;
236     else if (priority == TR_PRI_NORMAL)
237         index = OPTION_POPUP_PRIORITY_NORMAL;
238     else if (priority == TR_PRI_LOW)
239         index = OPTION_POPUP_PRIORITY_LOW;
240     else
241         index = -1;
242     [fPriorityPopUp selectItemAtIndex: index];
243     [fPriorityPopUp setEnabled: YES];
244     
245     //get peer info
246     enumerator = [fTorrents objectEnumerator];
247     torrent = [enumerator nextObject]; //first torrent
248     
249     NSInteger maxPeers = [torrent maxPeerConnect];
250     
251     while ((torrent = [enumerator nextObject]))
252     {
253         if (maxPeers != [torrent maxPeerConnect])
254         {
255             maxPeers = INVALID;
256             break;
257         }
258     }
259     
260     //set peer view
261     [fPeersConnectField setEnabled: YES];
262     [fPeersConnectLabel setEnabled: YES];
263     if (maxPeers != INVALID)
264         [fPeersConnectField setIntValue: maxPeers];
265     else
266         [fPeersConnectField setStringValue: @""];
269 - (void) setUseSpeedLimit: (id) sender
271     const BOOL upload = sender == fUploadLimitCheck;
272     
273     if ([(NSButton *)sender state] == NSMixedState)
274         [sender setState: NSOnState];
275     const BOOL limit = [(NSButton *)sender state] == NSOnState;
276     
277     for (Torrent * torrent in fTorrents)
278         [torrent setUseSpeedLimit: limit upload: upload];
279     
280     NSTextField * field = upload ? fUploadLimitField : fDownloadLimitField;
281     [field setEnabled: limit];
282     if (limit)
283     {
284         [field selectText: self];
285         [[[self view] window] makeKeyAndOrderFront: self];
286     }
287     
288     NSTextField * label = upload ? fUploadLimitLabel : fDownloadLimitLabel;
289     [label setEnabled: limit];
290     
291     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
294 - (void) setUseGlobalSpeedLimit: (id) sender
296     if ([(NSButton *)sender state] == NSMixedState)
297         [sender setState: NSOnState];
298     const BOOL limit = [(NSButton *)sender state] == NSOnState;
299     
300     for (Torrent * torrent in fTorrents)
301         [torrent setUseGlobalSpeedLimit: limit];
302     
303     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
306 - (void) setSpeedLimit: (id) sender
308     const BOOL upload = sender == fUploadLimitField;
309     const NSInteger limit = [sender intValue];
310     
311     for (Torrent * torrent in fTorrents)
312         [torrent setSpeedLimit: limit upload: upload];
313     
314     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
317 - (void) setRatioSetting: (id) sender
319     NSInteger setting;
320     BOOL single = NO;
321     switch ([sender indexOfSelectedItem])
322     {
323         case OPTION_POPUP_LIMIT:
324             setting = TR_RATIOLIMIT_SINGLE;
325             single = YES;
326             break;
327         case OPTION_POPUP_NO_LIMIT:
328             setting = TR_RATIOLIMIT_UNLIMITED;
329             break;
330         case OPTION_POPUP_GLOBAL:
331             setting = TR_RATIOLIMIT_GLOBAL;
332             break;
333         default:
334             NSAssert1(NO, @"Unknown option selected in ratio popup: %d", [sender indexOfSelectedItem]);
335             return;
336     }
337     
338     for (Torrent * torrent in fTorrents)
339         [torrent setRatioSetting: setting];
340     
341     [fRatioLimitField setHidden: !single];
342     if (single)
343     {
344         [fRatioLimitField selectText: self];
345         [[[self view] window] makeKeyAndOrderFront: self];
346     }
347     
348     [fRatioLimitGlobalLabel setHidden: setting != TR_RATIOLIMIT_GLOBAL];
349     
350     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
353 - (void) setRatioLimit: (id) sender
355     const CGFloat limit = [sender floatValue];
356     
357     for (Torrent * torrent in fTorrents)
358         [torrent setRatioLimit: limit];
359     
360     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
363 - (void) setIdleSetting: (id) sender
365     NSInteger setting;
366     BOOL single = NO;
367     switch ([sender indexOfSelectedItem])
368     {
369         case OPTION_POPUP_LIMIT:
370             setting = TR_IDLELIMIT_SINGLE;
371             single = YES;
372             break;
373         case OPTION_POPUP_NO_LIMIT:
374             setting = TR_IDLELIMIT_UNLIMITED;
375             break;
376         case OPTION_POPUP_GLOBAL:
377             setting = TR_IDLELIMIT_GLOBAL;
378             break;
379         default:
380             NSAssert1(NO, @"Unknown option selected in idle popup: %d", [sender indexOfSelectedItem]);
381             return;
382     }
383     
384     for (Torrent * torrent in fTorrents)
385         [torrent setIdleSetting: setting];
386     
387     [fIdleLimitField setHidden: !single];
388     [fIdleLimitLabel setHidden: !single];
389     if (single)
390     {
391         [fIdleLimitField selectText: self];
392         [[[self view] window] makeKeyAndOrderFront: self];
393     }
394     
395     [fIdleLimitGlobalLabel setHidden: setting != TR_IDLELIMIT_GLOBAL];
396     
397     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
400 - (void) setIdleLimit: (id) sender
402     const NSUInteger limit = [sender integerValue];
403     
404     for (Torrent * torrent in fTorrents)
405         [torrent setIdleLimitMinutes: limit];
406     
407     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
410 - (void) setPriority: (id) sender
412     tr_priority_t priority;
413     switch ([sender indexOfSelectedItem])
414     {
415         case OPTION_POPUP_PRIORITY_HIGH:
416             priority = TR_PRI_HIGH;
417             break;
418         case OPTION_POPUP_PRIORITY_NORMAL:
419             priority = TR_PRI_NORMAL;
420             break;
421         case OPTION_POPUP_PRIORITY_LOW:
422             priority = TR_PRI_LOW;
423             break;
424         default:
425             NSAssert1(NO, @"Unknown option selected in priority popup: %d", [sender indexOfSelectedItem]);
426             return;
427     }
428     
429     for (Torrent * torrent in fTorrents)
430         [torrent setPriority: priority];
431     
432     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil];
433     
434     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
437 - (void) setPeersConnectLimit: (id) sender
439     NSInteger limit = [sender intValue];
440     
441     for (Torrent * torrent in fTorrents)
442         [torrent setMaxPeerConnect: limit];
443     
444     [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
447 - (BOOL) control: (NSControl *) control textShouldBeginEditing: (NSText *) fieldEditor
449     [fInitialString release];
450     fInitialString = [[control stringValue] retain];
451     
452     return YES;
455 - (BOOL) control: (NSControl *) control didFailToFormatString: (NSString *) string errorDescription: (NSString *) error
457     NSBeep();
458     if (fInitialString)
459     {
460         [control setStringValue: fInitialString];
461         [fInitialString release];
462         fInitialString = nil;
463     }
464     return NO;
467 @end
469 @implementation InfoOptionsViewController (Private)
471 - (void) setupInfo
473     if ([fTorrents count] == 0)
474     {
475         [fUploadLimitCheck setEnabled: NO];
476         [fUploadLimitCheck setState: NSOffState];
477         [fUploadLimitField setEnabled: NO];
478         [fUploadLimitLabel setEnabled: NO];
479         [fUploadLimitField setStringValue: @""];
480         
481         [fDownloadLimitCheck setEnabled: NO];
482         [fDownloadLimitCheck setState: NSOffState];
483         [fDownloadLimitField setEnabled: NO];
484         [fDownloadLimitLabel setEnabled: NO];
485         [fDownloadLimitField setStringValue: @""];
486         
487         [fGlobalLimitCheck setEnabled: NO];
488         [fGlobalLimitCheck setState: NSOffState];
489         
490         [fPriorityPopUp setEnabled: NO];
491         [fPriorityPopUp selectItemAtIndex: -1];
492         
493         [fRatioPopUp setEnabled: NO];
494         [fRatioPopUp selectItemAtIndex: -1];
495         [fRatioLimitField setHidden: YES];
496         [fRatioLimitField setStringValue: @""];
497         [fRatioLimitGlobalLabel setHidden: YES];
498         
499         [fIdlePopUp setEnabled: NO];
500         [fIdlePopUp selectItemAtIndex: -1];
501         [fIdleLimitField setHidden: YES];
502         [fIdleLimitField setStringValue: @""];
503         [fIdleLimitLabel setHidden: YES];
504         [fIdleLimitGlobalLabel setHidden: YES];
505         
506         [fPeersConnectField setEnabled: NO];
507         [fPeersConnectField setStringValue: @""];
508         [fPeersConnectLabel setEnabled: NO];
509     }
510     else
511         [self updateOptions];
514 - (void) setGlobalLabels
516     NSString * global = [[NSUserDefaults standardUserDefaults] boolForKey: @"RatioCheck"]
517         ? [NSString stringForRatio: [[NSUserDefaults standardUserDefaults] floatForKey: @"RatioLimit"]]
518         : NSLocalizedString(@"disabled", "Info options -> global setting");
519     [fRatioLimitGlobalLabel setStringValue: global];
520     
521     //idle field
522     NSString * globalIdle;
523     if ([[NSUserDefaults standardUserDefaults] boolForKey: @"IdleLimitCheck"])
524     {
525         const NSInteger globalMin = [[NSUserDefaults standardUserDefaults] integerForKey: @"IdleLimitMinutes"];
526         globalIdle = globalMin == 1 ? NSLocalizedString(@"1 minute", "Info options -> global setting")
527             : [NSString stringWithFormat: NSLocalizedString(@"%d minutes", "Info options -> global setting"), globalMin];
528     }
529     else
530         globalIdle = NSLocalizedString(@"disabled", "Info options -> global setting");
531     [fIdleLimitGlobalLabel setStringValue: globalIdle];
534 - (void) updateOptionsNotification: (NSNotification *) notification
536     if ([notification object] != self)
537         [self updateOptions];
540 @end