source: trunk/macosx/CreatorWindowController.m @ 3112

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

get xcode project building again

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