source: branches/nat-traversal/macosx/PrefsController.m @ 889

Last change on this file since 889 was 889, checked in by livings124, 15 years ago

Include image with the nat status. It still needs an image for success.

  • Property svn:keywords set to Date Rev Author Id
File size: 30.3 KB
Line 
1/******************************************************************************
2 * $Id: PrefsController.m 889 2006-09-22 14:55:48Z livings124 $
3 *
4 * Copyright (c) 2005-2006 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 "PrefsController.h"
26#import "StringAdditions.h"
27#import "UKKQueue.h"
28
29#define MIN_PORT    1
30#define MAX_PORT    65535
31
32#define DOWNLOAD_FOLDER     0
33#define DOWNLOAD_TORRENT    2
34#define DOWNLOAD_ASK        3
35
36#define UPDATE_DAILY    0
37#define UPDATE_WEEKLY   1
38#define UPDATE_NEVER    2
39
40#define TOOLBAR_GENERAL     @"General"
41#define TOOLBAR_TRANSFERS   @"Transfers"
42#define TOOLBAR_BANDWIDTH   @"Bandwidth"
43#define TOOLBAR_NETWORK     @"Network"
44
45@interface PrefsController (Private)
46
47- (void) showGeneralPref: (id) sender;
48- (void) showTransfersPref: (id) sender;
49- (void) showBandwidthPref: (id) sender;
50- (void) showNetworkPref: (id) sender;
51
52- (void) setPrefView: (NSView *) view;
53
54- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
55- (void) updatePopUp;
56
57- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
58- (void) updateImportPopUp;
59
60@end
61
62@implementation PrefsController
63
64- (id) initWithWindowNibName: (NSString *) name handle: (tr_handle_t *) handle
65{
66    if ((self = [self initWithWindowNibName: name]))
67    {
68        fDefaults = [NSUserDefaults standardUserDefaults];
69        fHandle = handle;
70       
71        [[self window] update]; //make sure nib is loaded right away
72    }
73    return self;
74}
75
76- (void) dealloc
77{
78    [fNatStatusTimer invalidate];
79
80    [fDownloadFolder release];
81    [fImportFolder release];
82    [super dealloc];
83}
84
85- (void) awakeFromNib
86{
87    fToolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
88    [fToolbar setDelegate: self];
89    [fToolbar setAllowsUserCustomization: NO];
90    [[self window] setToolbar: fToolbar];
91    [fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
92    [fToolbar setSizeMode: NSToolbarSizeModeRegular];
93
94    [fToolbar setSelectedItemIdentifier: TOOLBAR_GENERAL];
95    [self showGeneralPref: nil];
96   
97    //set download folder
98    NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
99    fDownloadFolder = [[[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath] retain];
100    if ([downloadChoice isEqualToString: @"Constant"])
101        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
102    else if ([downloadChoice isEqualToString: @"Torrent"])
103        [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
104    else
105        [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
106    [self updatePopUp];
107   
108    //set auto import
109    fImportFolder = [[[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath] retain];
110    [self updateImportPopUp];
111 
112    BOOL autoImport = [fDefaults boolForKey: @"AutoImport"];
113    [fAutoImportCheck setState: autoImport];
114    [fImportFolderPopUp setEnabled: autoImport];
115   
116    if (autoImport)
117        [[UKKQueue sharedFileWatcher] addPath: fImportFolder];
118   
119    //set auto size
120    [fAutoSizeCheck setState: [fDefaults boolForKey: @"AutoSize"]];
121   
122    //set bind port
123    int bindPort = [fDefaults integerForKey: @"BindPort"];
124    [fPortField setIntValue: bindPort];
125    tr_setBindPort(fHandle, bindPort);
126   
127    //set NAT
128    BOOL natShouldEnable = [fDefaults boolForKey: @"NatTraversal"];
129    if (natShouldEnable)
130        tr_natTraversalEnable(fHandle);
131    [fNatCheck setState: natShouldEnable];
132   
133    [fNatStatusField setHidden: !natShouldEnable];
134    [fNatStatusImage setHidden: !natShouldEnable];
135    [self updateNatStatus];
136    fNatStatusTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 target: self
137                        selector: @selector(updateNatStatus) userInfo: nil repeats: YES];
138   
139    //checks for old version upload speed of -1
140    if ([fDefaults integerForKey: @"UploadLimit"] < 0)
141    {
142        [fDefaults setInteger: 20 forKey: @"UploadLimit"];
143        [fDefaults setBool: NO forKey: @"CheckUpload"];
144    }
145   
146    //set upload limit
147    BOOL checkUpload = [fDefaults boolForKey: @"CheckUpload"];
148    int uploadLimit = [fDefaults integerForKey: @"UploadLimit"];
149   
150    [fUploadCheck setState: checkUpload];
151    [fUploadField setIntValue: uploadLimit];
152    [fUploadField setEnabled: checkUpload];
153
154        //set download limit
155    BOOL checkDownload = [fDefaults boolForKey: @"CheckDownload"];
156    int downloadLimit = [fDefaults integerForKey: @"DownloadLimit"];
157   
158    [fDownloadCheck setState: checkDownload];
159    [fDownloadField setIntValue: downloadLimit];
160    [fDownloadField setEnabled: checkDownload];
161   
162    //set speed limit
163    int speedLimitUploadLimit = [fDefaults integerForKey: @"SpeedLimitUploadLimit"];
164    [fSpeedLimitUploadField setIntValue: speedLimitUploadLimit];
165   
166    int speedLimitDownloadLimit = [fDefaults integerForKey: @"SpeedLimitDownloadLimit"];
167    [fSpeedLimitDownloadField setIntValue: speedLimitDownloadLimit];
168   
169    //actually set bandwidth limits
170    if ([fDefaults boolForKey: @"SpeedLimit"])
171    {
172        tr_setUploadLimit(fHandle, speedLimitUploadLimit);
173        tr_setDownloadLimit(fHandle, speedLimitDownloadLimit);
174    }
175    else
176    {
177        tr_setUploadLimit(fHandle, checkUpload ? uploadLimit : -1);
178        tr_setDownloadLimit(fHandle, checkDownload ? downloadLimit : -1);
179    }
180   
181    //set auto speed limit
182    BOOL speedLimitAuto = [fDefaults boolForKey: @"SpeedLimitAuto"];
183    [fSpeedLimitAutoCheck setState: speedLimitAuto];
184   
185    int speedLimitAutoOnHour = [fDefaults integerForKey: @"SpeedLimitAutoOnHour"];
186    [fSpeedLimitAutoOnField setStringValue: [NSString stringWithFormat: @"%02d", speedLimitAutoOnHour]];
187    [fSpeedLimitAutoOnField setEnabled: speedLimitAuto];
188   
189    int speedLimitAutoOffHour = [fDefaults integerForKey: @"SpeedLimitAutoOffHour"];
190    [fSpeedLimitAutoOffField setStringValue: [NSString stringWithFormat: @"%02d", speedLimitAutoOffHour]];
191    [fSpeedLimitAutoOffField setEnabled: speedLimitAuto];
192   
193    //set ratio limit
194    BOOL ratioCheck = [fDefaults boolForKey: @"RatioCheck"];
195    [fRatioCheck setState: ratioCheck];
196    [fRatioField setEnabled: ratioCheck];
197    [fRatioField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]];
198   
199    //set remove and quit prompts
200    BOOL isQuitCheck = [fDefaults boolForKey: @"CheckQuit"],
201        isRemoveCheck = [fDefaults boolForKey: @"CheckRemove"];
202   
203    [fQuitCheck setState: isQuitCheck];
204    [fRemoveCheck setState: isRemoveCheck];
205   
206    [fQuitDownloadingCheck setState: [fDefaults boolForKey: @"CheckQuitDownloading"]];
207    [fQuitDownloadingCheck setEnabled: isQuitCheck];
208    [fRemoveDownloadingCheck setState: [fDefaults boolForKey: @"CheckRemoveDownloading"]];
209    [fRemoveDownloadingCheck setEnabled: isRemoveCheck];
210
211    //set dock badging
212    [fBadgeDownloadRateCheck setState: [fDefaults boolForKey: @"BadgeDownloadRate"]];
213    [fBadgeUploadRateCheck setState: [fDefaults boolForKey: @"BadgeUploadRate"]];
214   
215    //set play sound
216    NSMutableArray * sounds = [NSMutableArray array];
217    NSEnumerator * soundEnumerator,
218                * soundDirectoriesEnumerator = [[NSArray arrayWithObjects: @"System/Library/Sounds",
219                        [NSHomeDirectory() stringByAppendingPathComponent: @"Library/Sounds"], nil] objectEnumerator];
220    NSString * soundPath, * sound;
221   
222    //get list of all sounds and sort alphabetically
223    while ((soundPath = [soundDirectoriesEnumerator nextObject]))
224        if (soundEnumerator = [[NSFileManager defaultManager] enumeratorAtPath: soundPath])
225            while ((sound = [soundEnumerator nextObject]))
226            {
227                sound = [sound stringByDeletingPathExtension];
228                if ([NSSound soundNamed: sound])
229                    [sounds addObject: sound];
230            }
231   
232    [sounds sortUsingSelector: @selector(caseInsensitiveCompare:)];
233   
234    //set download sound
235    [fDownloadSoundPopUp removeAllItems];
236    [fDownloadSoundPopUp addItemsWithTitles: sounds];
237   
238    BOOL playDownloadSound = [fDefaults boolForKey: @"PlayDownloadSound"];
239    [fPlayDownloadSoundCheck setState: playDownloadSound];
240    [fDownloadSoundPopUp setEnabled: playDownloadSound];
241   
242    int downloadSoundIndex = [fDownloadSoundPopUp indexOfItemWithTitle: [fDefaults stringForKey: @"DownloadSound"]];
243    if (downloadSoundIndex >= 0)
244        [fDownloadSoundPopUp selectItemAtIndex: downloadSoundIndex];
245    else
246        [fDefaults setObject: [fDownloadSoundPopUp titleOfSelectedItem] forKey: @"DownloadSound"];
247   
248    //set seeding sound
249    [fSeedingSoundPopUp removeAllItems];
250    [fSeedingSoundPopUp addItemsWithTitles: sounds];
251   
252    BOOL playSeedingSound = [fDefaults boolForKey: @"PlaySeedingSound"];
253    [fPlaySeedingSoundCheck setState: playSeedingSound];
254    [fSeedingSoundPopUp setEnabled: playSeedingSound];
255   
256    int seedingSoundIndex = [fDownloadSoundPopUp indexOfItemWithTitle: [fDefaults stringForKey: @"SeedingSound"]];
257    if (seedingSoundIndex >= 0)
258        [fSeedingSoundPopUp selectItemAtIndex: seedingSoundIndex];
259    else
260        [fDefaults setObject: [fSeedingSoundPopUp titleOfSelectedItem] forKey: @"SeedingSound"];
261   
262    //set start settings
263    BOOL useQueue = [fDefaults boolForKey: @"Queue"];
264    [fQueueCheck setState: useQueue];
265    [fQueueNumberField setEnabled: useQueue];
266    [fQueueNumberField setIntValue: [fDefaults integerForKey: @"WaitToStartNumber"]];
267   
268    [fStartAtOpenCheck setState: [fDefaults boolForKey: @"StartAtOpen"]];
269   
270    //set private torrents
271    BOOL copyTorrents = [fDefaults boolForKey: @"SavePrivateTorrent"];
272    [fCopyTorrentCheck setState: copyTorrents];
273   
274    [fDeleteOriginalTorrentCheck setEnabled: copyTorrents];
275    [fDeleteOriginalTorrentCheck setState: [fDefaults boolForKey: @"DeleteOriginalTorrent"]];
276
277    //set update check
278    NSString * updateCheck = [fDefaults stringForKey: @"UpdateCheck"];
279    if ([updateCheck isEqualToString: @"Weekly"])
280        [fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
281    else if ([updateCheck isEqualToString: @"Never"])
282        [fUpdatePopUp selectItemAtIndex: UPDATE_NEVER];
283    else
284        [fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
285}
286
287- (NSToolbarItem *) toolbar: (NSToolbar *) t itemForItemIdentifier:
288    (NSString *) ident willBeInsertedIntoToolbar: (BOOL) flag
289{
290    NSToolbarItem * item;
291    item = [[NSToolbarItem alloc] initWithItemIdentifier: ident];
292
293    if ([ident isEqualToString: TOOLBAR_GENERAL])
294    {
295        [item setLabel: TOOLBAR_GENERAL];
296        [item setImage: [NSImage imageNamed: @"Preferences.png"]];
297        [item setTarget: self];
298        [item setAction: @selector(showGeneralPref:)];
299    }
300    else if ([ident isEqualToString: TOOLBAR_TRANSFERS])
301    {
302        [item setLabel: TOOLBAR_TRANSFERS];
303        [item setImage: [NSImage imageNamed: @"Transfers.png"]];
304        [item setTarget: self];
305        [item setAction: @selector(showTransfersPref:)];
306    }
307    else if ([ident isEqualToString: TOOLBAR_BANDWIDTH])
308    {
309        [item setLabel: TOOLBAR_BANDWIDTH];
310        [item setImage: [NSImage imageNamed: @"Bandwidth.png"]];
311        [item setTarget: self];
312        [item setAction: @selector(showBandwidthPref:)];
313    }
314    else if ([ident isEqualToString: TOOLBAR_NETWORK])
315    {
316        [item setLabel: TOOLBAR_NETWORK];
317        [item setImage: [NSImage imageNamed: @"Network.png"]];
318        [item setTarget: self];
319        [item setAction: @selector(showNetworkPref:)];
320    }
321    else
322    {
323        [item release];
324        return nil;
325    }
326
327    return item;
328}
329
330- (NSArray *) toolbarSelectableItemIdentifiers: (NSToolbar *) toolbar
331{
332    return [self toolbarDefaultItemIdentifiers: toolbar];
333}
334
335- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
336{
337    return [self toolbarAllowedItemIdentifiers: toolbar];
338}
339
340- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
341{
342    return [NSArray arrayWithObjects:
343            TOOLBAR_GENERAL, TOOLBAR_TRANSFERS,
344            TOOLBAR_BANDWIDTH, TOOLBAR_NETWORK, nil];
345}
346
347- (void) setPort: (id) sender
348{
349    int bindPort = [sender intValue];
350    if (![[NSString stringWithInt: bindPort] isEqualToString: [sender stringValue]]
351            || bindPort < MIN_PORT || bindPort > MAX_PORT)
352    {
353        NSBeep();
354        bindPort = [fDefaults integerForKey: @"BindPort"];
355        [sender setIntValue: bindPort];
356    }
357    else
358    {
359        tr_setBindPort(fHandle, bindPort);
360        [fDefaults setInteger: bindPort forKey: @"BindPort"];
361       
362        [self updateNatStatus];
363    }
364}
365
366- (void) setNat: (id) sender
367{
368    BOOL enable = [sender state] == NSOnState;
369    enable ? tr_natTraversalEnable(fHandle) : tr_natTraversalDisable(fHandle);
370    [fDefaults setBool: enable forKey: @"NatTraversal"];
371   
372    [fNatStatusField setHidden: !enable];
373    [fNatStatusImage setHidden: !enable];
374    [self updateNatStatus];
375}
376
377- (void) updateNatStatus
378{
379    if ([fNatStatusField isHidden])
380        return;
381   
382    int status = tr_natTraversalStatus(fHandle);
383    if (status == 2)
384    {
385        [fNatStatusField setStringValue: @"Ports have been successfully mapped"];
386        [fNatStatusImage setImage: nil];
387    }
388    else if (status == 3 || status == 4)
389    {
390        [fNatStatusField setStringValue: @"Error mapping ports"];
391        [fNatStatusImage setImage: [NSImage imageNamed: @"Error.tiff"]];
392    }
393    else
394    {
395        [fNatStatusField setStringValue: @""];
396        [fNatStatusImage setImage: nil];
397    }
398}
399
400- (void) setLimit: (id) sender
401{
402    NSString * key;
403    NSButton * check;
404    NSString * type;
405    if (sender == fUploadField)
406    {
407        key = @"UploadLimit";
408        check = fUploadCheck;
409        type = @"Upload";
410    }
411    else
412    {
413        key = @"DownloadLimit";
414        check = fDownloadCheck;
415        type = @"Download";
416    }
417
418    int limit = [sender intValue];
419    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]] || limit < 0)
420    {
421        NSBeep();
422        limit = [fDefaults integerForKey: key];
423        [sender setIntValue: limit];
424    }
425    else
426    {
427        if (![fDefaults boolForKey: @"SpeedLimit"])
428        {
429            int realLimit = [check state] ? limit : -1;
430            if (sender == fUploadField)
431                tr_setUploadLimit(fHandle, realLimit);
432            else
433                tr_setDownloadLimit(fHandle, realLimit);
434        }
435       
436        [fDefaults setInteger: limit forKey: key];
437    }
438   
439    NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
440                                    [NSNumber numberWithBool: [check state]], @"Enable",
441                                    [NSNumber numberWithInt: limit], @"Limit",
442                                    type, @"Type", nil];
443    [[NSNotificationCenter defaultCenter] postNotificationName: @"LimitGlobalChange" object: dict];
444}
445
446- (void) setLimitCheck: (id) sender
447{
448    NSString * key;
449    NSTextField * field;
450    if (sender == fUploadCheck)
451    {
452        key = @"CheckUpload";
453        field = fUploadField;
454    }
455    else
456    {
457        key = @"CheckDownload";
458        field = fDownloadField;
459    }
460   
461    BOOL check = [sender state] == NSOnState;
462    [self setLimit: field];
463    [field setEnabled: check];
464   
465    [fDefaults setBool: check forKey: key];
466}
467
468- (void) setLimitEnabled: (BOOL) enable type: (NSString *) type
469{
470    NSButton * check = [type isEqualToString: @"Upload"] ? fUploadCheck : fDownloadCheck;
471    [check setState: enable ? NSOnState : NSOffState];
472    [self setLimitCheck: check];
473}
474
475- (void) setQuickLimit: (int) limit type: (NSString *) type
476{
477    NSButton * check;
478    if ([type isEqualToString: @"Upload"])
479    {
480        [fUploadField setIntValue: limit];
481        check = fUploadCheck;
482    }
483    else
484    {
485        [fDownloadField setIntValue: limit];
486        check = fDownloadCheck;
487    }
488    [check setState: NSOnState];
489    [self setLimitCheck: check];
490}
491
492- (void) enableSpeedLimit: (BOOL) enable
493{
494    if ([fDefaults boolForKey: @"SpeedLimit"] != enable)
495    {
496        [fDefaults setBool: enable forKey: @"SpeedLimit"];
497       
498        if (enable)
499        {
500            tr_setUploadLimit(fHandle, [fDefaults integerForKey: @"SpeedLimitUploadLimit"]);
501            tr_setDownloadLimit(fHandle, [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]);
502        }
503        else
504        {
505            tr_setUploadLimit(fHandle, [fUploadCheck state] ? [fDefaults integerForKey: @"UploadLimit"] : -1);
506            tr_setDownloadLimit(fHandle, [fDownloadCheck state] ? [fDefaults integerForKey: @"DownloadLimit"] : -1);
507        }
508    }
509}
510
511- (void) setSpeedLimit: (id) sender
512{
513    NSString * key = sender == fSpeedLimitUploadField ? @"SpeedLimitUploadLimit" : @"SpeedLimitDownloadLimit";
514
515    int limit = [sender intValue];
516    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]] || limit < 0)
517    {
518        NSBeep();
519        limit = [fDefaults integerForKey: key];
520        [sender setIntValue: limit];
521    }
522    else
523    {
524        if ([fDefaults boolForKey: @"SpeedLimit"])
525        {
526            if (sender == fSpeedLimitUploadField)
527                tr_setUploadLimit(fHandle, limit);
528            else
529                tr_setDownloadLimit(fHandle, limit);
530        }
531       
532        [fDefaults setInteger: limit forKey: key];
533    }
534}
535
536- (void) setAutoSpeedLimitCheck: (id) sender
537{
538    BOOL check = [sender state] == NSOnState;
539   
540    [fDefaults setBool: check forKey: @"SpeedLimitAuto"];
541
542    [self setAutoSpeedLimitHour: fSpeedLimitAutoOnField];
543    [fSpeedLimitAutoOnField setEnabled: check];
544   
545    [self setAutoSpeedLimitHour: fSpeedLimitAutoOffField];
546    [fSpeedLimitAutoOffField setEnabled: check];
547}
548
549- (void) setAutoSpeedLimitHour: (id) sender
550{
551    NSString * key = (sender == fSpeedLimitAutoOnField) ? @"SpeedLimitAutoOnHour" : @"SpeedLimitAutoOffHour";
552
553    int hour = [sender intValue];
554   
555    //allow numbers under ten in the format 0x
556    if (!([[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", hour]]
557        || [[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%02d", hour]]) || hour < 0 || hour > 23
558        || [fSpeedLimitAutoOnField intValue] == [fSpeedLimitAutoOffField intValue])
559    {
560        NSBeep();
561        hour = [fDefaults integerForKey: key];
562        [sender setStringValue: [NSString stringWithFormat: @"%02d", hour]];
563    }
564    else
565        [fDefaults setInteger: hour forKey: key];
566   
567    [sender setStringValue: [NSString stringWithFormat: @"%02d", hour]]; //ensure number has 2 digits
568   
569    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSpeedLimitChange" object: self];
570}
571
572- (void) setRatio: (id) sender
573{
574    float ratioLimit = [sender floatValue];
575    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%.2f", ratioLimit]]
576            || ratioLimit < 0)
577    {
578        NSBeep();
579        ratioLimit = [fDefaults floatForKey: @"RatioLimit"];
580        [sender setFloatValue: ratioLimit];
581    }
582    else
583        [fDefaults setFloat: ratioLimit forKey: @"RatioLimit"];
584   
585    NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
586                                [NSNumber numberWithBool: [fRatioCheck state]], @"Enable",
587                                [NSNumber numberWithFloat: ratioLimit], @"Ratio", nil];
588    [[NSNotificationCenter defaultCenter] postNotificationName: @"RatioGlobalChange" object: dict];
589}
590
591- (void) setRatioCheck: (id) sender
592{
593    BOOL check = [sender state] == NSOnState;
594    [self setRatio: fRatioField];
595    [fRatioField setEnabled: check];
596   
597    [fDefaults setBool: check forKey: @"RatioCheck"];
598}
599
600- (void) setRatioEnabled: (BOOL) enable
601{
602    int state = enable ? NSOnState : NSOffState;
603   
604    [fRatioCheck setState: state];
605    [self setRatioCheck: fRatioCheck];
606}
607
608- (void) setQuickRatio: (float) ratioLimit
609{
610    [fRatioField setFloatValue: ratioLimit];
611   
612    [fRatioCheck setState: NSOnState];
613    [self setRatioCheck: fRatioCheck];
614}
615
616- (void) setShowMessage: (id) sender
617{
618    BOOL state = [sender state];
619
620    if (sender == fQuitCheck)
621    {
622        [fDefaults setBool: state forKey: @"CheckQuit"];
623        [fQuitDownloadingCheck setEnabled: state];
624    }
625    else if (sender == fRemoveCheck)
626    {
627        [fDefaults setBool: state forKey: @"CheckRemove"];
628        [fRemoveDownloadingCheck setEnabled: state];
629    }
630    if (sender == fQuitDownloadingCheck)
631        [fDefaults setBool: state forKey: @"CheckQuitDownloading"];
632    else if (sender == fRemoveDownloadingCheck)
633        [fDefaults setBool: state forKey: @"CheckRemoveDownloading"];
634    else;
635}
636
637- (void) setBadge: (id) sender
638{   
639    if (sender == fBadgeDownloadRateCheck)
640        [fDefaults setBool: [sender state] forKey: @"BadgeDownloadRate"];
641    else if (sender == fBadgeUploadRateCheck)
642        [fDefaults setBool: [sender state] forKey: @"BadgeUploadRate"];
643    else;
644   
645    [[NSNotificationCenter defaultCenter] postNotificationName: @"DockBadgeChange" object: self];
646}
647
648- (void) setPlaySound: (id) sender
649{
650    BOOL state = [sender state];
651
652    if (sender == fPlayDownloadSoundCheck)
653    {
654        [fDownloadSoundPopUp setEnabled: state];
655        [fDefaults setBool: state forKey: @"PlayDownloadSound"];
656    }
657    else if (sender == fPlaySeedingSoundCheck)
658    {
659        [fSeedingSoundPopUp setEnabled: state];
660        [fDefaults setBool: state forKey: @"PlaySeedingSound"];
661    }
662    else;
663}
664
665- (void) setSound: (id) sender
666{
667    //play sound when selecting
668    NSString * soundName = [sender titleOfSelectedItem];
669    NSSound * sound;
670    if ((sound = [NSSound soundNamed: soundName]))
671        [sound play];
672
673    if (sender == fDownloadSoundPopUp)
674        [fDefaults setObject: soundName forKey: @"DownloadSound"];
675    else if (sender == fSeedingSoundPopUp)
676        [fDefaults setObject: soundName forKey: @"SeedingSound"];
677    else;
678}
679
680- (void) setUpdate: (id) sender
681{
682    int index = [fUpdatePopUp indexOfSelectedItem];
683    NSTimeInterval seconds;
684    if (index == UPDATE_DAILY)
685    {
686        [fDefaults setObject: @"Daily" forKey: @"UpdateCheck"];
687        seconds = 86400;
688    }
689    else if (index == UPDATE_WEEKLY)
690    {
691        [fDefaults setObject: @"Weekly" forKey: @"UpdateCheck"];
692        seconds = 604800;
693    }
694    else
695    {
696        [fDefaults setObject: @"Never" forKey: @"UpdateCheck"];
697        seconds = 0;
698    }
699
700    [fDefaults setInteger: seconds forKey: @"SUScheduledCheckInterval"];
701    [fUpdater scheduleCheckWithInterval: seconds];
702}
703
704- (void) setStartAtOpen: (id) sender
705{
706    [fDefaults setBool: [sender state] == NSOnState forKey: @"StartAtOpen"];
707}
708
709- (void) setUseQueue: (id) sender
710{
711    BOOL useQueue = [sender state] == NSOnState;
712   
713    [fDefaults setBool: useQueue forKey: @"Queue"];
714    [self setQueueNumber: fQueueNumberField];
715    [fQueueNumberField setEnabled: useQueue];
716}
717
718- (void) setQueueNumber: (id) sender
719{
720    int queueNumber = [sender intValue];
721    if (![[sender stringValue] isEqualToString: [NSString stringWithInt: queueNumber]] || queueNumber < 1)
722    {
723        NSBeep();
724        queueNumber = [fDefaults integerForKey: @"WaitToStartNumber"];
725        [sender setIntValue: queueNumber];
726    }
727    else
728        [fDefaults setInteger: queueNumber forKey: @"WaitToStartNumber"];
729   
730    [[NSNotificationCenter defaultCenter] postNotificationName: @"GlobalStartSettingChange" object: self];
731}
732
733- (void) setMoveTorrent: (id) sender
734{
735    int state = [sender state];
736    if (sender == fCopyTorrentCheck)
737    {
738        [fDefaults setBool: state forKey: @"SavePrivateTorrent"];
739       
740        [fDeleteOriginalTorrentCheck setEnabled: state];
741        if (state == NSOffState)
742        {
743            [fDeleteOriginalTorrentCheck setState: NSOffState];
744            [fDefaults setBool: NO forKey: @"DeleteOriginalTorrent"];
745        }
746    }
747    else
748        [fDefaults setBool: state forKey: @"DeleteOriginalTorrent"];
749}
750
751- (void) setDownloadLocation: (id) sender
752{
753    //Download folder
754    switch ([fFolderPopUp indexOfSelectedItem])
755    {
756        case DOWNLOAD_FOLDER:
757            [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
758            break;
759        case DOWNLOAD_TORRENT:
760            [fDefaults setObject: @"Torrent" forKey: @"DownloadChoice"];
761            break;
762        case DOWNLOAD_ASK:
763            [fDefaults setObject: @"Ask" forKey: @"DownloadChoice"];
764            break;
765    }
766}
767
768- (void) checkUpdate
769{
770    [fUpdater checkForUpdates: nil];
771}
772
773- (void) folderSheetShow: (id) sender
774{
775    NSOpenPanel * panel = [NSOpenPanel openPanel];
776
777    [panel setPrompt: @"Select"];
778    [panel setAllowsMultipleSelection: NO];
779    [panel setCanChooseFiles: NO];
780    [panel setCanChooseDirectories: YES];
781    [panel setCanCreateDirectories: YES];
782
783    [panel beginSheetForDirectory: nil file: nil types: nil
784        modalForWindow: [self window] modalDelegate: self didEndSelector:
785        @selector(folderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
786}
787
788- (void) setAutoImport: (id) sender
789{
790    int state = [fAutoImportCheck state];
791    [fDefaults setBool: state forKey: @"AutoImport"];
792    [fImportFolderPopUp setEnabled: state];
793   
794    if (state == NSOnState)
795        [[UKKQueue sharedFileWatcher] addPath: fImportFolder];
796    else
797        [[UKKQueue sharedFileWatcher] removePathFromQueue: fImportFolder];
798   
799    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
800}
801
802- (void) importFolderSheetShow: (id) sender
803{
804    NSOpenPanel * panel = [NSOpenPanel openPanel];
805
806    [panel setPrompt: @"Select"];
807    [panel setAllowsMultipleSelection: NO];
808    [panel setCanChooseFiles: NO];
809    [panel setCanChooseDirectories: YES];
810    [panel setCanCreateDirectories: YES];
811
812    [panel beginSheetForDirectory: nil file: nil types: nil
813        modalForWindow: [self window] modalDelegate: self didEndSelector:
814        @selector(importFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
815}
816
817- (void) setAutoSize: (id) sender
818{
819    [fDefaults setBool: [sender state] forKey: @"AutoSize"];
820   
821    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSizeSettingChange" object: self];
822}
823
824- (void) helpForNetwork: (id) sender
825{
826    [[NSHelpManager sharedHelpManager] openHelpAnchor: @"PortForwarding"
827        inBook: [[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleHelpBookName"]];
828}
829
830@end
831
832@implementation PrefsController (Private)
833
834- (void) showGeneralPref: (id) sender
835{
836    [self setPrefView: fGeneralView];
837}
838
839- (void) showTransfersPref: (id) sender
840{
841    [self setPrefView: fTransfersView];
842}
843
844- (void) showBandwidthPref: (id) sender
845{
846    [self setPrefView: fBandwidthView];
847}
848
849- (void) showNetworkPref: (id) sender
850{
851    [self setPrefView: fNetworkView];
852}
853
854- (void) setPrefView: (NSView *) view
855{
856    NSWindow * window = [self window];
857   
858    if ([window contentView] == view)
859        return;
860   
861    NSRect windowRect = [window frame];
862    int difference = [view frame].size.height - [[window contentView] frame].size.height;
863    windowRect.origin.y -= difference;
864    windowRect.size.height += difference;
865
866    [window setTitle: [fToolbar selectedItemIdentifier]];
867   
868    [view setHidden: YES];
869    [window setContentView: view];
870    [window setFrame: windowRect display: YES animate: YES];
871    [view setHidden: NO];
872}
873
874- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
875{
876    if (code == NSOKButton)
877    {
878        [fDownloadFolder release];
879        fDownloadFolder = [[[openPanel filenames] objectAtIndex: 0] retain];
880       
881        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
882        [fDefaults setObject: fDownloadFolder forKey: @"DownloadFolder"];
883        [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
884       
885        [self updatePopUp];
886    }
887    else
888    {
889        //reset if cancelled
890        NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
891        if ([downloadChoice isEqualToString: @"Constant"])
892            [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
893        else if ([downloadChoice isEqualToString: @"Torrent"])
894            [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
895        else
896            [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
897    }
898}
899
900- (void) updatePopUp
901{
902    //get and resize the icon
903    NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile: fDownloadFolder];
904    [icon setScalesWhenResized: YES];
905    [icon setSize: NSMakeSize(16.0, 16.0)];
906
907    //update menu item
908    NSMenuItem * menuItem = (NSMenuItem *) [fFolderPopUp itemAtIndex: 0];
909    [menuItem setTitle: [fDownloadFolder lastPathComponent]];
910    [menuItem setImage: icon];
911}
912
913- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
914{
915    if (code == NSOKButton)
916    {
917        UKKQueue * sharedQueue = [UKKQueue sharedFileWatcher];
918        [sharedQueue removePathFromQueue: fImportFolder];
919       
920        [fImportFolder release];
921        fImportFolder = [[[openPanel filenames] objectAtIndex: 0] retain];
922       
923        [fDefaults setObject: fImportFolder forKey: @"AutoImportDirectory"];
924       
925        [self updateImportPopUp];
926       
927        [sharedQueue addPath: fImportFolder];
928       
929        [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
930    }
931    [fImportFolderPopUp selectItemAtIndex: 0];
932}
933
934- (void) updateImportPopUp
935{
936    //get and resize the icon
937    NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile: fImportFolder];
938    [icon setScalesWhenResized: YES];
939    [icon setSize: NSMakeSize(16.0, 16.0)];
940
941    //update menu item
942    NSMenuItem * menuItem = (NSMenuItem *) [fImportFolderPopUp itemAtIndex: 0];
943    [menuItem setTitle: [fImportFolder lastPathComponent]];
944    [menuItem setImage: icon];
945}
946
947@end
Note: See TracBrowser for help on using the repository browser.