source: trunk/macosx/PrefsController.m @ 272

Last change on this file since 272 was 272, checked in by livings124, 17 years ago

First commit on my own 8-)

Sorting by progress, sorting no longer causes crashes.
New look for the table.
Info is now inspector: can set individual and multiple ratio limits, shows listing of files, more info in general, resizes when changing tabs, can change tabs with cmd-left and cmd-right.
Menu items moved to "Transfers" menu.
Sliding status bar in its own view.
Prefs moved into their own nib.
Toolbar items for pause and resume selected (many wanted this, but it needs better icons)
New icons for Transfers and General.
A lot of tweaking of main window to fix alignment etc.
Sparkle used for updated (still needs to be added to website to work).

And a lot more tweaking and changes that I'm too lazy to list.

...now let's hope I commit this right

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