source: trunk/macosx/CreatorWindowController.m @ 2261

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

fix blurry icon when resizing the creator window

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