source: trunk/macosx/InfoOptionsViewController.m @ 12489

Last change on this file since 12489 was 12489, checked in by livings124, 10 years ago

When a setting in the Options inspector tab changes, send a notification, preparing for future changes.

  • Property svn:keywords set to Date Rev Author Id
File size: 17.5 KB
Line 
1/******************************************************************************
2 * $Id: InfoOptionsViewController.m 12489 2011-06-04 13:48:56Z livings124 $
3 *
4 * Copyright (c) 2010-2011 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 "InfoOptionsViewController.h"
26#import "NSStringAdditions.h"
27#import "Torrent.h"
28
29#define OPTION_POPUP_GLOBAL 0
30#define OPTION_POPUP_NO_LIMIT 1
31#define OPTION_POPUP_LIMIT 2
32
33#define OPTION_POPUP_PRIORITY_HIGH 0
34#define OPTION_POPUP_PRIORITY_NORMAL 1
35#define OPTION_POPUP_PRIORITY_LOW 2
36
37#define INVALID -99
38
39@interface InfoOptionsViewController (Private)
40
41- (void) setupInfo;
42- (void) setGlobalLabels;
43- (void) updateOptionsNotification: (NSNotification *) notification;
44
45@end
46
47@implementation InfoOptionsViewController
48
49- (id) init
50{
51    if ((self = [super initWithNibName: @"InfoOptionsView" bundle: nil]))
52    {
53        [self setTitle: NSLocalizedString(@"Options", "Inspector view -> title")];
54    }
55   
56    return self;
57}
58
59- (void) awakeFromNib
60{
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];
65}
66
67- (void) dealloc
68{
69    [[NSNotificationCenter defaultCenter] removeObserver: self];
70   
71    [fTorrents release];
72   
73    [super dealloc];
74}
75
76- (void) setInfoForTorrents: (NSArray *) torrents
77{
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;
83}
84
85- (void) updateInfo
86{
87    if (!fSet)
88        [self setupInfo];
89   
90    fSet = YES;
91}
92
93- (void) updateOptions
94{
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: @""];
267}
268
269- (void) setUseSpeedLimit: (id) sender
270{
271    const BOOL upload = sender == fUploadLimitCheck;
272   
273    if ([sender state] == NSMixedState)
274        [sender setState: NSOnState];
275    const BOOL limit = [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];
292}
293
294- (void) setUseGlobalSpeedLimit: (id) sender
295{
296    if ([sender state] == NSMixedState)
297        [sender setState: NSOnState];
298    const BOOL limit = [sender state] == NSOnState;
299   
300    for (Torrent * torrent in fTorrents)
301        [torrent setUseGlobalSpeedLimit: limit];
302   
303    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
304}
305
306- (void) setSpeedLimit: (id) sender
307{
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];
315}
316
317- (void) setRatioSetting: (id) sender
318{
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];
351}
352
353- (void) setRatioLimit: (id) sender
354{
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];
361}
362
363- (void) setIdleSetting: (id) sender
364{
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];
398}
399
400- (void) setIdleLimit: (id) sender
401{
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];
408}
409
410- (void) setPriority: (id) sender
411{
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];
435}
436
437- (void) setPeersConnectLimit: (id) sender
438{
439    NSInteger limit = [sender intValue];
440   
441    for (Torrent * torrent in fTorrents)
442        [torrent setMaxPeerConnect: limit];
443   
444    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
445}
446
447- (BOOL) control: (NSControl *) control textShouldBeginEditing: (NSText *) fieldEditor
448{
449    [fInitialString release];
450    fInitialString = [[control stringValue] retain];
451   
452    return YES;
453}
454
455- (BOOL) control: (NSControl *) control didFailToFormatString: (NSString *) string errorDescription: (NSString *) error
456{
457    NSBeep();
458    if (fInitialString)
459    {
460        [control setStringValue: fInitialString];
461        [fInitialString release];
462        fInitialString = nil;
463    }
464    return NO;
465}
466
467@end
468
469@implementation InfoOptionsViewController (Private)
470
471- (void) setupInfo
472{
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];
512}
513
514- (void) setGlobalLabels
515{
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];
532}
533
534- (void) updateOptionsNotification: (NSNotification *) notification
535{
536    if ([notification object] != self)
537        [self updateOptions];
538}
539
540@end
Note: See TracBrowser for help on using the repository browser.