summaryrefslogtreecommitdiffstats
path: root/chrome/browser/cocoa/web_drag_source.mm
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/cocoa/web_drag_source.mm')
-rw-r--r--chrome/browser/cocoa/web_drag_source.mm412
1 files changed, 0 insertions, 412 deletions
diff --git a/chrome/browser/cocoa/web_drag_source.mm b/chrome/browser/cocoa/web_drag_source.mm
deleted file mode 100644
index 95ab0d1..0000000
--- a/chrome/browser/cocoa/web_drag_source.mm
+++ /dev/null
@@ -1,412 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "chrome/browser/cocoa/web_drag_source.h"
-
-#include "base/file_path.h"
-#include "base/nsimage_cache_mac.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "base/task.h"
-#include "base/thread.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/download/download_manager.h"
-#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/download/drag_download_file.h"
-#include "chrome/browser/download/drag_download_util.h"
-#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/tab_contents/tab_contents_view_mac.h"
-#include "net/base/file_stream.h"
-#include "net/base/net_util.h"
-#import "third_party/mozilla/NSPasteboard+Utils.h"
-#include "webkit/glue/webdropdata.h"
-
-using base::SysNSStringToUTF8;
-using base::SysUTF8ToNSString;
-using base::SysUTF16ToNSString;
-using net::FileStream;
-
-
-namespace {
-
-// An unofficial standard pasteboard title type to be provided alongside the
-// |NSURLPboardType|.
-NSString* const kNSURLTitlePboardType = @"public.url-name";
-
-// Returns a filename appropriate for the drop data
-// TODO(viettrungluu): Refactor to make it common across platforms,
-// and move it somewhere sensible.
-FilePath GetFileNameFromDragData(const WebDropData& drop_data) {
- // Images without ALT text will only have a file extension so we need to
- // synthesize one from the provided extension and URL.
- FilePath file_name([SysUTF16ToNSString(drop_data.file_description_filename)
- fileSystemRepresentation]);
- file_name = file_name.BaseName().RemoveExtension();
-
- if (file_name.empty()) {
- // Retrieve the name from the URL.
- file_name = net::GetSuggestedFilename(drop_data.url, "", "", FilePath());
- }
-
- file_name = file_name.ReplaceExtension([SysUTF16ToNSString(
- drop_data.file_extension) fileSystemRepresentation]);
-
- return file_name;
-}
-
-// This class's sole task is to write out data for a promised file; the caller
-// is responsible for opening the file.
-class PromiseWriterTask : public Task {
- public:
- // Assumes ownership of file_stream.
- PromiseWriterTask(const WebDropData& drop_data,
- FileStream* file_stream);
- virtual ~PromiseWriterTask();
- virtual void Run();
-
- private:
- WebDropData drop_data_;
-
- // This class takes ownership of file_stream_ and will close and delete it.
- scoped_ptr<FileStream> file_stream_;
-};
-
-// Takes the drop data and an open file stream (which it takes ownership of and
-// will close and delete).
-PromiseWriterTask::PromiseWriterTask(const WebDropData& drop_data,
- FileStream* file_stream) :
- drop_data_(drop_data) {
- file_stream_.reset(file_stream);
- DCHECK(file_stream_.get());
-}
-
-PromiseWriterTask::~PromiseWriterTask() {
- DCHECK(file_stream_.get());
- if (file_stream_.get())
- file_stream_->Close();
-}
-
-void PromiseWriterTask::Run() {
- CHECK(file_stream_.get());
- file_stream_->Write(drop_data_.file_contents.data(),
- drop_data_.file_contents.length(),
- NULL);
-
- // Let our destructor take care of business.
-}
-
-} // namespace
-
-
-@interface WebDragSource(Private)
-
-- (void)fillPasteboard;
-- (NSImage*)dragImage;
-
-@end // @interface WebDragSource(Private)
-
-
-@implementation WebDragSource
-
-- (id)initWithContentsView:(TabContentsViewCocoa*)contentsView
- dropData:(const WebDropData*)dropData
- image:(NSImage*)image
- offset:(NSPoint)offset
- pasteboard:(NSPasteboard*)pboard
- dragOperationMask:(NSDragOperation)dragOperationMask {
- if ((self = [super init])) {
- contentsView_ = contentsView;
- DCHECK(contentsView_);
-
- dropData_.reset(new WebDropData(*dropData));
- DCHECK(dropData_.get());
-
- dragImage_.reset([image retain]);
- imageOffset_ = offset;
-
- pasteboard_.reset([pboard retain]);
- DCHECK(pasteboard_.get());
-
- dragOperationMask_ = dragOperationMask;
-
- [self fillPasteboard];
- }
-
- return self;
-}
-
-- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal {
- return dragOperationMask_;
-}
-
-- (void)lazyWriteToPasteboard:(NSPasteboard*)pboard forType:(NSString*)type {
- // NSHTMLPboardType requires the character set to be declared. Otherwise, it
- // assumes US-ASCII. Awesome.
- static const string16 kHtmlHeader =
- ASCIIToUTF16("<meta http-equiv=\"Content-Type\" "
- "content=\"text/html;charset=UTF-8\">");
-
- // Be extra paranoid; avoid crashing.
- if (!dropData_.get()) {
- NOTREACHED() << "No drag-and-drop data available for lazy write.";
- return;
- }
-
- // HTML.
- if ([type isEqualToString:NSHTMLPboardType]) {
- DCHECK(!dropData_->text_html.empty());
- // See comment on |kHtmlHeader| above.
- [pboard setString:SysUTF16ToNSString(kHtmlHeader + dropData_->text_html)
- forType:NSHTMLPboardType];
-
- // URL.
- } else if ([type isEqualToString:NSURLPboardType]) {
- DCHECK(dropData_->url.is_valid());
- NSURL* url = [NSURL URLWithString:SysUTF8ToNSString(dropData_->url.spec())];
- [url writeToPasteboard:pboard];
-
- // URL title.
- } else if ([type isEqualToString:kNSURLTitlePboardType]) {
- [pboard setString:SysUTF16ToNSString(dropData_->url_title)
- forType:kNSURLTitlePboardType];
-
- // File contents.
- } else if ([type isEqualToString:NSFileContentsPboardType] ||
- [type isEqualToString:NSCreateFileContentsPboardType(
- SysUTF16ToNSString(dropData_->file_extension))]) {
- // TODO(viettrungluu: find something which is known to accept
- // NSFileContentsPboardType to check that this actually works!
- scoped_nsobject<NSFileWrapper> file_wrapper(
- [[NSFileWrapper alloc] initRegularFileWithContents:[NSData
- dataWithBytes:dropData_->file_contents.data()
- length:dropData_->file_contents.length()]]);
- [file_wrapper setPreferredFilename:SysUTF8ToNSString(
- GetFileNameFromDragData(*dropData_).value())];
- [pboard writeFileWrapper:file_wrapper];
-
- // TIFF.
- } else if ([type isEqualToString:NSTIFFPboardType]) {
- // TODO(viettrungluu): This is a bit odd since we rely on Cocoa to render
- // our image into a TIFF. This is also suboptimal since this is all done
- // synchronously. I'm not sure there's much we can easily do about it.
- scoped_nsobject<NSImage> image(
- [[NSImage alloc] initWithData:[NSData
- dataWithBytes:dropData_->file_contents.data()
- length:dropData_->file_contents.length()]]);
- [pboard setData:[image TIFFRepresentation] forType:NSTIFFPboardType];
-
- // Plain text.
- } else if ([type isEqualToString:NSStringPboardType]) {
- DCHECK(!dropData_->plain_text.empty());
- [pboard setString:SysUTF16ToNSString(dropData_->plain_text)
- forType:NSStringPboardType];
-
- // Oops!
- } else {
- NOTREACHED() << "Asked for a drag pasteboard type we didn't offer.";
- }
-}
-
-- (NSPoint)convertScreenPoint:(NSPoint)screenPoint {
- DCHECK([contentsView_ window]);
- NSPoint basePoint = [[contentsView_ window] convertScreenToBase:screenPoint];
- return [contentsView_ convertPoint:basePoint fromView:nil];
-}
-
-- (void)startDrag {
- NSEvent* currentEvent = [NSApp currentEvent];
-
- // Synthesize an event for dragging, since we can't be sure that
- // [NSApp currentEvent] will return a valid dragging event.
- NSWindow* window = [contentsView_ window];
- NSPoint position = [window mouseLocationOutsideOfEventStream];
- NSTimeInterval eventTime = [currentEvent timestamp];
- NSEvent* dragEvent = [NSEvent mouseEventWithType:NSLeftMouseDragged
- location:position
- modifierFlags:NSLeftMouseDraggedMask
- timestamp:eventTime
- windowNumber:[window windowNumber]
- context:nil
- eventNumber:0
- clickCount:1
- pressure:1.0];
-
- if (dragImage_) {
- position.x -= imageOffset_.x;
- // Deal with Cocoa's flipped coordinate system.
- position.y -= [dragImage_.get() size].height - imageOffset_.y;
- }
- // Per kwebster, offset arg is ignored, see -_web_DragImageForElement: in
- // third_party/WebKit/WebKit/mac/Misc/WebNSViewExtras.m.
- [window dragImage:[self dragImage]
- at:position
- offset:NSZeroSize
- event:dragEvent
- pasteboard:pasteboard_
- source:contentsView_
- slideBack:YES];
-}
-
-- (void)endDragAt:(NSPoint)screenPoint
- operation:(NSDragOperation)operation {
- RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host();
- if (rvh) {
- rvh->DragSourceSystemDragEnded();
-
- // Convert |screenPoint| to view coordinates and flip it.
- NSPoint localPoint = [self convertScreenPoint:screenPoint];
- NSRect viewFrame = [contentsView_ frame];
- localPoint.y = viewFrame.size.height - localPoint.y;
- // Flip |screenPoint|.
- NSRect screenFrame = [[[contentsView_ window] screen] frame];
- screenPoint.y = screenFrame.size.height - screenPoint.y;
-
- rvh->DragSourceEndedAt(localPoint.x, localPoint.y,
- screenPoint.x, screenPoint.y,
- static_cast<WebKit::WebDragOperation>(operation));
- }
-
- // Make sure the pasteboard owner isn't us.
- [pasteboard_ declareTypes:[NSArray array] owner:nil];
-}
-
-- (void)moveDragTo:(NSPoint)screenPoint {
- RenderViewHost* rvh = [contentsView_ tabContents]->render_view_host();
- if (rvh) {
- // Convert |screenPoint| to view coordinates and flip it.
- NSPoint localPoint = [self convertScreenPoint:screenPoint];
- NSRect viewFrame = [contentsView_ frame];
- localPoint.y = viewFrame.size.height - localPoint.y;
- // Flip |screenPoint|.
- NSRect screenFrame = [[[contentsView_ window] screen] frame];
- screenPoint.y = screenFrame.size.height - screenPoint.y;
-
- rvh->DragSourceMovedTo(localPoint.x, localPoint.y,
- screenPoint.x, screenPoint.y);
- }
-}
-
-- (NSString*)dragPromisedFileTo:(NSString*)path {
- // Be extra paranoid; avoid crashing.
- if (!dropData_.get()) {
- NOTREACHED() << "No drag-and-drop data available for promised file.";
- return nil;
- }
-
- FilePath fileName = downloadFileName_.empty() ?
- GetFileNameFromDragData(*dropData_) : downloadFileName_;
- FilePath filePath(SysNSStringToUTF8(path));
- filePath = filePath.Append(fileName);
- FileStream* fileStream =
- drag_download_util::CreateFileStreamForDrop(&filePath);
- if (!fileStream)
- return nil;
-
- if (downloadURL_.is_valid()) {
- TabContents* tabContents = [contentsView_ tabContents];
- scoped_refptr<DragDownloadFile> dragFileDownloader(new DragDownloadFile(
- filePath,
- linked_ptr<net::FileStream>(fileStream),
- downloadURL_,
- tabContents->GetURL(),
- tabContents->encoding(),
- tabContents));
-
- // The finalizer will take care of closing and deletion.
- dragFileDownloader->Start(
- new drag_download_util::PromiseFileFinalizer(dragFileDownloader));
- } else {
- // The writer will take care of closing and deletion.
- g_browser_process->file_thread()->message_loop()->PostTask(FROM_HERE,
- new PromiseWriterTask(*dropData_, fileStream));
- }
-
- // Once we've created the file, we should return the file name.
- return SysUTF8ToNSString(filePath.BaseName().value());
-}
-
-@end // @implementation WebDragSource
-
-
-@implementation WebDragSource (Private)
-
-- (void)fillPasteboard {
- DCHECK(pasteboard_.get());
-
- [pasteboard_ declareTypes:[NSArray array] owner:contentsView_];
-
- // HTML.
- if (!dropData_->text_html.empty())
- [pasteboard_ addTypes:[NSArray arrayWithObject:NSHTMLPboardType]
- owner:contentsView_];
-
- // URL (and title).
- if (dropData_->url.is_valid())
- [pasteboard_ addTypes:[NSArray arrayWithObjects:NSURLPboardType,
- kNSURLTitlePboardType, nil]
- owner:contentsView_];
-
- // File.
- if (!dropData_->file_contents.empty() ||
- !dropData_->download_metadata.empty()) {
- NSString* fileExtension = 0;
-
- if (dropData_->download_metadata.empty()) {
- // |dropData_->file_extension| comes with the '.', which we must strip.
- fileExtension = (dropData_->file_extension.length() > 0) ?
- SysUTF16ToNSString(dropData_->file_extension.substr(1)) : @"";
- } else {
- string16 mimeType;
- FilePath fileName;
- if (drag_download_util::ParseDownloadMetadata(
- dropData_->download_metadata,
- &mimeType,
- &fileName,
- &downloadURL_)) {
- std::string contentDisposition =
- "attachment; filename=" + fileName.value();
- download_util::GenerateFileName(downloadURL_,
- contentDisposition,
- std::string(),
- UTF16ToUTF8(mimeType),
- &downloadFileName_);
- fileExtension = SysUTF8ToNSString(downloadFileName_.Extension());
- }
- }
-
- if (fileExtension) {
- // File contents (with and without specific type), file (HFS) promise,
- // TIFF.
- // TODO(viettrungluu): others?
- [pasteboard_ addTypes:[NSArray arrayWithObjects:
- NSFileContentsPboardType,
- NSCreateFileContentsPboardType(fileExtension),
- NSFilesPromisePboardType,
- NSTIFFPboardType,
- nil]
- owner:contentsView_];
-
- // For the file promise, we need to specify the extension.
- [pasteboard_ setPropertyList:[NSArray arrayWithObject:fileExtension]
- forType:NSFilesPromisePboardType];
- }
- }
-
- // Plain text.
- if (!dropData_->plain_text.empty())
- [pasteboard_ addTypes:[NSArray arrayWithObject:NSStringPboardType]
- owner:contentsView_];
-}
-
-- (NSImage*)dragImage {
- if (dragImage_)
- return dragImage_;
-
- // Default to returning a generic image.
- return nsimage_cache::ImageNamed(@"nav.pdf");
-}
-
-@end // @implementation WebDragSource (Private)