source: trunk/macosx/PrefsController.m @ 5913

Last change on this file since 5913 was 5913, checked in by charles, 14 years ago

sine we now have two public ports (peer and rpc), rename "publicPort" as "peerPort"

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