source: trunk/macosx/PrefsController.m @ 1050

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

remove some 10.3 checks

  • Property svn:keywords set to Date Rev Author Id
File size: 18.2 KB
Line 
1/******************************************************************************
2 * $Id: PrefsController.m 1050 2006-11-03 02:49:16Z livings124 $
3 *
4 * Copyright (c) 2005-2006 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "PrefsController.h"
26#import "StringAdditions.h"
27#import "UKKQueue.h"
28
29#define DOWNLOAD_FOLDER     0
30#define DOWNLOAD_TORRENT    2
31#define DOWNLOAD_ASK        3
32
33#define UPDATE_DAILY    0
34#define UPDATE_WEEKLY   1
35#define UPDATE_NEVER    2
36
37#define TOOLBAR_GENERAL     @"TOOLBAR_GENERAL"
38#define TOOLBAR_TRANSFERS   @"TOOLBAR_TRANSFERS"
39#define TOOLBAR_BANDWIDTH   @"TOOLBAR_BANDWIDTH"
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) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
48
49@end
50
51@implementation PrefsController
52
53- (id) initWithWindowNibName: (NSString *) name handle: (tr_handle_t *) handle
54{
55    if ((self = [self initWithWindowNibName: name]))
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 auto import
68        if ([fDefaults boolForKey: @"AutoImport"])
69            [[UKKQueue sharedFileWatcher] addPath:
70                [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath]];
71       
72        //set bind port
73        int bindPort = [fDefaults integerForKey: @"BindPort"];
74        tr_setBindPort(fHandle, bindPort);
75       
76        //set NAT
77        if ([fDefaults boolForKey: @"NatTraversal"])
78            tr_natTraversalEnable(fHandle);
79       
80        //actually set bandwidth limits
81        [self applySpeedSettings: nil];
82       
83        //set play sound
84        NSMutableArray * sounds = [NSMutableArray array];
85        NSEnumerator * soundEnumerator,
86                    * soundDirectoriesEnumerator = [[NSArray arrayWithObjects: @"System/Library/Sounds",
87                            [NSHomeDirectory() stringByAppendingPathComponent: @"Library/Sounds"], nil] objectEnumerator];
88        NSString * soundPath, * sound;
89       
90        //get list of all sounds and sort alphabetically
91        while ((soundPath = [soundDirectoriesEnumerator nextObject]))
92            if (soundEnumerator = [[NSFileManager defaultManager] enumeratorAtPath: soundPath])
93                while ((sound = [soundEnumerator nextObject]))
94                {
95                    sound = [sound stringByDeletingPathExtension];
96                    if ([NSSound soundNamed: sound])
97                        [sounds addObject: sound];
98                }
99       
100        fSounds = [[sounds sortedArrayUsingSelector: @selector(caseInsensitiveCompare:)] retain];
101    }
102    return self;
103}
104
105- (void) dealloc
106{
107    if (fNatStatusTimer)
108        [fNatStatusTimer invalidate];
109    [fSounds release];
110   
111    [super dealloc];
112}
113
114- (void) awakeFromNib
115{
116    fToolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
117    [fToolbar setDelegate: self];
118    [fToolbar setAllowsUserCustomization: NO];
119    [[self window] setToolbar: fToolbar];
120    [fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
121    [fToolbar setSizeMode: NSToolbarSizeModeRegular];
122
123    [fToolbar setSelectedItemIdentifier: TOOLBAR_GENERAL];
124    [self setPrefView: nil];
125   
126    //set download folder
127    NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
128    if ([downloadChoice isEqualToString: @"Constant"])
129        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
130    else if ([downloadChoice isEqualToString: @"Torrent"])
131        [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
132    else
133        [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
134   
135    [self updatePortStatus];
136   
137    fNatStatus = -1;
138    [self updateNatStatus];
139    fNatStatusTimer = [NSTimer scheduledTimerWithTimeInterval: 5.0 target: self
140                        selector: @selector(updateNatStatus) userInfo: nil repeats: YES];
141
142    //set update check
143    NSString * updateCheck = [fDefaults stringForKey: @"UpdateCheck"];
144    if ([updateCheck isEqualToString: @"Weekly"])
145        [fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
146    else if ([updateCheck isEqualToString: @"Never"])
147        [fUpdatePopUp selectItemAtIndex: UPDATE_NEVER];
148    else
149        [fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
150}
151
152- (void) setUpdater: (SUUpdater *) updater
153{
154    fUpdater = updater;
155}
156
157- (NSToolbarItem *) toolbar: (NSToolbar *) toolbar itemForItemIdentifier: (NSString *) ident
158                    willBeInsertedIntoToolbar: (BOOL) flag
159{
160    NSToolbarItem * item;
161    item = [[NSToolbarItem alloc] initWithItemIdentifier: ident];
162
163    if ([ident isEqualToString: TOOLBAR_GENERAL])
164    {
165        [item setLabel: NSLocalizedString(@"General", "Preferences -> General toolbar item title")];
166        [item setImage: [NSImage imageNamed: @"Preferences.png"]];
167        [item setTarget: self];
168        [item setAction: @selector(setPrefView:)];
169    }
170    else if ([ident isEqualToString: TOOLBAR_TRANSFERS])
171    {
172        [item setLabel: NSLocalizedString(@"Transfers", "Preferences -> Transfers toolbar item title")];
173        [item setImage: [NSImage imageNamed: @"Transfers.png"]];
174        [item setTarget: self];
175        [item setAction: @selector(setPrefView:)];
176    }
177    else if ([ident isEqualToString: TOOLBAR_BANDWIDTH])
178    {
179        [item setLabel: NSLocalizedString(@"Bandwidth", "Preferences -> Bandwidth toolbar item title")];
180        [item setImage: [NSImage imageNamed: @"Bandwidth.png"]];
181        [item setTarget: self];
182        [item setAction: @selector(setPrefView:)];
183    }
184    else if ([ident isEqualToString: TOOLBAR_NETWORK])
185    {
186        [item setLabel: NSLocalizedString(@"Network", "Preferences -> Network toolbar item title")];
187        [item setImage: [NSImage imageNamed: @"Network.png"]];
188        [item setTarget: self];
189        [item setAction: @selector(setPrefView:)];
190    }
191    else
192    {
193        [item release];
194        return nil;
195    }
196
197    return item;
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_NETWORK, nil];
214}
215
216- (void) setPort: (id) sender
217{
218    tr_setBindPort(fHandle, [fDefaults integerForKey: @"BindPort"]);
219    [self updateNatStatus];
220    [self updatePortStatus];
221}
222
223- (void) updatePortStatus
224{
225    PortChecker * portChecker = [[PortChecker alloc] initWithDelegate: self];
226
227    [fPortStatusField setStringValue: [NSLocalizedString(@"Checking port status",
228                                        "Preferences -> Network -> port status") stringByAppendingEllipsis]];
229    [fPortStatusImage setImage: nil];
230    [fPortStatusProgress startAnimation: self];
231       
232    [portChecker probePort: [fDefaults integerForKey: @"BindPort"]];
233}
234
235- (void) portCheckerDidFinishProbing: (PortChecker *) portChecker
236{
237    [fPortStatusProgress stopAnimation: self];
238    switch ([portChecker status])
239    {
240        case PORT_STATUS_OPEN:
241            [fPortStatusField setStringValue: NSLocalizedString(@"Port is open", "Preferences -> Network -> port status")];
242            [fPortStatusImage setImage: [NSImage imageNamed: @"GreenDot.tiff"]];
243            break;
244        case PORT_STATUS_STEALTH:
245            [fPortStatusField setStringValue: NSLocalizedString(@"Port is stealth", "Preferences -> Network -> port status")];
246            [fPortStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
247            break;
248        case PORT_STATUS_CLOSED:
249            [fPortStatusField setStringValue: NSLocalizedString(@"Port is closed", "Preferences -> Network -> port status")];
250            [fPortStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
251            break;
252        case PORT_STATUS_ERROR:
253            [fPortStatusField setStringValue: NSLocalizedString(@"Unable to check port status",
254                                                "Preferences -> Network -> port status")];
255            [fPortStatusImage setImage: [NSImage imageNamed: @"YellowDot.tiff"]];
256            break;
257    }
258    [portChecker release];
259}
260
261- (void) setNat: (id) sender
262{
263    [fDefaults boolForKey: @"NatTraversal"] ? tr_natTraversalEnable(fHandle) : tr_natTraversalDisable(fHandle);
264    [self updateNatStatus];
265}
266
267- (void) updateNatStatus
268{
269    int status = tr_natTraversalStatus(fHandle);
270    if (fNatStatus == status)
271        return;
272    fNatStatus = status;
273   
274    if (status == 2)
275    {
276        [fNatStatusField setStringValue: NSLocalizedString(@"Port successfully mapped",
277                                            "Preferences -> Network -> port map status")];
278        [fNatStatusImage setImage: [NSImage imageNamed: @"GreenDot.tiff"]];
279    }
280    else if (status == 3 || status == 4)
281    {
282        [fNatStatusField setStringValue: NSLocalizedString(@"Error mapping port",
283                                            "Preferences -> Network -> port map status")];
284        [fNatStatusImage setImage: [NSImage imageNamed: @"RedDot.tiff"]];
285    }
286    else
287    {
288        [fNatStatusField setStringValue: @""];
289        [fNatStatusImage setImage: nil];
290    }
291   
292    [self updatePortStatus];
293}
294
295- (void) applySpeedSettings: (id) sender
296{
297    if ([fDefaults boolForKey: @"SpeedLimit"])
298    {
299        tr_setUploadLimit(fHandle, [fDefaults integerForKey: @"SpeedLimitUploadLimit"]);
300        tr_setDownloadLimit(fHandle, [fDefaults integerForKey: @"SpeedLimitDownloadLimit"]);
301    }
302    else
303    {
304        tr_setUploadLimit(fHandle, [fDefaults boolForKey: @"CheckUpload"]
305                                        ? [fDefaults integerForKey: @"UploadLimit"] : -1);
306        tr_setDownloadLimit(fHandle, [fDefaults boolForKey: @"CheckDownload"]
307                                        ? [fDefaults integerForKey: @"DownloadLimit"] : -1);
308    }
309}
310
311- (void) setAutoSpeedLimit: (id) sender
312{
313    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSpeedLimitChange" object: self];
314}
315
316- (void) setBadge: (id) sender
317{   
318    [[NSNotificationCenter defaultCenter] postNotificationName: @"DockBadgeChange" object: self];
319}
320
321- (void) setSound: (id) sender
322{
323    //play sound when selecting
324    NSString * soundName = [sender titleOfSelectedItem];
325    NSSound * sound;
326    if ((sound = [NSSound soundNamed: soundName]))
327        [sound play];
328}
329
330- (void) setUpdate: (id) sender
331{
332    int index = [fUpdatePopUp indexOfSelectedItem];
333    NSTimeInterval seconds;
334    if (index == UPDATE_DAILY)
335    {
336        [fDefaults setObject: @"Daily" forKey: @"UpdateCheck"];
337        seconds = 86400;
338    }
339    else if (index == UPDATE_WEEKLY)
340    {
341        [fDefaults setObject: @"Weekly" forKey: @"UpdateCheck"];
342        seconds = 604800;
343    }
344    else
345    {
346        [fDefaults setObject: @"Never" forKey: @"UpdateCheck"];
347        seconds = 0;
348    }
349
350    [fDefaults setInteger: seconds forKey: @"SUScheduledCheckInterval"];
351   
352    if (fUpdater)
353        [fUpdater scheduleCheckWithInterval: seconds];
354}
355
356- (void) setQueueNumber: (id) sender
357{
358    [[NSNotificationCenter defaultCenter] postNotificationName: @"GlobalStartSettingChange" object: self];
359}
360
361- (void) setCopyTorrents: (id) sender
362{
363    if (![fDefaults boolForKey: @"SavePrivateTorrent"])
364        [fDefaults setBool: NO forKey: @"DeleteOriginalTorrent"];
365}
366
367- (void) setDownloadLocation: (id) sender
368{
369    //download folder
370    switch ([fFolderPopUp indexOfSelectedItem])
371    {
372        case DOWNLOAD_FOLDER:
373            [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
374            break;
375        case DOWNLOAD_TORRENT:
376            [fDefaults setObject: @"Torrent" forKey: @"DownloadChoice"];
377            break;
378        case DOWNLOAD_ASK:
379            [fDefaults setObject: @"Ask" forKey: @"DownloadChoice"];
380            break;
381    }
382}
383
384- (void) folderSheetShow: (id) sender
385{
386    NSOpenPanel * panel = [NSOpenPanel openPanel];
387
388    [panel setPrompt: @"Select"];
389    [panel setAllowsMultipleSelection: NO];
390    [panel setCanChooseFiles: NO];
391    [panel setCanChooseDirectories: YES];
392    [panel setCanCreateDirectories: YES];
393
394    [panel beginSheetForDirectory: nil file: nil types: nil
395        modalForWindow: [self window] modalDelegate: self didEndSelector:
396        @selector(folderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
397}
398
399- (void) setAutoImport: (id) sender
400{
401    if ([fDefaults boolForKey: @"AutoImport"])
402        [[UKKQueue sharedFileWatcher] addPath:
403            [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath]];
404    else
405        [[UKKQueue sharedFileWatcher] removePathFromQueue:
406            [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath]];
407   
408    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
409}
410
411- (void) importFolderSheetShow: (id) sender
412{
413    NSOpenPanel * panel = [NSOpenPanel openPanel];
414
415    [panel setPrompt: @"Select"];
416    [panel setAllowsMultipleSelection: NO];
417    [panel setCanChooseFiles: NO];
418    [panel setCanChooseDirectories: YES];
419    [panel setCanCreateDirectories: YES];
420
421    [panel beginSheetForDirectory: nil file: nil types: nil
422        modalForWindow: [self window] modalDelegate: self didEndSelector:
423        @selector(importFolderSheetClosed:returnCode:contextInfo:) contextInfo: nil];
424}
425
426- (void) setAutoSize: (id) sender
427{
428    [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoSizeSettingChange" object: self];
429}
430
431- (void) helpForNetwork: (id) sender
432{
433    [[NSHelpManager sharedHelpManager] openHelpAnchor: @"PortForwarding"
434        inBook: [[NSBundle mainBundle] objectForInfoDictionaryKey: @"CFBundleHelpBookName"]];
435}
436
437@end
438
439@implementation PrefsController (Private)
440
441- (void) setPrefView: (id) sender
442{
443    NSView * view = fGeneralView;
444    if (sender)
445    {
446        NSString * identifier = [sender itemIdentifier];
447        if ([identifier isEqualToString: TOOLBAR_TRANSFERS])
448            view = fTransfersView;
449        else if ([identifier isEqualToString: TOOLBAR_BANDWIDTH])
450            view = fBandwidthView;
451        else if ([identifier isEqualToString: TOOLBAR_NETWORK])
452            view = fNetworkView;
453        else;
454    }
455   
456    NSWindow * window = [self window];
457    if ([window contentView] == view)
458        return;
459   
460    NSRect windowRect = [window frame];
461    int difference = [view frame].size.height - [[window contentView] frame].size.height;
462    windowRect.origin.y -= difference;
463    windowRect.size.height += difference;
464   
465    [view setHidden: YES];
466    [window setContentView: view];
467    [window setFrame: windowRect display: YES animate: YES];
468    [view setHidden: NO];
469   
470    //set title label
471    if (sender)
472        [window setTitle: [sender label]];
473    else
474    {
475        NSToolbarItem * item;
476        NSEnumerator * enumerator = [[fToolbar items] objectEnumerator];
477        while ((item = [enumerator nextObject]))
478            if ([[item itemIdentifier] isEqualToString: [fToolbar selectedItemIdentifier]])
479            {
480                [window setTitle: [item label]];
481                break;
482            }
483    }
484   
485    //for network view make sure progress indicator hides itself
486    if (view == fNetworkView && [fPortStatusImage image])
487        [fPortStatusProgress setDisplayedWhenStopped: NO];
488}
489
490- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
491{
492    if (code == NSOKButton)
493    {
494        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
495        [fDefaults setObject: [[openPanel filenames] objectAtIndex: 0] forKey: @"DownloadFolder"];
496        [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
497    }
498    else
499    {
500        //reset if cancelled
501        NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
502        if ([downloadChoice isEqualToString: @"Constant"])
503            [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
504        else if ([downloadChoice isEqualToString: @"Torrent"])
505            [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
506        else
507            [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
508    }
509}
510
511- (void) importFolderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
512{
513    if (code == NSOKButton)
514    {
515        UKKQueue * sharedQueue = [UKKQueue sharedFileWatcher];
516        [sharedQueue removePathFromQueue: [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath]];
517       
518        [fDefaults setObject: [[openPanel filenames] objectAtIndex: 0] forKey: @"AutoImportDirectory"];
519       
520        [sharedQueue addPath: [[fDefaults stringForKey: @"AutoImportDirectory"] stringByExpandingTildeInPath]];
521       
522        [[NSNotificationCenter defaultCenter] postNotificationName: @"AutoImportSettingChange" object: self];
523    }
524    [fImportFolderPopUp selectItemAtIndex: 0];
525}
526
527@end
Note: See TracBrowser for help on using the repository browser.