1 /******************************************************************************
2 * $Id: InfoOptionsViewController.m 13251 2012-03-13 02:52:11Z livings124 $
4 * Copyright (c) 2010-2012 Transmission authors and contributors
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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"
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
39 @interface InfoOptionsViewController (Private)
42 - (void) setGlobalLabels;
43 - (void) updateOptionsNotification: (NSNotification *) notification;
47 @implementation InfoOptionsViewController
51 if ((self = [super initWithNibName: @"InfoOptionsView" bundle: nil]))
53 [self setTitle: NSLocalizedString(@"Options", "Inspector view -> title")];
61 [self setGlobalLabels];
63 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(setGlobalLabels) name: @"UpdateGlobalOptions" object: nil];
64 [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateOptionsNotification:) name: @"UpdateOptionsNotification" object: nil];
69 [[NSNotificationCenter defaultCenter] removeObserver: self];
76 - (void) setInfoForTorrents: (NSArray *) torrents
78 //don't check if it's the same in case the metadata changed
80 fTorrents = [torrents retain];
93 - (void) updateOptions
95 if ([fTorrents count] == 0)
99 NSEnumerator * enumerator = [fTorrents objectEnumerator];
100 Torrent * torrent = [enumerator nextObject]; //first torrent
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;
108 while ((torrent = [enumerator nextObject])
109 && (uploadUseSpeedLimit != NSMixedState || uploadSpeedLimit != INVALID
110 || downloadUseSpeedLimit != NSMixedState || downloadSpeedLimit != INVALID
111 || globalUseSpeedLimit != NSMixedState))
113 if (uploadUseSpeedLimit != NSMixedState && uploadUseSpeedLimit != ([torrent usesSpeedLimit: YES] ? NSOnState : NSOffState))
114 uploadUseSpeedLimit = NSMixedState;
116 if (uploadSpeedLimit != INVALID && uploadSpeedLimit != [torrent speedLimit: YES])
117 uploadSpeedLimit = INVALID;
119 if (downloadUseSpeedLimit != NSMixedState && downloadUseSpeedLimit != ([torrent usesSpeedLimit: NO] ? NSOnState : NSOffState))
120 downloadUseSpeedLimit = NSMixedState;
122 if (downloadSpeedLimit != INVALID && downloadSpeedLimit != [torrent speedLimit: NO])
123 downloadSpeedLimit = INVALID;
125 if (globalUseSpeedLimit != NSMixedState && globalUseSpeedLimit != ([torrent usesGlobalSpeedLimit] ? NSOnState : NSOffState))
126 globalUseSpeedLimit = NSMixedState;
130 [fUploadLimitCheck setState: uploadUseSpeedLimit];
131 [fUploadLimitCheck setEnabled: YES];
133 [fUploadLimitLabel setEnabled: uploadUseSpeedLimit == NSOnState];
134 [fUploadLimitField setEnabled: uploadUseSpeedLimit == NSOnState];
135 if (uploadSpeedLimit != INVALID)
136 [fUploadLimitField setIntValue: uploadSpeedLimit];
138 [fUploadLimitField setStringValue: @""];
141 [fDownloadLimitCheck setState: downloadUseSpeedLimit];
142 [fDownloadLimitCheck setEnabled: YES];
144 [fDownloadLimitLabel setEnabled: downloadUseSpeedLimit == NSOnState];
145 [fDownloadLimitField setEnabled: downloadUseSpeedLimit == NSOnState];
146 if (downloadSpeedLimit != INVALID)
147 [fDownloadLimitField setIntValue: downloadSpeedLimit];
149 [fDownloadLimitField setStringValue: @""];
152 [fGlobalLimitCheck setState: globalUseSpeedLimit];
153 [fGlobalLimitCheck setEnabled: YES];
155 //get ratio and idle info
156 enumerator = [fTorrents objectEnumerator];
157 torrent = [enumerator nextObject]; //first torrent
159 NSInteger checkRatio = [torrent ratioSetting], checkIdle = [torrent idleSetting];
160 CGFloat ratioLimit = [torrent ratioLimit];
161 NSUInteger idleLimit = [torrent idleLimitMinutes];
163 while ((torrent = [enumerator nextObject])
164 && (checkRatio != INVALID || ratioLimit != INVALID || checkIdle != INVALID || idleLimit != INVALID))
166 if (checkRatio != INVALID && checkRatio != [torrent ratioSetting])
167 checkRatio = INVALID;
169 if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
170 ratioLimit = INVALID;
172 if (checkIdle != INVALID && checkIdle != [torrent idleSetting])
175 if (idleLimit != INVALID && idleLimit != [torrent idleLimitMinutes])
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;
189 [fRatioPopUp selectItemAtIndex: index];
190 [fRatioPopUp setEnabled: YES];
192 [fRatioLimitField setHidden: checkRatio != TR_RATIOLIMIT_SINGLE];
193 if (ratioLimit != INVALID)
194 [fRatioLimitField setFloatValue: ratioLimit];
196 [fRatioLimitField setStringValue: @""];
198 [fRatioLimitGlobalLabel setHidden: checkRatio != TR_RATIOLIMIT_GLOBAL];
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;
209 [fIdlePopUp selectItemAtIndex: index];
210 [fIdlePopUp setEnabled: YES];
212 [fIdleLimitField setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
213 if (idleLimit != INVALID)
214 [fIdleLimitField setIntegerValue: idleLimit];
216 [fIdleLimitField setStringValue: @""];
217 [fIdleLimitLabel setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
219 [fIdleLimitGlobalLabel setHidden: checkIdle != TR_IDLELIMIT_GLOBAL];
222 enumerator = [fTorrents objectEnumerator];
223 torrent = [enumerator nextObject]; //first torrent
225 NSInteger priority = [torrent priority];
227 while ((torrent = [enumerator nextObject]) && priority != INVALID)
229 if (priority != INVALID && priority != [torrent priority])
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;
242 [fPriorityPopUp selectItemAtIndex: index];
243 [fPriorityPopUp setEnabled: YES];
246 enumerator = [fTorrents objectEnumerator];
247 torrent = [enumerator nextObject]; //first torrent
249 NSInteger maxPeers = [torrent maxPeerConnect];
251 while ((torrent = [enumerator nextObject]))
253 if (maxPeers != [torrent maxPeerConnect])
261 [fPeersConnectField setEnabled: YES];
262 [fPeersConnectLabel setEnabled: YES];
263 if (maxPeers != INVALID)
264 [fPeersConnectField setIntValue: maxPeers];
266 [fPeersConnectField setStringValue: @""];
269 - (void) setUseSpeedLimit: (id) sender
271 const BOOL upload = sender == fUploadLimitCheck;
273 if ([(NSButton *)sender state] == NSMixedState)
274 [sender setState: NSOnState];
275 const BOOL limit = [(NSButton *)sender state] == NSOnState;
277 for (Torrent * torrent in fTorrents)
278 [torrent setUseSpeedLimit: limit upload: upload];
280 NSTextField * field = upload ? fUploadLimitField : fDownloadLimitField;
281 [field setEnabled: limit];
284 [field selectText: self];
285 [[[self view] window] makeKeyAndOrderFront: self];
288 NSTextField * label = upload ? fUploadLimitLabel : fDownloadLimitLabel;
289 [label setEnabled: limit];
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;
300 for (Torrent * torrent in fTorrents)
301 [torrent setUseGlobalSpeedLimit: limit];
303 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
306 - (void) setSpeedLimit: (id) sender
308 const BOOL upload = sender == fUploadLimitField;
309 const NSInteger limit = [sender intValue];
311 for (Torrent * torrent in fTorrents)
312 [torrent setSpeedLimit: limit upload: upload];
314 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
317 - (void) setRatioSetting: (id) sender
321 switch ([sender indexOfSelectedItem])
323 case OPTION_POPUP_LIMIT:
324 setting = TR_RATIOLIMIT_SINGLE;
327 case OPTION_POPUP_NO_LIMIT:
328 setting = TR_RATIOLIMIT_UNLIMITED;
330 case OPTION_POPUP_GLOBAL:
331 setting = TR_RATIOLIMIT_GLOBAL;
334 NSAssert1(NO, @"Unknown option selected in ratio popup: %d", [sender indexOfSelectedItem]);
338 for (Torrent * torrent in fTorrents)
339 [torrent setRatioSetting: setting];
341 [fRatioLimitField setHidden: !single];
344 [fRatioLimitField selectText: self];
345 [[[self view] window] makeKeyAndOrderFront: self];
348 [fRatioLimitGlobalLabel setHidden: setting != TR_RATIOLIMIT_GLOBAL];
350 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
353 - (void) setRatioLimit: (id) sender
355 const CGFloat limit = [sender floatValue];
357 for (Torrent * torrent in fTorrents)
358 [torrent setRatioLimit: limit];
360 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
363 - (void) setIdleSetting: (id) sender
367 switch ([sender indexOfSelectedItem])
369 case OPTION_POPUP_LIMIT:
370 setting = TR_IDLELIMIT_SINGLE;
373 case OPTION_POPUP_NO_LIMIT:
374 setting = TR_IDLELIMIT_UNLIMITED;
376 case OPTION_POPUP_GLOBAL:
377 setting = TR_IDLELIMIT_GLOBAL;
380 NSAssert1(NO, @"Unknown option selected in idle popup: %d", [sender indexOfSelectedItem]);
384 for (Torrent * torrent in fTorrents)
385 [torrent setIdleSetting: setting];
387 [fIdleLimitField setHidden: !single];
388 [fIdleLimitLabel setHidden: !single];
391 [fIdleLimitField selectText: self];
392 [[[self view] window] makeKeyAndOrderFront: self];
395 [fIdleLimitGlobalLabel setHidden: setting != TR_IDLELIMIT_GLOBAL];
397 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
400 - (void) setIdleLimit: (id) sender
402 const NSUInteger limit = [sender integerValue];
404 for (Torrent * torrent in fTorrents)
405 [torrent setIdleLimitMinutes: limit];
407 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
410 - (void) setPriority: (id) sender
412 tr_priority_t priority;
413 switch ([sender indexOfSelectedItem])
415 case OPTION_POPUP_PRIORITY_HIGH:
416 priority = TR_PRI_HIGH;
418 case OPTION_POPUP_PRIORITY_NORMAL:
419 priority = TR_PRI_NORMAL;
421 case OPTION_POPUP_PRIORITY_LOW:
422 priority = TR_PRI_LOW;
425 NSAssert1(NO, @"Unknown option selected in priority popup: %d", [sender indexOfSelectedItem]);
429 for (Torrent * torrent in fTorrents)
430 [torrent setPriority: priority];
432 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil];
434 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
437 - (void) setPeersConnectLimit: (id) sender
439 NSInteger limit = [sender intValue];
441 for (Torrent * torrent in fTorrents)
442 [torrent setMaxPeerConnect: limit];
444 [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
447 - (BOOL) control: (NSControl *) control textShouldBeginEditing: (NSText *) fieldEditor
449 [fInitialString release];
450 fInitialString = [[control stringValue] retain];
455 - (BOOL) control: (NSControl *) control didFailToFormatString: (NSString *) string errorDescription: (NSString *) error
460 [control setStringValue: fInitialString];
461 [fInitialString release];
462 fInitialString = nil;
469 @implementation InfoOptionsViewController (Private)
473 if ([fTorrents count] == 0)
475 [fUploadLimitCheck setEnabled: NO];
476 [fUploadLimitCheck setState: NSOffState];
477 [fUploadLimitField setEnabled: NO];
478 [fUploadLimitLabel setEnabled: NO];
479 [fUploadLimitField setStringValue: @""];
481 [fDownloadLimitCheck setEnabled: NO];
482 [fDownloadLimitCheck setState: NSOffState];
483 [fDownloadLimitField setEnabled: NO];
484 [fDownloadLimitLabel setEnabled: NO];
485 [fDownloadLimitField setStringValue: @""];
487 [fGlobalLimitCheck setEnabled: NO];
488 [fGlobalLimitCheck setState: NSOffState];
490 [fPriorityPopUp setEnabled: NO];
491 [fPriorityPopUp selectItemAtIndex: -1];
493 [fRatioPopUp setEnabled: NO];
494 [fRatioPopUp selectItemAtIndex: -1];
495 [fRatioLimitField setHidden: YES];
496 [fRatioLimitField setStringValue: @""];
497 [fRatioLimitGlobalLabel setHidden: YES];
499 [fIdlePopUp setEnabled: NO];
500 [fIdlePopUp selectItemAtIndex: -1];
501 [fIdleLimitField setHidden: YES];
502 [fIdleLimitField setStringValue: @""];
503 [fIdleLimitLabel setHidden: YES];
504 [fIdleLimitGlobalLabel setHidden: YES];
506 [fPeersConnectField setEnabled: NO];
507 [fPeersConnectField setStringValue: @""];
508 [fPeersConnectLabel setEnabled: NO];
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];
522 NSString * globalIdle;
523 if ([[NSUserDefaults standardUserDefaults] boolForKey: @"IdleLimitCheck"])
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];
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];