source: trunk/macosx/PrefsController.m @ 486

Last change on this file since 486 was 486, checked in by livings124, 16 years ago

Some changes to the preference window to avoid crowding. Some panes will be expanded upon (like bandwidth) when new features are added.

  • Property svn:keywords set to Date Rev Author Id
File size: 19.0 KB
Line 
1/******************************************************************************
2 * $Id: PrefsController.m 486 2006-06-30 00:53:17Z 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
28#define MIN_PORT    1
29#define MAX_PORT    65535
30
31#define DOWNLOAD_FOLDER     0
32#define DOWNLOAD_TORRENT    2
33#define DOWNLOAD_ASK    3
34
35#define START_YES_CHECK_TAG     0
36#define START_WAIT_CHECK_TAG    1
37#define START_NO_CHECK_TAG      2
38
39#define UPDATE_DAILY    0
40#define UPDATE_WEEKLY   1
41#define UPDATE_NEVER    2
42
43#define TOOLBAR_GENERAL     @"General"
44#define TOOLBAR_TRANSFERS   @"Transfers"
45#define TOOLBAR_BANDWIDTH   @"Bandwidth"
46#define TOOLBAR_NETWORK     @"Network"
47
48@interface PrefsController (Private)
49
50- (void) showGeneralPref: (id) sender;
51- (void) showTransfersPref: (id) sender;
52- (void) showBandwidthPref: (id) sender;
53- (void) showNetworkPref: (id) sender;
54
55- (void) setPrefView: (NSView *) view;
56
57- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
58- (void) updatePopUp;
59
60@end
61
62@implementation PrefsController
63
64+ (void) initialize
65{
66    [[NSUserDefaults standardUserDefaults] registerDefaults:
67        [NSDictionary dictionaryWithContentsOfFile:
68        [[NSBundle mainBundle] pathForResource: @"Defaults" ofType: @"plist"]]];
69}
70
71- (void) dealloc
72{
73    [fDownloadFolder release];
74    [super dealloc];
75}
76
77- (void) setPrefs: (tr_handle_t *) handle
78{
79    fToolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
80    [fToolbar setDelegate: self];
81    [fToolbar setAllowsUserCustomization: NO];
82    [[self window] setToolbar: fToolbar];
83    [fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
84    [fToolbar setSizeMode: NSToolbarSizeModeRegular];
85
86    [fToolbar setSelectedItemIdentifier: TOOLBAR_GENERAL];
87    [self showGeneralPref: nil];
88
89    fDefaults = [NSUserDefaults standardUserDefaults];
90    fHandle = handle;
91   
92    //set download folder
93    NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
94    fDownloadFolder = [[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath];
95    [fDownloadFolder retain];
96
97    if ([downloadChoice isEqualToString: @"Constant"])
98        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
99    else if ([downloadChoice isEqualToString: @"Torrent"])
100        [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
101    else
102        [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
103    [self updatePopUp];
104
105    //set bind port
106    int bindPort = [fDefaults integerForKey: @"BindPort"];
107    [fPortField setIntValue: bindPort];
108    tr_setBindPort(fHandle, bindPort);
109   
110    //checks for old version upload speed of -1
111    if ([fDefaults integerForKey: @"UploadLimit"] < 0)
112    {
113        [fDefaults setInteger: 20 forKey: @"UploadLimit"];
114        [fDefaults setBool: NO forKey: @"CheckUpload"];
115    }
116   
117    //set upload limit
118    BOOL checkUpload = [fDefaults boolForKey: @"CheckUpload"];
119    int uploadLimit = [fDefaults integerForKey: @"UploadLimit"];
120   
121    [fUploadCheck setState: checkUpload];
122    [fUploadField setIntValue: uploadLimit];
123    [fUploadField setEnabled: checkUpload];
124   
125    tr_setUploadLimit(fHandle, checkUpload ? uploadLimit : -1);
126
127        //set download limit
128    BOOL checkDownload = [fDefaults boolForKey: @"CheckDownload"];
129    int downloadLimit = [fDefaults integerForKey: @"DownloadLimit"];
130   
131    [fDownloadCheck setState: checkDownload];
132    [fDownloadField setIntValue: downloadLimit];
133    [fDownloadField setEnabled: checkDownload];
134   
135    tr_setDownloadLimit(fHandle, checkDownload ? downloadLimit : -1);
136   
137    //set ratio limit
138    BOOL ratioCheck = [fDefaults boolForKey: @"RatioCheck"];
139    [fRatioCheck setState: ratioCheck];
140    [fRatioField setEnabled: ratioCheck];
141    [fRatioField setFloatValue: [fDefaults floatForKey: @"RatioLimit"]];
142   
143    //set remove and quit prompts
144    BOOL isQuitCheck = [fDefaults boolForKey: @"CheckQuit"],
145        isRemoveCheck = [fDefaults boolForKey: @"CheckRemove"];
146   
147    [fQuitCheck setState: isQuitCheck];
148    [fRemoveCheck setState: isRemoveCheck];
149   
150    [fQuitDownloadingCheck setState: [fDefaults boolForKey: @"CheckQuitDownloading"]];
151    [fQuitDownloadingCheck setEnabled: isQuitCheck];
152    [fRemoveDownloadingCheck setState: [fDefaults boolForKey: @"CheckRemoveDownloading"]];
153    [fRemoveDownloadingCheck setEnabled: isRemoveCheck];
154
155    //set dock badging
156    [fBadgeDownloadRateCheck setState: [fDefaults boolForKey: @"BadgeDownloadRate"]];
157    [fBadgeUploadRateCheck setState: [fDefaults boolForKey: @"BadgeUploadRate"]];
158   
159    //set start setting
160    NSString * startSetting = [fDefaults stringForKey: @"StartSetting"];
161    int tag;
162    if ([startSetting isEqualToString: @"Start"])
163        tag = START_YES_CHECK_TAG;
164    else if ([startSetting isEqualToString: @"Wait"])
165        tag = START_WAIT_CHECK_TAG;
166    else
167        tag = START_NO_CHECK_TAG;
168   
169    [fStartMatrix selectCellWithTag: tag];
170    [fWaitToStartField setEnabled: tag == START_WAIT_CHECK_TAG];
171    [fWaitToStartField setIntValue: [fDefaults integerForKey: @"WaitToStartNumber"]];
172   
173    //set private torrents
174    BOOL copyTorrents = [fDefaults boolForKey: @"SavePrivateTorrent"];
175    [fCopyTorrentCheck setState: copyTorrents];
176   
177    [fDeleteOriginalTorrentCheck setEnabled: copyTorrents];
178    [fDeleteOriginalTorrentCheck setState: [fDefaults boolForKey: @"DeleteOriginalTorrent"]];
179
180    //set update check
181    NSString * updateCheck = [fDefaults stringForKey: @"UpdateCheck"];
182    if ([updateCheck isEqualToString: @"Weekly"])
183        [fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
184    else if ([updateCheck isEqualToString: @"Never"])
185        [fUpdatePopUp selectItemAtIndex: UPDATE_NEVER];
186    else
187        [fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
188}
189
190- (NSToolbarItem *) toolbar: (NSToolbar *) t itemForItemIdentifier:
191    (NSString *) ident willBeInsertedIntoToolbar: (BOOL) flag
192{
193    NSToolbarItem * item;
194    item = [[NSToolbarItem alloc] initWithItemIdentifier: ident];
195
196    if ([ident isEqualToString: TOOLBAR_GENERAL])
197    {
198        [item setLabel: TOOLBAR_GENERAL];
199        [item setImage: [NSImage imageNamed: @"Preferences.png"]];
200        [item setTarget: self];
201        [item setAction: @selector( showGeneralPref: )];
202    }
203    else if ([ident isEqualToString: TOOLBAR_TRANSFERS])
204    {
205        [item setLabel: TOOLBAR_TRANSFERS];
206        [item setImage: [NSImage imageNamed: @"Transfers.png"]];
207        [item setTarget: self];
208        [item setAction: @selector( showTransfersPref: )];
209    }
210    else if ([ident isEqualToString: TOOLBAR_BANDWIDTH])
211    {
212        [item setLabel: TOOLBAR_BANDWIDTH];
213        [item setImage: [NSImage imageNamed: @"Bandwidth.png"]];
214        [item setTarget: self];
215        [item setAction: @selector( showBandwidthPref: )];
216    }
217    else if ([ident isEqualToString: TOOLBAR_NETWORK])
218    {
219        [item setLabel: TOOLBAR_NETWORK];
220        [item setImage: [NSImage imageNamed: @"Network.png"]];
221        [item setTarget: self];
222        [item setAction: @selector( showNetworkPref: )];
223    }
224    else
225    {
226        [item release];
227        return nil;
228    }
229
230    return item;
231}
232
233- (NSArray *) toolbarSelectableItemIdentifiers: (NSToolbar *) toolbar
234{
235    return [self toolbarDefaultItemIdentifiers: toolbar];
236}
237
238- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *) toolbar
239{
240    return [self toolbarAllowedItemIdentifiers: toolbar];
241}
242
243- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *) toolbar
244{
245    return [NSArray arrayWithObjects:
246            TOOLBAR_GENERAL, TOOLBAR_TRANSFERS,
247            TOOLBAR_BANDWIDTH, TOOLBAR_NETWORK, nil];
248}
249
250- (void) setPort: (id) sender
251{
252    int bindPort = [sender intValue];
253    if (![[NSString stringWithInt: bindPort] isEqualToString: [sender stringValue]]
254            || bindPort < MIN_PORT || bindPort > MAX_PORT)
255    {
256        NSBeep();
257        bindPort = [fDefaults integerForKey: @"BindPort"];
258        [sender setIntValue: bindPort];
259    }
260    else
261    {
262        tr_setBindPort( fHandle, bindPort );
263        [fDefaults setInteger: bindPort forKey: @"BindPort"];
264    }
265}
266
267- (void) setLimit: (id) sender
268{
269    NSString * key;
270    NSButton * check;
271    NSString * type;
272    if (sender == fUploadField)
273    {
274        key = @"UploadLimit";
275        check = fUploadCheck;
276        type = @"Upload";
277    }
278    else
279    {
280        key = @"DownloadLimit";
281        check = fDownloadCheck;
282        type = @"Download";
283    }
284
285    int limit = [sender intValue];
286    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%d", limit]]
287            || limit < 0)
288    {
289        NSBeep();
290        limit = [fDefaults integerForKey: key];
291        [sender setIntValue: limit];
292    }
293    else
294    {
295        if (sender == fUploadField)
296            tr_setUploadLimit(fHandle, [fUploadCheck state] == NSOffState ? -1 : limit);
297        else
298            tr_setDownloadLimit(fHandle, [fDownloadCheck state] == NSOffState ? -1 : limit);
299       
300        [fDefaults setInteger: limit forKey: key];
301    }
302   
303    NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
304                                    [NSNumber numberWithBool: [check state]], @"Enable",
305                                    [NSNumber numberWithInt: limit], @"Limit",
306                                    type, @"Type", nil];
307    [[NSNotificationCenter defaultCenter] postNotificationName: @"LimitGlobalChange" object: dict];
308}
309
310- (void) setLimitCheck: (id) sender
311{
312    NSString * key;
313    NSTextField * field;
314    if (sender == fUploadCheck)
315    {
316        key = @"CheckUpload";
317        field = fUploadField;
318    }
319    else
320    {
321        key = @"CheckDownload";
322        field = fDownloadField;
323    }
324   
325    BOOL check = [sender state] == NSOnState;
326    [self setLimit: field];
327    [field setEnabled: check];
328   
329    [fDefaults setBool: check forKey: key];
330}
331
332- (void) setLimitEnabled: (BOOL) enable type: (NSString *) type
333{
334    NSButton * check = [type isEqualToString: @"Upload"] ? fUploadCheck : fDownloadCheck;
335    [check setState: enable ? NSOnState : NSOffState];
336    [self setLimitCheck: check];
337}
338
339- (void) setQuickLimit: (int) limit type: (NSString *) type
340{
341    NSButton * check;
342    if ([type isEqualToString: @"Upload"])
343    {
344        [fUploadField setIntValue: limit];
345        check = fUploadCheck;
346    }
347    else
348    {
349        [fDownloadField setIntValue: limit];
350        check = fDownloadCheck;
351    }
352    [check setState: NSOnState];
353    [self setLimitCheck: check];
354}
355
356- (void) setRatio: (id) sender
357{
358    float ratioLimit = [sender floatValue];
359    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%.2f", ratioLimit]]
360            || ratioLimit < 0)
361    {
362        NSBeep();
363        ratioLimit = [fDefaults floatForKey: @"RatioLimit"];
364        [sender setFloatValue: ratioLimit];
365    }
366    else
367        [fDefaults setFloat: ratioLimit forKey: @"RatioLimit"];
368   
369    NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:
370                                    [NSNumber numberWithBool: [fRatioCheck state]], @"Enable",
371                                    [NSNumber numberWithFloat: ratioLimit], @"Ratio", nil];
372    [[NSNotificationCenter defaultCenter] postNotificationName: @"RatioGlobalChange" object: dict];
373}
374
375- (void) setRatioCheck: (id) sender
376{
377    BOOL check = [sender state] == NSOnState;
378    [self setRatio: fRatioField];
379    [fRatioField setEnabled: check];
380   
381    [fDefaults setBool: check forKey: @"RatioCheck"];
382}
383
384- (void) setRatioEnabled: (BOOL) enable
385{
386    int state = enable ? NSOnState : NSOffState;
387   
388    [fRatioCheck setState: state];
389    [self setRatioCheck: fRatioCheck];
390}
391
392- (void) setQuickRatio: (float) ratioLimit
393{
394    [fRatioField setFloatValue: ratioLimit];
395   
396    [fRatioCheck setState: NSOnState];
397    [self setRatioCheck: fRatioCheck];
398}
399
400- (void) setShowMessage: (id) sender
401{
402    BOOL state = [sender state];
403
404    if (sender == fQuitCheck)
405    {
406        [fDefaults setBool: state forKey: @"CheckQuit"];
407        [fQuitDownloadingCheck setEnabled: state];
408    }
409    else if (sender == fRemoveCheck)
410    {
411        [fDefaults setBool: state forKey: @"CheckRemove"];
412        [fRemoveDownloadingCheck setEnabled: state];
413    }
414    if (sender == fQuitDownloadingCheck)
415        [fDefaults setBool: state forKey: @"CheckQuitDownloading"];
416    else if (sender == fRemoveDownloadingCheck)
417        [fDefaults setBool: state forKey: @"CheckRemoveDownloading"];
418    else;
419}
420
421- (void) setBadge: (id) sender
422{   
423    if (sender == fBadgeDownloadRateCheck)
424        [fDefaults setBool: [sender state] forKey: @"BadgeDownloadRate"];
425    else if (sender == fBadgeUploadRateCheck)
426        [fDefaults setBool: [sender state] forKey: @"BadgeUploadRate"];
427    else;
428}
429
430- (void) setUpdate: (id) sender
431{
432    int index = [fUpdatePopUp indexOfSelectedItem];
433    NSTimeInterval seconds;
434    if (index == UPDATE_DAILY)
435    {
436        [fDefaults setObject: @"Daily" forKey: @"UpdateCheck"];
437        seconds = 86400;
438    }
439    else if (index == UPDATE_WEEKLY)
440    {
441        [fDefaults setObject: @"Weekly" forKey: @"UpdateCheck"];
442        seconds = 604800;
443    }
444    else
445    {
446        [fDefaults setObject: @"Never" forKey: @"UpdateCheck"];
447        seconds = 0;
448    }
449
450    [fDefaults setInteger: seconds forKey: @"SUScheduledCheckInterval"];
451    [fUpdater scheduleCheckWithInterval: seconds];
452}
453
454- (void) setStartSetting: (id) sender
455{
456    NSString * startSetting;
457
458    int tag = [[fStartMatrix selectedCell] tag];
459    if (tag == START_YES_CHECK_TAG)
460        startSetting = @"Start";
461    else if (tag == START_WAIT_CHECK_TAG)
462        startSetting = @"Wait";
463    else
464        startSetting = @"Manual";
465   
466    [fDefaults setObject: startSetting forKey: @"StartSetting"];
467   
468    [self setWaitToStart: fWaitToStartField];
469    [fWaitToStartField setEnabled: tag == START_WAIT_CHECK_TAG];
470}
471
472- (void) setWaitToStart: (id) sender
473{
474    int waitNumber = [sender intValue];
475    if (![[sender stringValue] isEqualToString: [NSString stringWithInt: waitNumber]] || waitNumber < 1)
476    {
477        NSBeep();
478        waitNumber = [fDefaults floatForKey: @"WaitToStartNumber"];
479        [sender setIntValue: waitNumber];
480    }
481    else
482        [fDefaults setInteger: waitNumber forKey: @"WaitToStartNumber"];
483   
484    [[NSNotificationCenter defaultCenter] postNotificationName: @"GlobalStartSettingChange" object: self];
485}
486
487- (void) setMoveTorrent: (id) sender
488{
489    int state = [sender state];
490    if (sender == fCopyTorrentCheck)
491    {
492        [fDefaults setBool: state forKey: @"SavePrivateTorrent"];
493       
494        [fDeleteOriginalTorrentCheck setEnabled: state];
495        if (state == NSOffState)
496        {
497            [fDeleteOriginalTorrentCheck setState: NSOffState];
498            [fDefaults setBool: NO forKey: @"DeleteOriginalTorrent"];
499        }
500    }
501    else
502        [fDefaults setBool: state forKey: @"DeleteOriginalTorrent"];
503}
504
505- (void) setDownloadLocation: (id) sender
506{
507    //Download folder
508    switch ([fFolderPopUp indexOfSelectedItem])
509    {
510        case DOWNLOAD_FOLDER:
511            [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
512            break;
513        case DOWNLOAD_TORRENT:
514            [fDefaults setObject: @"Torrent" forKey: @"DownloadChoice"];
515            break;
516        case DOWNLOAD_ASK:
517            [fDefaults setObject: @"Ask" forKey: @"DownloadChoice"];
518            break;
519    }
520}
521
522- (void) checkUpdate
523{
524    [fUpdater checkForUpdates: nil];
525}
526
527- (void) folderSheetShow: (id) sender
528{
529    NSOpenPanel * panel = [NSOpenPanel openPanel];
530
531    [panel setPrompt: @"Select"];
532    [panel setAllowsMultipleSelection: NO];
533    [panel setCanChooseFiles: NO];
534    [panel setCanChooseDirectories: YES];
535    [panel setCanCreateDirectories: YES];
536
537    [panel beginSheetForDirectory: nil file: nil types: nil
538        modalForWindow: [self window] modalDelegate: self didEndSelector:
539        @selector( folderSheetClosed:returnCode:contextInfo: )
540        contextInfo: nil];
541}
542
543@end
544
545@implementation PrefsController (Private)
546
547- (void) showGeneralPref: (id) sender
548{
549    [self setPrefView: fGeneralView];
550}
551
552- (void) showTransfersPref: (id) sender
553{
554    [self setPrefView: fTransfersView];
555}
556
557- (void) showBandwidthPref: (id) sender
558{
559    [self setPrefView: fBandwidthView];
560}
561
562- (void) showNetworkPref: (id) sender
563{
564    [self setPrefView: fNetworkView];
565}
566
567- (void) setPrefView: (NSView *) view
568{
569    NSWindow * window = [self window];
570   
571    NSRect windowRect = [window frame];
572    int difference = [view frame].size.height - [[window contentView] frame].size.height;
573    windowRect.origin.y -= difference;
574    windowRect.size.height += difference;
575
576    [window setTitle: [fToolbar selectedItemIdentifier]];
577   
578    [window setContentView: view];
579    [view setHidden: YES];
580    [window setFrame: windowRect display: YES animate: YES];
581    [view setHidden: NO];
582}
583
584- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code contextInfo: (void *) info
585{
586   if (code == NSOKButton)
587   {
588       [fDownloadFolder release];
589       fDownloadFolder = [[openPanel filenames] objectAtIndex: 0];
590       [fDownloadFolder retain];
591
592       [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
593       [fDefaults setObject: fDownloadFolder forKey: @"DownloadFolder"];
594       [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
595
596       [self updatePopUp];
597   }
598   else
599   {
600       //reset if cancelled
601       NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
602       if ([downloadChoice isEqualToString: @"Constant"])
603           [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
604       else if ([downloadChoice isEqualToString: @"Torrent"])
605           [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
606       else
607           [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
608   }
609}
610
611- (void) updatePopUp
612{
613    //get and resize the icon
614    NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFile: fDownloadFolder];
615    [icon setScalesWhenResized: YES];
616    [icon setSize: NSMakeSize(16.0, 16.0)];
617
618    //update menu item
619    NSMenuItem * menuItem = (NSMenuItem *) [fFolderPopUp itemAtIndex: 0];
620    [menuItem setTitle: [fDownloadFolder lastPathComponent]];
621    [menuItem setImage: icon];
622}
623
624@end
Note: See TracBrowser for help on using the repository browser.