diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-23 20:38:38 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-23 20:38:38 +0000 |
commit | 86230b9e9dcd8731ddbc3bb0acd257837789d704 (patch) | |
tree | 3add3a32bc1a620c0ba49afd00510c3bfaea4790 /chrome/browser/tab_contents/web_drop_target_win.cc | |
parent | ae3968b3e76f0fd95b9a34c762e936f0bfde65d3 (diff) | |
download | chromium_src-86230b9e9dcd8731ddbc3bb0acd257837789d704.zip chromium_src-86230b9e9dcd8731ddbc3bb0acd257837789d704.tar.gz chromium_src-86230b9e9dcd8731ddbc3bb0acd257837789d704.tar.bz2 |
Assorted cleanup.
process: grep for TODO(port), find cruft, clean it up
Review URL: http://codereview.chromium.org/427004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@32844 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents/web_drop_target_win.cc')
-rw-r--r-- | chrome/browser/tab_contents/web_drop_target_win.cc | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/chrome/browser/tab_contents/web_drop_target_win.cc b/chrome/browser/tab_contents/web_drop_target_win.cc new file mode 100644 index 0000000..ed2c7c6 --- /dev/null +++ b/chrome/browser/tab_contents/web_drop_target_win.cc @@ -0,0 +1,187 @@ +// 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. + +#include <windows.h> +#include <shlobj.h> + +#include "chrome/browser/tab_contents/web_drop_target_win.h" + +#include "app/clipboard/clipboard_util_win.h" +#include "app/os_exchange_data.h" +#include "app/os_exchange_data_provider_win.h" +#include "base/gfx/point.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "googleurl/src/gurl.h" +#include "net/base/net_util.h" +#include "webkit/glue/webdropdata.h" +#include "webkit/glue/window_open_disposition.h" + +using WebKit::WebDragOperationCopy; + +namespace { + +// A helper method for getting the preferred drop effect. +DWORD GetPreferredDropEffect(DWORD effect) { + if (effect & DROPEFFECT_COPY) + return DROPEFFECT_COPY; + if (effect & DROPEFFECT_LINK) + return DROPEFFECT_LINK; + if (effect & DROPEFFECT_MOVE) + return DROPEFFECT_MOVE; + return DROPEFFECT_NONE; +} + +} // anonymous namespace + +// InterstitialDropTarget is like a BaseDropTarget implementation that +// WebDropTarget passes through to if an interstitial is showing. Rather than +// passing messages on to the renderer, we just check to see if there's a link +// in the drop data and handle links as navigations. +class InterstitialDropTarget { + public: + explicit InterstitialDropTarget(TabContents* tab_contents) + : tab_contents_(tab_contents) {} + + DWORD OnDragEnter(IDataObject* data_object, DWORD effect) { + return ClipboardUtil::HasUrl(data_object) ? GetPreferredDropEffect(effect) + : DROPEFFECT_NONE; + } + + DWORD OnDragOver(IDataObject* data_object, DWORD effect) { + return ClipboardUtil::HasUrl(data_object) ? GetPreferredDropEffect(effect) + : DROPEFFECT_NONE; + } + + void OnDragLeave(IDataObject* data_object) { + } + + DWORD OnDrop(IDataObject* data_object, DWORD effect) { + if (ClipboardUtil::HasUrl(data_object)) { + std::wstring url; + std::wstring title; + ClipboardUtil::GetUrl(data_object, &url, &title); + tab_contents_->OpenURL(GURL(url), GURL(), CURRENT_TAB, + PageTransition::AUTO_BOOKMARK); + return GetPreferredDropEffect(effect); + } + return DROPEFFECT_NONE; + } + + private: + TabContents* tab_contents_; + + DISALLOW_EVIL_CONSTRUCTORS(InterstitialDropTarget); +}; + +/////////////////////////////////////////////////////////////////////////////// +// WebDropTarget, public: + +WebDropTarget::WebDropTarget(HWND source_hwnd, TabContents* tab_contents) + : BaseDropTarget(source_hwnd), + tab_contents_(tab_contents), + current_rvh_(NULL), + is_drop_target_(false), + interstitial_drop_target_(new InterstitialDropTarget(tab_contents)) { +} + +WebDropTarget::~WebDropTarget() { +} + +DWORD WebDropTarget::OnDragEnter(IDataObject* data_object, + DWORD key_state, + POINT cursor_position, + DWORD effect) { + current_rvh_ = tab_contents_->render_view_host(); + + // Don't pass messages to the renderer if an interstitial page is showing + // because we don't want the interstitial page to navigate. Instead, + // pass the messages on to a separate interstitial DropTarget handler. + if (tab_contents_->showing_interstitial_page()) + return interstitial_drop_target_->OnDragEnter(data_object, effect); + + // TODO(tc): PopulateWebDropData can be slow depending on what is in the + // IDataObject. Maybe we can do this in a background thread. + WebDropData drop_data(GetDragIdentity()); + WebDropData::PopulateWebDropData(data_object, &drop_data); + + if (drop_data.url.is_empty()) + OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url); + + is_drop_target_ = true; + + POINT client_pt = cursor_position; + ScreenToClient(GetHWND(), &client_pt); + tab_contents_->render_view_host()->DragTargetDragEnter(drop_data, + gfx::Point(client_pt.x, client_pt.y), + gfx::Point(cursor_position.x, cursor_position.y), + WebDragOperationCopy); // FIXME(snej): Send actual operation + + // We lie here and always return a DROPEFFECT because we don't want to + // wait for the IPC call to return. + return GetPreferredDropEffect(effect); +} + +DWORD WebDropTarget::OnDragOver(IDataObject* data_object, + DWORD key_state, + POINT cursor_position, + DWORD effect) { + DCHECK(current_rvh_); + if (current_rvh_ != tab_contents_->render_view_host()) + OnDragEnter(data_object, key_state, cursor_position, effect); + + if (tab_contents_->showing_interstitial_page()) + return interstitial_drop_target_->OnDragOver(data_object, effect); + + POINT client_pt = cursor_position; + ScreenToClient(GetHWND(), &client_pt); + tab_contents_->render_view_host()->DragTargetDragOver( + gfx::Point(client_pt.x, client_pt.y), + gfx::Point(cursor_position.x, cursor_position.y), + WebDragOperationCopy); // FIXME(snej): Send actual operation + + if (!is_drop_target_) + return DROPEFFECT_NONE; + + return GetPreferredDropEffect(effect); +} + +void WebDropTarget::OnDragLeave(IDataObject* data_object) { + DCHECK(current_rvh_); + if (current_rvh_ != tab_contents_->render_view_host()) + return; + + if (tab_contents_->showing_interstitial_page()) { + interstitial_drop_target_->OnDragLeave(data_object); + } else { + tab_contents_->render_view_host()->DragTargetDragLeave(); + } +} + +DWORD WebDropTarget::OnDrop(IDataObject* data_object, + DWORD key_state, + POINT cursor_position, + DWORD effect) { + DCHECK(current_rvh_); + if (current_rvh_ != tab_contents_->render_view_host()) + OnDragEnter(data_object, key_state, cursor_position, effect); + + if (tab_contents_->showing_interstitial_page()) + interstitial_drop_target_->OnDragOver(data_object, effect); + + if (tab_contents_->showing_interstitial_page()) + return interstitial_drop_target_->OnDrop(data_object, effect); + + POINT client_pt = cursor_position; + ScreenToClient(GetHWND(), &client_pt); + tab_contents_->render_view_host()->DragTargetDrop( + gfx::Point(client_pt.x, client_pt.y), + gfx::Point(cursor_position.x, cursor_position.y)); + + current_rvh_ = NULL; + + // We lie and always claim that the drop operation didn't happen because we + // don't want to wait for the renderer to respond. + return DROPEFFECT_NONE; +} |