source: branches/file_selection/macosx/CreatorWindowController.m @ 2145

Last change on this file since 2145 was 2145, checked in by livings124, 15 years ago

don't allow creating torrents with no url

File size: 12.3 KB
Line 
1/******************************************************************************
2 * $Id$
3 *
4 * Copyright (c) 2007 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 "CreatorWindowController.h"
26#import "StringAdditions.h"
27
28#define DEFAULT_SAVE_LOCATION @"~/Desktop/"
29
30@interface CreatorWindowController (Private)
31
32+ (NSString *) chooseFile;
33- (void) locationSheetClosed: (NSSavePanel *) openPanel returnCode: (int) code contextInfo: (void *) info;
34- (void) checkProgress;
35- (void) failureSheetClosed: (NSAlert *) alert returnCode: (int) code contextInfo: (void *) info;
36
37@end
38
39@implementation CreatorWindowController
40
41+ (void) createTorrentFile: (tr_handle_t *) handle
42{
43    //get file/folder for torrent
44    NSString * path;
45    if (!(path = [CreatorWindowController chooseFile]))
46        return;
47   
48    CreatorWindowController * creator = [[self alloc] initWithWindowNibName: @"Creator" handle: handle path: path];
49    [creator showWindow: nil];
50}
51
52+ (void) createTorrentFile: (tr_handle_t *) handle forFile: (NSString *) file
53{
54    CreatorWindowController * creator = [[self alloc] initWithWindowNibName: @"Creator" handle: handle path: file];
55    [creator showWindow: nil];
56}
57
58- (id) initWithWindowNibName: (NSString *) name handle: (tr_handle_t *) handle path: (NSString *) path
59{
60    if ((self = [super initWithWindowNibName: name]))
61    {
62        fStarted = NO;
63       
64        fPath = [path retain];
65        fInfo = tr_metaInfoBuilderCreate(handle, [fPath UTF8String]);
66        if (fInfo->fileCount == 0)
67        {
68            NSAlert * alert = [[[NSAlert alloc] init] autorelease];
69            [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> no files -> button")];
70            [alert setMessageText: NSLocalizedString(@"This folder contains no files.",
71                                                    "Create torrent -> no files -> title")];
72            [alert setInformativeText: NSLocalizedString(@"There must be at least one file in a folder to create a torrent file.",
73                                                        "Create torrent -> no files -> warning")];
74            [alert setAlertStyle: NSWarningAlertStyle];
75           
76            [alert runModal];
77           
78            [self release];
79            return nil;
80        }
81    }
82    return self;
83}
84
85- (void) awakeFromNib
86{
87    NSString * name = [fPath lastPathComponent];
88   
89    [[self window] setTitle: name];
90   
91    [fNameField setStringValue: name];
92    [fNameField setToolTip: fPath];
93   
94    BOOL multifile = !fInfo->isSingleFile;
95   
96    #warning fix when resizing window
97    [fIcon setImage: [[NSWorkspace sharedWorkspace] iconForFileType: multifile
98                        ? NSFileTypeForHFSTypeCode('fldr') : [fPath pathExtension]]];
99   
100    NSString * statusString = [NSString stringForFileSize: fInfo->totalSize];
101    if (multifile)
102    {
103        NSString * fileString;
104        int count = fInfo->fileCount;
105        if (count != 1)
106            fileString = [NSString stringWithFormat: NSLocalizedString(@"%d Files, ", "Create torrent -> info"), count];
107        else
108            fileString = NSLocalizedString(@"1 File, ", "Create torrent -> info");
109        statusString = [fileString stringByAppendingString: statusString];
110    }
111    [fStatusField setStringValue: statusString];
112   
113    NSString * piecesCountString;
114    int piecesCount = fInfo->pieceCount;
115    if (piecesCount == 1)
116        piecesCountString = NSLocalizedString(@"1 piece", "Create torrent -> info");
117    else
118        piecesCountString = [NSString stringWithFormat: NSLocalizedString(@"%d pieces", "Create torrent -> info"),
119                                                                piecesCount];
120    [fPiecesField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@, %@ each", "Create torrent -> info"),
121                                        piecesCountString, [NSString stringForFileSize: fInfo->pieceSize]]];
122   
123    fLocation = [[[DEFAULT_SAVE_LOCATION stringByAppendingPathComponent: [name stringByAppendingPathExtension: @"torrent"]]
124                                            stringByExpandingTildeInPath] retain];
125    [fLocationField setStringValue: [fLocation stringByAbbreviatingWithTildeInPath]];
126    [fLocationField setToolTip: fLocation];
127}
128
129- (void) dealloc
130{
131    [fPath release];
132    if (fLocation)
133        [fLocation release];
134   
135    if (fInfo)
136        tr_metaInfoBuilderFree(fInfo);
137   
138    if (fTimer)
139        [fTimer invalidate];
140   
141    [super dealloc];
142}
143
144- (void) setLocation: (id) sender
145{
146    NSSavePanel * panel = [NSSavePanel savePanel];
147
148    [panel setPrompt: @"Select"];
149    [panel setRequiredFileType: @"torrent"];
150    [panel setCanSelectHiddenExtension: YES];
151
152    [panel beginSheetForDirectory: nil file: [fLocation lastPathComponent] modalForWindow: [self window] modalDelegate: self
153            didEndSelector: @selector(locationSheetClosed:returnCode:contextInfo:) contextInfo: nil];
154}
155
156- (void) create: (id) sender
157{
158    #warning check already exists
159   
160    //parse tracker string
161    NSString * trackerString = [fTrackerField stringValue];
162    if ([trackerString rangeOfString: @"://"].location != NSNotFound)
163    {
164        if (![trackerString hasPrefix: @"http://"])
165        {
166            NSAlert * alert = [[[NSAlert alloc] init] autorelease];
167            [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> http warning -> button")];
168            [alert setMessageText: NSLocalizedString(@"The tracker address must begin with \"http://\".",
169                                                    "Create torrent -> http warning -> title")];
170            [alert setInformativeText: NSLocalizedString(@"Change the tracker address to create the torrent.",
171                                                        "Create torrent -> http warning -> warning")];
172            [alert setAlertStyle: NSWarningAlertStyle];
173           
174            [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil];
175            return;
176        }
177    }
178    else
179        trackerString = [@"http://" stringByAppendingString: trackerString];
180   
181    //don't allow blank addresses
182    if ([trackerString length] <= 7)
183    {
184        NSAlert * alert = [[[NSAlert alloc] init] autorelease];
185        [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> no url warning -> button")];
186        [alert setMessageText: NSLocalizedString(@"The tracker address cannot be blank.",
187                                                "Create torrent -> no url warning -> title")];
188        [alert setInformativeText: NSLocalizedString(@"Change the tracker address to create the torrent.",
189                                                    "Create torrent -> no url warning -> warning")];
190        [alert setAlertStyle: NSWarningAlertStyle];
191       
192        [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil];
193        return;
194    }
195   
196    fOpenTorrent = [fOpenCheck state] == NSOnState;
197    tr_makeMetaInfo(fInfo, [fLocation UTF8String], [trackerString UTF8String], [[fCommentView string] UTF8String],
198                    [fPrivateCheck state] == NSOnState);
199   
200    fTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(checkProgress)
201                        userInfo: nil repeats: YES];
202}
203
204- (void) cancelCreateWindow: (id) sender
205{
206    [[self window] close];
207}
208
209- (void) windowWillClose: (NSNotification *) notification
210{
211    [self release];
212}
213
214- (void) cancelCreateProgress: (id) sender
215{
216    fInfo->abortFlag = 1;
217    [fTimer fire];
218}
219
220@end
221
222@implementation CreatorWindowController (Private)
223
224+ (NSString *) chooseFile
225{
226    NSOpenPanel * panel = [NSOpenPanel openPanel];
227   
228    [panel setPrompt: NSLocalizedString(@"Select", "Create torrent -> select file")];
229    [panel setAllowsMultipleSelection: NO];
230    [panel setCanChooseFiles: YES];
231    [panel setCanChooseDirectories: YES];
232    [panel setCanCreateDirectories: NO];
233
234    [panel setMessage: NSLocalizedString(@"Select a file or folder for the torrent file.", "Create torrent -> select file")];
235   
236    BOOL success = [panel runModal] == NSOKButton;
237    return success ? [[panel filenames] objectAtIndex: 0] : nil;
238}
239
240- (void) locationSheetClosed: (NSSavePanel *) panel returnCode: (int) code contextInfo: (void *) info
241{
242    if (code == NSOKButton)
243    {
244        [fLocation release];
245        fLocation = [[panel filename] retain];
246       
247        [fLocationField setStringValue: [fLocation stringByAbbreviatingWithTildeInPath]];
248        [fLocationField setToolTip: fLocation];
249    }
250}
251
252- (void) checkProgress
253{
254    if (fInfo->isDone)
255    {
256        [fTimer invalidate];
257        fTimer = nil;
258       
259        if (fInfo->failed)
260        {
261            if (!fInfo->abortFlag)
262            {
263                NSAlert * alert = [[[NSAlert alloc] init] autorelease];
264                [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> failed -> button")];
265                [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Creation of \"%@\" failed.",
266                                                "Create torrent -> failed -> title"), [fLocation lastPathComponent]]];
267                [alert setInformativeText: NSLocalizedString(@"There was an error parsing the data file. "
268                                            "The torrent file was not created.", "Create torrent -> failed -> warning")];
269                [alert setAlertStyle: NSWarningAlertStyle];
270               
271                [alert beginSheetModalForWindow: [self window] modalDelegate: self
272                        didEndSelector: @selector(failureSheetClosed:returnCode:contextInfo:) contextInfo: nil];
273                return;
274            }
275        }
276        else
277        {
278            if (fOpenTorrent)
279            {
280                NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys: fLocation, @"File",
281                                        [fPath stringByDeletingLastPathComponent], @"Path", nil];
282                [[NSNotificationCenter defaultCenter] postNotificationName: @"OpenCreatedTorrentFile" object: self userInfo: dict];
283            }
284        }
285       
286        [[self window] close];
287    }
288    else
289    {
290        [fProgressIndicator setDoubleValue: (double)fInfo->pieceIndex / fInfo->pieceCount];
291       
292        if (!fStarted)
293        {
294            NSWindow * window = [self window];
295           
296            NSRect windowRect = [window frame];
297            float difference = [fProgressView frame].size.height - [[window contentView] frame].size.height;
298            windowRect.origin.y -= difference;
299            windowRect.size.height += difference;
300           
301            //don't allow vertical resizing
302            float height = windowRect.size.height;
303            [window setMinSize: NSMakeSize([window minSize].width, height)];
304            [window setMaxSize: NSMakeSize([window maxSize].width, height)];
305           
306            [window setContentView: fProgressView];
307            [window setFrame: windowRect display: YES animate: YES];
308            [fProgressView setHidden: NO];
309           
310            fStarted = YES;
311        }
312    }
313}
314
315- (void) failureSheetClosed: (NSAlert *) alert returnCode: (int) code contextInfo: (void *) info
316{
317    [[alert window] orderOut: nil];
318    [[self window] close];
319}
320
321@end
Note: See TracBrowser for help on using the repository browser.