source: branches/0.9x/macosx/PrefsController.m @ 3709

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

fix bug with setting port value in prefs

  • Property svn:keywords set to Date Rev Author Id
File size: 23.8 KB
Line 
1/******************************************************************************
2 * $Id: PrefsController.m 3709 2007-11-05 04:02:21Z livings124 $
3 *
4 * Copyright (c) 2005-2007 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 "NSStringAdditions.h"
27#import "UKKQueue.h"
28
29#define DOWNLOAD_FOLDER     0
30#define DOWNLOAD_TORRENT    2
31#define DOWNLOAD_ASK        3
32
33#define UPDATE_SECONDS 86400
34
35#define TOOLBAR_GENERAL     @"TOOLBAR_GENERAL"
36#define TOOLBAR_TRANSFERS   @"TOOLBAR_TRANSFERS"
37#define TOOLBAR_BANDWIDTH   @"TOOLBAR_BANDWIDTH"
38#define TOOLBAR_ADVANCED    @"TOOLBAR_ADVANCED"
39
40@interface PrefsController (Private)
41
42- (void) setPrefView: (id) sender;
43
44- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
45- (void) incompleteFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
46- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
47
48@end
49
50@implementation PrefsController
51
52- (id) initWithHandle: (tr_handle *) handle
53{
54    if ((self = [super initWithWindowNibName: @"PrefsWindow"]))
55    {
56        fDefaults = [NSUserDefaults standardUserDefaults];
57        fHandle = handle;
58       
59        //checks for old version upload speed of -1
60        if ([fDefaults integerForKey: @"UploadLimit"] < 0)
61        {
62            [fDefaults setInteger: 20 forKey: @"UploadLimit"];
63            [fDefaults setBool: NO forKey: @"CheckUpload"];
64        }
65       
66        //set check for update to right value
67        [self setCheckForUpdate: nil];
68       
69        //set auto import
70        NSString * autoPath;
71        if ([fDefaults boolForKey: @"AutoImport"] && (autoPath = [fDefaults stringForKey: @"AutoImportDirectory"]))
72            [[UKKQueue sharedFileWatcher] addPath: [autoPath stringByExpandingTildeInPath]];
73       
74        //set bind port
75        int bindPort = [fDefaults integerForKey: @"BindPort"];
76        tr_setBindPort(fHandle, bindPort);
77       
78        //set NAT
79        tr_natTraversalEnable(fHandle, [fDefaults boolForKey: @"NatTraversal"]);
80       
81        //set encryption
82        tr_setEncryptionMode(fHandle, [fDefaults boolForKey: @"EncryptionRequire"] ? TR_ENCRYPTION_REQUIRED : TR_ENCRYPTION_PREFERRED);
83       
84        //actually set bandwidth limits
85        [self applySpeedSettings: nil];
86    }
87   
88    return self;
89}
90
91- (void) dealloc
92{
93    if (fNatStatusTimer)
94        [fNatStatusTimer invalidate];
95   
96    [super dealloc];
97}
98
99- (void) awakeFromNib
100{
101    fHasLoaded = YES;
102   
103    NSToolbar * toolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
104    [toolbar setDelegate: self];
105    [toolbar setAllowsUserCustomization: NO];
106    [toolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
107    [toolbar setSizeMode: NSToolbarSizeModeRegular];
108    [[self window] setToolbar: toolbar];
109
110    [toolbar setSelectedItemIdentifier: TOOLBAR_GENERAL];
111    [self setPrefView: nil];
112   
113    //set download folder
114    NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
115    if ([downloadChoice isEqualToString: @"Constant"])
116        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
117    else if ([downloadChoice isEqualToString: @"Torrent"])
118        [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
119    else
120        [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
121   
122    //set stop ratio
123    [self updateRatioStopField];
124   
125    //set limits
126    [self updateLimitFields];
127   
128    //set speed limit
129    [fSpeedLimitUploadField setIntValue: [fDefaults integerForKey: @"SpeedLimitUploadLimit"]];
130    [fSpeedLimitDownloadField setIntValue: [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]];
131   
132    //set port
133    [fPortField setIntValue: [fDefaults integerForKey: @"BindPort"]];
134    fNatStatus = -1;
135   
136    [self updatePortStatus];
137    fNatStatusTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 target: self
138                        selector: @selector(updatePortStatus) userInfo: nil repeats: YES];
139   
140    //set queue values
141    [fQueueDownloadField setIntValue: [fDefaults integerForKey: @"QueueDownloadNumber"]];
142    [fQueueSeedField setIntValue: [fDefaults integerForKey: @"QueueSeedNumber"]];
143   
144    //set stalled value
145    [fStalledField setIntValue: [fDefaults integerForKey: @"StalledMinutes"]];
146}
147
148- (void) setUpdater: (SUUpdater *) updater
149{
150    fUpdater = updater;
151}
152
153- (NSToolbarItem *) toolbar: (NSToolbar *) toolbar itemForItemIdentifier: (NSString *) ident willBeInsertedIntoToolbar: (BOOL) flag
154{
155    NSToolbarItem * item;
156    item = [[NSToolbarItem alloc] initWithItemIdentifier: ident];
157
158    if ([ident isEqualToString: TOOLBAR_GENERAL])
159    {
160        [item setLabel: NSLocalizedString(@"General", "Preferences -> General toolbar item title")];
161        [item setImage: [NSImage imageNamed: @"Preferences.png"]];
162        [item setTarget: self];
163        [item setAction: @selector(setPrefView:)];
164        [item setAutovalidates: NO];
165    }
166    else if ([ident isEqualToString: TOOLBAR_TRANSFERS])
167    {
168        [item setLabel: NSLocalizedString(@"Transfers", "Preferences -> Transfers toolbar item title")];
169        [item setImage: [NSImage imageNamed: @"Transfers.png"]];
170        [item setTarget: self];
171        [item setAction: @selector(setPrefView:)];
172        [item setAutovalidates: NO];
173    }
174    else if ([ident isEqualToString: TOOLBAR_BANDWIDTH])
175    {
176        [item setLabel: NSLocalizedString(@"Bandwidth", "Preferences -> Bandwidth toolbar item title")];
177        [item setImage: [NSImage imageNamed: @"Bandwidth.png"]];
178        [item setTarget: self];
179        [item setAction: @selector(setPrefView:)];
180        [item setAutovalidates: NO];
181    }
182    else if ([ident isEqualToString: TOOLBAR_ADVANCED])
183    {
184        [item setLabel: NSLocalizedString(@"Advanced", "Preferences -> Advanced toolbar item title")];
185        [item setImage: [NSImage imageNamed: @"Advanced.png"]];
186        [item setTarget: self];
187        [item setAction: @selector(setPrefView:)];
188        [item setAutovalidates: NO];
189    }
190    else
191    {
192        [item release];
193        return nil;
194    }
195
196    return [item autorelease];
197}
198
199- (NSArray *) toolbarSelectableItemIdentifiers: (NSToolbar *) toolbar
200{
201    return [self toolbarDefaultItemIdentifiers: toolbar];
202}
203
204- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
205{
206    return [self toolbarAllowedItemIdentifiers: toolbar];
207}
208
209- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
210{
211    return [NSArray arrayWithObjects: TOOLBAR_GENERAL, TOOLBAR_TRANSFERS,
212                                        TOOLBAR_BANDWIDTH, TOOLBAR_ADVANCED, nil];
213}
214
215- (void) setPort: (id) sender
216{
217    int port = [sender intValue];
218    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", port]])
219    {
220        NSBeep();
221        [sender setIntValue: [fDefaults integerForKey: @"BindPort"]];
222        return;
223    }
224   
225    [fDefaults setInteger: port forKey: @"BindPort"];
226   
227    tr_setBindPort(fHandle, port);
228   
229    fPublicPort = -1;
230    [self updatePortStatus];
231}
232
233- (void) setNat: (id) sender
234{
235    tr_natTraversalEnable(fHandle, [fDefaults boolForKey: @"NatTraversal"]);
236    [self updatePortStatus];
237}
238
239- (void) updatePortStatus
240{
241    tr_handle_status * stat = tr_handleStatus(fHandle);
242   
243    BOOL change;
244    if (change = (fNatStatus != stat->natTraversalStatus))
245    {
246        fNatStatus = stat->natTraversalStatus;
247        switch (fNatStatus)
248        {
249            case TR_NAT_TRAVERSAL_MAPPED:
250                [fNatStatusField setStringValue: NSLocalizedString(@"Port successfully mapped",
251                                                    "Preferences -> Advanced -> port map status")];
252                [fNatStatusImage setImage: [NSImage imageNamed: @"GreenDot.tiff"]];
253                break;
254           
255            case TR_NAT_TRAVERSAL_NOTFOUND:
256            case TR_NAT_TRAVERSAL_ERROR:
257                [fNatStatusField setStringValue: NSLocalizedString(@"Error mapping port",
258                                                    "Preferences -> Advanced -> port map status")];
259                [fNatStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
260                break;
261           
262            default:
263                [fNatStatusField setStringValue: @""];
264                [fNatStatusImage setImage: nil];
265        }
266    }
267   
268    if (change || fPublicPort != stat->publicPort)
269    {
270        fPublicPort = stat->publicPort;
271       
272        [fPortStatusField setStringValue: [NSLocalizedString(@"Checking port status",
273                                            "Preferences -> Advanced -> port status") stringByAppendingEllipsis]];
274        [fPortStatusImage setImage: nil];
275        [fPortStatusProgress startAnimation: self];
276       
277        PortChecker * portChecker = [[PortChecker alloc] initWithDelegate: self];
278        [portChecker probePort: fPublicPort];
279    }
280}
281
282- (void) portCheckerDidFinishProbing: (PortChecker *) portChecker
283{
284    [fPortStatusProgress stopAnimation: self];
285    switch ([portChecker status])
286    {
287        case PORT_STATUS_OPEN:
288            [fPortStatusField setStringValue: NSLocalizedString(@"Port is open", "Preferences -> Advanced -> port status")];
289            [fPortStatusImage setImage: [NSImage imageNamed: @"GreenDot.tiff"]];
290            break;
291        case PORT_STATUS_STEALTH:
292            [fPortStatusField setStringValue: NSLocalizedString(@"Port is stealth", "Preferences -> Advanced -> port status")];
293            [fPortStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
294            break;
295        case PORT_STATUS_CLOSED:
296            [fPortStatusField setStringValue: NSLocalizedString(@"Port is closed", "Preferences -> Advanced -> port status")];
297            [fPortStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
298            break;
299        case PORT_STATUS_ERROR:
300            [fPortStatusField setStringValue: NSLocalizedString(@"Unable to check port status",
301                                                "Preferences -> Advanced -> port status")];
302            [fPortStatusImage setImage: [NSImage imageNamed: @"YellowDot.tiff"]];
303            break;
304    }
305    [portChecker release];
306}
307
308- (NSArray *) sounds
309{
310    NSMutableArray * sounds = [NSMutableArray array];
311   
312    //until Apple can fix soundNamed to not crash on invalid sound files, don't use custom sounds
313    NSArray * directories = [NSArray arrayWithObjects: @"/System/Library/Sounds", @"/Library/Sounds",
314                                /*[NSHomeDirectory() stringByAppendingPathComponent: @"Library/Sounds"],*/ nil];
315    BOOL isDirectory;
316    NSEnumerator * soundEnumerator;
317    NSString * sound;
318   
319    NSString * directory;
320    NSEnumerator * enumerator = [directories objectEnumerator];
321    while ((directory = [enumerator nextObject]))
322        if ([[NSFileManager defaultManager] fileExistsAtPath: directory isDirectory: &isDirectory] && isDirectory)
323        {
324                soundEnumerator = [[[NSFileManager defaultManager] directoryContentsAtPath: directory] objectEnumerator];
325                while ((sound = [soundEnumerator nextObject]))
326                {
327                    sound = [sound stringByDeletingPathExtension];
328                    if ([NSSound soundNamed: sound])
329                        [sounds addObject: sound];
330                }
331        }
332   
333    return sounds;
334}
335
336- (void) setSound: (id) sender
337{
338    //play sound when selecting
339    NSSound * sound;
340    if ((sound = [NSSound soundNamed: [sender titleOfSelectedItem]]))
341        [sound play];
342}
343
344- (void) setEncryptionRequired: (id) sender
345{
346    tr_setEncryptionMode(fHandle, [fDefaults boolForKey: @"EncryptionRequire"] ? TR_ENCRYPTION_REQUIRED : TR_ENCRYPTION_PREFERRED);
347}
348
349- (void) applySpeedSettings: (id) sender
350{
351    if ([fDefaults boolForKey: @"SpeedLimit"])
352    {
353        tr_setUseGlobalSpeedLimit(fHandle, TR_UP, 1);
354        tr_setGlobalSpeedLimit(fHandle, TR_UP, [fDefaults integerForKey: @"SpeedLimitUploadLimit"]);
355       
356        tr_setUseGlobalSpeedLimit(fHandle, TR_DOWN, 1);
357        tr_setGlobalSpeedLimit(fHandle, TR_DOWN, [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]);
358    }
359    else
360    {
361        tr_setUseGlobalSpeedLimit(fHandle, TR_UP, [fDefaults boolForKey: @"CheckUpload"]);
362        tr_setGlobalSpeedLimit(fHandle, TR_UP, [fDefaults integerForKey: @"UploadLimit"]);
363       
364        tr_setUseGlobalSpeedLimit(fHandle, TR_DOWN, [fDefaults boolForKey: @"CheckDownload"]);
365        tr_setGlobalSpeedLimit(fHandle, TR_DOWN, [fDefaults integerForKey: @"DownloadLimit"]);
366    }
367}
368
369- (void) applyRatioSetting: (id) sender
370{
371    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: nil];
372}
373
374- (void) updateRatioStopField
375{
376    if (!fHasLoaded)
377        return;
378   
379    [fRatioStopField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]];
380   
381    [self applyRatioSetting: nil];
382}
383
384- (void) setRatioStop: (id) sender
385{
386    float ratio = [sender floatValue];
387    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%.2f", ratio]] || ratio < 0)
388    {
389        NSBeep();
390        [sender setFloatValue: [fDefaults floatForKey: @"RatioLimit"]];
391        return;
392    }
393   
394    [fDefaults setFloat: ratio forKey: @"RatioLimit"];
395   
396    [self applyRatioSetting: nil];
397}
398
399- (void) updateLimitFields
400{
401    if (!fHasLoaded)
402        return;
403   
404    [fUploadField setIntValue: [fDefaults integerForKey: @"UploadLimit"]];
405    [fDownloadField setIntValue: [fDefaults integerForKey: @"DownloadLimit"]];
406}
407
408- (void) setGlobalLimit: (id) sender
409{
410    BOOL upload = sender == fUploadField;
411   
412    int limit = [sender intValue];
413    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]] || limit < 0)
414    {
415        NSBeep();
416        [sender setIntValue: [fDefaults integerForKey: upload ? @"UploadLimit" : @"DownloadLimit"]];
417        return;
418    }
419   
420    [fDefaults setInteger: limit forKey: upload ? @"UploadLimit" : @"DownloadLimit"];
421   
422    [self applySpeedSettings: self];
423}
424
425- (void) setSpeedLimit: (id) sender
426{
427    BOOL upload = sender == fSpeedLimitUploadField;
428   
429    int limit = [sender intValue];
430    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]])
431    {
432        NSBeep();
433        [sender setIntValue: [fDefaults integerForKey: upload ? @"SpeedLimitUploadLimit" : @"SpeedLimitDownloadLimit"]];
434        return;
435    }
436   
437    [fDefaults setInteger: limit forKey: upload ? @"SpeedLimitUploadLimit" : @"SpeedLimitDownloadLimit"];
438   
439    [self applySpeedSettings: self];
440}
441
442- (void) setAutoSpeedLimit: (id) sender
443{
444    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSpeedLimitChange" object: self];
445}
446
447- (void) setBadge: (id) sender
448{   
449    [[NSNotificationCenter defaultCenter] postNotificationName: @"DockBadgeChange" object: self];
450}
451
452- (void) resetWarnings: (id) sender
453{
454    [fDefaults setBool: YES forKey: @"WarningDebug"];
455    [fDefaults setBool: YES forKey: @"WarningDuplicate"];
456    [fDefaults setBool: YES forKey: @"WarningRemainingSpace"];
457}
458
459- (void) setCheckForUpdate: (id) sender
460{
461    NSTimeInterval seconds = [fDefaults boolForKey: @"CheckForUpdates"] ? UPDATE_SECONDS : 0;
462    [fDefaults setInteger: seconds forKey: @"SUScheduledCheckInterval"];
463    if (fUpdater)
464        [fUpdater scheduleCheckWithInterval: seconds];
465}
466
467- (void) setQueue: (id) sender
468{
469    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateQueue" object: self];
470}
471
472- (void) setQueueNumber: (id) sender
473{
474    BOOL download = sender == fQueueDownloadField;
475   
476    int limit = [sender intValue];
477    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]] || limit < 1)
478    {
479        NSBeep();
480        [sender setIntValue: [fDefaults integerForKey: download ? @"QueueDownloadNumber" : @"QueueSeedNumber"]];
481        return;
482    }
483   
484    [fDefaults setInteger: limit forKey: download ? @"QueueDownloadNumber" : @"QueueSeedNumber"];
485    [self setQueue: nil];
486}
487
488- (void) setStalled: (id) sender
489{
490    [[NSNotificationCenter defaultCenter] postNotificationName: @"UpdateUI" object: self];
491}
492
493- (void) setStalledMinutes: (id) sender
494{
495    int minutes = [sender intValue];
496    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", minutes]] || minutes < 1)
497    {
498        NSBeep();
499        [sender setIntValue: [fDefaults integerForKey: @"StalledMinutes"]];
500        return;
501    }
502   
503    [fDefaults setInteger: minutes forKey: @"StalledMinutes"];
504    [self setStalled: nil];
505}
506
507- (void) setDownloadLocation: (id) sender
508{
509    switch ([fFolderPopUp indexOfSelectedItem])
510    {
511        case DOWNLOAD_FOLDER:
512            [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
513            break;
514        case DOWNLOAD_TORRENT:
515            [fDefaults setObject: @"Torrent" forKey: @"DownloadChoice"];
516            break;
517        case DOWNLOAD_ASK:
518            [fDefaults setObject: @"Ask" forKey: @"DownloadChoice"];
519            break;
520    }
521}
522
523- (void) folderSheetShow: (id) sender
524{
525    NSOpenPanel * panel = [NSOpenPanel openPanel];
526
527    [panel setPrompt: @"Select"];
528    [panel setAllowsMultipleSelection: NO];
529    [panel setCanChooseFiles: NO];
530    [panel setCanChooseDirectories: YES];
531    [panel setCanCreateDirectories: YES];
532
533    [panel beginSheetForDirectory: nil file: nil types: nil
534        modalForWindow: [self window] modalDelegate: self didEndSelector:
535        @selector(folderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
536}
537
538- (void) incompleteFolderSheetShow: (id) sender
539{
540    NSOpenPanel * panel = [NSOpenPanel openPanel];
541
542    [panel setPrompt: @"Select"];
543    [panel setAllowsMultipleSelection: NO];
544    [panel setCanChooseFiles: NO];
545    [panel setCanChooseDirectories: YES];
546    [panel setCanCreateDirectories: YES];
547
548    [panel beginSheetForDirectory: nil file: nil types: nil
549        modalForWindow: [self window] modalDelegate: self didEndSelector:
550        @selector(incompleteFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
551}
552
553- (void) setAutoImport: (id) sender
554{
555    NSString * path;
556    if ((path = [fDefaults stringForKey: @"AutoImportDirectory"]))
557    {
558        path = [path stringByExpandingTildeInPath];
559        if ([fDefaults boolForKey: @"AutoImport"])
560            [[UKKQueue sharedFileWatcher] addPath: path];
561        else
562            [[UKKQueue sharedFileWatcher] removePathFromQueue: path];
563       
564        [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
565    }
566    else
567        [self importFolderSheetShow: nil];
568}
569
570- (void) importFolderSheetShow: (id) sender
571{
572    NSOpenPanel * panel = [NSOpenPanel openPanel];
573
574    [panel setPrompt: @"Select"];
575    [panel setAllowsMultipleSelection: NO];
576    [panel setCanChooseFiles: NO];
577    [panel setCanChooseDirectories: YES];
578    [panel setCanCreateDirectories: YES];
579
580    [panel beginSheetForDirectory: nil file: nil types: nil
581        modalForWindow: [self window] modalDelegate: self didEndSelector:
582        @selector(importFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
583}
584
585- (void) setAutoSize: (id) sender
586{
587    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSizeSettingChange" object: self];
588}
589
590- (void) helpForNetwork: (id) sender
591{
592    [[NSHelpManager sharedHelpManager] openHelpAnchor: @"PortForwarding"
593        inBook: [[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleHelpBookName"]];
594}
595
596@end
597
598@implementation PrefsController (Private)
599
600- (void) setPrefView: (id) sender
601{
602    NSView * view = fGeneralView;
603    if (sender)
604    {
605        NSString * identifier = [sender itemIdentifier];
606        if ([identifier isEqualToString: TOOLBAR_TRANSFERS])
607            view = fTransfersView;
608        else if ([identifier isEqualToString: TOOLBAR_BANDWIDTH])
609            view = fBandwidthView;
610        else if ([identifier isEqualToString: TOOLBAR_ADVANCED])
611            view = fAdvancedView;
612        else;
613    }
614   
615    NSWindow * window = [self window];
616    if ([window contentView] == view)
617        return;
618   
619    NSRect windowRect = [window frame];
620    float difference = ([view frame].size.height - [[window contentView] frame].size.height) * [window userSpaceScaleFactor];
621    windowRect.origin.y -= difference;
622    windowRect.size.height += difference;
623   
624    [view setHidden: YES];
625    [window setContentView: view];
626    [window setFrame: windowRect display: YES animate: YES];
627    [view setHidden: NO];
628   
629    //set title label
630    if (sender)
631        [window setTitle: [sender label]];
632    else
633    {
634        NSToolbar * toolbar = [window toolbar];
635        NSString * itemIdentifier = [toolbar selectedItemIdentifier];
636        NSEnumerator * enumerator = [[toolbar items] objectEnumerator];
637        NSToolbarItem * item;
638        while ((item = [enumerator nextObject]))
639            if ([[item itemIdentifier] isEqualToString: itemIdentifier])
640            {
641                [window setTitle: [item label]];
642                break;
643            }
644    }
645   
646    //for advanced view make sure progress indicator hides itself
647    if (view == fAdvancedView && [fPortStatusImage image])
648        [fPortStatusProgress setDisplayedWhenStopped: NO];
649}
650
651- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
652{
653    if (code == NSOKButton)
654    {
655        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
656        [fDefaults setObject: [[openPanel filenames] objectAtIndex: 0] forKey: @"DownloadFolder"];
657        [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
658    }
659    else
660    {
661        //reset if cancelled
662        NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
663        if ([downloadChoice isEqualToString: @"Constant"])
664            [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
665        else if ([downloadChoice isEqualToString: @"Torrent"])
666            [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
667        else
668            [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
669    }
670}
671
672- (void) incompleteFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
673{
674    if (code == NSOKButton)
675        [fDefaults setObject: [[openPanel filenames] objectAtIndex: 0] forKey: @"IncompleteDownloadFolder"];
676    [fIncompleteFolderPopUp selectItemAtIndex: 0];
677}
678
679- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
680{
681    NSString * path = [fDefaults stringForKey: @"AutoImportDirectory"];
682    if (code == NSOKButton)
683    {
684        UKKQueue * sharedQueue = [UKKQueue sharedFileWatcher];
685        if (path)
686            [sharedQueue removePathFromQueue: [path stringByExpandingTildeInPath]];
687       
688        path = [[openPanel filenames] objectAtIndex: 0];
689        [fDefaults setObject: path forKey: @"AutoImportDirectory"];
690        [sharedQueue addPath: [path stringByExpandingTildeInPath]];
691       
692        [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
693    }
694    else if (!path)
695        [fDefaults setBool: NO forKey: @"AutoImport"];
696   
697    [fImportFolderPopUp selectItemAtIndex: 0];
698}
699
700@end
Note: See TracBrowser for help on using the repository browser.