transmission 2.51 update
[tomato.git] / release / src / router / transmission / macosx / AddWindowController.m
blob049b8477876e7e009962cb3e7033b525a9b07f6e
1 /******************************************************************************
2  * $Id: AddWindowController.m 13251 2012-03-13 02:52:11Z livings124 $
3  *
4  * Copyright (c) 2008-2012 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  *****************************************************************************/
25 #import "AddWindowController.h"
26 #import "Controller.h"
27 #import "ExpandedPathToIconTransformer.h"
28 #import "FileOutlineController.h"
29 #import "GroupsController.h"
30 #import "NSStringAdditions.h"
31 #import "Torrent.h"
33 #define UPDATE_SECONDS 1.0
35 #define POPUP_PRIORITY_HIGH 0
36 #define POPUP_PRIORITY_NORMAL 1
37 #define POPUP_PRIORITY_LOW 2
39 @interface AddWindowController (Private)
41 - (void) updateFiles;
43 - (void) confirmAdd;
45 - (void) setDestinationPath: (NSString *) destination;
47 - (void) setGroupsMenu;
48 - (void) changeGroupValue: (id) sender;
50 - (void) sameNameAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo;
52 @end
54 @implementation AddWindowController
56 - (id) initWithTorrent: (Torrent *) torrent destination: (NSString *) path lockDestination: (BOOL) lockDestination
57     controller: (Controller *) controller torrentFile: (NSString *) torrentFile
58     deleteTorrent: (BOOL) deleteTorrent canToggleDelete: (BOOL) canToggleDelete
60     if ((self = [super initWithWindowNibName: @"AddWindow"]))
61     {
62         fTorrent = torrent;
63         fDestination = [[path stringByExpandingTildeInPath] retain];
64         fLockDestination = lockDestination;
65         
66         fController = controller;
67         
68         fTorrentFile = [[torrentFile stringByExpandingTildeInPath] retain];
69         
70         fDeleteTorrentInitial = deleteTorrent;
71         fDeleteEnableInitial = canToggleDelete;
72         
73         fGroupValue = [torrent groupValue];
74         
75         [fVerifyIndicator setUsesThreadedAnimation: YES];
76     }
77     return self;
80 - (void) awakeFromNib
82     [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateStatusField:)
83         name: @"TorrentFileCheckChange" object: fTorrent];
84     
85     [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroupMenu:)
86         name: @"UpdateGroups" object: nil];
87     
88     [fFileController setTorrent: fTorrent];
89     
90     NSString * name = [fTorrent name];
91     [[self window] setTitle: name];
92     [fNameField setStringValue: name];
93     [fNameField setToolTip: name];
94     
95     [fIconView setImage: [fTorrent icon]];
96     
97     [self updateStatusField: nil];
98     
99     [self setGroupsMenu];
100     [fGroupPopUp selectItemWithTag: fGroupValue];
101     
102     NSInteger priorityIndex;
103     switch ([fTorrent priority])
104     {
105         case TR_PRI_HIGH: priorityIndex = POPUP_PRIORITY_HIGH; break;
106         case TR_PRI_NORMAL: priorityIndex = POPUP_PRIORITY_NORMAL; break;
107         case TR_PRI_LOW: priorityIndex = POPUP_PRIORITY_LOW; break;
108         default: NSAssert1(NO, @"Unknown priority for adding torrent: %d", [fTorrent priority]);
109     }
110     [fPriorityPopUp selectItemAtIndex: priorityIndex];
111     
112     [fStartCheck setState: [[NSUserDefaults standardUserDefaults] boolForKey: @"AutoStartDownload"] ? NSOnState : NSOffState];
113     
114     [fDeleteCheck setState: fDeleteTorrentInitial ? NSOnState : NSOffState];
115     [fDeleteCheck setEnabled: fDeleteEnableInitial];
116     
117     if (fDestination)
118         [self setDestinationPath: fDestination];
119     else
120     {
121         [fLocationField setStringValue: @""];
122         [fLocationImageView setImage: nil];
123     }
124     
125     fTimer = [NSTimer scheduledTimerWithTimeInterval: UPDATE_SECONDS target: self
126                 selector: @selector(updateFiles) userInfo: nil repeats: YES];
127     [self updateFiles];
130 - (void) windowDidLoad
132     //if there is no destination, prompt for one right away
133     if (!fDestination)
134         [self setDestination: nil];
137 - (void) dealloc
139     [[NSNotificationCenter defaultCenter] removeObserver: self];
140     
141     [fTimer invalidate];
142     
143     [fDestination release];
144     [fTorrentFile release];
145     
146     [super dealloc];
149 - (Torrent *) torrent
151     return fTorrent;
154 - (void) setDestination: (id) sender
156     NSOpenPanel * panel = [NSOpenPanel openPanel];
158     [panel setPrompt: NSLocalizedString(@"Select", "Open torrent -> prompt")];
159     [panel setAllowsMultipleSelection: NO];
160     [panel setCanChooseFiles: NO];
161     [panel setCanChooseDirectories: YES];
162     [panel setCanCreateDirectories: YES];
163     
164     [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the download folder for \"%@\"",
165                         "Add -> select destination folder"), [fTorrent name]]];
166     
167     [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) {
168         if (result == NSFileHandlingPanelOKButton)
169         {
170             fLockDestination = NO;
171             [self setDestinationPath: [[[panel URLs] objectAtIndex: 0] path]];
172         }
173         else
174         {
175             if (!fDestination)
176                 [self performSelectorOnMainThread: @selector(cancelAdd:) withObject: nil waitUntilDone: NO];
177         }
178     }];
181 - (void) add: (id) sender
183     if ([[fDestination lastPathComponent] isEqualToString: [fTorrent name]]
184         && [[NSUserDefaults standardUserDefaults] boolForKey: @"WarningFolderDataSameName"])
185     {
186         NSAlert * alert = [[NSAlert alloc] init];
187         [alert setMessageText: NSLocalizedString(@"The destination directory and root data directory have the same name.",
188                                 "Add torrent -> same name -> title")];
189         [alert setInformativeText: NSLocalizedString(@"If you are attempting to use already existing data,"
190             " the root data directory should be inside the destination directory.", "Add torrent -> same name -> message")];
191         [alert setAlertStyle: NSWarningAlertStyle];
192         [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Add torrent -> same name -> button")];
193         [alert addButtonWithTitle: NSLocalizedString(@"Add", "Add torrent -> same name -> button")];
194         [alert setShowsSuppressionButton: YES];
195         
196         [alert beginSheetModalForWindow: [self window] modalDelegate: self
197             didEndSelector: @selector(sameNameAlertDidEnd:returnCode:contextInfo:) contextInfo: nil];
198     }
199     else
200         [self confirmAdd];
203 - (void) cancelAdd: (id) sender
205     [[self window] performClose: sender];
208 //only called on cancel
209 - (BOOL) windowShouldClose: (id) window
211     [fTimer invalidate];
212     fTimer = nil;
213     
214     [fFileController setTorrent: nil]; //avoid a crash when window tries to update
215     
216     [fController askOpenConfirmed: self add: NO];
217     return YES;
220 - (void) verifyLocalData: (id) sender
222     [fTorrent resetCache];
223     [self updateFiles];
226 - (void) changePriority: (id) sender
228     tr_priority_t priority;
229     switch ([sender indexOfSelectedItem])
230     {
231         case POPUP_PRIORITY_HIGH: priority = TR_PRI_HIGH; break;
232         case POPUP_PRIORITY_NORMAL: priority = TR_PRI_NORMAL; break;
233         case POPUP_PRIORITY_LOW: priority = TR_PRI_LOW; break;
234         default: NSAssert1(NO, @"Unknown priority tag for adding torrent: %d", [sender tag]);
235     }
236     [fTorrent setPriority: priority];
239 - (void) updateStatusField: (NSNotification *) notification
241     NSString * statusString = [NSString stringForFileSize: [fTorrent size]];
242     if ([fTorrent isFolder])
243     {
244         NSString * fileString;
245         NSInteger count = [fTorrent fileCount];
246         if (count != 1)
247             fileString = [NSString stringWithFormat: NSLocalizedString(@"%@ files", "Add torrent -> info"),
248                             [NSString formattedUInteger: count]];
249         else
250             fileString = NSLocalizedString(@"1 file", "Add torrent -> info");
251         
252         NSString * selectedString = [NSString stringWithFormat: NSLocalizedString(@"%@ selected", "Add torrent -> info"),
253                                         [NSString stringForFileSize: [fTorrent totalSizeSelected]]];
254         
255         statusString = [NSString stringWithFormat: @"%@, %@ (%@)", fileString, statusString, selectedString];
256     }
257     
258     [fStatusField setStringValue: statusString];
261 - (void) updateGroupMenu: (NSNotification *) notification
263     [self setGroupsMenu];
264     if (![fGroupPopUp selectItemWithTag: fGroupValue])
265     {
266         fGroupValue = -1;
267         [fGroupPopUp selectItemWithTag: fGroupValue];
268     }
271 @end
273 @implementation AddWindowController (Private)
275 - (void) updateFiles
277     [fTorrent update];
278     
279     [fFileController refresh];
280     
281     if ([fTorrent isChecking])
282     {
283         const BOOL waiting = [fTorrent isCheckingWaiting];
284         [fVerifyIndicator setIndeterminate: waiting];
285         if (waiting)
286             [fVerifyIndicator startAnimation: self];
287         else
288             [fVerifyIndicator setDoubleValue: [fTorrent checkingProgress]];
289     }
290     else {
291         [fVerifyIndicator setIndeterminate: YES]; //we want to hide when stopped, which only applies when indeterminate
292         [fVerifyIndicator stopAnimation: self];
293     }
296 - (void) confirmAdd
298     [fTimer invalidate];
299     fTimer = nil;
300     [fTorrent setGroupValue: fGroupValue];
301     
302     if (fTorrentFile && [fDeleteCheck state] == NSOnState)
303         [Torrent trashFile: fTorrentFile];
304     
305     if ([fStartCheck state] == NSOnState)
306         [fTorrent startTransfer];
307     
308     [fFileController setTorrent: nil]; //avoid a crash when window tries to update
309     
310     [self close];
311     [fController askOpenConfirmed: self add: YES]; //ensure last, since it releases this controller
314 - (void) setDestinationPath: (NSString *) destination
316     destination = [destination stringByExpandingTildeInPath];
317     if (!fDestination || ![fDestination isEqualToString: destination])
318     { 
319         [fDestination release];
320         fDestination = [destination retain];
321         
322         [fTorrent changeDownloadFolderBeforeUsing: fDestination];
323     }
324     
325     [fLocationField setStringValue: [fDestination stringByAbbreviatingWithTildeInPath]];
326     [fLocationField setToolTip: fDestination];
327     
328     ExpandedPathToIconTransformer * iconTransformer = [[ExpandedPathToIconTransformer alloc] init];
329     [fLocationImageView setImage: [iconTransformer transformedValue: fDestination]];
330     [iconTransformer release];
333 - (void) setGroupsMenu
335     NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(changeGroupValue:) isSmall: NO];
336     [fGroupPopUp setMenu: groupMenu];
339 - (void) changeGroupValue: (id) sender
341     NSInteger previousGroup = fGroupValue;
342     fGroupValue = [sender tag];
343     
344     if (!fLockDestination)
345     {
346         if ([[GroupsController groups] usesCustomDownloadLocationForIndex: fGroupValue])
347             [self setDestinationPath: [[GroupsController groups] customDownloadLocationForIndex: fGroupValue]];
348         else if ([fDestination isEqualToString: [[GroupsController groups] customDownloadLocationForIndex: previousGroup]])
349             [self setDestinationPath: [[NSUserDefaults standardUserDefaults] stringForKey: @"DownloadFolder"]];
350         else;
351     }
354 - (void) sameNameAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
356     if ([[alert suppressionButton] state] == NSOnState)
357         [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningFolderDataSameName"];
358     
359     [alert release];
360     
361     if (returnCode == NSAlertSecondButtonReturn)
362         [self performSelectorOnMainThread: @selector(confirmAdd) withObject: nil waitUntilDone: NO];
365 @end