source: trunk/macosx/PrefsController.m @ 247

Last change on this file since 247 was 247, checked in by titer, 16 years ago

Adds Action button that allows quick setting of upload and download limits,
Makes the bottom bar look like Mail's,
Moves stats to a top, hideable bar.

File size: 15.3 KB
Line 
1/******************************************************************************
2 * Copyright (c) 2005-2006 Transmission authors and contributors
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 *****************************************************************************/
22
23#import "PrefsController.h"
24#import "StringAdditions.h"
25#import "Utils.h"
26
27#define MIN_PORT            1
28#define MAX_PORT            65535
29
30#define DOWNLOAD_FOLDER     0
31#define DOWNLOAD_TORRENT    2
32#define DOWNLOAD_ASK        3
33
34#define UPDATE_DAILY        0
35#define UPDATE_WEEKLY       1
36#define UPDATE_NEVER        2
37
38#define TOOLBAR_GENERAL     @"General"
39#define TOOLBAR_NETWORK     @"Network"
40
41@interface PrefsController (Private)
42
43- (void) showGeneralPref: (id) sender;
44- (void) showNetworkPref: (id) sender;
45
46- (void) setPrefView: (NSView *) view;
47
48- (void) folderSheetClosed: (NSOpenPanel *) s returnCode: (int) code
49                                contextInfo: (void *) info;
50- (void) updatePopUp;
51
52@end
53
54@implementation PrefsController
55
56+ (void) initialize
57{
58    [[NSUserDefaults standardUserDefaults] registerDefaults:
59        [NSDictionary dictionaryWithContentsOfFile:
60            [[NSBundle mainBundle] pathForResource: @"Defaults"
61                ofType: @"plist"]]];
62}
63
64- (void)dealloc
65{
66    [fDownloadFolder release];
67    [super dealloc];
68}
69
70- (void) setPrefsWindow: (tr_handle_t *) handle
71{
72    fToolbar = [[NSToolbar alloc] initWithIdentifier: @"Preferences Toolbar"];
73    [fToolbar setDelegate: self];
74    [fToolbar setAllowsUserCustomization: NO];
75    [fPrefsWindow setToolbar: fToolbar];
76    [fToolbar setDisplayMode: NSToolbarDisplayModeIconAndLabel];
77    [fToolbar setSizeMode: NSToolbarSizeModeRegular];
78    [[fPrefsWindow standardWindowButton: NSWindowToolbarButton]
79        setFrame: NSZeroRect];
80
81    if( [fToolbar respondsToSelector: @selector(setSelectedItemIdentifier:) ] )
82        [fToolbar setSelectedItemIdentifier: TOOLBAR_GENERAL];
83    [self setPrefView: fGeneralView];
84
85    fDefaults = [NSUserDefaults standardUserDefaults];
86   
87    //set download folder
88    NSString * downloadChoice  = [fDefaults stringForKey: @"DownloadChoice"];
89    fDownloadFolder = [[fDefaults stringForKey: @"DownloadFolder"] stringByExpandingTildeInPath];
90    [fDownloadFolder retain];
91
92    if( [downloadChoice isEqualToString: @"Constant"] )
93    {
94        [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
95    }
96    else if( [downloadChoice isEqualToString: @"Torrent"] )
97    {
98        [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
99    }
100    else
101    {
102        [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
103    }
104    [self updatePopUp];
105
106    //set bind port
107    int bindPort = [fDefaults integerForKey: @"BindPort"];
108    [fPortField setIntValue: bindPort];
109    fHandle = handle;
110    tr_setBindPort( fHandle, bindPort );
111   
112    //checks for old version upload speed of -1
113    if ([fDefaults integerForKey: @"UploadLimit"] < 0)
114    {
115        [fDefaults setInteger: 20 forKey: @"UploadLimit"];
116        [fDefaults setBool: NO forKey: @"CheckUpload"];
117    }
118   
119    //set upload limit
120    BOOL checkUpload = [fDefaults boolForKey: @"CheckUpload"];
121    int uploadLimit = [fDefaults integerForKey: @"UploadLimit"];
122   
123    [fUploadCheck setState: checkUpload ? NSOnState : NSOffState];
124    [fUploadField setIntValue: uploadLimit];
125    [fUploadField setEnabled: checkUpload];
126   
127    [fUploadLimitItem setTitle:
128                [NSString stringWithFormat: @"Limit (%d KB/s)", uploadLimit]];
129    if (checkUpload)
130        [fUploadLimitItem setState: NSOnState];
131    else
132        [fUploadNoLimitItem setState: NSOnState];
133   
134    tr_setUploadLimit( fHandle, checkUpload ? uploadLimit : -1 );
135
136    //set download limit
137    BOOL checkDownload = [fDefaults boolForKey: @"CheckDownload"];
138    int downloadLimit = [fDefaults integerForKey: @"DownloadLimit"];
139   
140    [fDownloadCheck setState: checkDownload ? NSOnState : NSOffState];
141    [fDownloadField setIntValue: downloadLimit];
142    [fDownloadField setEnabled: checkDownload];
143   
144    [fDownloadLimitItem setTitle:
145                [NSString stringWithFormat: @"Limit (%d KB/s)", downloadLimit]];
146    if (checkDownload)
147        [fDownloadLimitItem setState: NSOnState];
148    else
149        [fDownloadNoLimitItem setState: NSOnState];
150   
151    tr_setDownloadLimit( fHandle, checkDownload ? downloadLimit : -1 );
152   
153    //set remove and quit prompts
154    [fQuitCheck setState: [fDefaults boolForKey: @"CheckQuit"] ?
155        NSOnState : NSOffState];
156    [fRemoveCheck setState: [fDefaults boolForKey: @"CheckRemove"] ?
157        NSOnState : NSOffState];
158
159    //set dock badging
160    [fBadgeDownloadRateCheck setState: [fDefaults boolForKey: @"BadgeDownloadRate"]];
161    [fBadgeUploadRateCheck setState: [fDefaults boolForKey: @"BadgeUploadRate"]];
162
163    /* Check for update */
164    NSString * versionCheck  = [fDefaults stringForKey: @"VersionCheck"];
165    if( [versionCheck isEqualToString: @"Daily"] )
166        [fUpdatePopUp selectItemAtIndex: UPDATE_DAILY];
167    else if( [versionCheck isEqualToString: @"Weekly"] )
168        [fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
169    else if( [versionCheck isEqualToString: @"Never"] )
170        [fUpdatePopUp selectItemAtIndex: UPDATE_NEVER];
171    else
172    {
173        [fDefaults setObject: @"Weekly" forKey: @"VersionCheck"];
174        [fUpdatePopUp selectItemAtIndex: UPDATE_WEEKLY];
175    }
176}
177
178- (NSToolbarItem *) toolbar: (NSToolbar *) t itemForItemIdentifier:
179    (NSString *) ident willBeInsertedIntoToolbar: (BOOL) flag
180{
181    NSToolbarItem * item;
182    item = [[NSToolbarItem alloc] initWithItemIdentifier: ident];
183
184    if ([ident isEqualToString: TOOLBAR_GENERAL])
185    {
186        [item setLabel: TOOLBAR_GENERAL];
187        [item setImage: [NSImage imageNamed: @"Preferences.png"]];
188        [item setTarget: self];
189        [item setAction: @selector( showGeneralPref: )];
190    }
191    else if ([ident isEqualToString: TOOLBAR_NETWORK])
192    {
193        [item setLabel: TOOLBAR_NETWORK];
194        [item setImage: [NSImage imageNamed: @"Network.png"]];
195        [item setTarget: self];
196        [item setAction: @selector( showNetworkPref: )];
197    }
198    else
199    {
200        [item release];
201        return nil;
202    }
203
204    return item;
205}
206
207/* Only used on OS X >= 10.3 */
208- (NSArray *) toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar
209{
210    return [self toolbarDefaultItemIdentifiers: nil];
211}
212
213- (NSArray *) toolbarDefaultItemIdentifiers: (NSToolbar *)toolbar
214{
215    return [self toolbarAllowedItemIdentifiers: nil];
216}
217
218- (NSArray *) toolbarAllowedItemIdentifiers: (NSToolbar *)toolbar
219{
220    return [NSArray arrayWithObjects:
221            TOOLBAR_GENERAL,
222            TOOLBAR_NETWORK,
223            nil];
224}
225
226- (void) setPort: (id) sender
227{
228    int bindPort = [fPortField intValue];
229   
230    //if value entered is not an int or is not in range do not change
231    if (![[fPortField stringValue] isEqualToString:
232            [NSString stringWithInt: bindPort]]
233            || bindPort < MIN_PORT
234            || bindPort > MAX_PORT)
235    {
236        NSBeep();
237        bindPort = [fDefaults integerForKey: @"BindPort"];
238        [fPortField setIntValue: bindPort];
239    }
240    else
241    {
242        tr_setBindPort( fHandle, bindPort );
243        [fDefaults setInteger: bindPort forKey: @"BindPort"];
244    }
245}
246
247- (void) setLimit: (id) sender
248{
249    int limit = [sender intValue];
250   
251    NSString * key;
252    NSMenuItem * menuItem;
253    if (sender == fUploadField)
254    {
255        key = @"UploadLimit";
256        menuItem = fUploadLimitItem;
257    }
258    else
259    {
260        key = @"DownloadLimit";
261        menuItem = fDownloadLimitItem;
262    }
263
264    //if value entered is not an int or is less than 0 do not change
265    if (![[sender stringValue] isEqualToString:
266            [NSString stringWithInt: limit]] || limit < 0)
267    {
268        NSBeep();
269        limit = [fDefaults integerForKey: key];
270        [sender setIntValue: limit];
271    }
272    else
273    {
274        [menuItem setTitle: [NSString stringWithFormat: @"Limit (%d KB/s)", limit]];
275        [fDefaults setInteger: limit forKey: key];
276    }
277
278    if( sender == fUploadField )
279        tr_setUploadLimit( fHandle,
280            ( [fUploadCheck state] == NSOffState ) ? -1 : limit );
281    else
282        tr_setDownloadLimit( fHandle,
283            ( [fDownloadCheck state] == NSOffState ) ? -1 : limit );
284}
285
286- (void) setLimitCheck: (id) sender
287{
288    NSString * key;
289    NSTextField * field;
290    NSMenuItem * limitItem, * noLimitItem;
291    if( sender == fUploadCheck )
292    {
293        key = @"CheckUpload";
294        field = fUploadField;
295        limitItem = fUploadLimitItem;
296        noLimitItem = fUploadNoLimitItem;
297    }
298    else
299    {
300        key = @"CheckDownload";
301        field = fDownloadField;
302        limitItem = fDownloadLimitItem;
303        noLimitItem = fDownloadNoLimitItem;
304    }
305
306    BOOL check = [sender state] == NSOnState;
307    [limitItem setState: check ? NSOnState : NSOffState];
308    [noLimitItem setState: !check ? NSOnState : NSOffState];
309   
310    [fDefaults setBool: check forKey: key];
311
312    [self setLimit: field];
313   
314    [field setEnabled: check];
315}
316
317- (void) setLimitMenu: (id) sender
318{
319    NSButton * check = (sender == fUploadLimitItem || sender == fUploadNoLimitItem)
320                        ? fUploadCheck : fDownloadCheck;
321    int state = (sender == fUploadLimitItem || sender == fDownloadLimitItem)
322                    ? NSOnState : NSOffState;
323               
324    [check setState: state];
325    [self setLimitCheck: check];
326}
327
328- (void) setQuickSpeed: (id) sender
329{
330    NSString * title = [sender title];
331    int limit = [[title substringToIndex: [title length] - [@" KB/s" length]] intValue];
332   
333    if ([sender menu] == fUploadMenu)
334    {
335        [fUploadField setIntValue: limit];
336        [self setLimitMenu: fUploadLimitItem];
337    }
338    else
339    {
340        [fDownloadField setIntValue: limit];
341        [self setLimitMenu: fDownloadLimitItem];
342    }
343}
344
345- (void) setQuitMessage: (id) sender
346{
347    [fDefaults setBool: ( [fQuitCheck state] == NSOnState )
348        forKey: @"CheckQuit"];
349}
350
351- (void) setRemoveMessage: (id) sender
352{
353    [fDefaults setBool: ( [fRemoveCheck state] == NSOnState )
354        forKey: @"CheckRemove"];
355}
356
357- (void) setBadge: (id) sender
358{   
359    BOOL state = [sender state];
360   
361    if (sender == fBadgeDownloadRateCheck)
362        [fDefaults setBool: state forKey: @"BadgeDownloadRate"];
363    else if (sender == fBadgeUploadRateCheck)
364        [fDefaults setBool: state forKey: @"BadgeUploadRate"];
365    else;
366}
367
368- (void) setUpdate: (id) sender
369{
370    switch( [fUpdatePopUp indexOfSelectedItem] )
371    {
372        case UPDATE_DAILY:
373            [fDefaults setObject: @"Daily" forKey: @"VersionCheck"];
374            break;
375        case UPDATE_WEEKLY:
376            [fDefaults setObject: @"Weekly" forKey: @"VersionCheck"];
377            break;
378        case UPDATE_NEVER:
379            [fDefaults setObject: @"Never" forKey: @"VersionCheck"];
380            break;
381    }
382}
383
384- (void) setDownloadLocation: (id) sender
385{
386    //Download folder
387    switch( [fFolderPopUp indexOfSelectedItem] )
388    {
389        case DOWNLOAD_FOLDER:
390            [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
391            break;
392        case DOWNLOAD_TORRENT:
393            [fDefaults setObject: @"Torrent" forKey: @"DownloadChoice"];
394            break;
395        case DOWNLOAD_ASK:
396            [fDefaults setObject: @"Ask" forKey: @"DownloadChoice"];
397            break;
398    }
399}
400
401- (void) folderSheetShow: (id) sender
402{
403    NSOpenPanel * panel = [NSOpenPanel openPanel];
404
405    [panel setPrompt:                  @"Select"];
406    [panel setAllowsMultipleSelection:        NO];
407    [panel setCanChooseFiles:                 NO];
408    [panel setCanChooseDirectories:          YES];
409
410    [panel beginSheetForDirectory: NULL file: NULL types: NULL
411        modalForWindow: fPrefsWindow modalDelegate: self didEndSelector:
412        @selector( folderSheetClosed:returnCode:contextInfo: )
413        contextInfo: NULL];
414}
415
416@end // @implementation PrefsController
417
418@implementation PrefsController (Private)
419
420- (void) showGeneralPref: (id) sender
421{
422    [self setPrefView: fGeneralView];
423}
424
425- (void) showNetworkPref: (id) sender
426{
427    [self setPrefView: fNetworkView];
428}
429
430- (void) setPrefView: (NSView *) view
431{
432    NSRect windowRect = [fPrefsWindow frame];
433    int difference = [view frame].size.height - [[fPrefsWindow contentView] frame].size.height;
434
435    windowRect.origin.y -= difference;
436    windowRect.size.height += difference;
437   
438    if( [fToolbar respondsToSelector: @selector(selectedItemIdentifier) ] )
439        [fPrefsWindow setTitle: [fToolbar selectedItemIdentifier]];
440    [fPrefsWindow setContentView: fBlankView];
441    [fPrefsWindow setFrame:windowRect display: YES animate: YES];
442    [fPrefsWindow setContentView: view];
443}
444
445- (void) folderSheetClosed: (NSOpenPanel *) openPanel returnCode: (int) code
446    contextInfo: (void *) info
447{
448   if (code == NSOKButton)
449   {
450       [fDownloadFolder release];
451       fDownloadFolder = [[openPanel filenames] objectAtIndex: 0];
452       [fDownloadFolder retain];
453
454       [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
455       [fDefaults setObject: fDownloadFolder forKey: @"DownloadFolder"];
456       [fDefaults setObject: @"Constant" forKey: @"DownloadChoice"];
457
458       [self updatePopUp];
459   }
460   else
461   {
462       //reset if cancelled
463       NSString * downloadChoice = [fDefaults stringForKey: @"DownloadChoice"];
464       if( [downloadChoice isEqualToString: @"Constant"] )
465       {
466           [fFolderPopUp selectItemAtIndex: DOWNLOAD_FOLDER];
467       }
468       else if( [downloadChoice isEqualToString: @"Torrent"] )
469       {
470           [fFolderPopUp selectItemAtIndex: DOWNLOAD_TORRENT];
471       }
472       else
473       {
474           [fFolderPopUp selectItemAtIndex: DOWNLOAD_ASK];
475       }
476   }
477}
478
479- (void) updatePopUp
480{
481    NSMenuItem     * menuItem;
482    NSImage        * image32, * image16;
483
484    // Get the icon for the folder
485    image32 = [[NSWorkspace sharedWorkspace] iconForFile:
486                fDownloadFolder];
487    image16 = [[NSImage alloc] initWithSize: NSMakeSize(16,16)];
488
489    // 32x32 -> 16x16 scaling
490    [image16 lockFocus];
491    [[NSGraphicsContext currentContext]
492        setImageInterpolation: NSImageInterpolationHigh];
493    [image32 drawInRect: NSMakeRect(0,0,16,16)
494        fromRect: NSMakeRect(0,0,32,32) operation: NSCompositeCopy
495        fraction: 1.0];
496    [image16 unlockFocus];
497
498    // Update the menu item
499    menuItem = (NSMenuItem *) [fFolderPopUp itemAtIndex: 0];
500    [menuItem setTitle: [fDownloadFolder lastPathComponent]];
501    [menuItem setImage: image16];
502
503    [image16 release];
504}
505
506@end /* @implementation PrefsController (Private) */
Note: See TracBrowser for help on using the repository browser.