3 Copyright 2002, Apple, Inc. All rights reserved.
6 #import <WebKit/WebImageView.h>
8 #import <WebKit/WebAssertions.h>
9 #import <WebKit/WebDataSource.h>
10 #import <WebKit/WebDocument.h>
11 #import <WebKit/WebFrameView.h>
12 #import <WebKit/WebImageRenderer.h>
13 #import <WebKit/WebImageRendererFactory.h>
14 #import <WebKit/WebImageRepresentation.h>
15 #import <WebKit/WebNSObjectExtras.h>
16 #import <WebKit/WebNSPasteboardExtras.h>
17 #import <WebKit/WebNSViewExtras.h>
18 #import <WebKit/WebViewPrivate.h>
19 #import <WebKit/WebUIDelegatePrivate.h>
21 #import <WebCore/WebCoreImageRenderer.h>
23 #import <Foundation/NSFileManager_NSURLExtras.h>
25 @implementation WebImageView
29 [NSApp registerServicesMenuSendTypes:[NSArray arrayWithObject:NSTIFFPboardType] returnTypes:nil];
32 + (NSArray *)supportedImageMIMETypes
34 static NSMutableArray *imageMIMETypes = nil;
35 if (imageMIMETypes == nil) {
36 imageMIMETypes = [[[WebImageRendererFactory sharedFactory] supportedMIMETypes] mutableCopy];
37 [imageMIMETypes removeObject:@"application/pdf"];
38 [imageMIMETypes removeObject:@"application/postscript"];
40 return imageMIMETypes;
43 - (id)initWithFrame:(NSRect)frame
45 self = [super initWithFrame:frame];
46 [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
52 [[rep image] stopAnimation];
54 [mouseDownEvent release];
61 [[rep image] stopAnimation];
65 - (BOOL)haveCompleteImage
67 NSSize imageSize = [[rep image] size];
68 return [rep doneLoading] && imageSize.width > 0 && imageSize.width > 0;
76 - (BOOL)acceptsFirstResponder
78 // Being first responder is useful for scrolling from the keyboard at least.
84 NSSize imageSize = [[rep image] size];
85 return NSMakeRect(0, 0, imageSize.width, imageSize.height);
88 - (void)drawRect:(NSRect)rect
94 if ([[self _webView] drawsBackground]) {
95 [[NSColor whiteColor] set];
99 NSRect drawingRect = [self drawingRect];
100 [[rep image] drawImageInRect:drawingRect fromRect:drawingRect];
103 - (void)adjustFrameSize
105 NSSize size = [[rep image] size];
107 // When drawing on screen, ensure that the view always fills the content area
108 // (so we draw over the entire previous page), and that the view is at least
109 // as large as the image.. Otherwise we're printing, and we want the image to
110 // fill the view so that the printed size doesn't depend on the window size.
111 if ([NSGraphicsContext currentContextDrawingToScreen]) {
112 NSSize clipViewSize = [[self _web_superviewOfClass:[NSClipView class]] frame].size;
113 size.width = MAX(size.width, clipViewSize.width);
114 size.height = MAX(size.height, clipViewSize.height);
117 [super setFrameSize:size];
120 - (void)setFrameSize:(NSSize)size
122 [self adjustFrameSize];
127 [self adjustFrameSize];
131 - (void)setDataSource:(WebDataSource *)dataSource
134 rep = [[dataSource representation] retain];
137 - (void)dataSourceUpdated:(WebDataSource *)dataSource
139 NSSize imageSize = [[rep image] size];
140 if (imageSize.width > 0 && imageSize.height > 0) {
141 [self setNeedsLayout:YES];
142 [self setNeedsDisplay:YES];
146 - (void)setNeedsLayout: (BOOL)flag
151 - (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
155 - (void)viewDidMoveToHostWindow
159 - (void)viewDidMoveToWindow
162 [[rep image] stopAnimation];
165 [super viewDidMoveToWindow];
170 return [self _web_parentWebView];
173 - (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
175 if ([item action] == @selector(copy:)){
176 return [self haveCompleteImage];
182 - (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
184 if (sendType && [sendType isEqualToString:NSTIFFPboardType]){
188 return [super validRequestorForSendType:sendType returnType:returnType];
191 - (BOOL)writeImageToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
193 if ([self haveCompleteImage]) {
194 [pasteboard _web_writeImage:[rep image] URL:[rep URL] title:nil archive:[rep archive] types:types];
201 - (void)copy:(id)sender
203 [self writeImageToPasteboard:[NSPasteboard generalPasteboard] types:[NSPasteboard _web_writableTypesForImageIncludingArchive:([rep archive] != nil)]];
206 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
208 return [self writeImageToPasteboard:pasteboard types:types];
211 - (NSDictionary *)elementAtPoint:(NSPoint)point
213 WebFrame *frame = [[self _web_parentWebFrameView] webFrame];
216 return [NSDictionary dictionaryWithObjectsAndKeys:
217 [rep image], WebElementImageKey,
218 [NSValue valueWithRect:[self bounds]], WebElementImageRectKey,
219 [rep URL], WebElementImageURLKey,
220 [NSNumber numberWithBool:NO], WebElementIsSelectedKey,
221 frame, WebElementFrameKey, nil];
224 - (NSMenu *)menuForEvent:(NSEvent *)theEvent
226 WebView *webView = [self webView];
228 return [webView _menuForElement:[self elementAtPoint:NSZeroPoint]];
231 - (void)mouseDown:(NSEvent *)event
233 ignoringMouseDraggedEvents = NO;
234 [mouseDownEvent release];
235 mouseDownEvent = [event retain];
237 WebView *webView = [self webView];
238 NSPoint point = [webView convertPoint:[mouseDownEvent locationInWindow] fromView:nil];
239 dragSourceActionMask = [[webView _UIDelegateForwarder] webView:webView dragSourceActionMaskForPoint:point];
241 [super mouseDown:event];
244 - (void)mouseDragged:(NSEvent *)mouseDraggedEvent
246 if (ignoringMouseDraggedEvents || ![self haveCompleteImage] || !(dragSourceActionMask & WebDragSourceActionImage)) {
250 NSPasteboard *pasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
251 id source = [pasteboard _web_declareAndWriteDragImage:[rep image]
254 archive:[rep archive]
257 WebView *webView = [self webView];
258 NSPoint point = [webView convertPoint:[mouseDownEvent locationInWindow] fromView:nil];
259 [[webView _UIDelegateForwarder] webView:webView willPerformDragSourceAction:WebDragSourceActionImage fromPoint:point withPasteboard:pasteboard];
261 [[self webView] _setInitiatedDrag:YES];
263 // Retain this view during the drag because it may be released before the drag ends.
266 [self _web_dragImage:[rep image]
267 rect:[self drawingRect]
268 event:mouseDraggedEvent
269 pasteboard:pasteboard
274 - (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
276 // FIXME: Report an error if we fail to create a file.
277 NSString *path = [[dropDestination path] stringByAppendingPathComponent:[rep filename]];
278 path = [[NSFileManager defaultManager] _web_pathWithUniqueFilenameForPath:path];
279 [[rep data] writeToFile:path atomically:NO];
280 return [NSArray arrayWithObject:[path lastPathComponent]];
283 - (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
285 // Prevent queued mouseDragged events from coming after the drag which can cause a double drag.
286 ignoringMouseDraggedEvents = YES;
288 [[self webView] _setInitiatedDrag:NO];
290 // Balance the previous retain from when the drag started.
296 return [[rep image] image];
299 #pragma mark PRINTING
301 - (void)drawPageBorderWithSize:(NSSize)borderSize
303 ASSERT(NSEqualSizes(borderSize, [[[NSPrintOperation currentOperation] printInfo] paperSize]));
304 // FIXME: How to determine the number of pages required to print the whole image?
305 [[self webView] _drawHeaderAndFooter];
308 - (void)beginDocument
310 [self adjustFrameSize];
311 [[self webView] _adjustPrintingMarginsForHeaderAndFooter];
312 [super beginDocument];
318 [self adjustFrameSize];
321 - (BOOL)canPrintHeadersAndFooters