source: trunk/macosx/PrefsController.m @ 3646

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

use built-in general and advanced images in the preferences window on Leopard

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