From ecc314c694d3fa735855d10d57770ba447332816 Mon Sep 17 00:00:00 2001 From: Sven Weidauer Date: Fri, 14 Jan 2011 12:46:06 +0000 Subject: Implemented download window svn path=/trunk/netsurf/; revision=11317 --- cocoa/DownloadWindowController.h | 49 ++++ cocoa/DownloadWindowController.m | 242 +++++++++++++++++ cocoa/NetSurf.xcodeproj/project.pbxproj | 10 + cocoa/gui.m | 29 -- cocoa/res/DownloadWindow.xib | 454 ++++++++++++++++++++++++++++++++ 5 files changed, 755 insertions(+), 29 deletions(-) create mode 100644 cocoa/DownloadWindowController.h create mode 100644 cocoa/DownloadWindowController.m create mode 100644 cocoa/res/DownloadWindow.xib (limited to 'cocoa') diff --git a/cocoa/DownloadWindowController.h b/cocoa/DownloadWindowController.h new file mode 100644 index 000000000..0115c4597 --- /dev/null +++ b/cocoa/DownloadWindowController.h @@ -0,0 +1,49 @@ +/* + * Copyright 2011 Sven Weidauer + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import + + +@interface DownloadWindowController : NSWindowController { + struct download_context *context; + unsigned long totalSize; + unsigned long receivedSize; + + NSURL *url; + NSString *mimeType; + NSURL *saveURL; + NSFileHandle *outputFile; + NSMutableData *savedData; + NSDate *startDate; +} + +@property (readwrite, copy, nonatomic) NSURL *URL; +@property (readwrite, copy, nonatomic) NSString *MIMEType; +@property (readwrite, assign, nonatomic) unsigned long totalSize; +@property (readwrite, copy, nonatomic) NSURL *saveURL; +@property (readwrite, assign, nonatomic) unsigned long receivedSize; + +@property (readonly, nonatomic) NSString *fileName; +@property (readonly, nonatomic) NSImage *icon; +@property (readonly, nonatomic) NSString *statusText; + +- initWithContext: (struct download_context *)ctx; + +- (void) abort; + +@end diff --git a/cocoa/DownloadWindowController.m b/cocoa/DownloadWindowController.m new file mode 100644 index 000000000..832ffc01c --- /dev/null +++ b/cocoa/DownloadWindowController.m @@ -0,0 +1,242 @@ +/* + * Copyright 2011 Sven Weidauer + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#import "DownloadWindowController.h" + +#import "desktop/download.h" + +#define UNIMPL() NSLog( @"Function '%s' unimplemented", __func__ ) + +@interface DownloadWindowController () + +@property (readwrite, retain, nonatomic) NSFileHandle *outputFile; +@property (readwrite, retain, nonatomic) NSMutableData *savedData; +@property (readwrite, copy, nonatomic) NSDate *startDate; + +- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; + +- (BOOL) receivedData: (NSData *)data; + +- (void) showError: (NSString *)error; + +@end + + +@implementation DownloadWindowController + +- initWithContext: (struct download_context *)ctx; +{ + if ((self = [super initWithWindowNibName: @"DownloadWindow"]) == nil) return nil; + + context = ctx; + totalSize = download_context_get_total_length( context ); + [self setURL: [NSURL URLWithString: [NSString stringWithUTF8String: download_context_get_url( context )]]]; + [self setMIMEType: [NSString stringWithUTF8String: download_context_get_mime_type( context )]]; + [self setStartDate: [NSDate date]]; + + return self; +} + +- (void) dealloc; +{ + download_context_destroy( context ); + + [self setURL: nil]; + [self setMIMEType: nil]; + [self setSaveURL: nil]; + [self setOutputFile: nil]; + [self setSavedData: nil]; + [self setStartDate: nil]; + + [super dealloc]; +} + +- (void) abort; +{ + download_context_abort( context ); +} + +- (void) askForSave; +{ + [[NSSavePanel savePanel] beginSheetForDirectory: nil + file: [[url path] lastPathComponent] + modalForWindow: [self window] + modalDelegate: self + didEndSelector: @selector(savePanelDidEnd:returnCode:contextInfo:) + contextInfo: NULL]; +} + +- (void)savePanelDidEnd:(NSSavePanel *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo; +{ + if (returnCode == NSCancelButton) { + [self abort]; + return; + } + + NSURL *targetURL = [sheet URL]; + NSString *path = [targetURL path]; + + [[NSFileManager defaultManager] createFileAtPath: path contents: nil attributes: nil]; + [self setOutputFile: [NSFileHandle fileHandleForWritingAtPath: path]]; + [self setSaveURL: targetURL]; + + NSWindow *win = [self window]; + [win setRepresentedURL: targetURL]; + [win setTitle: [self fileName]]; + + if (nil == outputFile) { + [self performSelector: @selector(showError:) withObject: @"Cannot create file" afterDelay: 0]; + return; + } + + if (nil != savedData) { + [outputFile writeData: savedData]; + [self setSavedData: nil]; + } +} + +- (BOOL) receivedData: (NSData *)data; +{ + if (outputFile) { + [outputFile writeData: data]; + } else { + if (nil == savedData) [self setSavedData: [NSMutableData data]]; + [savedData appendData: data]; + } + + [self setReceivedSize: receivedSize + [data length]]; + + return YES; +} + +- (void) showError: (NSString *)error; +{ + NSAlert *alert = [NSAlert alertWithMessageText: @"Error" defaultButton: @"OK" + alternateButton: nil otherButton: nil + informativeTextWithFormat: @"%@", error]; + + [alert beginSheetModalForWindow: [self window] modalDelegate: self + didEndSelector: @selector(alertDidEnd:returnCode:contextInfo:) + contextInfo: NULL]; +} + +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; +{ + [self abort]; +} + +#pragma mark - +#pragma mark Properties + +@synthesize URL = url; +@synthesize MIMEType = mimeType; +@synthesize totalSize; +@synthesize saveURL; +@synthesize outputFile; +@synthesize savedData; +@synthesize receivedSize; +@synthesize startDate; + ++ (NSSet *) keyPathsForValuesAffectingStatusText; +{ + return [NSSet setWithObjects: @"totalSize", @"receivedSize", nil]; +} + +static NSString *cocoa_file_size_string( float size ) +{ + if (size < 1023) return [NSString stringWithFormat:@"%1.0f bytes",size]; + + size /= 1024; + if (size < 1023) return [NSString stringWithFormat:@"%1.1f KiB", size]; + + size /= 1024; + if (size < 1023) return [NSString stringWithFormat:@"%1.1f MiB", size]; + + size /= 1024; + return [NSString stringWithFormat:@"%1.1f GiB", size]; +} + +- (NSString *) statusText; +{ + NSString *speedString = @""; + + float elapsedTime = [[NSDate date] timeIntervalSinceDate: startDate]; + if (elapsedTime >= 0.1) { + float speed = (float)receivedSize / elapsedTime; + speedString = [NSString stringWithFormat: @" (%@/s)", cocoa_file_size_string( speed )]; + } + + return [NSString stringWithFormat: @"%@ of %@%@", cocoa_file_size_string( receivedSize ), + cocoa_file_size_string( totalSize ), speedString]; +} + ++ (NSSet *) keyPathsForValuesAffectingFileName; +{ + return [NSSet setWithObject: @"saveURL"]; +} + +- (NSString *) fileName; +{ + return [[saveURL path] lastPathComponent]; +} + ++ (NSSet *) keyPathsForValuesAffectingIcon; +{ + return [NSSet setWithObject: @"saveURL"]; +} + +- (NSImage *) icon; +{ + return saveURL != nil ? [[NSWorkspace sharedWorkspace] iconForFile: [saveURL path]] : nil; +} + + +#pragma mark - +#pragma mark NetSurf interface functions + +struct gui_download_window *gui_download_window_create(download_context *ctx, + struct gui_window *parent) +{ + DownloadWindowController * const window = [[DownloadWindowController alloc] initWithContext: ctx]; + [window askForSave]; + + return (struct gui_download_window *)window; +} + +nserror gui_download_window_data(struct gui_download_window *dw, + const char *data, unsigned int size) +{ + DownloadWindowController * const window = (DownloadWindowController *)dw; + return [window receivedData: [NSData dataWithBytes: data length: size]] ? NSERROR_OK : NSERROR_SAVE_FAILED; +} + +void gui_download_window_error(struct gui_download_window *dw, + const char *error_msg) +{ + DownloadWindowController * const window = (DownloadWindowController *)dw; + [window showError: [NSString stringWithUTF8String: error_msg]]; +} + +void gui_download_window_done(struct gui_download_window *dw) +{ + DownloadWindowController * const window = (DownloadWindowController *)dw; + [window release]; +} + +@end diff --git a/cocoa/NetSurf.xcodeproj/project.pbxproj b/cocoa/NetSurf.xcodeproj/project.pbxproj index 97ca2d496..aefe384f3 100644 --- a/cocoa/NetSurf.xcodeproj/project.pbxproj +++ b/cocoa/NetSurf.xcodeproj/project.pbxproj @@ -113,6 +113,8 @@ 26AFE63F12DDEB0A005AD082 /* NetSurf.icns in Resources */ = {isa = PBXBuildFile; fileRef = 26AFE63E12DDEB0A005AD082 /* NetSurf.icns */; }; 26AFE8E412DF4200005AD082 /* ScrollableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AFE8E312DF4200005AD082 /* ScrollableView.m */; }; 26AFE97C12DF514C005AD082 /* NetSurfAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AFE97B12DF514C005AD082 /* NetSurfAppDelegate.m */; }; + 26AFEAEB12E04253005AD082 /* DownloadWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 26AFEAEA12E04253005AD082 /* DownloadWindowController.m */; }; + 26AFEAF112E042F9005AD082 /* DownloadWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 26AFEAF012E042F9005AD082 /* DownloadWindow.xib */; }; 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ @@ -331,6 +333,9 @@ 26AFE8E312DF4200005AD082 /* ScrollableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ScrollableView.m; sourceTree = ""; }; 26AFE97A12DF514C005AD082 /* NetSurfAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetSurfAppDelegate.h; sourceTree = ""; }; 26AFE97B12DF514C005AD082 /* NetSurfAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NetSurfAppDelegate.m; sourceTree = ""; }; + 26AFEAE912E04253005AD082 /* DownloadWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadWindowController.h; sourceTree = ""; }; + 26AFEAEA12E04253005AD082 /* DownloadWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadWindowController.m; sourceTree = ""; }; + 26AFEAF012E042F9005AD082 /* DownloadWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DownloadWindow.xib; sourceTree = ""; }; 8D1107320486CEB800E47090 /* NetSurf.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NetSurf.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -610,6 +615,8 @@ 26AFE8E312DF4200005AD082 /* ScrollableView.m */, 26AFE97A12DF514C005AD082 /* NetSurfAppDelegate.h */, 26AFE97B12DF514C005AD082 /* NetSurfAppDelegate.m */, + 26AFEAE912E04253005AD082 /* DownloadWindowController.h */, + 26AFEAEA12E04253005AD082 /* DownloadWindowController.m */, ); name = cocoa; sourceTree = ""; @@ -625,6 +632,7 @@ 265F30A712D6637E0048B600 /* NetSurf-Info.plist */, 26121DA812D700B800E10F91 /* MainMenu.xib */, 26121EAB12D70E0A00E10F91 /* Browser.xib */, + 26AFEAF012E042F9005AD082 /* DownloadWindow.xib */, ); path = res; sourceTree = ""; @@ -748,6 +756,7 @@ 2612266D12D7AD6800E10F91 /* adblock.css in Resources */, 2612269112D7AE4100E10F91 /* Messages in Resources */, 26AFE63F12DDEB0A005AD082 /* NetSurf.icns in Resources */, + 26AFEAF112E042F9005AD082 /* DownloadWindow.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -857,6 +866,7 @@ 2622F1D712DCD84600CD5A62 /* TreeView.m in Sources */, 26AFE8E412DF4200005AD082 /* ScrollableView.m in Sources */, 26AFE97C12DF514C005AD082 /* NetSurfAppDelegate.m in Sources */, + 26AFEAEB12E04253005AD082 /* DownloadWindowController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/cocoa/gui.m b/cocoa/gui.m index 363961dc4..09c80c7b2 100644 --- a/cocoa/gui.m +++ b/cocoa/gui.m @@ -252,33 +252,6 @@ void gui_window_set_scale(struct gui_window *g, float scale) gui_window_redraw_window( g ); } - -struct gui_download_window *gui_download_window_create(download_context *ctx, - struct gui_window *parent) -{ - UNIMPL(); - return NULL; -} - -nserror gui_download_window_data(struct gui_download_window *dw, - const char *data, unsigned int size) -{ - UNIMPL(); - return 0; -} - -void gui_download_window_error(struct gui_download_window *dw, - const char *error_msg) -{ - UNIMPL(); -} - -void gui_download_window_done(struct gui_download_window *dw) -{ - UNIMPL(); -} - - void gui_drag_save_object(gui_save_type type, hlcache_handle *c, struct gui_window *g) { @@ -338,8 +311,6 @@ void gui_launch_url(const char *url) [[NSWorkspace sharedWorkspace] openURL: [NSURL URLWithString: [NSString stringWithUTF8String: url]]]; } - - struct ssl_cert_info; void gui_cert_verify(const char *url, const struct ssl_cert_info *certs, diff --git a/cocoa/res/DownloadWindow.xib b/cocoa/res/DownloadWindow.xib new file mode 100644 index 000000000..9d960d019 --- /dev/null +++ b/cocoa/res/DownloadWindow.xib @@ -0,0 +1,454 @@ + + + + 1050 + 10J567 + 804 + 1038.35 + 462.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 804 + + + YES + + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + YES + + YES + + + YES + + + + YES + + DownloadWindowController + + + FirstResponder + + + NSApplication + + + 15 + 2 + {{196, 429}, {376, 90}} + 544735232 + Download + NSWindow + + {1000, 90} + {330, 90} + + + 256 + + YES + + + 1290 + + {{79, 33}, {279, 20}} + + 16392 + 100 + + + + 268 + + YES + + YES + Apple PDF pasteboard type + Apple PICT pasteboard type + Apple PNG pasteboard type + NSFilenamesPboardType + NeXT Encapsulated PostScript v1.2 pasteboard type + NeXT TIFF v4.0 pasteboard type + + + {{17, 17}, {56, 56}} + + YES + + 130560 + 33554432 + 0 + 3 + 0 + NO + + YES + + + + 266 + {{78, 56}, {261, 17}} + + YES + + 68288064 + 272630784 + Label + + LucidaGrande + 13 + 1044 + + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 266 + {{78, 17}, {281, 14}} + + YES + + 68288064 + 272761856 + Label + + LucidaGrande + 11 + 3100 + + + + + + + + {376, 90} + + + {{0, 0}, {1680, 1028}} + {330, 112} + {1000, 112} + + + + + YES + + + window + + + + 3 + + + + maxValue: totalSize + + + + + + maxValue: totalSize + maxValue + totalSize + 2 + + + 6 + + + + value: receivedSize + + + + + + value: receivedSize + value + receivedSize + + 2 + + + 7 + + + + value: fileName + + + + + + value: fileName + value + fileName + 2 + + + 22 + + + + value: icon + + + + + + value: icon + value + icon + 2 + + + 23 + + + + value: statusText + + + + + + value: statusText + value + statusText + 2 + + + 24 + + + + + YES + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 1 + + + YES + + + + + + 2 + + + YES + + + + + + + + + 4 + + + + + 14 + + + YES + + + + + + 15 + + + + + 16 + + + YES + + + + + + 17 + + + + + 18 + + + YES + + + + + + 19 + + + + + + + YES + + YES + 1.IBEditorWindowLastContentRect + 1.IBPluginDependency + 1.IBWindowTemplateEditedContentRect + 1.NSWindowTemplate.visibleAtLaunch + 1.WindowOrigin + 1.editorWindowContentRectSynchronizationRect + 1.windowTemplate.hasMaxSize + 1.windowTemplate.hasMinSize + 1.windowTemplate.maxSize + 1.windowTemplate.minSize + 14.IBPluginDependency + 14.IBViewBoundsToFrameTransform + 15.IBPluginDependency + 16.IBPluginDependency + 16.IBViewBoundsToFrameTransform + 17.IBPluginDependency + 18.IBPluginDependency + 18.IBViewBoundsToFrameTransform + 19.IBPluginDependency + 2.IBPluginDependency + 4.IBPluginDependency + 4.IBViewBoundsToFrameTransform + + + YES + {{305, 231}, {376, 90}} + com.apple.InterfaceBuilder.CocoaPlugin + {{305, 231}, {376, 90}} + + {196, 240} + {{202, 428}, {480, 270}} + + + {1000, 90} + {330, 90} + com.apple.InterfaceBuilder.CocoaPlugin + + AUGIAABBiAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCzAAAwo4AAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCnAAAwgAAAA + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + P4AAAL+AAABCngAAwkAAAA + + + + + YES + + + YES + + + + + YES + + + YES + + + + 24 + + + + YES + + DownloadWindowController + NSWindowController + + IBProjectSource + DownloadWindowController.h + + + + + 0 + IBCocoaFramework + + com.apple.InterfaceBuilder.CocoaPlugin.macosx + + + + com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3 + + + YES + ../NetSurf.xcodeproj + 3 + + -- cgit v1.2.3