source: trunk/macosx/InfoOptionsViewController.m

Last change on this file was 14685, checked in by mikedld, 6 years ago

Use autolayout for torrent info window (OS X)

  • Property svn:keywords set to Date Rev Author Id
File size: 18.6 KB
Line 
1/******************************************************************************
2 * $Id: InfoOptionsViewController.m 14685 2016-02-27 20:29:57Z mikedld $
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 *****************************************************************************/
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            removeWhenFinishSeeding = [torrent removeWhenFinishSeeding] ? NSOnState : NSOffState;
161    CGFloat ratioLimit = [torrent ratioLimit];
162    NSUInteger idleLimit = [torrent idleLimitMinutes];
163   
164    while ((torrent = [enumerator nextObject])
165            && (checkRatio != INVALID || ratioLimit != INVALID || checkIdle != INVALID || idleLimit != INVALID))
166    {
167        if (checkRatio != INVALID && checkRatio != [torrent ratioSetting])
168            checkRatio = INVALID;
169       
170        if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
171            ratioLimit = INVALID;
172       
173        if (checkIdle != INVALID && checkIdle != [torrent idleSetting])
174            checkIdle = INVALID;
175       
176        if (idleLimit != INVALID && idleLimit != [torrent idleLimitMinutes])
177            idleLimit = INVALID;
178       
179        if (removeWhenFinishSeeding != NSMixedState && removeWhenFinishSeeding != ([torrent removeWhenFinishSeeding] ? NSOnState : NSOffState))
180            removeWhenFinishSeeding = NSMixedState;
181    }
182   
183    //set ratio view
184    NSInteger index;
185    if (checkRatio == TR_RATIOLIMIT_SINGLE)
186        index = OPTION_POPUP_LIMIT;
187    else if (checkRatio == TR_RATIOLIMIT_UNLIMITED)
188        index = OPTION_POPUP_NO_LIMIT;
189    else if (checkRatio == TR_RATIOLIMIT_GLOBAL)
190        index = OPTION_POPUP_GLOBAL;
191    else
192        index = -1;
193    [fRatioPopUp selectItemAtIndex: index];
194    [fRatioPopUp setEnabled: YES];
195   
196    [fRatioLimitField setHidden: checkRatio != TR_RATIOLIMIT_SINGLE];
197    if (ratioLimit != INVALID)
198        [fRatioLimitField setFloatValue: ratioLimit];
199    else
200        [fRatioLimitField setStringValue: @""];
201   
202    [fRatioLimitGlobalLabel setHidden: checkRatio != TR_RATIOLIMIT_GLOBAL];
203   
204    //set idle view
205    if (checkIdle == TR_IDLELIMIT_SINGLE)
206        index = OPTION_POPUP_LIMIT;
207    else if (checkIdle == TR_IDLELIMIT_UNLIMITED)
208        index = OPTION_POPUP_NO_LIMIT;
209    else if (checkIdle == TR_IDLELIMIT_GLOBAL)
210        index = OPTION_POPUP_GLOBAL;
211    else
212        index = -1;
213    [fIdlePopUp selectItemAtIndex: index];
214    [fIdlePopUp setEnabled: YES];
215   
216    [fIdleLimitField setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
217    if (idleLimit != INVALID)
218        [fIdleLimitField setIntegerValue: idleLimit];
219    else
220        [fIdleLimitField setStringValue: @""];
221    [fIdleLimitLabel setHidden: checkIdle != TR_IDLELIMIT_SINGLE];
222   
223    [fIdleLimitGlobalLabel setHidden: checkIdle != TR_IDLELIMIT_GLOBAL];
224   
225    //set remove transfer when seeding finishes
226    [fRemoveSeedingCompleteCheck setState: removeWhenFinishSeeding];
227    [fRemoveSeedingCompleteCheck setEnabled: YES];
228   
229    //get priority info
230    enumerator = [fTorrents objectEnumerator];
231    torrent = [enumerator nextObject]; //first torrent
232   
233    NSInteger priority = [torrent priority];
234   
235    while ((torrent = [enumerator nextObject]) && priority != INVALID)
236    {
237        if (priority != INVALID && priority != [torrent priority])
238            priority = INVALID;
239    }
240   
241    //set priority view
242    if (priority == TR_PRI_HIGH)
243        index = OPTION_POPUP_PRIORITY_HIGH;
244    else if (priority == TR_PRI_NORMAL)
245        index = OPTION_POPUP_PRIORITY_NORMAL;
246    else if (priority == TR_PRI_LOW)
247        index = OPTION_POPUP_PRIORITY_LOW;
248    else
249        index = -1;
250    [fPriorityPopUp selectItemAtIndex: index];
251    [fPriorityPopUp setEnabled: YES];
252   
253    //get peer info
254    enumerator = [fTorrents objectEnumerator];
255    torrent = [enumerator nextObject]; //first torrent
256   
257    NSInteger maxPeers = [torrent maxPeerConnect];
258   
259    while ((torrent = [enumerator nextObject]))
260    {
261        if (maxPeers != [torrent maxPeerConnect])
262        {
263            maxPeers = INVALID;
264            break;
265        }
266    }
267   
268    //set peer view
269    [fPeersConnectField setEnabled: YES];
270    [fPeersConnectLabel setEnabled: YES];
271    if (maxPeers != INVALID)
272        [fPeersConnectField setIntValue: maxPeers];
273    else
274        [fPeersConnectField setStringValue: @""];
275}
276
277- (void) setUseSpeedLimit: (id) sender
278{
279    const BOOL upload = sender == fUploadLimitCheck;
280   
281    if ([(NSButton *)sender state] == NSMixedState)
282        [sender setState: NSOnState];
283    const BOOL limit = [(NSButton *)sender state] == NSOnState;
284   
285    for (Torrent * torrent in fTorrents)
286        [torrent setUseSpeedLimit: limit upload: upload];
287   
288    NSTextField * field = upload ? fUploadLimitField : fDownloadLimitField;
289    [field setEnabled: limit];
290    if (limit)
291    {
292        [field selectText: self];
293        [[[self view] window] makeKeyAndOrderFront: self];
294    }
295   
296    NSTextField * label = upload ? fUploadLimitLabel : fDownloadLimitLabel;
297    [label setEnabled: limit];
298   
299    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
300}
301
302- (void) setUseGlobalSpeedLimit: (id) sender
303{
304    if ([(NSButton *)sender state] == NSMixedState)
305        [sender setState: NSOnState];
306    const BOOL limit = [(NSButton *)sender state] == NSOnState;
307   
308    for (Torrent * torrent in fTorrents)
309        [torrent setUseGlobalSpeedLimit: limit];
310   
311    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
312}
313
314- (void) setSpeedLimit: (id) sender
315{
316    const BOOL upload = sender == fUploadLimitField;
317    const NSInteger limit = [sender intValue];
318   
319    for (Torrent * torrent in fTorrents)
320        [torrent setSpeedLimit: limit upload: upload];
321   
322    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
323}
324
325- (void) setRatioSetting: (id) sender
326{
327    NSInteger setting;
328    BOOL single = NO;
329    switch ([sender indexOfSelectedItem])
330    {
331        case OPTION_POPUP_LIMIT:
332            setting = TR_RATIOLIMIT_SINGLE;
333            single = YES;
334            break;
335        case OPTION_POPUP_NO_LIMIT:
336            setting = TR_RATIOLIMIT_UNLIMITED;
337            break;
338        case OPTION_POPUP_GLOBAL:
339            setting = TR_RATIOLIMIT_GLOBAL;
340            break;
341        default:
342            NSAssert1(NO, @"Unknown option selected in ratio popup: %ld", [sender indexOfSelectedItem]);
343            return;
344    }
345   
346    for (Torrent * torrent in fTorrents)
347        [torrent setRatioSetting: setting];
348   
349    [fRatioLimitField setHidden: !single];
350    if (single)
351    {
352        [fRatioLimitField selectText: self];
353        [[[self view] window] makeKeyAndOrderFront: self];
354    }
355   
356    [fRatioLimitGlobalLabel setHidden: setting != TR_RATIOLIMIT_GLOBAL];
357   
358    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
359}
360
361- (void) setRatioLimit: (id) sender
362{
363    const CGFloat limit = [sender floatValue];
364   
365    for (Torrent * torrent in fTorrents)
366        [torrent setRatioLimit: limit];
367   
368    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
369}
370
371- (void) setIdleSetting: (id) sender
372{
373    NSInteger setting;
374    BOOL single = NO;
375    switch ([sender indexOfSelectedItem])
376    {
377        case OPTION_POPUP_LIMIT:
378            setting = TR_IDLELIMIT_SINGLE;
379            single = YES;
380            break;
381        case OPTION_POPUP_NO_LIMIT:
382            setting = TR_IDLELIMIT_UNLIMITED;
383            break;
384        case OPTION_POPUP_GLOBAL:
385            setting = TR_IDLELIMIT_GLOBAL;
386            break;
387        default:
388            NSAssert1(NO, @"Unknown option selected in idle popup: %ld", [sender indexOfSelectedItem]);
389            return;
390    }
391   
392    for (Torrent * torrent in fTorrents)
393        [torrent setIdleSetting: setting];
394   
395    [fIdleLimitField setHidden: !single];
396    [fIdleLimitLabel setHidden: !single];
397    if (single)
398    {
399        [fIdleLimitField selectText: self];
400        [[[self view] window] makeKeyAndOrderFront: self];
401    }
402   
403    [fIdleLimitGlobalLabel setHidden: setting != TR_IDLELIMIT_GLOBAL];
404   
405    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
406}
407
408- (void) setIdleLimit: (id) sender
409{
410    const NSUInteger limit = [sender integerValue];
411   
412    for (Torrent * torrent in fTorrents)
413        [torrent setIdleLimitMinutes: limit];
414   
415    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
416}
417
418- (IBAction) setRemoveWhenSeedingCompletes: (id) sender
419{
420    if ([(NSButton *)sender state] == NSMixedState)
421        [sender setState: NSOnState];
422    const BOOL enable = [(NSButton *)sender state] == NSOnState;
423   
424    for (Torrent * torrent in fTorrents)
425        [torrent setRemoveWhenFinishSeeding: enable];
426   
427    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
428}
429
430- (void) setPriority: (id) sender
431{
432    tr_priority_t priority;
433    switch ([sender indexOfSelectedItem])
434    {
435        case OPTION_POPUP_PRIORITY_HIGH:
436            priority = TR_PRI_HIGH;
437            break;
438        case OPTION_POPUP_PRIORITY_NORMAL:
439            priority = TR_PRI_NORMAL;
440            break;
441        case OPTION_POPUP_PRIORITY_LOW:
442            priority = TR_PRI_LOW;
443            break;
444        default:
445            NSAssert1(NO, @"Unknown option selected in priority popup: %ld", [sender indexOfSelectedItem]);
446            return;
447    }
448   
449    for (Torrent * torrent in fTorrents)
450        [torrent setPriority: priority];
451   
452    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil];
453   
454    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
455}
456
457- (void) setPeersConnectLimit: (id) sender
458{
459    NSInteger limit = [sender intValue];
460   
461    for (Torrent * torrent in fTorrents)
462        [torrent setMaxPeerConnect: limit];
463   
464    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateOptionsNotification" object: self];
465}
466
467- (BOOL) control: (NSControl *) control textShouldBeginEditing: (NSText *) fieldEditor
468{
469    [fInitialString release];
470    fInitialString = [[control stringValue] retain];
471   
472    return YES;
473}
474
475- (BOOL) control: (NSControl *) control didFailToFormatString: (NSString *) string errorDescription: (NSString *) error
476{
477    NSBeep();
478    if (fInitialString)
479    {
480        [control setStringValue: fInitialString];
481        [fInitialString release];
482        fInitialString = nil;
483    }
484    return NO;
485}
486
487@end
488
489@implementation InfoOptionsViewController (Private)
490
491- (void) setupInfo
492{
493    if ([fTorrents count] == 0)
494    {
495        [fUploadLimitCheck setEnabled: NO];
496        [fUploadLimitCheck setState: NSOffState];
497        [fUploadLimitField setEnabled: NO];
498        [fUploadLimitLabel setEnabled: NO];
499        [fUploadLimitField setStringValue: @""];
500       
501        [fDownloadLimitCheck setEnabled: NO];
502        [fDownloadLimitCheck setState: NSOffState];
503        [fDownloadLimitField setEnabled: NO];
504        [fDownloadLimitLabel setEnabled: NO];
505        [fDownloadLimitField setStringValue: @""];
506       
507        [fGlobalLimitCheck setEnabled: NO];
508        [fGlobalLimitCheck setState: NSOffState];
509       
510        [fPriorityPopUp setEnabled: NO];
511        [fPriorityPopUp selectItemAtIndex: -1];
512       
513        [fRatioPopUp setEnabled: NO];
514        [fRatioPopUp selectItemAtIndex: -1];
515        [fRatioLimitField setHidden: YES];
516        [fRatioLimitField setStringValue: @""];
517        [fRatioLimitGlobalLabel setHidden: YES];
518       
519        [fIdlePopUp setEnabled: NO];
520        [fIdlePopUp selectItemAtIndex: -1];
521        [fIdleLimitField setHidden: YES];
522        [fIdleLimitField setStringValue: @""];
523        [fIdleLimitLabel setHidden: YES];
524        [fIdleLimitGlobalLabel setHidden: YES];
525       
526        [fRemoveSeedingCompleteCheck setEnabled: NO];
527        [fRemoveSeedingCompleteCheck setState: NSOffState];
528       
529        [fPeersConnectField setEnabled: NO];
530        [fPeersConnectField setStringValue: @""];
531        [fPeersConnectLabel setEnabled: NO];
532    }
533    else
534        [self updateOptions];
535}
536
537- (void) setGlobalLabels
538{
539    NSString * global = [[NSUserDefaults standardUserDefaults] boolForKey: @"RatioCheck"]
540        ? [NSString stringForRatio: [[NSUserDefaults standardUserDefaults] floatForKey: @"RatioLimit"]]
541        : NSLocalizedString(@"disabled", "Info options -> global setting");
542    [fRatioLimitGlobalLabel setStringValue: global];
543   
544    //idle field
545    NSString * globalIdle;
546    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"IdleLimitCheck"])
547    {
548        const NSInteger globalMin = [[NSUserDefaults standardUserDefaults] integerForKey: @"IdleLimitMinutes"];
549        globalIdle = globalMin == 1 ? NSLocalizedString(@"1 minute", "Info options -> global setting")
550            : [NSString localizedStringWithFormat: NSLocalizedString(@"%d minutes", "Info options -> global setting"), globalMin];
551    }
552    else
553        globalIdle = NSLocalizedString(@"disabled", "Info options -> global setting");
554    [fIdleLimitGlobalLabel setStringValue: globalIdle];
555}
556
557- (void) updateOptionsNotification: (NSNotification *) notification
558{
559    if ([notification object] != self)
560        [self updateOptions];
561}
562
563@end
Note: See TracBrowser for help on using the repository browser.