source: trunk/macosx/CreatorWindowController.m @ 13251

Last change on this file since 13251 was 13251, checked in by livings124, 9 years ago

reverse r13248-r13250, since ARC doesn't support 32-bit.

  • Property Id set to /Users/mitchell/Desktop/Transmission/macosx/ActionMenuRatioToDisplayRatioTransformer.h
  • Property svn:keywords set to Date Rev Author Id
File size: 23.5 KB
Line 
1/******************************************************************************
2 * $Id: CreatorWindowController.m 13251 2012-03-13 02:52:11Z livings124 $
3 *
4 * Copyright (c) 2007-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 *****************************************************************************/
24
25#import "CreatorWindowController.h"
26#import "NSStringAdditions.h"
27
28#import "transmission.h" // required by utils.h
29#import "utils.h" // tr_urlIsValidTracker()
30
31#define TRACKER_ADD_TAG 0
32#define TRACKER_REMOVE_TAG 1
33
34@interface CreatorWindowController (Private)
35
36+ (NSString *) chooseFile;
37
38- (void) createBlankAddressAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo;
39- (void) createReal;
40- (void) checkProgress;
41- (void) failureSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info;
42
43@end
44
45@implementation CreatorWindowController
46
47+ (void) createTorrentFile: (tr_session *) handle
48{
49    //get file/folder for torrent
50    NSString * path;
51    if (!(path = [CreatorWindowController chooseFile]))
52        return;
53   
54    CreatorWindowController * creator = [[self alloc] initWithHandle: handle path: path];
55    [creator showWindow: nil];
56}
57
58+ (void) createTorrentFile: (tr_session *) handle forFile: (NSString *) file
59{
60    CreatorWindowController * creator = [[self alloc] initWithHandle: handle path: file];
61    [creator showWindow: nil];
62}
63
64- (id) initWithHandle: (tr_session *) handle path: (NSString *) path
65{
66    if ((self = [super initWithWindowNibName: @"Creator"]))
67    {
68        fStarted = NO;
69       
70        fPath = [path retain];
71        fInfo = tr_metaInfoBuilderCreate([fPath UTF8String]);
72       
73        if (fInfo->fileCount == 0)
74        {
75            NSAlert * alert = [[NSAlert alloc] init];
76            [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> no files -> button")];
77            [alert setMessageText: NSLocalizedString(@"This folder contains no files.",
78                                                    "Create torrent -> no files -> title")];
79            [alert setInformativeText: NSLocalizedString(@"There must be at least one file in a folder to create a torrent file.",
80                                                        "Create torrent -> no files -> warning")];
81            [alert setAlertStyle: NSWarningAlertStyle];
82           
83            [alert runModal];
84            [alert release];
85           
86            [self release];
87            return nil;
88        }
89        if (fInfo->totalSize == 0)
90        {
91            NSAlert * alert = [[NSAlert alloc] init];
92            [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> zero size -> button")];
93            [alert setMessageText: NSLocalizedString(@"The total file size is zero bytes.",
94                                                    "Create torrent -> zero size -> title")];
95            [alert setInformativeText: NSLocalizedString(@"A torrent file cannot be created for files with no size.",
96                                                        "Create torrent -> zero size -> warning")];
97            [alert setAlertStyle: NSWarningAlertStyle];
98           
99            [alert runModal];
100            [alert release];
101           
102            [self release];
103            return nil;
104        }
105       
106        fDefaults = [NSUserDefaults standardUserDefaults];
107       
108        //get list of trackers
109        if (!(fTrackers = [[fDefaults arrayForKey: @"CreatorTrackers"] mutableCopy]))
110        {
111            fTrackers = [[NSMutableArray alloc] initWithCapacity: 1];
112           
113            //check for single tracker from versions before 1.3
114            NSString * tracker;
115            if ((tracker = [fDefaults stringForKey: @"CreatorTracker"]))
116            {
117                [fDefaults removeObjectForKey: @"CreatorTracker"];
118                if (![tracker isEqualToString: @""])
119                {
120                    [fTrackers addObject: tracker];
121                    [fDefaults setObject: fTrackers forKey: @"CreatorTrackers"];
122                }
123            }
124        }
125       
126        //remove potentially invalid addresses
127        for (NSInteger i = [fTrackers count]-1; i >= 0; i--)
128        {
129            if (!tr_urlIsValidTracker([[fTrackers objectAtIndex: i] UTF8String]))
130                [fTrackers removeObjectAtIndex: i];
131        }
132    }
133    return self;
134}
135
136- (void) awakeFromNib
137{
138    NSString * name = [fPath lastPathComponent];
139   
140    [[self window] setTitle: name];
141   
142    [fNameField setStringValue: name];
143    [fNameField setToolTip: fPath];
144   
145    const BOOL multifile = !fInfo->isSingleFile;
146   
147    NSImage * icon = [[NSWorkspace sharedWorkspace] iconForFileType: multifile
148                        ? NSFileTypeForHFSTypeCode(kGenericFolderIcon) : [fPath pathExtension]];
149    [icon setSize: [fIconView frame].size];
150    [fIconView setImage: icon];
151   
152    NSString * statusString = [NSString stringForFileSize: fInfo->totalSize];
153    if (multifile)
154    {
155        NSString * fileString;
156        NSInteger count = fInfo->fileCount;
157        if (count != 1)
158            fileString = [NSString stringWithFormat: NSLocalizedString(@"%@ files", "Create torrent -> info"),
159                            [NSString formattedUInteger: count]];
160        else
161            fileString = NSLocalizedString(@"1 file", "Create torrent -> info");
162        statusString = [NSString stringWithFormat: @"%@, %@", fileString, statusString];
163    }
164    [fStatusField setStringValue: statusString];
165   
166    if (fInfo->pieceCount == 1)
167        [fPiecesField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"1 piece, %@", "Create torrent -> info"),
168                                                            [NSString stringForFileSize: fInfo->pieceSize]]];
169    else
170        [fPiecesField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%d pieces, %@ each", "Create torrent -> info"),
171                                                            fInfo->pieceCount, [NSString stringForFileSize: fInfo->pieceSize]]];
172   
173    fLocation = [[[[fDefaults stringForKey: @"CreatorLocation"] stringByExpandingTildeInPath] stringByAppendingPathComponent:
174                    [name stringByAppendingPathExtension: @"torrent"]] retain];
175    [fLocationField setStringValue: [fLocation stringByAbbreviatingWithTildeInPath]];
176    [fLocationField setToolTip: fLocation];
177   
178    //set previously saved values
179    if ([fDefaults objectForKey: @"CreatorPrivate"])
180        [fPrivateCheck setState: [fDefaults boolForKey: @"CreatorPrivate"] ? NSOnState : NSOffState];
181   
182    [fOpenCheck setState: [fDefaults boolForKey: @"CreatorOpen"] ? NSOnState : NSOffState];
183}
184
185- (void) dealloc
186{
187    [fPath release];
188    [fLocation release];
189   
190    [fTrackers release];
191   
192    if (fInfo)
193        tr_metaInfoBuilderFree(fInfo);
194   
195    [fTimer invalidate];
196   
197    [super dealloc];
198}
199
200- (void) setLocation: (id) sender
201{
202    NSSavePanel * panel = [NSSavePanel savePanel];
203
204    [panel setPrompt: NSLocalizedString(@"Select", "Create torrent -> location sheet -> button")];
205    [panel setMessage: NSLocalizedString(@"Select the name and location for the torrent file.",
206                                        "Create torrent -> location sheet -> message")];
207   
208    [panel setAllowedFileTypes: [NSArray arrayWithObjects: @"org.bittorrent.torrent", @"torrent", nil]];
209    [panel setCanSelectHiddenExtension: YES];
210   
211    [panel setDirectoryURL: [NSURL fileURLWithPath: [fLocation stringByDeletingLastPathComponent]]];
212    [panel setNameFieldStringValue: [fLocation lastPathComponent]];
213   
214    [panel beginSheetModalForWindow: [self window] completionHandler: ^(NSInteger result) {
215        if (result == NSFileHandlingPanelOKButton)
216        {
217            [fLocation release];
218            fLocation = [[[panel URL] path] retain];
219           
220            [fLocationField setStringValue: [fLocation stringByAbbreviatingWithTildeInPath]];
221            [fLocationField setToolTip: fLocation];
222        }
223    }];
224}
225
226- (void) create: (id) sender
227{
228    //make sure the trackers are no longer being verified
229    if ([fTrackerTable editedRow] != -1)
230        [[self window] endEditingFor: fTrackerTable];
231   
232    const BOOL isPrivate = [fPrivateCheck state] == NSOnState;
233    if ([fTrackers count] == 0
234        && [fDefaults boolForKey: isPrivate ? @"WarningCreatorPrivateBlankAddress" : @"WarningCreatorBlankAddress"])
235    {
236        NSAlert * alert = [[NSAlert alloc] init];
237        [alert setMessageText: NSLocalizedString(@"There are no tracker addresses.", "Create torrent -> blank address -> title")];
238       
239        NSString * infoString = isPrivate
240                    ? NSLocalizedString(@"A transfer marked as private with no tracker addresses will be unable to connect to peers."
241                        " The torrent file will only be useful if you plan to upload the file to a tracker website"
242                        " that will add the addresses for you.", "Create torrent -> blank address -> message")
243                    : NSLocalizedString(@"The transfer will not contact trackers for peers, and will have to rely solely on"
244                        " non-tracker peer discovery methods such as PEX and DHT to download and seed.",
245                        "Create torrent -> blank address -> message");
246       
247        [alert setInformativeText: infoString];
248        [alert addButtonWithTitle: NSLocalizedString(@"Create", "Create torrent -> blank address -> button")];
249        [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Create torrent -> blank address -> button")];
250        [alert setShowsSuppressionButton: YES];
251
252        [alert beginSheetModalForWindow: [self window] modalDelegate: self
253            didEndSelector: @selector(createBlankAddressAlertDidEnd:returnCode:contextInfo:) contextInfo: nil];
254    }
255    else
256        [self createReal];
257}
258
259- (void) cancelCreateWindow: (id) sender
260{
261    [[self window] close];
262}
263
264- (void) windowWillClose: (NSNotification *) notification
265{
266    [self autorelease];
267}
268
269- (void) cancelCreateProgress: (id) sender
270{
271    fInfo->abortFlag = 1;
272    [fTimer fire];
273}
274
275- (NSInteger) numberOfRowsInTableView: (NSTableView *) tableView
276{
277    return [fTrackers count];
278}
279
280- (id) tableView: (NSTableView *) tableView objectValueForTableColumn: (NSTableColumn *) tableColumn row: (NSInteger) row
281{
282    return [fTrackers objectAtIndex: row];
283}
284
285- (void) addRemoveTracker: (id) sender
286{
287    //don't allow add/remove when currently adding - it leads to weird results
288    if ([fTrackerTable editedRow] != -1)
289        return;
290   
291    if ([[sender cell] tagForSegment: [sender selectedSegment]] == TRACKER_REMOVE_TAG)
292    {
293        [fTrackers removeObjectsAtIndexes: [fTrackerTable selectedRowIndexes]];
294       
295        [fTrackerTable deselectAll: self];
296        [fTrackerTable reloadData];
297    }
298    else
299    {
300        [fTrackers addObject: @""];
301        [fTrackerTable reloadData];
302       
303        const NSInteger row = [fTrackers count] - 1;
304        [fTrackerTable selectRowIndexes: [NSIndexSet indexSetWithIndex: row] byExtendingSelection: NO];
305        [fTrackerTable editColumn: 0 row: row withEvent: nil select: YES];
306    }
307}
308
309- (void) tableView: (NSTableView *) tableView setObjectValue: (id) object forTableColumn: (NSTableColumn *) tableColumn
310    row: (NSInteger) row
311{
312    NSString * tracker = (NSString *)object;
313   
314    tracker = [tracker stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
315   
316    if ([tracker rangeOfString: @"://"].location == NSNotFound)
317        tracker = [@"http://" stringByAppendingString: tracker];
318   
319    if (!tr_urlIsValidTracker([tracker UTF8String]))
320    {
321        NSBeep();
322        [fTrackers removeObjectAtIndex: row];
323    }
324    else
325        [fTrackers replaceObjectAtIndex: row withObject: tracker];
326   
327    [fTrackerTable deselectAll: self];
328    [fTrackerTable reloadData];
329}
330
331- (void) tableViewSelectionDidChange: (NSNotification *) notification
332{
333    [fTrackerAddRemoveControl setEnabled: [fTrackerTable numberOfSelectedRows] > 0 forSegment: TRACKER_REMOVE_TAG];
334}
335
336- (void) copy: (id) sender
337{
338    NSArray * addresses = [fTrackers objectsAtIndexes: [fTrackerTable selectedRowIndexes]];
339    NSString * text = [addresses componentsJoinedByString: @"\n"];
340   
341    NSPasteboard * pb = [NSPasteboard generalPasteboard];
342    [pb clearContents];
343    [pb writeObjects: [NSArray arrayWithObject: text]];
344}
345
346- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
347{
348    const SEL action = [menuItem action];
349   
350    if (action == @selector(copy:))
351        return [[self window] firstResponder] == fTrackerTable && [fTrackerTable numberOfSelectedRows] > 0;
352   
353    if (action == @selector(paste:))
354        return [[self window] firstResponder] == fTrackerTable
355            && [[NSPasteboard generalPasteboard] canReadObjectForClasses: [NSArray arrayWithObject: [NSString class]] options: nil];
356   
357    return YES;
358}
359
360- (void) paste: (id) sender
361{
362    NSMutableArray * tempTrackers = [NSMutableArray array];
363   
364    NSArray * items = [[NSPasteboard generalPasteboard] readObjectsForClasses: [NSArray arrayWithObject: [NSString class]] options: nil];
365    NSAssert(items != nil, @"no string items to paste; should not be able to call this method");
366   
367    for (NSString * pbItem in items)
368    {
369        for (NSString * tracker in [pbItem componentsSeparatedByString: @"\n"])
370            [tempTrackers addObject: tracker];
371    }
372   
373    BOOL added = NO;
374   
375    for (NSString * tracker in tempTrackers)
376    {
377        tracker = [tracker stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]];
378       
379        if ([tracker rangeOfString: @"://"].location == NSNotFound)
380            tracker = [@"http://" stringByAppendingString: tracker];
381       
382        if (tr_urlIsValidTracker([tracker UTF8String]))
383        {
384            [fTrackers addObject: tracker];
385            added = YES;
386        }
387    }
388   
389    if (added)
390    {
391        [fTrackerTable deselectAll: self];
392        [fTrackerTable reloadData];
393    }
394    else
395        NSBeep();
396}
397
398@end
399
400@implementation CreatorWindowController (Private)
401
402+ (NSString *) chooseFile
403{
404    NSOpenPanel * panel = [NSOpenPanel openPanel];
405   
406    [panel setTitle: NSLocalizedString(@"Create Torrent File", "Create torrent -> select file")];
407    [panel setPrompt: NSLocalizedString(@"Select", "Create torrent -> select file")];
408    [panel setAllowsMultipleSelection: NO];
409    [panel setCanChooseFiles: YES];
410    [panel setCanChooseDirectories: YES];
411    [panel setCanCreateDirectories: NO];
412
413    [panel setMessage: NSLocalizedString(@"Select a file or folder for the torrent file.", "Create torrent -> select file")];
414   
415    BOOL success = [panel runModal] == NSOKButton;
416    return success ? [[[panel URLs] objectAtIndex: 0] path] : nil;
417}
418
419- (void) createBlankAddressAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
420{
421    if ([[alert suppressionButton] state] == NSOnState)
422    {
423        [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningCreatorBlankAddress"]; //set regardless of private/public
424        if ([fPrivateCheck state] == NSOnState)
425            [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningCreatorPrivateBlankAddress"];
426    }
427   
428    [alert release];
429   
430    if (returnCode == NSAlertFirstButtonReturn)
431        [self performSelectorOnMainThread: @selector(createReal) withObject: nil waitUntilDone: NO];
432}
433
434- (void) createReal
435{
436    //check if the location currently exists
437    if (![[NSFileManager defaultManager] fileExistsAtPath: [fLocation stringByDeletingLastPathComponent]])
438    {
439        NSAlert * alert = [[[NSAlert alloc] init] autorelease];
440        [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> directory doesn't exist warning -> button")];
441        [alert setMessageText: NSLocalizedString(@"The chosen torrent file location does not exist.",
442                                                "Create torrent -> directory doesn't exist warning -> title")];
443        [alert setInformativeText: [NSString stringWithFormat:
444                NSLocalizedString(@"The directory \"%@\" does not currently exist. "
445                    "Create this directory or choose a different one to create the torrent file.",
446                    "Create torrent -> directory doesn't exist warning -> warning"),
447                    [fLocation stringByDeletingLastPathComponent]]];
448        [alert setAlertStyle: NSWarningAlertStyle];
449       
450        [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil];
451        return;
452    }
453   
454    //check if a file with the same name and location already exists
455    if ([[NSFileManager defaultManager] fileExistsAtPath: fLocation])
456    {
457        NSArray * pathComponents = [fLocation pathComponents];
458        NSInteger count = [pathComponents count];
459       
460        NSAlert * alert = [[[NSAlert alloc] init] autorelease];
461        [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> file already exists warning -> button")];
462        [alert setMessageText: NSLocalizedString(@"A torrent file with this name and directory cannot be created.",
463                                                "Create torrent -> file already exists warning -> title")];
464        [alert setInformativeText: [NSString stringWithFormat:
465                NSLocalizedString(@"A file with the name \"%@\" already exists in the directory \"%@\". "
466                    "Choose a new name or directory to create the torrent file.",
467                    "Create torrent -> file already exists warning -> warning"),
468                    [pathComponents objectAtIndex: count-1], [pathComponents objectAtIndex: count-2]]];
469        [alert setAlertStyle: NSWarningAlertStyle];
470       
471        [alert beginSheetModalForWindow: [self window] modalDelegate: self didEndSelector: nil contextInfo: nil];
472        return;
473    }
474   
475    //parse non-empty tracker strings
476    tr_tracker_info * trackerInfo = tr_new0(tr_tracker_info, [fTrackers count]);
477   
478    for (NSUInteger i = 0; i < [fTrackers count]; i++)
479    {
480        trackerInfo[i].announce = (char *)[[fTrackers objectAtIndex: i] UTF8String];
481        trackerInfo[i].tier = i;
482    }
483   
484    //store values
485    [fDefaults setObject: fTrackers forKey: @"CreatorTrackers"];
486    [fDefaults setBool: [fPrivateCheck state] == NSOnState forKey: @"CreatorPrivate"];
487    [fDefaults setBool: [fOpenCheck state] == NSOnState forKey: @"CreatorOpen"];
488    [fDefaults setObject: [fLocation stringByDeletingLastPathComponent] forKey: @"CreatorLocation"];
489   
490    [[NSNotificationCenter defaultCenter] postNotificationName: @"BeginCreateTorrentFile" object: fLocation userInfo: nil];
491    tr_makeMetaInfo(fInfo, [fLocation UTF8String], trackerInfo, [fTrackers count], [[fCommentView string] UTF8String],
492                    [fPrivateCheck state] == NSOnState);
493    tr_free(trackerInfo);
494   
495    fTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(checkProgress)
496                userInfo: nil repeats: YES];
497}
498
499- (void) checkProgress
500{
501    if (fInfo->isDone)
502    {
503        [fTimer invalidate];
504        fTimer = nil;
505       
506        NSAlert * alert;
507        switch (fInfo->result)
508        {
509            case TR_MAKEMETA_OK:
510                if ([fDefaults boolForKey: @"CreatorOpen"])
511                {
512                    NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys: fLocation, @"File",
513                                            [fPath stringByDeletingLastPathComponent], @"Path", nil];
514                    [[NSNotificationCenter defaultCenter] postNotificationName: @"OpenCreatedTorrentFile" object: self userInfo: dict];
515                }
516               
517                [[self window] close];
518                break;
519           
520            case TR_MAKEMETA_CANCELLED:
521                [[self window] close];
522                break;
523           
524            default:
525                alert = [[[NSAlert alloc] init] autorelease];
526                [alert addButtonWithTitle: NSLocalizedString(@"OK", "Create torrent -> failed -> button")];
527                [alert setMessageText: [NSString stringWithFormat: NSLocalizedString(@"Creation of \"%@\" failed.",
528                                                "Create torrent -> failed -> title"), [fLocation lastPathComponent]]];
529                [alert setAlertStyle: NSWarningAlertStyle];
530               
531                if (fInfo->result == TR_MAKEMETA_IO_READ)
532                    [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"Could not read \"%s\": %s.",
533                        "Create torrent -> failed -> warning"), fInfo->errfile, strerror(fInfo->my_errno)]];
534                else if (fInfo->result == TR_MAKEMETA_IO_WRITE)
535                    [alert setInformativeText: [NSString stringWithFormat: NSLocalizedString(@"Could not write \"%s\": %s.",
536                        "Create torrent -> failed -> warning"), fInfo->errfile, strerror(fInfo->my_errno)]];
537                else //invalid url should have been caught before creating
538                    [alert setInformativeText: [NSString stringWithFormat: @"%@ (%d)",
539                        NSLocalizedString(@"An unknown error has occurred.", "Create torrent -> failed -> warning"), fInfo->result]];
540               
541                [alert beginSheetModalForWindow: [self window] modalDelegate: self
542                    didEndSelector: @selector(failureSheetClosed:returnCode:contextInfo:) contextInfo: nil];
543        }
544    }
545    else
546    {
547        [fProgressIndicator setDoubleValue: (double)fInfo->pieceIndex / fInfo->pieceCount];
548       
549        if (!fStarted)
550        {
551            fStarted = YES;
552           
553            [fProgressView setHidden: YES];
554           
555            NSWindow * window = [self window];
556            [window setFrameAutosaveName: @""];
557           
558            NSRect windowRect = [window frame];
559            CGFloat difference = [fProgressView frame].size.height - [[window contentView] frame].size.height;
560            windowRect.origin.y -= difference;
561            windowRect.size.height += difference;
562           
563            //don't allow vertical resizing
564            CGFloat height = windowRect.size.height;
565            [window setMinSize: NSMakeSize([window minSize].width, height)];
566            [window setMaxSize: NSMakeSize([window maxSize].width, height)];
567           
568            [window setContentView: fProgressView];
569            [window setFrame: windowRect display: YES animate: YES];
570            [fProgressView setHidden: NO];
571           
572            [[window standardWindowButton: NSWindowCloseButton] setEnabled: NO];
573        }
574    }
575}
576
577- (void) failureSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info
578{
579    [[alert window] orderOut: nil];
580    [[self window] close];
581}
582
583@end
Note: See TracBrowser for help on using the repository browser.