root/branches/0_9_1/qcontrol/cocoaDownloadController.m

Revision 84, 31.8 KB (checked in by cordney, 3 years ago)

[fix] downloader: check if freeoszoo is up, else show only kju-app guests
[new] hint for keyboard shortcuts when entering fullscreen mode
[fix] localization: German (several)
[fix] some NSLog's ;)

Line 
1/*
2 * QEMU Cocoa Control Download Controller
3 *
4 * Copyright (c) 2006 René Korthaus
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * 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
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24 
25#import "cocoaDownloadController.h"
26#import "cocoaControlController.h"
27
28#define preferences [NSUserDefaults standardUserDefaults]
29
30@implementation cocoaDownloadController
31
32- (id) init
33{
34    self = [super init];
35    return self;
36}
37
38- (id) initWithSender:(id)sender
39{
40    [sender retain];
41    controller = sender;
42    showsDetails = NO;
43    tableEnabled = YES;
44   
45    return self;
46}
47
48- (void)awakeFromNib
49{
50    [self initDownloadInterface];
51}
52
53#pragma mark -
54#pragma mark Interface Functions
55
56- (void) initDownloadInterface
57{
58    [table setDoubleAction:@selector(startDownload:)];
59    [self showWindow];
60   
61    [NSThread detachNewThreadSelector:@selector(showAllDownloads) toTarget:self withObject:nil];
62    //[self showAllDownloads];
63}
64
65- (void) showWindow
66{
67    [mainDlWindow makeKeyAndOrderFront:self];
68    // if the download-manager is accessed for the 1st time
69    // show the welcome panel
70    /* CRASHES with: "modal session requires modal window" !
71    if(![preferences objectForKey:@"freeOSZooWelcomeShowed"]) {
72        [NSApp beginModalSessionForWindow:mainDlWindow];
73        [NSApp beginSheet:welcomePanel modalForWindow:mainDlWindow modalDelegate:nil didEndSelector:nil contextInfo:nil];
74        [preferences setObject:[NSNumber numberWithBool:YES] forKey:@"freeOSZooWelcomeShowed"];
75    }
76    */
77}
78
79- (BOOL) returnShowsDetails
80{
81    return showsDetails;
82}
83
84- (void) resizeSmall
85{
86    NSRect windowFrame;
87        NSRect newWindowFrame;
88
89        windowFrame = [mainDlWindow frame];
90        newWindowFrame = NSMakeRect(windowFrame.origin.x, windowFrame.origin.y + [detailsNSView bounds].size.height, windowFrame.size.width, windowFrame.size.height - [detailsNSView bounds].size.height);
91
92    if ([detailsNSView superview]) {
93        [detailsNSView retain];
94        [detailsNSView removeFromSuperview];
95    }
96        [mainDlWindow setFrame:newWindowFrame display:YES animate:YES];
97        showsDetails = NO;
98}
99
100- (void) resizeBig
101{
102    NSRect windowFrame;
103        NSRect newWindowFrame;
104
105        windowFrame = [mainDlWindow frame];
106        newWindowFrame = NSMakeRect(windowFrame.origin.x, windowFrame.origin.y - [detailsNSView bounds].size.height,    windowFrame.size.width, [detailsNSView bounds].size.height + windowFrame.size.height);
107   
108    [mainDlWindow setFrame:newWindowFrame display:YES animate:YES];
109    [[mainDlWindow contentView] addSubview:detailsNSView];
110        showsDetails = YES;
111}
112
113- (void) showAllDownloads
114{
115    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
116    // load downloadLists
117    // save an original of the list so we dont have to load it again
118    if(downloadOriginalList == nil || [downloadOriginalList count] == 0) {
119        // first call in the class || call again when initially list not loaded
120        if(downloadOriginalList == nil) {
121            downloadOriginalList = [[[NSMutableArray alloc] init] retain];
122            downloadList = [[[NSMutableArray alloc] init] retain];
123        }
124       
125        [statusText setStringValue: NSLocalizedStringFromTable(@"showAllDownloads:statusText", @"Localizable", @"cocoaDownloadController")];
126        [statusBar setDoubleValue:0.0];
127        [statusText setHidden:NO];
128        [statusBar setHidden:NO];
129        [statusBar setIndeterminate:YES];
130        [statusBar startAnimation:self];
131   
132        NSArray * dlList = [self getDownloadListFromServer];
133       
134        BOOL serverUp = [self checkFreeOSZooIsUp];
135       
136        [statusText setStringValue: NSLocalizedStringFromTable(@"showAllDownloads:statusText2", @"Localizable", @"cocoaDownloadController")];
137        [statusBar setDoubleValue:0.0];
138        //[statusText setHidden:YES];
139        //[statusBar setHidden:YES];
140        [statusBar setIndeterminate:NO];
141        [statusBar stopAnimation:self];
142   
143        // copy downloadList
144        if(dlList != nil) {
145            // check if freeoszoo is up, else only add the kju-app guests
146            if(serverUp) {
147                [downloadList addObjectsFromArray:dlList];
148            } else {
149            int i;
150                for (i=0; i < [dlList count]; i++) {
151                    if([[dlList objectAtIndex:i] valueForKey:@"Kju"] == [NSNumber numberWithInt:1])
152                        [downloadList addObject: [dlList objectAtIndex:i]];
153                }
154            }
155            [self prepareOSTypeSelector];
156            [self showWindow];
157        } else {
158            // download list is nil, spawn error message
159            //NSLog(@"Could not load list.");
160            NSBeginAlertSheet(NSLocalizedStringFromTable(@"showAllDownloads:AlertSheet:standardAlert", @"Localizable", @"cocoaDownloadController"),NSLocalizedStringFromTable(@"showAllDownloads:AlertSheet:defaultButton", @"Localizable", @"cocoaDownloadController"),nil,nil,mainDlWindow,self,@selector(listDownloadFailedAlertSheetDidEnd:returnCode:contextInfo:),nil,nil,NSLocalizedStringFromTable(@"showAllDownloads:AlertSheet:informativeText", @"Localizable", @"cocoaDownloadController"));
161        }
162        [downloadOriginalList addObjectsFromArray:downloadList];
163    } else {
164        // list is still there, we dont have to download it again
165        // when we call it later we only need the original list
166        [downloadList removeAllObjects];
167        [downloadList addObjectsFromArray:downloadOriginalList];
168        [self showWindow];
169    }
170    // force table reload
171    [table reloadData];
172    // force showDetails update
173    if([self returnShowsDetails]) [self showDetails:[table selectedRow]];
174   
175    [pool release];     
176}
177
178- (BOOL) checkFreeOSZooIsUp
179{
180    BOOL isUp = NO;
181    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString:@"http://oszoo.org"]];
182    [request setHTTPMethod:@"HEAD"];
183    NSHTTPURLResponse *response = nil;
184    [NSURLConnection sendSynchronousRequest:request
185                              returningResponse:&response
186                                          error:NULL];
187    if ((response != nil) && ([response statusCode] == 200))
188        isUp = YES;
189    return isUp;
190}
191
192- (void) listDownloadFailedAlertSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(id)contextInfo
193{
194    // return code of no interest here, we just want to have the downloads window closed
195    [mainDlWindow orderOut:self];
196}
197- (void) prepareOSTypeSelector
198{
199    // fill 'all' and space
200    [osTypeSelect removeAllItems];
201    [osTypeSelect addItemWithTitle:@"All"];
202    [[osTypeSelect menu] addItem:[NSMenuItem separatorItem]];
203    int i,j;
204    BOOL found = NO;
205    NSMutableArray * array = [NSMutableArray arrayWithCapacity:1];
206    for(i=0; i<[downloadList count]; i++) {
207        // if the Category is not listed yet in array add it
208        for(j=0; j<[array count]; j++) {
209            // search array
210            if([[array objectAtIndex:j] isEqualTo:[[downloadList objectAtIndex:i] objectForKey:@"Category"]]) {
211                found = YES;
212            }
213        }
214        if(!found) [array addObject:[[downloadList objectAtIndex:i] objectForKey:@"Category"]];
215        found = NO;
216    }
217   
218    // add to selector
219    for(i=0; i<[array count]; i++) {
220        [osTypeSelect addItemWithTitle:[array objectAtIndex:i]];
221    }
222}
223
224- (IBAction) showDownloadsByType:(id)sender
225{
226    //NSLog(@"showDownloadsByType:");
227    // method for the popupbutton to select os type
228    NSMutableArray * array = [NSMutableArray arrayWithCapacity:1];
229    if([[osTypeSelect titleOfSelectedItem] isEqualToString:@"All"]) {
230        //NSLog(@"dlO: %@", downloadOriginalList);
231        [array addObjectsFromArray:downloadOriginalList];
232    } else {
233        // be sure that we have the original downloadList here
234        [downloadList removeAllObjects];
235        [downloadList addObjectsFromArray:downloadOriginalList];
236        int i;
237        for (i=0; i<=[downloadList count]-1; i++) {
238            // search for ostype and add equalling entries
239            if ([[[downloadList objectAtIndex:i] valueForKey:@"Category"] isEqualTo:[osTypeSelect titleOfSelectedItem]]) {
240                [array addObject:[downloadList objectAtIndex:i]];
241            }
242        }
243    }
244   
245    // write os by found criteria/original downloads into downloadList
246    [downloadList removeAllObjects];
247    [downloadList addObjectsFromArray:array];
248       
249    // force table reload
250    [table reloadData];
251    // force showDetails update
252    if([self returnShowsDetails]) [self showDetails:[table selectedRow]];
253}
254
255- (void) disableTableView:(BOOL)disable
256{
257    NSEnumerator * ec = [[table tableColumns] objectEnumerator];
258    NSTableColumn * curColumn;
259    NSColor * textColor = nil;
260    NSColor * backgroundColor = nil;
261   
262    if(disable) {
263        textColor = [NSColor colorWithCalibratedWhite:0.50 alpha:1.0];
264        backgroundColor = [NSColor colorWithCalibratedWhite:0.94 alpha:1.0];
265        tableEnabled = NO;
266    } else {
267        textColor = [NSColor blackColor];
268        backgroundColor = [NSColor colorWithCalibratedWhite:0.94 alpha:1.0];
269        tableEnabled = YES;
270    }
271   
272    while ((curColumn = [ec nextObject])) {
273        if([[curColumn dataCell] isKindOfClass:[NSTextFieldCell class]]) {
274                [[curColumn dataCell] setTextColor:textColor];
275                [[curColumn dataCell] setBackgroundColor:backgroundColor];
276        }
277    }
278   
279    if([[table enclosingScrollView] hasVerticalScroller])
280        [[[table enclosingScrollView] verticalScroller] setEnabled:!disable];
281
282    //if([[table enclosingScrollView] hasHorizontalScroller])
283        //[[[table enclosingScrollView] horizontalScroller] setEnabled:(bEnable && saveHorizontalScrollerEnabled)];
284}
285
286#pragma mark Table Delegate Methods needed for the disableTableView method
287
288- (BOOL)selectionShouldChangeInTableView:(NSTableView *)aTableView
289{
290    return tableEnabled;
291}
292
293- (BOOL)tableView:(NSTableView *)aTableView shouldEditTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
294{
295    return tableEnabled;
296}
297
298- (BOOL)tableView:(NSTableView *)aTableView shouldSelectRow:(int)rowIndex
299{
300    return tableEnabled;
301}
302
303- (BOOL)tableView:(NSTableView *)aTableView shouldSelectTableColumn:(NSTableColumn *)aTableColumn
304{
305    return tableEnabled;
306}
307
308#pragma mark main table Delegate Methods
309
310- (int)numberOfRowsInTableView:(NSTableView *)tableView
311{
312        return [downloadList count];
313}
314
315- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(int)row
316{       
317        id thisDownload;
318        thisDownload = [downloadList objectAtIndex:row];
319       
320        if ([[tableColumn identifier] isEqualToString:@"name"]) {
321           // return name and version
322           NSMutableAttributedString *attrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat: @"%@ %@\n", [thisDownload objectForKey:@"Name"], [thisDownload objectForKey:@"Version"]] attributes:[NSDictionary dictionaryWithObject: [NSFont boldSystemFontOfSize:[NSFont systemFontSize]] forKey:NSFontAttributeName]] autorelease];
323           [attrString appendAttributedString: [[[NSAttributedString alloc] initWithString:[NSString stringWithFormat: @"%@, %@. %@: %@ MB\n%@ %@.", [thisDownload objectForKey:@"Category"], [thisDownload objectForKey:@"InstallType"], NSLocalizedStringFromTable(@"tableView:objectValueForTableColumn:Size", @"Localizable", @"cocoaDownloadController"), [thisDownload objectForKey:@"DownloadSize"], NSLocalizedStringFromTable(@"tableView:objectValueForTableColumn:Author", @"Localizable", @"cocoaDownloadController"), [thisDownload objectForKey:@"Author"]] attributes:[NSDictionary dictionaryWithObject:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]] forKey:NSFontAttributeName]] autorelease]];
324           
325                return attrString;
326        } else if([[tableColumn identifier] isEqualToString:@"kju"]) {
327                if([thisDownload valueForKey:@"Kju"] == [NSNumber numberWithInt:1])
328                  return [NSImage imageNamed:@"q_icon.icns"];
329        return nil;
330    } else {
331        return @"";
332        }
333        return nil;
334}
335
336- (void)tableViewSelectionDidChange:(NSNotification *)aNotification
337{
338        // TODO: implement window size change for the first selection
339        if([table selectedRow] != -1) {
340        if(![self returnShowsDetails]) {
341            [self resizeBig];
342        }
343        [self showDetails:[table selectedRow]];
344    } else {
345        // reset OS details and make window small
346        [detailsTextView setString:@""];
347        if([self returnShowsDetails]) [self resizeSmall];
348    }
349}
350
351#pragma mark -
352#pragma mark Data Functions
353
354- (NSArray *)getDownloadListFromServer
355{
356    // show status panel
357    /*[NSApp beginSheet:precheckPanel
358        modalForWindow:mainDlWindow
359        modalDelegate:nil
360        didEndSelector:nil
361        contextInfo:nil];
362    [precheckPanel orderFront:self];
363    //[NSApp runModalForWindow: precheckPanel];
364    [precheckStatusTextView setStringValue:@"Getting list from server.."];
365    [precheckStatusProgressView startAnimation:self];
366    // arrayWithContentsOfURL: url
367    NSURLResponse * response;
368    NSError * error;
369    NSData * data = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://cordney.com/q/freeoszoo.plist"]] returningResponse:nil error:nil];
370    NSArray * downloadList = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListMutableContainersAndLeaves format:nil errorDescription:nil];
371    */
372       
373    NSArray * downloadList = [NSArray arrayWithContentsOfURL:[NSURL URLWithString:@"http://kju-app.org/data/freeoszoo_v2.plist"]];
374    return downloadList;
375}
376
377// NSURLHandleClient This informal protocol defines the interface for clients to NSURL. A client is an object loading a URL resource in the background.
378/*
379- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
380{   
381    NSLog(@"Data available..");
382    //[[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantPast]];
383}
384-(void)connectionDidFinishLoading:(NSURLConnection *)connection
385{
386    NSLog(@"Download finished");
387    [precheckStatusTextView setStringValue:@"Got list from server.."];
388    // todo: connectivity check freeoszoo.org
389    [NSApp endSheet:precheckPanel];
390    //[NSApp stopModal];
391    [precheckPanel orderOut:self];
392    [precheckStatusTextView setStringValue:@"Loading.."];
393    [precheckStatusProgressView stopAnimation:self];
394    [table reloadData];
395}
396
397- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
398{
399    NSLog(@"Download failed: %@", error);
400}
401*/
402
403- (void) showDetails:(int)row
404{
405    showsDetails = YES;
406    // clear textView
407    [detailsTextView setString:@""];
408    NSDictionary * details = [[NSDictionary alloc] initWithDictionary:[downloadList objectAtIndex:row]];
409   
410    // create name and version
411    NSDictionary * nameAttr = [NSDictionary dictionaryWithObject:[NSFont boldSystemFontOfSize:12] forKey:NSFontAttributeName];
412    NSAttributedString * detailsName = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%@ %@", [details objectForKey:@"Name"], [details objectForKey:@"Version"]] attributes:nameAttr];
413    NSAttributedString * detailsDesc = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n%@", [details objectForKey:@"Description"]]];
414    NSAttributedString * detailsURLpre = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"\n%@: ", NSLocalizedStringFromTable(@"showDetails:MoreInfo", @"Localizable", @"cocoaDownloadController")]];
415    NSAttributedString * detailsURL = [[NSAttributedString alloc] initWithString:[details objectForKey:@"InfopageURL"] attributes:[NSDictionary dictionaryWithObject:[details objectForKey:@"InfopageURL"] forKey:NSLinkAttributeName]];
416    // create spacer
417    NSAttributedString * spacer = [[NSAttributedString alloc] initWithString:@"\n"];
418   
419    // append strings to textView
420    [[detailsTextView textStorage] appendAttributedString:spacer];
421    //[[detailsTextView textStorage] appendAttributedString:detailsLogo];
422    [[detailsTextView textStorage] appendAttributedString:detailsName];
423    [[detailsTextView textStorage] appendAttributedString:spacer];
424    [[detailsTextView textStorage] appendAttributedString:detailsDesc];
425    [[detailsTextView textStorage] appendAttributedString:spacer];
426    [[detailsTextView textStorage] appendAttributedString:detailsURLpre];
427    [[detailsTextView textStorage] appendAttributedString:detailsURL];
428
429   
430    // release objects
431    //[logo release];
432    //[attachment release];
433    [detailsName release];
434    [detailsDesc release];
435    [detailsURLpre release];
436    [detailsURL release];
437    [spacer release];
438    [details release];
439}
440
441- (IBAction)startDownload:(id)sender
442{
443    if ([table selectedRow] != -1) {
444        id thisDownload = [downloadList objectAtIndex:[table selectedRow]];
445       
446        // 1. init download object, set values
447        // TODO: distinguish between HTTP&BT, url pathExtension?
448        if([thisDownload valueForKey:@"Torrent"] == [NSNumber numberWithInt:1])
449            download = [[[cocoaDownload alloc] initWithBT] retain];
450        else
451            download = [[[cocoaDownload alloc] initWithHTTP] retain];
452           
453        if([[thisDownload objectForKey:@"Version"] isEqualToString:@""])
454            [download setName:[thisDownload objectForKey:@"Name"]];
455        else
456            [download setName:[NSString stringWithFormat:@"%@ %@", [thisDownload objectForKey:@"Name"], [thisDownload objectForKey:@"Version"]]];
457       
458        if([thisDownload valueForKey:@"Kju"] == [NSNumber numberWithInt:1])
459            [download setQVM: YES];
460           
461        [download setURL:[thisDownload objectForKey:@"DownloadURL"]];
462        // - monitor the download object with NSNotifications
463        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidReceiveResponse:) name:@"DownloadDidReceiveResponse" object:download];
464        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(startStatusTimer:) name:@"DownloadDidReceiveData" object:download];
465        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidFinish:) name:@"DownloadDidFinish" object:download];
466        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidFail:) name:@"DownloadDidFail" object:download];
467                                                       
468        // 2. set to downloading mode
469        [self disableTableView:YES];
470        [osTypeSelect setEnabled:NO];
471        [table setDoubleAction:nil];
472        [downloadButton setTitle:NSLocalizedStringFromTable(@"startDownload:downloadButton:Title", @"Localizable", @"cocoaDownloadController")];
473        [downloadButton setAction:@selector(stopDownload:)];
474        if([self returnShowsDetails]) [self resizeSmall];
475       
476        [statusText setStringValue:NSLocalizedStringFromTable(@"startDownload:statusText:Text", @"Localizable", @"cocoaDownloadController")];
477        [statusBar setDoubleValue:0.0];
478        [statusText setHidden:NO];
479        [statusBar setHidden:NO];
480        [statusBar setIndeterminate:YES];
481        [statusBar startAnimation:self];
482       
483        [download startDownload];
484    }
485}
486
487- (IBAction)stopDownload:(id)sender
488{
489    NSBeginAlertSheet(NSLocalizedStringFromTable(@"stopDownload:AlertSheet:standardAlert", @"Localizable", @"cocoaDownloadController"),NSLocalizedStringFromTable(@"stopDownload:AlertSheet:defaultButton", @"Localizable", @"cocoaDownloadController"),NSLocalizedStringFromTable(@"stopDownload:AlertSheet:alternativeButton", @"Localizable", @"cocoaDownloadController"),nil,mainDlWindow,self,@selector(stopDownloadSheetDidEnd:returnCode:contextInfo:),nil,nil,NSLocalizedStringFromTable(@"stopDownload:AlertSheet:informativeText", @"Localizable", @"cocoaDownloadController"));
490}
491
492- (void)stopDownloadSheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
493{       
494        if ( returnCode == NSAlertDefaultReturn ) {
495                // Stop download and delete files
496                [download stopDownload];
497        [statusText setStringValue:@"Download cancelled."];
498        [self cleanupDownload:[[download getSavePath] stringByDeletingLastPathComponent]];
499        [[NSFileManager defaultManager] removeFileAtPath:[[download getSavePath] stringByDeletingLastPathComponent] handler:nil];
500        [download release];
501        }
502}
503
504#pragma mark -
505#pragma mark Download Notification Functions
506
507- (void) downloadDidReceiveResponse:(NSNotification *)aNotification
508{
509    [statusText setStringValue:@"Download started..."];
510    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidReceiveResponse" object:download];
511    // do we need to do more here ?
512}
513
514- (void) startStatusTimer:(NSNotification *)aNotification
515{
516    // start the timer to update the text progress every 1sec
517    statusTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateProgressText:) userInfo:nil repeats:YES];
518   
519    // change receiveData notification to downloadDidReceiveData notification
520    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidReceiveData" object:download];
521    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downloadDidReceiveData:) name:@"DownloadDidReceiveData" object:download];
522}
523
524// Update the progressBar whenever data was received to have
525// a smooth progress view
526- (void) downloadDidReceiveData:(NSNotification *)aNotification
527{
528    float expectedData = [download getExpectedData];
529    float receivedData = [download getReceivedData];
530   
531    if([statusBar maxValue] == 100.0)
532        [statusBar setMaxValue:(double)expectedData];
533    [statusBar setDoubleValue:(double)receivedData];
534}
535
536// Update the progress text only every 1sec
537- (void) updateProgressText:(NSTimer *)theTimer
538{
539    int lastRCVData = [download getLastReceivedData];
540    float expectedData = [download getExpectedData];
541    float receivedData = [download getReceivedData];
542   
543    float expectedKB = expectedData/1024;
544    float expectedMB = expectedKB/1024;
545    float receivedKB = receivedData/1024;
546    float receivedMB = receivedKB/1024;
547   
548    float expectedD = expectedKB;
549    float receivedD = receivedKB;
550    NSString * dSize = @"kB";
551    NSString * tDSize = @"kB";
552   
553    if(expectedKB >= 1024) {
554        expectedD = expectedMB;
555        tDSize = @"MB";
556    }
557    if(receivedKB >= 1024) {
558        receivedD = receivedMB;
559        dSize = @"MB";
560    }
561   
562    int time_rsec = (expectedData-receivedData)/lastRCVData;
563    int time_rmin = time_rsec / 60;
564    int time_rhour = time_rsec / 60 / 60;
565    int time_rlmin = time_rmin - time_rhour*60;
566    int time_rlsec = time_rsec - time_rlmin*60 - time_rhour*60*60;
567   
568    NSString * remainingString;
569   
570    if(time_rhour >= 1) {
571        remainingString = [NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:remainingString1", @"Localizable", @"cocoaDownloadController"), time_rhour, time_rlmin, time_rlsec];
572    } else if(time_rmin >= 1 && time_rmin < 10) {
573        remainingString = [NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:remainingString2", @"Localizable", @"cocoaDownloadController"), time_rmin, time_rlsec];
574    } else if(time_rmin >=1) {
575        remainingString = [NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:remainingString3", @"Localizable", @"cocoaDownloadController"), time_rmin];
576    } else {
577        remainingString = [NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:remainingString4", @"Localizable", @"cocoaDownloadController"), time_rsec];
578    }
579   
580    if(receivedKB < 10.0) {
581        [statusText setStringValue:NSLocalizedStringFromTable(@"downloadDidReceiveData:connecting", @"Localizable", @"cocoaDownloadController")];
582    } else {
583        if([statusBar isIndeterminate])
584            [statusBar setIndeterminate:NO];
585        if(receivedKB <= 1024) {
586            [statusText setStringValue:[NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:statusText1", @"Localizable", @"cocoaDownloadController"), receivedD, dSize, expectedD, tDSize, lastRCVData/1024, remainingString]];
587        } else {
588            [statusText setStringValue:[NSString stringWithFormat:NSLocalizedStringFromTable(@"downloadDidReceiveData:statusText2", @"Localizable", @"cocoaDownloadController"), receivedD, dSize, expectedD, tDSize, lastRCVData/1024, remainingString]];
589        }
590    }
591}
592
593- (void) downloadDidFinish:(NSNotification *)aNotification
594{
595    /* XXX FEHLERQUELLE !!! XXX */
596   
597    [statusText setStringValue: NSLocalizedStringFromTable(@"downloadDidFinish:statusText", @"Localizable", @"cocoaDownloadController")];
598    [downloadButton setAction:nil];
599   
600    // call some File Manipulation Functions here
601    // e.g. uncompress, move, ...
602    [download stopDownload];
603    [self cleanupDownload:[[download getSavePath] stringByDeletingLastPathComponent]];
604    [self uncompressPC:[download getSavePath]];
605}
606
607- (void) downloadDidFail:(NSNotification *)aNotification
608{
609    //NSLog(@"Download did fail: %@", [[aNotification userInfo] objectForKey:@"ERROR_DESCRIPTION"]);
610   
611    // delete qvm
612    //NSLog(@"savepath: %@", [download getSavePath]);
613    if(![[[download getSavePath] stringByDeletingLastPathComponent] isEqualTo:@""] || [[download getSavePath] stringByDeletingLastPathComponent] != nil) {
614        NSFileManager * manager = [NSFileManager defaultManager];
615        [manager removeFileAtPath:[[download getSavePath] stringByDeletingLastPathComponent] handler:nil];
616    }
617   
618    // reset UI
619    [self cleanupDownload:[[download getSavePath] stringByDeletingLastPathComponent]];
620    [statusText setStringValue: NSLocalizedStringFromTable(@"downloadDidFail:statusText", @"Localizable", @"cocoaDownloadController")];
621   
622    [download release];
623   
624    // alert sheet
625    NSBeginAlertSheet(NSLocalizedStringFromTable(@"downloadDidFail:AlertSheet:standardAlert", @"Localizable", @"cocoaDownloadController"),NSLocalizedStringFromTable(@"downloadDidFail:AlertSheet:defaultButton", @"Localizable", @"cocoaDownloadController"),nil,nil,mainDlWindow,self,nil,nil,nil,[[aNotification userInfo] objectForKey:@"ERROR_DESCRIPTION"]);
626}
627
628- (void) cleanupDownload:(NSString *)path
629{
630    //NSLog(@"Cleaning up after download..");
631    if(statusTimer) {
632        [statusTimer invalidate];
633    }     
634   
635    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidReceiveResponse" object:download];
636    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidReceiveData" object:download];
637    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidFinish" object:download];
638    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"DownloadDidFail" object:download];
639   
640    [statusBar stopAnimation:self];
641    [statusBar setIndeterminate:NO];
642    [statusBar setDoubleValue:0.0];
643    [statusBar setMaxValue:100.0];
644   
645    [table setDoubleAction:@selector(startDownload:)];
646    [downloadButton setTitle:@"Download"];
647    [downloadButton setAction:@selector(startDownload:)];
648    // enable tableview
649    [osTypeSelect setEnabled:YES];
650    [self disableTableView:NO];
651}
652
653#pragma mark -
654#pragma mark File Manipulation Functions
655
656- (void)uncompressPC:(NSString *)path
657{
658    [statusText setStringValue: NSLocalizedStringFromTable(@"uncompressPC:statusText", @"Localizable", @"cocoaDownloadController")];
659    [statusBar setIndeterminate:YES];
660    [statusBar startAnimation:self];
661    NSTask * task = [[[NSTask alloc] init] retain];
662    BOOL isArchive = NO;
663    if([[path pathExtension] isEqualTo:@"tar"] || [[path pathExtension] isEqualTo:@"bz"] || [[path pathExtension] isEqualTo:@"bz2"] || [[path pathExtension] isEqualTo:@"gz"]) {
664        [task setLaunchPath:@"/usr/bin/tar"];
665        NSString * fmtArgs;
666        if([[path pathExtension] isEqualTo:@"bz"] || [[path pathExtension] isEqualTo:@"bz2"]) {
667            fmtArgs = @"-xjf";
668        } else if ([[path pathExtension] isEqualTo:@"gz"]) {
669            fmtArgs = @"-xzf";
670        } else {
671            fmtArgs = @"-xf";
672        }
673        [task setArguments:[NSArray arrayWithObjects:fmtArgs, path, nil]];
674        isArchive = YES;
675    } else if([[path pathExtension] isEqualTo:@"zip"]) {
676        [task setLaunchPath:@"/usr/bin/unzip"];
677        [task setArguments:[NSArray arrayWithObjects:path, nil]];
678        isArchive = YES;
679    }
680
681    if(isArchive) {
682        [task setCurrentDirectoryPath:[path stringByDeletingLastPathComponent]];
683        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(uncompressPCFinished:) name:NSTaskDidTerminateNotification object:task];
684        [task launch];
685    } else {
686        NSLog(@"Could not detect file format. No archive?");
687        [self finishDownload:1 withStatus:0];
688    }
689    [task release];
690}
691
692- (void)uncompressPCFinished:(NSNotification *)aNotification
693{
694    [self finishDownload:0 withStatus:[[aNotification object] terminationStatus]];
695    //NSLog(@"extract finished Notify");
696}
697
698- (void) finishDownload:(int)sender withStatus:(int)status
699{
700//  NSLog(@"cocoaDownloadController: finishDownload");
701    NSString * message;       
702    NSString * path = [download getSavePath];
703    NSString * name = [download getName];
704   
705    // start import into Q
706    [statusText setStringValue: NSLocalizedStringFromTable(@"finishDownload:statusText1", @"Localizable", @"cocoaDownloadController")];
707    if([controller importFreeOSZooPC:name withPath: [path stringByDeletingLastPathComponent]]) {
708        message = NSLocalizedStringFromTable(@"finishDownload:message1", @"Localizable", @"cocoaDownloadController");
709    } else {
710        message = NSLocalizedStringFromTable(@"finishDownload:message2", @"Localizable", @"cocoaDownloadController");
711    }
712   
713    // sender: 0: task, 1: file check
714    if(sender == 0) {
715        if(status == 0) {
716            //NSLog(@"Task succeeded.");
717            // delete downloaded file, leave message unchanged
718            NSFileManager * manager = [NSFileManager defaultManager];
719            [manager removeFileAtPath:path handler:nil];
720        } else {
721            //NSLog(@"Task failed.");
722            // do not delete file, set message to failed
723            message = [NSString stringWithFormat: NSLocalizedStringFromTable(@"finishDownload:message2", @"Localizable", @"cocoaDownloadController"), path];
724        }
725    } else if(sender == 1) {
726        message = [NSString stringWithFormat: NSLocalizedStringFromTable(@"finishDownload:message2", @"Localizable", @"cocoaDownloadController"), path];
727    }
728   
729    NSAlert *alert = [NSAlert alertWithMessageText:  NSLocalizedStringFromTable(@"finishDownload:AlertSheet:messageText", @"Localizable", @"cocoaDownloadController")
730                defaultButton:  NSLocalizedStringFromTable(@"finishDownload:AlertSheet:defaultButton", @"Localizable", @"cocoaDownloadController")
731                alternateButton:nil
732                otherButton:nil
733                informativeTextWithFormat:message];
734
735    [alert beginSheetModalForWindow:mainDlWindow
736                modalDelegate:self
737                didEndSelector:nil
738                contextInfo:nil];
739   
740    [statusText setStringValue:  NSLocalizedStringFromTable(@"finishDownload:statusText2", @"Localizable", @"cocoaDownloadController")];
741    [statusBar setMaxValue:100.0];
742    [statusBar setDoubleValue:0.0];
743    [statusBar setIndeterminate:NO];
744    [downloadButton setAction:@selector(startDownload:)];
745    [download release];
746}
747
748- (void) dealloc
749{
750    // cleanup here..
751    [downloadList release];
752    [downloadOriginalList release];
753    [controller release];
754    [super dealloc];
755}
756
757@end
Note: See TracBrowser for help on using the browser.