source: trunk/macosx/AddWindowController.m @ 10056

Last change on this file since 10056 was 10056, checked in by livings124, 12 years ago

#2791 show a progress indicator when verifying local data in the add window

  • Property svn:keywords set to Date Rev Author Id
File size: 11.0 KB
Line 
1/******************************************************************************
2 * $Id: AddWindowController.m 10056 2010-01-31 23:36:48Z livings124 $
3 *
4 * Copyright (c) 2008-2010 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 "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"
32
33#define UPDATE_SECONDS 1.0
34
35@interface AddWindowController (Private)
36
37- (void) updateFiles;
38
39- (void) confirmAdd;
40
41- (void) setDestinationPath: (NSString *) destination;
42
43- (void) folderChoiceClosed: (NSOpenPanel *) openPanel returnCode: (NSInteger) code contextInfo: (void *) contextInfo;
44
45- (void) setGroupsMenu;
46- (void) changeGroupValue: (id) sender;
47
48- (void) sameNameAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo;
49
50@end
51
52@implementation AddWindowController
53
54- (id) initWithTorrent: (Torrent *) torrent destination: (NSString *) path lockDestination: (BOOL) lockDestination
55    controller: (Controller *) controller torrentFile: (NSString *) torrentFile
56    deleteTorrent: (BOOL) deleteTorrent canToggleDelete: (BOOL) canToggleDelete
57{
58    if ((self = [super initWithWindowNibName: @"AddWindow"]))
59    {
60        fTorrent = torrent;
61        fDestination = [[path stringByExpandingTildeInPath] retain];
62        fLockDestination = lockDestination;
63       
64        fController = controller;
65       
66        fTorrentFile = [[torrentFile stringByExpandingTildeInPath] retain];
67       
68        fDeleteTorrent = deleteTorrent;
69        fDeleteEnable = canToggleDelete;
70       
71        fGroupValue = [torrent groupValue];
72    }
73    return self;
74}
75
76- (void) awakeFromNib
77{
78    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateStatusField:)
79        name: @"TorrentFileCheckChange" object: fTorrent];
80   
81    [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(updateGroupMenu:)
82        name: @"UpdateGroups" object: nil];
83   
84    [fFileController setTorrent: fTorrent];
85   
86    NSString * name = [fTorrent name];
87    [[self window] setTitle: name];
88    [fNameField setStringValue: name];
89   
90    [fIconView setImage: [fTorrent icon]];
91   
92    [self updateStatusField: nil];
93   
94    [self setGroupsMenu];
95    [fGroupPopUp selectItemWithTag: fGroupValue];
96   
97    [fStartCheck setState: [[NSUserDefaults standardUserDefaults] boolForKey: @"AutoStartDownload"] ? NSOnState : NSOffState];
98   
99    [fDeleteCheck setState: fDeleteTorrent ? NSOnState : NSOffState];
100    [fDeleteCheck setEnabled: fDeleteEnable];
101   
102    if (fDestination)
103        [self setDestinationPath: fDestination];
104    else
105    {
106        [fLocationField setStringValue: @""];
107        [fLocationImageView setImage: nil];
108    }
109   
110    fTimer = [NSTimer scheduledTimerWithTimeInterval: UPDATE_SECONDS target: self
111                selector: @selector(updateFiles) userInfo: nil repeats: YES];
112    [self updateFiles];
113}
114
115- (void) windowDidLoad
116{
117    //if there is no destination, prompt for one right away
118    if (!fDestination)
119        [self setDestination: nil];
120}
121
122- (void) dealloc
123{
124    [[NSNotificationCenter defaultCenter] removeObserver: self];
125   
126    [fTimer invalidate];
127   
128    [fDestination release];
129   
130    [super dealloc];
131}
132
133- (Torrent *) torrent
134{
135    return fTorrent;
136}
137
138- (void) setDestination: (id) sender
139{
140    NSOpenPanel * panel = [NSOpenPanel openPanel];
141
142    [panel setPrompt: NSLocalizedString(@"Select", "Open torrent -> prompt")];
143    [panel setAllowsMultipleSelection: NO];
144    [panel setCanChooseFiles: NO];
145    [panel setCanChooseDirectories: YES];
146    [panel setCanCreateDirectories: YES];
147   
148    [panel setMessage: [NSString stringWithFormat: NSLocalizedString(@"Select the download folder for \"%@\"",
149                        "Add -> select destination folder"), [fTorrent name]]];
150   
151    [panel beginSheetForDirectory: nil file: nil types: nil modalForWindow: [self window] modalDelegate: self
152            didEndSelector: @selector(folderChoiceClosed:returnCode:contextInfo:) contextInfo: nil];
153}
154
155- (void) add: (id) sender
156{
157    if ([[fDestination lastPathComponent] isEqualToString: [fTorrent name]]
158        && [[NSUserDefaults standardUserDefaults] boolForKey: @"WarningFolderDataSameName"])
159    {
160        NSAlert * alert = [[NSAlert alloc] init];
161        [alert setMessageText: NSLocalizedString(@"The destination directory and root data directory have the same name.",
162                                "Add torrent -> same name -> title")];
163        [alert setInformativeText: NSLocalizedString(@"If you are attempting to use already existing data,"
164            " the root data directory should be inside the destination directory.", "Add torrent -> same name -> message")];
165        [alert setAlertStyle: NSWarningAlertStyle];
166        [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Add torrent -> same name -> button")];
167        [alert addButtonWithTitle: NSLocalizedString(@"Add", "Add torrent -> same name -> button")];
168        [alert setShowsSuppressionButton: YES];
169       
170        [alert beginSheetModalForWindow: [self window] modalDelegate: self
171            didEndSelector: @selector(sameNameAlertDidEnd:returnCode:contextInfo:) contextInfo: nil];
172    }
173    else
174        [self confirmAdd];
175}
176
177- (void) cancelAdd: (id) sender
178{
179    [[self window] performClose: sender];
180}
181
182//only called on cancel
183- (BOOL) windowShouldClose: (id) window
184{
185    [fTimer invalidate];
186    fTimer = nil;
187   
188    [fFileController setTorrent: nil]; //avoid a crash when window tries to update
189   
190    [fController askOpenConfirmed: self add: NO];
191    return YES;
192}
193
194- (void) verifyLocalData: (id) sender
195{
196    [fTorrent resetCache];
197    [self updateFiles];
198}
199
200- (void) updateStatusField: (NSNotification *) notification
201{
202    NSString * statusString = [NSString stringForFileSize: [fTorrent size]];
203    if ([fTorrent isFolder])
204    {
205        NSString * fileString;
206        NSInteger count = [fTorrent fileCount];
207        if (count != 1)
208            fileString = [NSString stringWithFormat: NSLocalizedString(@"%d files", "Add torrent -> info"), count];
209        else
210            fileString = NSLocalizedString(@"1 file", "Add torrent -> info");
211       
212        NSString * selectedString = [NSString stringWithFormat: NSLocalizedString(@"%@ selected", "Add torrent -> info"),
213                                        [NSString stringForFileSize: [fTorrent totalSizeSelected]]];
214       
215        statusString = [NSString stringWithFormat: @"%@, %@ (%@)", fileString, statusString, selectedString];
216    }
217   
218    [fStatusField setStringValue: statusString];
219}
220
221- (void) updateGroupMenu: (NSNotification *) notification
222{
223    [self setGroupsMenu];
224    if (![fGroupPopUp selectItemWithTag: fGroupValue])
225    {
226        fGroupValue = -1;
227        [fGroupPopUp selectItemWithTag: fGroupValue];
228    }
229}
230
231@end
232
233@implementation AddWindowController (Private)
234
235- (void) updateFiles
236{
237    [fTorrent update];
238   
239    [fFileController reloadData];
240   
241    if ([fTorrent isChecking])
242    {
243        [fVerifyIndicator setHidden: NO];
244        [fVerifyIndicator setDoubleValue: [fTorrent checkingProgress]];
245    }
246    else
247        [fVerifyIndicator setHidden: YES];
248}
249
250- (void) confirmAdd
251{
252    [fTimer invalidate];
253    fTimer = nil;
254   
255    [fTorrent setWaitToStart: [fStartCheck state] == NSOnState];
256    [fTorrent setGroupValue: fGroupValue];
257   
258    if (fTorrentFile && [fDeleteCheck state] == NSOnState)
259        [Torrent trashFile: fTorrentFile];
260   
261    [fFileController setTorrent: nil]; //avoid a crash when window tries to update
262   
263    [self close];
264    [fController askOpenConfirmed: self add: YES]; //ensure last, since it releases this controller
265}
266
267- (void) setDestinationPath: (NSString *) destination
268{
269    destination = [destination stringByExpandingTildeInPath];
270    if (!fDestination || ![fDestination isEqualToString: destination])
271    {
272        [fDestination release];
273        fDestination = [destination retain];
274       
275        [fTorrent changeDownloadFolderBeforeUsing: fDestination];
276    }
277   
278    [fLocationField setStringValue: [fDestination stringByAbbreviatingWithTildeInPath]];
279    [fLocationField setToolTip: fDestination];
280   
281    ExpandedPathToIconTransformer * iconTransformer = [[ExpandedPathToIconTransformer alloc] init];
282    [fLocationImageView setImage: [iconTransformer transformedValue: fDestination]];
283    [iconTransformer release];
284}
285
286- (void) folderChoiceClosed: (NSOpenPanel *) openPanel returnCode: (NSInteger) code contextInfo: (void *) contextInfo
287{
288    if (code == NSOKButton)
289    {
290        fLockDestination = NO;
291        [self setDestinationPath: [[openPanel filenames] objectAtIndex: 0]];
292    }
293    else
294    {
295        if (!fDestination)
296            [self performSelectorOnMainThread: @selector(cancelAdd:) withObject: nil waitUntilDone: NO];
297    }
298}
299
300- (void) setGroupsMenu
301{
302    NSMenu * groupMenu = [[GroupsController groups] groupMenuWithTarget: self action: @selector(changeGroupValue:) isSmall: NO];
303    [fGroupPopUp setMenu: groupMenu];
304}
305
306- (void) changeGroupValue: (id) sender
307{
308    NSInteger previousGroup = fGroupValue;
309    fGroupValue = [sender tag];
310   
311    if (!fLockDestination)
312    {
313        if ([[GroupsController groups] usesCustomDownloadLocationForIndex: fGroupValue])
314            [self setDestinationPath: [[GroupsController groups] customDownloadLocationForIndex: fGroupValue]];
315        else if ([fDestination isEqualToString: [[GroupsController groups] customDownloadLocationForIndex: previousGroup]])
316            [self setDestinationPath: [[NSUserDefaults standardUserDefaults] stringForKey: @"DownloadFolder"]];
317        else;
318    }
319}
320
321- (void) sameNameAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
322{
323    if ([[alert suppressionButton] state] == NSOnState)
324        [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningFolderDataSameName"];
325   
326    [alert release];
327   
328    if (returnCode == NSAlertSecondButtonReturn)
329        [self performSelectorOnMainThread: @selector(confirmAdd) withObject: nil waitUntilDone: NO];
330}
331
332@end
Note: See TracBrowser for help on using the repository browser.