source: trunk/macosx/PrefsController.m @ 3776

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

when sorting by queue order, allow torrents to be reordered even if they are filtered (put below the one above it in the total queue)

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