summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 21:58:18 +0000
committersky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-12 21:58:18 +0000
commit8c3dc79bc13ba84f418d3c135e1bf296a3e29722 (patch)
tree32eb9688d500a90eb74a7c4f8cb5a97e507dd0fc
parentabaccb2cb8cff8138e5ea9daf420645e5852c9eb (diff)
downloadchromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.zip
chromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.tar.gz
chromium_src-8c3dc79bc13ba84f418d3c135e1bf296a3e29722.tar.bz2
Refactors OSExchangeData for easier portability.
BUG=none TEST=none Review URL: http://codereview.chromium.org/164401 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23230 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--app/app.gyp18
-rw-r--r--app/os_exchange_data.cc125
-rw-r--r--app/os_exchange_data.h164
-rw-r--r--app/os_exchange_data_provider_gtk.cc170
-rw-r--r--app/os_exchange_data_provider_gtk.h106
-rw-r--r--app/os_exchange_data_provider_win.cc (renamed from app/os_exchange_data_win.cc)183
-rw-r--r--app/os_exchange_data_provider_win.h128
-rw-r--r--app/os_exchange_data_win_unittest.cc127
-rw-r--r--base/clipboard_util.cc11
-rw-r--r--base/clipboard_util.h2
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc17
-rw-r--r--chrome/browser/bookmarks/bookmark_context_menu_controller.cc2
-rw-r--r--chrome/browser/bookmarks/bookmark_context_menu_controller.h1
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.cc56
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data.h11
-rw-r--r--chrome/browser/bookmarks/bookmark_drag_data_unittest.cc54
-rw-r--r--chrome/browser/download/download_util.cc14
-rw-r--r--chrome/browser/tab_contents/web_drop_target.cc3
-rw-r--r--chrome/browser/views/bookmark_folder_tree_view.cc7
-rw-r--r--chrome/browser/views/bookmark_table_view.cc7
-rw-r--r--chrome/browser/views/tab_contents/tab_contents_view_win.cc16
-rw-r--r--views/controls/menu/chrome_menu.cc11
-rw-r--r--views/drag_utils_win.cc8
-rw-r--r--views/view_win.cc8
-rw-r--r--views/widget/drop_target_win.cc7
25 files changed, 945 insertions, 311 deletions
diff --git a/app/app.gyp b/app/app.gyp
index 77e3a3d..0a36bd5 100644
--- a/app/app.gyp
+++ b/app/app.gyp
@@ -95,8 +95,11 @@
'l10n_util_win.cc',
'l10n_util_win.h',
'message_box_flags.h',
- 'os_exchange_data_win.cc',
- 'os_exchange_data_gtk.cc',
+ 'os_exchange_data_provider_gtk.cc',
+ 'os_exchange_data_provider_gtk.h',
+ 'os_exchange_data_provider_win.cc',
+ 'os_exchange_data_provider_win.h',
+ 'os_exchange_data.cc',
'os_exchange_data.h',
'resource_bundle.cc',
'resource_bundle.h',
@@ -131,11 +134,20 @@
# Note: because of gyp predence rules this has to be defined as
# 'sources/' rather than 'sources!'.
'sources/': [
- ['exclude', '^os_exchange_data_gtk.cc'],
+ ['exclude', '^os_exchange_data.cc'],
['exclude', '^os_exchange_data.h'],
+ ['exclude', '^os_exchange_data_provider_gtk.cc'],
+ ['exclude', '^os_exchange_data_provider_gtk.h'],
['exclude', '^drag_drop_types_gtk.cc'],
],
}],
+ ['toolkit_views==1 or chromeos==1', {
+ # Note: because of gyp predence rules this has to be defined as
+ # 'sources/' rather than 'sources!'.
+ 'sources/': [
+ ['include', '^os_exchange_data.cc'],
+ ],
+ }],
],
}],
['OS=="win"', {
diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc
new file mode 100644
index 0000000..9361466
--- /dev/null
+++ b/app/os_exchange_data.cc
@@ -0,0 +1,125 @@
+// 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 "app/os_exchange_data.h"
+
+#include "base/pickle.h"
+#include "googleurl/src/gurl.h"
+
+OSExchangeData::OSExchangeData() : provider_(CreateProvider()) {
+}
+
+OSExchangeData::OSExchangeData(Provider* provider) : provider_(provider) {
+}
+
+OSExchangeData::~OSExchangeData() {
+}
+
+void OSExchangeData::SetString(const std::wstring& data) {
+ provider_->SetString(data);
+}
+
+void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
+ provider_->SetURL(url, title);
+}
+
+void OSExchangeData::SetFilename(const std::wstring& full_path) {
+ provider_->SetFilename(full_path);
+}
+
+void OSExchangeData::SetPickledData(CustomFormat format, const Pickle& data) {
+ provider_->SetPickledData(format, data);
+}
+
+void OSExchangeData::SetFileContents(const std::wstring& filename,
+ const std::string& file_contents) {
+ provider_->SetFileContents(filename, file_contents);
+}
+
+void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) {
+ provider_->SetHtml(html, base_url);
+}
+
+bool OSExchangeData::GetString(std::wstring* data) const {
+ return provider_->GetString(data);
+}
+
+bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const {
+ return provider_->GetURLAndTitle(url, title);
+}
+
+bool OSExchangeData::GetFilename(std::wstring* full_path) const {
+ return provider_->GetFilename(full_path);
+}
+
+bool OSExchangeData::GetPickledData(CustomFormat format, Pickle* data) const {
+ return provider_->GetPickledData(format, data);
+}
+
+bool OSExchangeData::GetFileContents(std::wstring* filename,
+ std::string* file_contents) const {
+ return provider_->GetFileContents(filename, file_contents);
+}
+
+bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const {
+ return provider_->GetHtml(html, base_url);
+}
+
+bool OSExchangeData::HasString() const {
+ return provider_->HasString();
+}
+
+bool OSExchangeData::HasURL() const {
+ return provider_->HasURL();
+}
+
+bool OSExchangeData::HasFile() const {
+ return provider_->HasFile();
+}
+
+bool OSExchangeData::HasCustomFormat(CustomFormat format) const {
+ return provider_->HasCustomFormat(format);
+}
+
+bool OSExchangeData::HasAllFormats(
+ int formats,
+ const std::set<CustomFormat>& custom_formats) const {
+ if ((formats & STRING) != 0 && !HasString())
+ return false;
+ if ((formats & URL) != 0 && !HasURL())
+ return false;
+ if ((formats & FILE_CONTENTS) != 0 && !provider_->HasFileContents())
+ return false;
+ if ((formats & FILE_NAME) != 0 && !provider_->HasFile())
+ return false;
+ if ((formats & HTML) != 0 && !provider_->HasHtml())
+ return false;
+ for (std::set<CustomFormat>::const_iterator i = custom_formats.begin();
+ i != custom_formats.end(); ++i) {
+ if (!HasCustomFormat(*i))
+ return false;
+ }
+ return true;
+}
+
+bool OSExchangeData::HasAnyFormat(
+ int formats,
+ const std::set<CustomFormat>& custom_formats) const {
+ if ((formats & STRING) != 0 && HasString())
+ return true;
+ if ((formats & URL) != 0 && HasURL())
+ return true;
+ if ((formats & FILE_CONTENTS) != 0 && provider_->HasFileContents())
+ return true;
+ if ((formats & FILE_NAME) != 0 && provider_->HasFile())
+ return true;
+ if ((formats & HTML) != 0 && provider_->HasHtml())
+ return true;
+ for (std::set<CustomFormat>::const_iterator i = custom_formats.begin();
+ i != custom_formats.end(); ++i) {
+ if (HasCustomFormat(*i))
+ return true;
+ }
+ return false;
+}
diff --git a/app/os_exchange_data.h b/app/os_exchange_data.h
index 2400266..a956b80 100644
--- a/app/os_exchange_data.h
+++ b/app/os_exchange_data.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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.
@@ -7,15 +7,18 @@
#include "build/build_config.h"
+#include <set>
+#include <string>
+#include <vector>
+
#if defined(OS_WIN)
#include <objidl.h>
-#include "base/scoped_comptr_win.h"
+#elif defined(OS_LINUX)
+#include <gtk/gtk.h>
#endif
-#include <string>
-#include <vector>
-
#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
class GURL;
class Pickle;
@@ -29,25 +32,71 @@ class Pickle;
// translating that into something the OS can understand.
//
///////////////////////////////////////////////////////////////////////////////
-#if defined(OS_WIN)
-class OSExchangeData : public IDataObject {
-#else
class OSExchangeData {
-#endif
public:
+ // CustomFormats are used for non-standard data types. For example, bookmark
+ // nodes are written using a CustomFormat.
#if defined(OS_WIN)
- // Returns true if source has plain text that is a valid url.
- static bool HasPlainTextURL(IDataObject* source);
+ typedef CLIPFORMAT CustomFormat;
+#elif defined(OS_LINUX)
+ typedef GdkAtom CustomFormat;
+#endif
- // Returns true if source has plain text that is a valid URL and sets url to
- // that url.
- static bool GetPlainTextURL(IDataObject* source, GURL* url);
+ // Enumeration of the known formats.
+ enum Format {
+ STRING = 1 << 0,
+ URL = 1 << 1,
+ FILE_CONTENTS = 1 << 2,
+ FILE_NAME = 1 << 3,
+ PICKLED_DATA = 1 << 4,
+ HTML = 1 << 5
+ };
- explicit OSExchangeData(IDataObject* source);
-#endif
+ // Provider defines the platform specific part of OSExchangeData that
+ // interacts with the native system.
+ class Provider {
+ public:
+ Provider() {}
+ virtual ~Provider() {}
+
+ virtual void SetString(const std::wstring& data) = 0;
+ virtual void SetURL(const GURL& url, const std::wstring& title) = 0;
+ virtual void SetFilename(const std::wstring& full_path) = 0;
+ virtual void SetPickledData(CustomFormat format, const Pickle& data) = 0;
+ virtual void SetFileContents(const std::wstring& filename,
+ const std::string& file_contents) = 0;
+ virtual void SetHtml(const std::wstring& html, const GURL& base_url) = 0;
+
+ virtual bool GetString(std::wstring* data) const = 0;
+ virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const = 0;
+ virtual bool GetFilename(std::wstring* full_path) const = 0;
+ virtual bool GetPickledData(CustomFormat format, Pickle* data) const = 0;
+ virtual bool GetFileContents(std::wstring* filename,
+ std::string* file_contents) const = 0;
+ virtual bool GetHtml(std::wstring* html, GURL* base_url) const = 0;
+
+ virtual bool HasString() const = 0;
+ virtual bool HasURL() const = 0;
+ virtual bool HasFile() const = 0;
+ virtual bool HasFileContents() const = 0;
+ virtual bool HasHtml() const = 0;
+ virtual bool HasCustomFormat(
+ OSExchangeData::CustomFormat format) const = 0;
+ };
OSExchangeData();
- virtual ~OSExchangeData();
+ // Creates an OSExchangeData with the specified provider. OSExchangeData
+ // takes ownership of the supplied provider.
+ explicit OSExchangeData(Provider* provider);
+
+ ~OSExchangeData();
+
+ // Registers the specific string as a possible format for data.
+ static CustomFormat RegisterCustomFormat(const std::string& type);
+
+ // Returns the Provider, which actually stores and manages the data.
+ const Provider& provider() const { return *provider_; }
+ Provider& provider() { return *provider_; }
// These functions add data to the OSExchangeData object of various Chrome
// types. The OSExchangeData object takes care of translating the data into
@@ -64,10 +113,8 @@ class OSExchangeData {
void SetURL(const GURL& url, const std::wstring& title);
// A full path to a file
void SetFilename(const std::wstring& full_path);
-#if defined(OS_WIN)
// Adds pickled data of the specified format.
- void SetPickledData(CLIPFORMAT format, const Pickle& data);
-#endif
+ void SetPickledData(CustomFormat format, const Pickle& data);
// Adds the bytes of a file (CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR).
void SetFileContents(const std::wstring& filename,
const std::string& file_contents);
@@ -83,9 +130,7 @@ class OSExchangeData {
bool GetURLAndTitle(GURL* url, std::wstring* title) const;
// Return the path of a file, if available.
bool GetFilename(std::wstring* full_path) const;
-#if defined(OS_WIN)
- bool GetPickledData(CLIPFORMAT format, Pickle* data) const;
-#endif
+ bool GetPickledData(CustomFormat format, Pickle* data) const;
bool GetFileContents(std::wstring* filename,
std::string* file_contents) const;
bool GetHtml(std::wstring* html, GURL* base_url) const;
@@ -94,70 +139,25 @@ class OSExchangeData {
// returning anything.
bool HasString() const;
bool HasURL() const;
- bool HasURLTitle() const;
bool HasFile() const;
-#if defined(OS_WIN)
- bool HasFormat(CLIPFORMAT format) const;
-
- // IDataObject implementation:
- HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium);
- HRESULT __stdcall GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium);
- HRESULT __stdcall QueryGetData(FORMATETC* format_etc);
- HRESULT __stdcall GetCanonicalFormatEtc(
- FORMATETC* format_etc, FORMATETC* result);
- HRESULT __stdcall SetData(
- FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release);
- HRESULT __stdcall EnumFormatEtc(
- DWORD direction, IEnumFORMATETC** enumerator);
- HRESULT __stdcall DAdvise(
- FORMATETC* format_etc, DWORD advf, IAdviseSink* sink, DWORD* connection);
- HRESULT __stdcall DUnadvise(DWORD connection);
- HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** enumerator);
-
- // IUnknown implementation:
- HRESULT __stdcall QueryInterface(const IID& iid, void** object);
- ULONG __stdcall AddRef();
- ULONG __stdcall Release();
-#endif
+ bool HasCustomFormat(CustomFormat format) const;
- private:
-#if defined(OS_WIN)
- // FormatEtcEnumerator only likes us for our StoredDataMap typedef.
- friend class FormatEtcEnumerator;
-
- // Our internal representation of stored data & type info.
- struct StoredDataInfo {
- FORMATETC format_etc;
- STGMEDIUM* medium;
- bool owns_medium;
-
- StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* a_medium) {
- format_etc.cfFormat = cf;
- format_etc.dwAspect = DVASPECT_CONTENT;
- format_etc.lindex = -1;
- format_etc.ptd = NULL;
- format_etc.tymed = a_medium->tymed;
-
- owns_medium = true;
-
- medium = a_medium;
- }
-
- ~StoredDataInfo() {
- if (owns_medium) {
- ReleaseStgMedium(medium);
- delete medium;
- }
- }
- };
+ // Returns true if this OSExchangeData has data for ALL the formats in
+ // |formats| and ALL the custom formats in |custom_formats|.
+ bool HasAllFormats(int formats,
+ const std::set<CustomFormat>& custom_formats) const;
- typedef std::vector<StoredDataInfo*> StoredData;
- StoredData contents_;
+ // Returns true if this OSExchangeData has data in any of the formats in
+ // |formats| or any custom format in |custom_formats|.
+ bool HasAnyFormat(int formats,
+ const std::set<CustomFormat>& custom_formats) const;
- ScopedComPtr<IDataObject> source_object_;
+ private:
+ // Creates the platform specific Provider.
+ static Provider* CreateProvider();
- LONG ref_count_;
-#endif
+ // Provides the actual data.
+ scoped_ptr<Provider> provider_;
DISALLOW_COPY_AND_ASSIGN(OSExchangeData);
};
diff --git a/app/os_exchange_data_provider_gtk.cc b/app/os_exchange_data_provider_gtk.cc
new file mode 100644
index 0000000..5aaa414
--- /dev/null
+++ b/app/os_exchange_data_provider_gtk.cc
@@ -0,0 +1,170 @@
+// 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 "app/os_exchange_data_provider_gtk.h"
+
+#include <algorithm>
+
+#include "base/string_util.h"
+
+OSExchangeDataProviderGtk::OSExchangeDataProviderGtk(
+ int known_formats,
+ const std::set<GdkAtom>& known_custom_formats)
+ : known_formats_(known_formats),
+ known_custom_formats_(known_custom_formats),
+ formats_(0) {
+}
+
+OSExchangeDataProviderGtk::OSExchangeDataProviderGtk()
+ : known_formats_(0),
+ formats_(0) {
+}
+
+OSExchangeDataProviderGtk::~OSExchangeDataProviderGtk() {
+}
+
+bool OSExchangeDataProviderGtk::HasDataForAllFormats(
+ int formats,
+ const std::set<GdkAtom>& custom_formats) const {
+ if ((formats_ & formats) != formats)
+ return false;
+ return std::includes(custom_formats_.begin(),
+ custom_formats_.end(),
+ custom_formats.begin(), custom_formats.end());
+}
+
+void OSExchangeDataProviderGtk::SetString(const std::wstring& data) {
+ string_ = WideToUTF16Hack(data);
+ formats_ |= OSExchangeData::STRING;
+}
+
+void OSExchangeDataProviderGtk::SetURL(const GURL& url,
+ const std::wstring& title) {
+ url_ = url;
+ title_ = WideToUTF16Hack(title);
+ formats_ |= OSExchangeData::URL;
+}
+
+void OSExchangeDataProviderGtk::SetFilename(const std::wstring& full_path) {
+ filename_ = WideToUTF16Hack(full_path);
+ formats_ |= OSExchangeData::FILE_NAME;
+}
+
+void OSExchangeDataProviderGtk::SetPickledData(GdkAtom format,
+ const Pickle& data) {
+ pickle_data_[format] = data;
+ formats_ |= OSExchangeData::PICKLED_DATA;
+}
+
+void OSExchangeDataProviderGtk::SetFileContents(
+ const std::wstring& filename,
+ const std::string& file_contents) {
+ filename_ = WideToUTF16Hack(filename);
+ file_contents_ = file_contents;
+ formats_ |= OSExchangeData::FILE_CONTENTS;
+}
+
+void OSExchangeDataProviderGtk::SetHtml(const std::wstring& html,
+ const GURL& base_url) {
+ html_ = WideToUTF16Hack(html);
+ base_url_ = base_url;
+ formats_ |= OSExchangeData::HTML;
+}
+
+bool OSExchangeDataProviderGtk::GetString(std::wstring* data) const {
+ if (formats_ & OSExchangeData::STRING == 0)
+ return false;
+ *data = UTF16ToWideHack(string_);
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::GetURLAndTitle(GURL* url,
+ std::wstring* title) const {
+ if (formats_ & OSExchangeData::URL == 0)
+ return false;
+ if (!url_.is_valid())
+ return false;
+
+ *url = url_;
+ *title = UTF16ToWideHack(title_);
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::GetFilename(std::wstring* full_path) const {
+ if (formats_ & OSExchangeData::FILE_NAME == 0)
+ return false;
+ *full_path = UTF16ToWideHack(filename_);
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::GetPickledData(GdkAtom format,
+ Pickle* data) const {
+ PickleData::const_iterator i = pickle_data_.find(format);
+ if (i == pickle_data_.end())
+ return false;
+
+ *data = i->second;
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::GetFileContents(
+ std::wstring* filename,
+ std::string* file_contents) const {
+ if (formats_ & OSExchangeData::FILE_CONTENTS == 0)
+ return false;
+ *filename = UTF16ToWideHack(filename_);
+ *file_contents = file_contents_;
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::GetHtml(std::wstring* html,
+ GURL* base_url) const {
+ if (formats_ & OSExchangeData::HTML == 0)
+ return false;
+ *html = UTF16ToWideHack(filename_);
+ *base_url = base_url_;
+ return true;
+}
+
+bool OSExchangeDataProviderGtk::HasString() const {
+ return (known_formats_ & OSExchangeData::STRING) != 0 ||
+ (formats_ & OSExchangeData::STRING) != 0;
+}
+
+bool OSExchangeDataProviderGtk::HasURL() const {
+ return (known_formats_ & OSExchangeData::URL) != 0 ||
+ (formats_ & OSExchangeData::URL) != 0;
+}
+
+bool OSExchangeDataProviderGtk::HasFile() const {
+ return (known_formats_ & OSExchangeData::FILE_NAME) != 0 ||
+ (formats_ & OSExchangeData::FILE_NAME) != 0;
+ }
+
+bool OSExchangeDataProviderGtk::HasFileContents() const {
+ return (known_formats_ & OSExchangeData::FILE_CONTENTS) != 0 ||
+ (formats_ & OSExchangeData::FILE_CONTENTS) != 0;
+}
+
+bool OSExchangeDataProviderGtk::HasHtml() const {
+ return (known_formats_ & OSExchangeData::HTML) != 0 ||
+ (formats_ & OSExchangeData::HTML) != 0;
+}
+
+bool OSExchangeDataProviderGtk::HasCustomFormat(GdkAtom format) const {
+ return known_custom_formats_.find(format) != known_custom_formats_.end() ||
+ custom_formats_.find(format) != custom_formats_.end();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// OSExchangeData, public:
+
+// static
+OSExchangeData::Provider* OSExchangeData::CreateProvider() {
+ return new OSExchangeDataProviderGtk();
+}
+
+GdkAtom OSExchangeData::RegisterCustomFormat(const std::string& type) {
+ return gdk_atom_intern(type.c_str(), false);
+}
diff --git a/app/os_exchange_data_provider_gtk.h b/app/os_exchange_data_provider_gtk.h
new file mode 100644
index 0000000..dd9c009
--- /dev/null
+++ b/app/os_exchange_data_provider_gtk.h
@@ -0,0 +1,106 @@
+// 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.
+
+#ifndef APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_
+#define APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_
+
+#include <gtk/gtk.h>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include "app/os_exchange_data.h"
+#include "base/pickle.h"
+#include "base/string16.h"
+#include "googleurl/src/gurl.h"
+
+// OSExchangeData::Provider implementation for Gtk. OSExchangeDataProviderGtk
+// is created with a set of known data types. In addition specific data
+// types can be set on OSExchangeDataProviderGtk by way of the various setters.
+// The various has methods return true if the format was supplied to the
+// constructor, or explicitly set.
+class OSExchangeDataProviderGtk : public OSExchangeData::Provider {
+ public:
+ OSExchangeDataProviderGtk(int known_formats,
+ const std::set<GdkAtom>& known_custom_formats_);
+ OSExchangeDataProviderGtk();
+
+ virtual ~OSExchangeDataProviderGtk();
+
+ int known_formats() const { return known_formats_; }
+ const std::set<GdkAtom>& known_custom_formats() const {
+ return known_custom_formats_;
+ }
+
+ // Returns true if all the formats and custom formats identified by |formats|
+ // and |custom_formats| have been set in this provider.
+ //
+ // NOTE: this is NOT the same as whether a format may be provided (as is
+ // returned by the various HasXXX methods), but rather if the data for the
+ // formats has been set on this provider by way of the various Setter
+ // methods.
+ bool HasDataForAllFormats(int formats,
+ const std::set<GdkAtom>& custom_formats) const;
+
+ // Provider methods.
+ virtual void SetString(const std::wstring& data);
+ virtual void SetURL(const GURL& url, const std::wstring& title);
+ virtual void SetFilename(const std::wstring& full_path);
+ virtual void SetPickledData(OSExchangeData::CustomFormat format,
+ const Pickle& data);
+ virtual void SetFileContents(const std::wstring& filename,
+ const std::string& file_contents);
+ virtual void SetHtml(const std::wstring& html, const GURL& base_url);
+ virtual bool GetString(std::wstring* data) const;
+ virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const;
+ virtual bool GetFilename(std::wstring* full_path) const;
+ virtual bool GetPickledData(OSExchangeData::CustomFormat format,
+ Pickle* data) const;
+ virtual bool GetFileContents(std::wstring* filename,
+ std::string* file_contents) const;
+ virtual bool GetHtml(std::wstring* html, GURL* base_url) const;
+ virtual bool HasString() const;
+ virtual bool HasURL() const;
+ virtual bool HasFile() const;
+ virtual bool HasFileContents() const;
+ virtual bool HasHtml() const;
+ virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const;
+
+ private:
+ typedef std::map<OSExchangeData::CustomFormat, Pickle> PickleData;
+
+ // These are the possible formats the OSExchangeData may contain. Don't
+ // confuse this with the actual formats that have been set, which are
+ // |formats_| and |custom_formats_|.
+ const int known_formats_;
+ const std::set<GdkAtom> known_custom_formats_;
+
+ // Actual formats that have been set. See comment above |known_formats_|
+ // for details.
+ int formats_;
+ std::set<GdkAtom> custom_formats_;
+
+ // String contents.
+ string16 string_;
+
+ // URL contents.
+ GURL url_;
+ string16 title_;
+
+ // File contents.
+ string16 filename_;
+ std::string file_contents_;
+
+ // HTML contents.
+ string16 html_;
+ GURL base_url_;
+
+ // PICKLED_DATA contents.
+ PickleData pickle_data_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderGtk);
+};
+
+#endif // APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_
diff --git a/app/os_exchange_data_win.cc b/app/os_exchange_data_provider_win.cc
index c7bd18b..1d8bdd8 100644
--- a/app/os_exchange_data_win.cc
+++ b/app/os_exchange_data_provider_win.cc
@@ -1,8 +1,8 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// 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 "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "app/l10n_util.h"
#include "base/clipboard_util.h"
@@ -48,8 +48,8 @@ static STGMEDIUM* GetStorageForFileDescriptor(
//
class FormatEtcEnumerator : public IEnumFORMATETC {
public:
- FormatEtcEnumerator(OSExchangeData::StoredData::const_iterator begin,
- OSExchangeData::StoredData::const_iterator end);
+ FormatEtcEnumerator(DataObjectImpl::StoredData::const_iterator begin,
+ DataObjectImpl::StoredData::const_iterator end);
~FormatEtcEnumerator();
// IEnumFORMATETC implementation:
@@ -99,8 +99,8 @@ static void CloneFormatEtc(FORMATETC* source, FORMATETC* clone) {
}
FormatEtcEnumerator::FormatEtcEnumerator(
- OSExchangeData::StoredData::const_iterator start,
- OSExchangeData::StoredData::const_iterator end)
+ DataObjectImpl::StoredData::const_iterator start,
+ DataObjectImpl::StoredData::const_iterator end)
: ref_count_(0), cursor_(0) {
// Copy FORMATETC data from our source into ourselves.
while (start != end) {
@@ -200,17 +200,18 @@ FormatEtcEnumerator* FormatEtcEnumerator::CloneFromOther(
}
///////////////////////////////////////////////////////////////////////////////
-// OSExchangeData, public:
+// OSExchangeDataProviderWin, public:
// static
-bool OSExchangeData::HasPlainTextURL(IDataObject* source) {
+bool OSExchangeDataProviderWin::HasPlainTextURL(IDataObject* source) {
std::wstring plain_text;
return (ClipboardUtil::GetPlainText(source, &plain_text) &&
!plain_text.empty() && GURL(plain_text).is_valid());
}
// static
-bool OSExchangeData::GetPlainTextURL(IDataObject* source, GURL* url) {
+bool OSExchangeDataProviderWin::GetPlainTextURL(IDataObject* source,
+ GURL* url) {
std::wstring plain_text;
if (ClipboardUtil::GetPlainText(source, &plain_text) &&
!plain_text.empty()) {
@@ -223,29 +224,39 @@ bool OSExchangeData::GetPlainTextURL(IDataObject* source, GURL* url) {
return false;
}
-OSExchangeData::OSExchangeData()
- : ref_count_(0) {
+// static
+IDataObject* OSExchangeDataProviderWin::GetIDataObject(
+ const OSExchangeData& data) {
+ return static_cast<const OSExchangeDataProviderWin&>(data.provider()).
+ data_object();
}
-OSExchangeData::OSExchangeData(IDataObject* source)
- : ref_count_(0) {
- source_object_ = source;
+OSExchangeDataProviderWin::OSExchangeDataProviderWin(IDataObject* source)
+ : data_(new DataObjectImpl()),
+ source_object_(source) {
}
-OSExchangeData::~OSExchangeData() {
- STLDeleteContainerPointers(contents_.begin(), contents_.end());
+OSExchangeDataProviderWin::OSExchangeDataProviderWin()
+ : data_(new DataObjectImpl()),
+ source_object_(data_.get()) {
}
-void OSExchangeData::SetString(const std::wstring& data) {
+OSExchangeDataProviderWin::~OSExchangeDataProviderWin() {
+}
+
+void OSExchangeDataProviderWin::SetString(const std::wstring& data) {
STGMEDIUM* storage = GetStorageForWString(data);
- contents_.push_back(new StoredDataInfo(CF_UNICODETEXT, storage));
+ data_->contents_.push_back(
+ new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage));
// Also add plain text.
storage = GetStorageForString(WideToUTF8(data));
- contents_.push_back(new StoredDataInfo(CF_TEXT, storage));
+ data_->contents_.push_back(
+ new DataObjectImpl::StoredDataInfo(CF_TEXT, storage));
}
-void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
+void OSExchangeDataProviderWin::SetURL(const GURL& url,
+ const std::wstring& title) {
// NOTE WELL:
// Every time you change the order of the first two CLIPFORMATS that get
// added here, you need to update the EnumerationViaCOM test case in
@@ -257,7 +268,7 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
x_moz_url_str += '\n';
x_moz_url_str += title;
STGMEDIUM* storage = GetStorageForWString(x_moz_url_str);
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetMozUrlFormat()->cfFormat, storage));
// Add a .URL shortcut file for dragging to Explorer.
@@ -269,10 +280,10 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
// Add a UniformResourceLocator link for apps like IE and Word.
storage = GetStorageForWString(UTF8ToWide(url.spec()));
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetUrlWFormat()->cfFormat, storage));
storage = GetStorageForString(url.spec());
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetUrlFormat()->cfFormat, storage));
// TODO(beng): (http://b/1085501) add CF_HTML...
@@ -280,12 +291,14 @@ void OSExchangeData::SetURL(const GURL& url, const std::wstring& title) {
// Also add text representations (these should be last since they're the
// least preferable).
storage = GetStorageForWString(UTF8ToWide(url.spec()));
- contents_.push_back(new StoredDataInfo(CF_UNICODETEXT, storage));
+ data_->contents_.push_back(
+ new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage));
storage = GetStorageForString(url.spec());
- contents_.push_back(new StoredDataInfo(CF_TEXT, storage));
+ data_->contents_.push_back(
+ new DataObjectImpl::StoredDataInfo(CF_TEXT, storage));
}
-void OSExchangeData::SetFilename(const std::wstring& full_path) {
+void OSExchangeDataProviderWin::SetFilename(const std::wstring& full_path) {
const size_t drop_size = sizeof(DROPFILES);
const size_t bytes = drop_size + (full_path.length() + 2) * sizeof(wchar_t);
HANDLE hdata = ::GlobalAlloc(GMEM_MOVEABLE, bytes);
@@ -308,51 +321,57 @@ void OSExchangeData::SetFilename(const std::wstring& full_path) {
storage->pUnkForRelease = NULL;
// Set up the StoredDataInfo
- StoredDataInfo* info = new StoredDataInfo(CF_HDROP, storage);
- contents_.push_back(info);
+ DataObjectImpl::StoredDataInfo* info =
+ new DataObjectImpl::StoredDataInfo(CF_HDROP, storage);
+ data_->contents_.push_back(info);
}
-void OSExchangeData::SetPickledData(CLIPFORMAT format, const Pickle& data) {
+void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format,
+ const Pickle& data) {
STGMEDIUM* storage = GetStorageForString(
std::string(static_cast<const char *>(data.data()),
static_cast<size_t>(data.size())));
- contents_.push_back(new StoredDataInfo(format, storage));
+ data_->contents_.push_back(
+ new DataObjectImpl::StoredDataInfo(format, storage));
}
-void OSExchangeData::SetFileContents(const std::wstring& filename,
- const std::string& file_contents) {
+void OSExchangeDataProviderWin::SetFileContents(
+ const std::wstring& filename,
+ const std::string& file_contents) {
// Add CFSTR_FILEDESCRIPTOR
STGMEDIUM* storage = GetStorageForFileDescriptor(filename);
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetFileDescriptorFormat()->cfFormat, storage));
// Add CFSTR_FILECONTENTS
storage = GetStorageForBytes(file_contents.data(), file_contents.length());
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetFileContentFormatZero()->cfFormat, storage));
}
-void OSExchangeData::SetHtml(const std::wstring& html, const GURL& base_url) {
+void OSExchangeDataProviderWin::SetHtml(const std::wstring& html,
+ const GURL& base_url) {
// Add both MS CF_HTML and text/html format. CF_HTML should be in utf-8.
std::string utf8_html = WideToUTF8(html);
std::string url = base_url.is_valid() ? base_url.spec() : std::string();
std::string cf_html = ClipboardUtil::HtmlToCFHtml(utf8_html, url);
STGMEDIUM* storage = GetStorageForBytes(cf_html.c_str(), cf_html.size());
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetHtmlFormat()->cfFormat, storage));
STGMEDIUM* storage_plain = GetStorageForBytes(utf8_html.c_str(),
utf8_html.size());
- contents_.push_back(new StoredDataInfo(
+ data_->contents_.push_back(new DataObjectImpl::StoredDataInfo(
ClipboardUtil::GetTextHtmlFormat()->cfFormat, storage_plain));
}
-bool OSExchangeData::GetString(std::wstring* data) const {
+bool OSExchangeDataProviderWin::GetString(std::wstring* data) const {
return ClipboardUtil::GetPlainText(source_object_, data);
}
-bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const {
+bool OSExchangeDataProviderWin::GetURLAndTitle(GURL* url,
+ std::wstring* title) const {
std::wstring url_str;
bool success = ClipboardUtil::GetUrl(source_object_, &url_str, title);
if (success) {
@@ -368,7 +387,7 @@ bool OSExchangeData::GetURLAndTitle(GURL* url, std::wstring* title) const {
return false;
}
-bool OSExchangeData::GetFilename(std::wstring* full_path) const {
+bool OSExchangeDataProviderWin::GetFilename(std::wstring* full_path) const {
std::vector<std::wstring> filenames;
bool success = ClipboardUtil::GetFilenames(source_object_, &filenames);
if (success)
@@ -376,7 +395,8 @@ bool OSExchangeData::GetFilename(std::wstring* full_path) const {
return success;
}
-bool OSExchangeData::GetPickledData(CLIPFORMAT format, Pickle* data) const {
+bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format,
+ Pickle* data) const {
DCHECK(data);
FORMATETC format_etc =
{ format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
@@ -395,13 +415,15 @@ bool OSExchangeData::GetPickledData(CLIPFORMAT format, Pickle* data) const {
return success;
}
-bool OSExchangeData::GetFileContents(std::wstring* filename,
- std::string* file_contents) const {
+bool OSExchangeDataProviderWin::GetFileContents(
+ std::wstring* filename,
+ std::string* file_contents) const {
return ClipboardUtil::GetFileContents(source_object_, filename,
file_contents);
}
-bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const {
+bool OSExchangeDataProviderWin::GetHtml(std::wstring* html,
+ GURL* base_url) const {
std::string url;
bool success = ClipboardUtil::GetHtml(source_object_, html, &url);
if (success)
@@ -409,27 +431,35 @@ bool OSExchangeData::GetHtml(std::wstring* html, GURL* base_url) const {
return success;
}
-bool OSExchangeData::HasString() const {
+bool OSExchangeDataProviderWin::HasString() const {
return ClipboardUtil::HasPlainText(source_object_);
}
-bool OSExchangeData::HasURL() const {
+bool OSExchangeDataProviderWin::HasURL() const {
return (ClipboardUtil::HasUrl(source_object_) ||
HasPlainTextURL(source_object_));
}
-bool OSExchangeData::HasFile() const {
+bool OSExchangeDataProviderWin::HasFile() const {
return ClipboardUtil::HasFilenames(source_object_);
}
-bool OSExchangeData::HasFormat(CLIPFORMAT format) const {
+bool OSExchangeDataProviderWin::HasFileContents() const {
+ return ClipboardUtil::HasFileContents(source_object_);
+}
+
+bool OSExchangeDataProviderWin::HasHtml() const {
+ return ClipboardUtil::HasHtml(source_object_);
+}
+
+bool OSExchangeDataProviderWin::HasCustomFormat(CLIPFORMAT format) const {
FORMATETC format_etc =
{ format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
return (source_object_->QueryGetData(&format_etc) == S_OK);
}
///////////////////////////////////////////////////////////////////////////////
-// OSExchangeData, IDataObject implementation:
+// DataObjectImpl, IDataObject implementation:
// The following function, DuplicateMedium, is derived from WCDataObject.cpp
// in the WebKit source code. This is the license information for the file:
@@ -502,7 +532,15 @@ static void DuplicateMedium(CLIPFORMAT source_clipformat,
destination->pUnkForRelease->AddRef();
}
-HRESULT OSExchangeData::GetData(FORMATETC* format_etc, STGMEDIUM* medium) {
+DataObjectImpl::DataObjectImpl() : ref_count_(0) {
+ STLDeleteContainerPointers(contents_.begin(), contents_.end());
+}
+
+DataObjectImpl::~DataObjectImpl() {
+ STLDeleteContainerPointers(contents_.begin(), contents_.end());
+}
+
+HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) {
StoredData::const_iterator iter = contents_.begin();
while (iter != contents_.end()) {
if ((*iter)->format_etc.cfFormat == format_etc->cfFormat) {
@@ -515,11 +553,12 @@ HRESULT OSExchangeData::GetData(FORMATETC* format_etc, STGMEDIUM* medium) {
return DV_E_FORMATETC;
}
-HRESULT OSExchangeData::GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium) {
+HRESULT DataObjectImpl::GetDataHere(FORMATETC* format_etc,
+ STGMEDIUM* medium) {
return DATA_E_FORMATETC;
}
-HRESULT OSExchangeData::QueryGetData(FORMATETC* format_etc) {
+HRESULT DataObjectImpl::QueryGetData(FORMATETC* format_etc) {
StoredData::const_iterator iter = contents_.begin();
while (iter != contents_.end()) {
if ((*iter)->format_etc.cfFormat == format_etc->cfFormat)
@@ -529,13 +568,13 @@ HRESULT OSExchangeData::QueryGetData(FORMATETC* format_etc) {
return DV_E_FORMATETC;
}
-HRESULT OSExchangeData::GetCanonicalFormatEtc(
+HRESULT DataObjectImpl::GetCanonicalFormatEtc(
FORMATETC* format_etc, FORMATETC* result) {
format_etc->ptd = NULL;
return E_NOTIMPL;
}
-HRESULT OSExchangeData::SetData(
+HRESULT DataObjectImpl::SetData(
FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release) {
STGMEDIUM* local_medium = new STGMEDIUM;
if (should_release) {
@@ -544,8 +583,8 @@ HRESULT OSExchangeData::SetData(
DuplicateMedium(format_etc->cfFormat, medium, local_medium);
}
- StoredDataInfo* info =
- new StoredDataInfo(format_etc->cfFormat, local_medium);
+ DataObjectImpl::StoredDataInfo* info =
+ new DataObjectImpl::StoredDataInfo(format_etc->cfFormat, local_medium);
info->medium->tymed = format_etc->tymed;
info->owns_medium = !!should_release;
contents_.push_back(info);
@@ -553,7 +592,7 @@ HRESULT OSExchangeData::SetData(
return S_OK;
}
-HRESULT OSExchangeData::EnumFormatEtc(
+HRESULT DataObjectImpl::EnumFormatEtc(
DWORD direction, IEnumFORMATETC** enumerator) {
if (direction == DATADIR_GET) {
FormatEtcEnumerator* e =
@@ -565,23 +604,23 @@ HRESULT OSExchangeData::EnumFormatEtc(
return E_NOTIMPL;
}
-HRESULT OSExchangeData::DAdvise(
+HRESULT DataObjectImpl::DAdvise(
FORMATETC* format_etc, DWORD advf, IAdviseSink* sink, DWORD* connection) {
return OLE_E_ADVISENOTSUPPORTED;
}
-HRESULT OSExchangeData::DUnadvise(DWORD connection) {
+HRESULT DataObjectImpl::DUnadvise(DWORD connection) {
return OLE_E_ADVISENOTSUPPORTED;
}
-HRESULT OSExchangeData::EnumDAdvise(IEnumSTATDATA** enumerator) {
+HRESULT DataObjectImpl::EnumDAdvise(IEnumSTATDATA** enumerator) {
return OLE_E_ADVISENOTSUPPORTED;
}
///////////////////////////////////////////////////////////////////////////////
-// OSExchangeData, IUnknown implementation:
+// DataObjectImpl, IUnknown implementation:
-HRESULT OSExchangeData::QueryInterface(const IID& iid, void** object) {
+HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) {
*object = NULL;
if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IDataObject)) {
*object = this;
@@ -592,11 +631,11 @@ HRESULT OSExchangeData::QueryInterface(const IID& iid, void** object) {
return S_OK;
}
-ULONG OSExchangeData::AddRef() {
+ULONG DataObjectImpl::AddRef() {
return InterlockedIncrement(&ref_count_);
}
-ULONG OSExchangeData::Release() {
+ULONG DataObjectImpl::Release() {
if (InterlockedDecrement(&ref_count_) == 0) {
ULONG copied_refcnt = ref_count_;
delete this;
@@ -606,7 +645,7 @@ ULONG OSExchangeData::Release() {
}
///////////////////////////////////////////////////////////////////////////////
-// OSExchangeData, private:
+// DataObjectImpl, private:
static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes) {
HANDLE handle = GlobalAlloc(GPTR, static_cast<int>(bytes));
@@ -702,3 +741,17 @@ static STGMEDIUM* GetStorageForFileDescriptor(
storage->pUnkForRelease = NULL;
return storage;
}
+
+///////////////////////////////////////////////////////////////////////////////
+// OSExchangeData, public:
+
+// static
+OSExchangeData::Provider* OSExchangeData::CreateProvider() {
+ return new OSExchangeDataProviderWin();
+}
+
+// static
+OSExchangeData::CustomFormat OSExchangeData::RegisterCustomFormat(
+ const std::string& type) {
+ return RegisterClipboardFormat(ASCIIToWide(type).c_str());
+}
diff --git a/app/os_exchange_data_provider_win.h b/app/os_exchange_data_provider_win.h
new file mode 100644
index 0000000..42b11e2
--- /dev/null
+++ b/app/os_exchange_data_provider_win.h
@@ -0,0 +1,128 @@
+// 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.
+
+#ifndef APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
+#define APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
+
+#include <objidl.h>
+#include <string>
+
+#include "app/os_exchange_data.h"
+#include "base/scoped_comptr_win.h"
+
+class DataObjectImpl : public IDataObject {
+ public:
+ DataObjectImpl();
+ ~DataObjectImpl();
+
+ // IDataObject implementation:
+ HRESULT __stdcall GetData(FORMATETC* format_etc, STGMEDIUM* medium);
+ HRESULT __stdcall GetDataHere(FORMATETC* format_etc, STGMEDIUM* medium);
+ HRESULT __stdcall QueryGetData(FORMATETC* format_etc);
+ HRESULT __stdcall GetCanonicalFormatEtc(
+ FORMATETC* format_etc, FORMATETC* result);
+ HRESULT __stdcall SetData(
+ FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release);
+ HRESULT __stdcall EnumFormatEtc(
+ DWORD direction, IEnumFORMATETC** enumerator);
+ HRESULT __stdcall DAdvise(FORMATETC* format_etc, DWORD advf,
+ IAdviseSink* sink, DWORD* connection);
+ HRESULT __stdcall DUnadvise(DWORD connection);
+ HRESULT __stdcall EnumDAdvise(IEnumSTATDATA** enumerator);
+
+ // IUnknown implementation:
+ HRESULT __stdcall QueryInterface(const IID& iid, void** object);
+ ULONG __stdcall AddRef();
+ ULONG __stdcall Release();
+
+ private:
+ // FormatEtcEnumerator only likes us for our StoredDataMap typedef.
+ friend class FormatEtcEnumerator;
+ friend class OSExchangeDataProviderWin;
+
+ // Our internal representation of stored data & type info.
+ struct StoredDataInfo {
+ FORMATETC format_etc;
+ STGMEDIUM* medium;
+ bool owns_medium;
+
+ StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* a_medium) {
+ format_etc.cfFormat = cf;
+ format_etc.dwAspect = DVASPECT_CONTENT;
+ format_etc.lindex = -1;
+ format_etc.ptd = NULL;
+ format_etc.tymed = a_medium->tymed;
+
+ owns_medium = true;
+
+ medium = a_medium;
+ }
+
+ ~StoredDataInfo() {
+ if (owns_medium) {
+ ReleaseStgMedium(medium);
+ delete medium;
+ }
+ }
+ };
+
+ typedef std::vector<StoredDataInfo*> StoredData;
+ StoredData contents_;
+
+ ScopedComPtr<IDataObject> source_object_;
+
+ LONG ref_count_;
+};
+
+class OSExchangeDataProviderWin : public OSExchangeData::Provider {
+ public:
+ // Returns true if source has plain text that is a valid url.
+ static bool HasPlainTextURL(IDataObject* source);
+
+ // Returns true if source has plain text that is a valid URL and sets url to
+ // that url.
+ static bool GetPlainTextURL(IDataObject* source, GURL* url);
+
+ static IDataObject* GetIDataObject(const OSExchangeData& data);
+
+ explicit OSExchangeDataProviderWin(IDataObject* source);
+ OSExchangeDataProviderWin();
+
+ virtual ~OSExchangeDataProviderWin();
+
+ IDataObject* data_object() const { return data_.get(); }
+
+ // OSExchangeData::Provider methods.
+ virtual void SetString(const std::wstring& data);
+ virtual void SetURL(const GURL& url, const std::wstring& title);
+ virtual void SetFilename(const std::wstring& full_path);
+ virtual void SetPickledData(OSExchangeData::CustomFormat format,
+ const Pickle& data);
+ virtual void SetFileContents(const std::wstring& filename,
+ const std::string& file_contents);
+ virtual void SetHtml(const std::wstring& html, const GURL& base_url);
+
+ virtual bool GetString(std::wstring* data) const;
+ virtual bool GetURLAndTitle(GURL* url, std::wstring* title) const;
+ virtual bool GetFilename(std::wstring* full_path) const;
+ virtual bool GetPickledData(OSExchangeData::CustomFormat format,
+ Pickle* data) const;
+ virtual bool GetFileContents(std::wstring* filename,
+ std::string* file_contents) const;
+ virtual bool GetHtml(std::wstring* html, GURL* base_url) const;
+ virtual bool HasString() const;
+ virtual bool HasURL() const;
+ virtual bool HasFile() const;
+ virtual bool HasFileContents() const;
+ virtual bool HasHtml() const;
+ virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const;
+
+ private:
+ scoped_refptr<DataObjectImpl> data_;
+ ScopedComPtr<IDataObject> source_object_;
+
+ DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderWin);
+};
+
+#endif // APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_
diff --git a/app/os_exchange_data_win_unittest.cc b/app/os_exchange_data_win_unittest.cc
index 981a8d1..88f33b0 100644
--- a/app/os_exchange_data_win_unittest.cc
+++ b/app/os_exchange_data_win_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/clipboard_util.h"
#include "base/pickle.h"
#include "base/ref_counted.h"
@@ -14,32 +15,40 @@
typedef testing::Test OSExchangeDataTest;
+namespace {
+
+OSExchangeData::Provider* CloneProvider(const OSExchangeData& data) {
+ return new OSExchangeDataProviderWin(
+ OSExchangeDataProviderWin::GetIDataObject(data));
+}
+
+} // namespace
+
// Test setting/getting using the OSExchangeData API
TEST(OSExchangeDataTest, StringDataGetAndSet) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
std::wstring input = L"I can has cheezburger?";
- data->SetString(input);
+ data.SetString(input);
- OSExchangeData* data2 = new OSExchangeData(data);
+ OSExchangeData data2(CloneProvider(data));
std::wstring output;
- EXPECT_TRUE(data2->GetString(&output));
+ EXPECT_TRUE(data2.GetString(&output));
EXPECT_EQ(input, output);
std::string url_spec = "http://www.goats.com/";
GURL url(url_spec);
std::wstring title;
- EXPECT_FALSE(data2->GetURLAndTitle(&url, &title));
+ EXPECT_FALSE(data2.GetURLAndTitle(&url, &title));
// No URLs in |data|, so url should be untouched.
EXPECT_EQ(url_spec, url.spec());
- // data gets freed when data2 releases the ref on it
- delete data2;
}
// Test getting using the IDataObject COM API
TEST(OSExchangeDataTest, StringDataAccessViaCOM) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
std::wstring input = L"O hai googlz.";
- data->SetString(input);
- ScopedComPtr<IDataObject> com_data(data);
+ data.SetString(input);
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
FORMATETC format_etc =
{ CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
@@ -55,10 +64,11 @@ TEST(OSExchangeDataTest, StringDataAccessViaCOM) {
// Test setting using the IDataObject COM API
TEST(OSExchangeDataTest, StringDataWritingViaCOM) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
std::wstring input = L"http://www.google.com/";
- ScopedComPtr<IDataObject> com_data(data);
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
// Store data in the object using the COM SetData API.
CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL);
@@ -78,22 +88,21 @@ TEST(OSExchangeDataTest, StringDataWritingViaCOM) {
// Construct a new object with the old object so that we can use our access
// APIs.
- OSExchangeData* data2 = new OSExchangeData(com_data);
- EXPECT_TRUE(data2->HasURL());
+ OSExchangeData data2(CloneProvider(data));
+ EXPECT_TRUE(data2.HasURL());
GURL url_from_data;
std::wstring title;
- EXPECT_TRUE(data2->GetURLAndTitle(&url_from_data, &title));
+ EXPECT_TRUE(data2.GetURLAndTitle(&url_from_data, &title));
GURL reference_url(input);
EXPECT_EQ(reference_url.spec(), url_from_data.spec());
- // deleting data2 will free data because it holds a ref to it.
- delete data2;
}
TEST(OSExchangeDataTest, URLDataAccessViaCOM) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
GURL url("http://www.google.com/");
- data->SetURL(url, L"");
- ScopedComPtr<IDataObject> com_data(data);
+ data.SetURL(url, L"");
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL);
FORMATETC format_etc =
@@ -109,14 +118,15 @@ TEST(OSExchangeDataTest, URLDataAccessViaCOM) {
}
TEST(OSExchangeDataTest, MultipleFormatsViaCOM) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
std::string url_spec = "http://www.google.com/";
GURL url(url_spec);
std::wstring text = L"O hai googlz.";
- data->SetURL(url, L"Google");
- data->SetString(text);
+ data.SetURL(url, L"Google");
+ data.SetString(text);
- ScopedComPtr<IDataObject> com_data(data);
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL);
FORMATETC url_format_etc =
@@ -143,15 +153,16 @@ TEST(OSExchangeDataTest, MultipleFormatsViaCOM) {
}
TEST(OSExchangeDataTest, EnumerationViaCOM) {
- OSExchangeData* data = new OSExchangeData;
- data->SetURL(GURL("http://www.google.com/"), L"");
- data->SetString(L"O hai googlz.");
+ OSExchangeData data;
+ data.SetURL(GURL("http://www.google.com/"), L"");
+ data.SetString(L"O hai googlz.");
CLIPFORMAT cfstr_file_group_descriptor =
RegisterClipboardFormat(CFSTR_FILEDESCRIPTOR);
CLIPFORMAT text_x_moz_url = RegisterClipboardFormat(L"text/x-moz-url");
- ScopedComPtr<IDataObject> com_data(data);
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
ScopedComPtr<IEnumFORMATETC> enumerator;
EXPECT_EQ(S_OK, com_data.get()->EnumFormatEtc(DATADIR_GET,
enumerator.Receive()));
@@ -231,29 +242,30 @@ TEST(OSExchangeDataTest, EnumerationViaCOM) {
}
TEST(OSExchangeDataTest, TestURLExchangeFormats) {
- OSExchangeData* data = new OSExchangeData;
+ OSExchangeData data;
std::string url_spec = "http://www.google.com/";
GURL url(url_spec);
std::wstring url_title = L"Google";
- data->SetURL(url, url_title);
+ data.SetURL(url, url_title);
std::wstring output;
- OSExchangeData* data2 = new OSExchangeData(data);
+ OSExchangeData data2(CloneProvider(data));
// URL spec and title should match
GURL output_url;
std::wstring output_title;
- EXPECT_TRUE(data2->GetURLAndTitle(&output_url, &output_title));
+ EXPECT_TRUE(data2.GetURLAndTitle(&output_url, &output_title));
EXPECT_EQ(url_spec, output_url.spec());
EXPECT_EQ(url_title, output_title);
std::wstring output_string;
// URL should be the raw text response
- EXPECT_TRUE(data2->GetString(&output_string));
+ EXPECT_TRUE(data2.GetString(&output_string));
EXPECT_EQ(url_spec, WideToUTF8(output_string));
// File contents access via COM
- ScopedComPtr<IDataObject> com_data(data);
+ ScopedComPtr<IDataObject> com_data(
+ OSExchangeDataProviderWin::GetIDataObject(data));
{
CLIPFORMAT cfstr_file_contents =
RegisterClipboardFormat(CFSTR_FILECONTENTS);
@@ -271,9 +283,6 @@ TEST(OSExchangeDataTest, TestURLExchangeFormats) {
EXPECT_EQ(file_contents, output);
ReleaseStgMedium(&medium);
}
-
- // Need to manually free data2 since we never stuff it into a COMPtr.
- delete data2;
}
TEST(OSExchangeDataTest, TestPickledData) {
@@ -282,14 +291,14 @@ TEST(OSExchangeDataTest, TestPickledData) {
Pickle saved_pickle;
saved_pickle.WriteInt(1);
saved_pickle.WriteInt(2);
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- data->SetPickledData(test_cf, saved_pickle);
+ OSExchangeData data;
+ data.SetPickledData(test_cf, saved_pickle);
- scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get()));
- EXPECT_TRUE(copy->HasFormat(test_cf));
+ OSExchangeData copy(CloneProvider(data));
+ EXPECT_TRUE(copy.HasCustomFormat(test_cf));
Pickle restored_pickle;
- EXPECT_TRUE(copy->GetPickledData(test_cf, &restored_pickle));
+ EXPECT_TRUE(copy.GetPickledData(test_cf, &restored_pickle));
void* p_iterator = NULL;
int value;
EXPECT_TRUE(restored_pickle.ReadInt(&p_iterator, &value));
@@ -299,30 +308,30 @@ TEST(OSExchangeDataTest, TestPickledData) {
}
TEST(OSExchangeDataTest, FileContents) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
+ OSExchangeData data;
std::string file_contents("data\0with\0nulls", 15);
- data->SetFileContents(L"filename.txt", file_contents);
+ data.SetFileContents(L"filename.txt", file_contents);
- scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get()));
+ OSExchangeData copy(CloneProvider(data));
std::wstring filename;
std::string read_contents;
- EXPECT_TRUE(copy->GetFileContents(&filename, &read_contents));
+ EXPECT_TRUE(copy.GetFileContents(&filename, &read_contents));
EXPECT_EQ(L"filename.txt", filename);
EXPECT_EQ(file_contents, read_contents);
}
TEST(OSExchangeDataTest, Html) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
+ OSExchangeData data;
GURL url("http://www.google.com/");
std::wstring html(
L"<HTML>\n<BODY>\n"
L"<b>bold.</b> <i><b>This is bold italic.</b></i>\n"
L"</BODY>\n</HTML>");
- data->SetHtml(html, url);
+ data.SetHtml(html, url);
- scoped_refptr<OSExchangeData> copy(new OSExchangeData(data.get()));
+ OSExchangeData copy(CloneProvider(data));
std::wstring read_html;
- EXPECT_TRUE(copy->GetHtml(&read_html, &url));
+ EXPECT_TRUE(copy.GetHtml(&read_html, &url));
EXPECT_EQ(html, read_html);
// Check the CF_HTML too.
@@ -335,7 +344,9 @@ TEST(OSExchangeDataTest, Html) {
expected_cf_html.append("\r\n<!--EndFragment-->\r\n</body>\r\n</html>");
STGMEDIUM medium;
- EXPECT_EQ(S_OK, data->GetData(ClipboardUtil::GetHtmlFormat(), &medium));
+ IDataObject* data_object = OSExchangeDataProviderWin::GetIDataObject(data);
+ EXPECT_EQ(S_OK,
+ data_object->GetData(ClipboardUtil::GetHtmlFormat(), &medium));
ScopedHGlobal<char> glob(medium.hGlobal);
std::string output(glob.get(), glob.Size());
EXPECT_EQ(expected_cf_html, output);
@@ -343,19 +354,19 @@ TEST(OSExchangeDataTest, Html) {
}
TEST(OSExchangeDataTest, SetURLWithMaxPath) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
+ OSExchangeData data;
std::wstring long_title(L'a', MAX_PATH + 1);
- data->SetURL(GURL("http://google.com"), long_title);
+ data.SetURL(GURL("http://google.com"), long_title);
}
TEST(OSExchangeDataTest, ProvideURLForPlainTextURL) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
- data->SetString(L"http://google.com");
+ OSExchangeData data;
+ data.SetString(L"http://google.com");
- scoped_ptr<OSExchangeData> data2(new OSExchangeData(data.get()));
- ASSERT_TRUE(data2->HasURL());
+ OSExchangeData data2(CloneProvider(data));
+ ASSERT_TRUE(data2.HasURL());
GURL read_url;
std::wstring title;
- EXPECT_TRUE(data2->GetURLAndTitle(&read_url, &title));
+ EXPECT_TRUE(data2.GetURLAndTitle(&read_url, &title));
EXPECT_EQ(GURL("http://google.com"), read_url);
}
diff --git a/base/clipboard_util.cc b/base/clipboard_util.cc
index 74f34e3..0102ebd 100644
--- a/base/clipboard_util.cc
+++ b/base/clipboard_util.cc
@@ -165,6 +165,17 @@ bool ClipboardUtil::HasFilenames(IDataObject* data_object) {
return SUCCEEDED(data_object->QueryGetData(GetCFHDropFormat()));
}
+bool ClipboardUtil::HasFileContents(IDataObject* data_object) {
+ DCHECK(data_object);
+ return SUCCEEDED(data_object->QueryGetData(GetFileContentFormatZero()));
+}
+
+bool ClipboardUtil::HasHtml(IDataObject* data_object) {
+ DCHECK(data_object);
+ return SUCCEEDED(data_object->QueryGetData(GetHtmlFormat())) ||
+ SUCCEEDED(data_object->QueryGetData(GetTextHtmlFormat()));
+}
+
bool ClipboardUtil::HasPlainText(IDataObject* data_object) {
DCHECK(data_object);
return SUCCEEDED(data_object->QueryGetData(GetPlainTextWFormat())) ||
diff --git a/base/clipboard_util.h b/base/clipboard_util.h
index bed0eef..2a0b15e 100644
--- a/base/clipboard_util.h
+++ b/base/clipboard_util.h
@@ -37,6 +37,8 @@ class ClipboardUtil {
static bool HasUrl(IDataObject* data_object);
static bool HasFilenames(IDataObject* data_object);
static bool HasPlainText(IDataObject* data_object);
+ static bool HasFileContents(IDataObject* data_object);
+ static bool HasHtml(IDataObject* data_object);
/////////////////////////////////////////////////////////////////////////////
// Helper methods to extract information from an IDataObject. These methods
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index 5e88e94..839e1b3 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -10,6 +10,7 @@
#include "app/l10n_util.h"
#include "app/l10n_util_win.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "app/win_util.h"
#include "base/base_drag_source.h"
#include "base/base_drop_target.h"
@@ -127,7 +128,7 @@ DWORD EditDropTarget::OnDragEnter(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
- OSExchangeData os_data(data_object);
+ OSExchangeData os_data(new OSExchangeDataProviderWin(data_object));
drag_has_url_ = os_data.HasURL();
drag_has_string_ = !drag_has_url_ && os_data.HasString();
if (drag_has_url_) {
@@ -177,7 +178,7 @@ DWORD EditDropTarget::OnDrop(IDataObject* data_object,
DWORD key_state,
POINT cursor_position,
DWORD effect) {
- OSExchangeData os_data(data_object);
+ OSExchangeData os_data(new OSExchangeDataProviderWin(data_object));
if (drag_has_url_) {
GURL url;
@@ -2230,7 +2231,7 @@ void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) {
if (initiated_drag_ || !win_util::IsDrag(mouse_down_point_, point))
return;
- scoped_refptr<OSExchangeData> data = new OSExchangeData;
+ OSExchangeData data;
DWORD supported_modes = DROPEFFECT_COPY;
@@ -2258,8 +2259,8 @@ void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) {
std::wstring title;
SkBitmap favicon;
model_->GetDataForURLExport(&url, &title, &favicon);
- drag_utils::SetURLAndDragImage(url, title, favicon, data.get());
- data->SetURL(url, title);
+ drag_utils::SetURLAndDragImage(url, title, favicon, &data);
+ data.SetURL(url, title);
supported_modes |= DROPEFFECT_LINK;
UserMetrics::RecordAction(L"Omnibox_DragURL", model_->profile());
} else {
@@ -2267,13 +2268,13 @@ void AutocompleteEditViewWin::StartDragIfNecessary(const CPoint& point) {
UserMetrics::RecordAction(L"Omnibox_DragString", model_->profile());
}
- data->SetString(GetSelectedText());
+ data.SetString(GetSelectedText());
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
DWORD dropped_mode;
in_drag_ = true;
- if (DoDragDrop(data, drag_source, supported_modes, &dropped_mode) ==
- DRAGDROP_S_DROP) {
+ if (DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
+ supported_modes, &dropped_mode) == DRAGDROP_S_DROP) {
if ((dropped_mode == DROPEFFECT_MOVE) && (start_text == GetText())) {
ScopedFreeze freeze(this, GetTextObjectModel());
OnBeforePossibleChange();
diff --git a/chrome/browser/bookmarks/bookmark_context_menu_controller.cc b/chrome/browser/bookmarks/bookmark_context_menu_controller.cc
index 4f6d941..81fbcc9 100644
--- a/chrome/browser/bookmarks/bookmark_context_menu_controller.cc
+++ b/chrome/browser/bookmarks/bookmark_context_menu_controller.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/views/bookmark_context_menu.h"
+#include "chrome/browser/bookmarks/bookmark_context_menu_controller.h"
#include "app/l10n_util.h"
#include "base/compiler_specific.h"
diff --git a/chrome/browser/bookmarks/bookmark_context_menu_controller.h b/chrome/browser/bookmarks/bookmark_context_menu_controller.h
index 4d611d8..03a57c4 100644
--- a/chrome/browser/bookmarks/bookmark_context_menu_controller.h
+++ b/chrome/browser/bookmarks/bookmark_context_menu_controller.h
@@ -10,7 +10,6 @@
#include "base/basictypes.h"
#include "base/gfx/native_widget_types.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
-#include "views/controls/menu/chrome_menu.h"
class Browser;
class PageNavigator;
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.cc b/chrome/browser/bookmarks/bookmark_drag_data.cc
index 0ed2273..47ea0c0 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.cc
+++ b/chrome/browser/bookmarks/bookmark_drag_data.cc
@@ -13,29 +13,9 @@
#include "chrome/common/url_constants.h"
#include "chrome/browser/browser_process.h"
-// TODO(port): Port this file.
-#if defined(TOOLKIT_VIEWS)
-#include "app/os_exchange_data.h"
-#else
-#include "chrome/common/temp_scaffolding_stubs.h"
-#endif
-
const char* BookmarkDragData::kClipboardFormatString =
"chromium/x-bookmark-entries";
-#if defined(OS_WIN)
-static CLIPFORMAT clipboard_format = 0;
-
-static void RegisterFormat() {
- if (clipboard_format == 0) {
- clipboard_format =
- ::RegisterClipboardFormat(ASCIIToWide(
- BookmarkDragData::kClipboardFormatString).c_str());
- DCHECK(clipboard_format);
- }
-}
-#endif
-
BookmarkDragData::Element::Element(const BookmarkNode* node)
: is_url(node->is_url()),
url(node->GetURL()),
@@ -84,6 +64,21 @@ bool BookmarkDragData::Element::ReadFromPickle(Pickle* pickle,
return true;
}
+#if defined(TOOLKIT_VIEWS)
+// static
+OSExchangeData::CustomFormat BookmarkDragData::GetBookmarkCustomFormat() {
+ static OSExchangeData::CustomFormat format;
+ static bool format_valid = false;
+
+ if (!format_valid) {
+ format_valid = true;
+ format = OSExchangeData::RegisterCustomFormat(
+ BookmarkDragData::kClipboardFormatString);
+ }
+ return format;
+}
+#endif
+
BookmarkDragData::BookmarkDragData(const BookmarkNode* node) {
elements.push_back(Element(node));
}
@@ -139,10 +134,8 @@ bool BookmarkDragData::ReadFromClipboard() {
}
#endif // !defined(OS_MACOSX)
-#if defined(OS_WIN)
+#if defined(TOOLKIT_VIEWS)
void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
- RegisterFormat();
-
DCHECK(data);
// If there is only one element and it is a URL, write the URL to the
@@ -158,19 +151,17 @@ void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
Pickle data_pickle;
WriteToPickle(profile, &data_pickle);
- data->SetPickledData(clipboard_format, data_pickle);
+ data->SetPickledData(GetBookmarkCustomFormat(), data_pickle);
}
bool BookmarkDragData::Read(const OSExchangeData& data) {
- RegisterFormat();
-
elements.clear();
profile_path_.clear();
- if (data.HasFormat(clipboard_format)) {
+ if (data.HasCustomFormat(GetBookmarkCustomFormat())) {
Pickle drag_data_pickle;
- if (data.GetPickledData(clipboard_format, &drag_data_pickle)) {
+ if (data.GetPickledData(GetBookmarkCustomFormat(), &drag_data_pickle)) {
if (!ReadFromPickle(&drag_data_pickle))
return false;
}
@@ -186,15 +177,6 @@ bool BookmarkDragData::Read(const OSExchangeData& data) {
return is_valid();
}
-#elif defined(TOOLKIT_VIEWS)
-void BookmarkDragData::Write(Profile* profile, OSExchangeData* data) const {
- NOTIMPLEMENTED();
-}
-
-bool BookmarkDragData::Read(const OSExchangeData& data) {
- NOTIMPLEMENTED();
- return false;
-}
#endif
void BookmarkDragData::WriteToPickle(Profile* profile, Pickle* pickle) const {
diff --git a/chrome/browser/bookmarks/bookmark_drag_data.h b/chrome/browser/bookmarks/bookmark_drag_data.h
index 815e8e1d..0b9736c 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data.h
+++ b/chrome/browser/bookmarks/bookmark_drag_data.h
@@ -11,6 +11,13 @@
#include "chrome/browser/history/history.h"
#include "googleurl/src/gurl.h"
+// TODO(port): Port this file.
+#if defined(TOOLKIT_VIEWS)
+#include "app/os_exchange_data.h"
+#else
+#include "chrome/common/temp_scaffolding_stubs.h"
+#endif
+
class BookmarkModel;
class BookmarkNode;
class OSExchangeData;
@@ -67,6 +74,10 @@ struct BookmarkDragData {
BookmarkDragData() { }
+#if defined(TOOLKIT_VIEWS)
+ static OSExchangeData::CustomFormat GetBookmarkCustomFormat();
+#endif
+
// Created a BookmarkDragData populated from the arguments.
explicit BookmarkDragData(const BookmarkNode* node);
explicit BookmarkDragData(const std::vector<const BookmarkNode*>& nodes);
diff --git a/chrome/browser/bookmarks/bookmark_drag_data_unittest.cc b/chrome/browser/bookmarks/bookmark_drag_data_unittest.cc
index 02b2016..77d999a 100644
--- a/chrome/browser/bookmarks/bookmark_drag_data_unittest.cc
+++ b/chrome/browser/bookmarks/bookmark_drag_data_unittest.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/scoped_ptr.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
@@ -12,6 +13,15 @@
typedef testing::Test BookmarkDragDataTest;
+namespace {
+
+OSExchangeData::Provider* CloneProvider(const OSExchangeData& data) {
+ return new OSExchangeDataProviderWin(
+ OSExchangeDataProviderWin::GetIDataObject(data));
+}
+
+} // namespace
+
// Makes sure BookmarkDragData is initially invalid.
TEST_F(BookmarkDragDataTest, InitialState) {
BookmarkDragData data;
@@ -20,9 +30,9 @@ TEST_F(BookmarkDragDataTest, InitialState) {
// Makes sure reading bogus data leaves the BookmarkDragData invalid.
TEST_F(BookmarkDragDataTest, BogusRead) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
+ OSExchangeData data;
BookmarkDragData drag_data;
- EXPECT_FALSE(drag_data.Read(OSExchangeData(data.get())));
+ EXPECT_FALSE(drag_data.Read(OSExchangeData(CloneProvider(data))));
EXPECT_FALSE(drag_data.is_valid());
}
@@ -32,11 +42,11 @@ TEST_F(BookmarkDragDataTest, JustURL) {
const GURL url("http://google.com");
const std::wstring title(L"title");
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- data->SetURL(url, title);
+ OSExchangeData data;
+ data.SetURL(url, title);
BookmarkDragData drag_data;
- EXPECT_TRUE(drag_data.Read(OSExchangeData(data.get())));
+ EXPECT_TRUE(drag_data.Read(OSExchangeData(CloneProvider(data))));
EXPECT_TRUE(drag_data.is_valid());
ASSERT_EQ(1, drag_data.elements.size());
EXPECT_TRUE(drag_data.elements[0].is_url);
@@ -61,13 +71,13 @@ TEST_F(BookmarkDragDataTest, URL) {
EXPECT_TRUE(drag_data.elements[0].is_url);
EXPECT_TRUE(drag_data.elements[0].url == url);
EXPECT_EQ(title, drag_data.elements[0].title);
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- drag_data.Write(&profile, data.get());
+ OSExchangeData data;
+ drag_data.Write(&profile, &data);
// Now read the data back in.
- scoped_refptr<OSExchangeData> data2(new OSExchangeData(data.get()));
+ OSExchangeData data2(CloneProvider(data));
BookmarkDragData read_data;
- EXPECT_TRUE(read_data.Read(*data2));
+ EXPECT_TRUE(read_data.Read(data2));
EXPECT_TRUE(read_data.is_valid());
ASSERT_EQ(1, read_data.elements.size());
EXPECT_TRUE(read_data.elements[0].is_url);
@@ -82,7 +92,7 @@ TEST_F(BookmarkDragDataTest, URL) {
// Writing should also put the URL and title on the clipboard.
GURL read_url;
std::wstring read_title;
- EXPECT_TRUE(data2->GetURLAndTitle(&read_url, &read_title));
+ EXPECT_TRUE(data2.GetURLAndTitle(&read_url, &read_title));
EXPECT_TRUE(read_url == url);
EXPECT_EQ(title, read_title);
}
@@ -104,13 +114,13 @@ TEST_F(BookmarkDragDataTest, Group) {
EXPECT_EQ(g12->GetTitle(), drag_data.elements[0].title);
EXPECT_FALSE(drag_data.elements[0].is_url);
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- drag_data.Write(&profile, data.get());
+ OSExchangeData data;
+ drag_data.Write(&profile, &data);
// Now read the data back in.
- scoped_refptr<OSExchangeData> data2(new OSExchangeData(data.get()));
+ OSExchangeData data2(CloneProvider(data));
BookmarkDragData read_data;
- EXPECT_TRUE(read_data.Read(*data2));
+ EXPECT_TRUE(read_data.Read(data2));
EXPECT_TRUE(read_data.is_valid());
ASSERT_EQ(1, read_data.elements.size());
EXPECT_EQ(g12->GetTitle(), read_data.elements[0].title);
@@ -141,13 +151,13 @@ TEST_F(BookmarkDragDataTest, GroupWithChild) {
BookmarkDragData drag_data(group);
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- drag_data.Write(&profile, data.get());
+ OSExchangeData data;
+ drag_data.Write(&profile, &data);
// Now read the data back in.
- scoped_refptr<OSExchangeData> data2(new OSExchangeData(data.get()));
+ OSExchangeData data2(CloneProvider(data));
BookmarkDragData read_data;
- EXPECT_TRUE(read_data.Read(*data2));
+ EXPECT_TRUE(read_data.Read(data2));
ASSERT_EQ(1, read_data.elements.size());
ASSERT_EQ(1, read_data.elements[0].children.size());
const BookmarkDragData::Element& read_child =
@@ -182,13 +192,13 @@ TEST_F(BookmarkDragDataTest, MultipleNodes) {
nodes.push_back(group);
nodes.push_back(url_node);
BookmarkDragData drag_data(nodes);
- scoped_refptr<OSExchangeData> data(new OSExchangeData());
- drag_data.Write(&profile, data.get());
+ OSExchangeData data;
+ drag_data.Write(&profile, &data);
// Read the data back in.
- scoped_refptr<OSExchangeData> data2(new OSExchangeData(data.get()));
+ OSExchangeData data2(CloneProvider(data));
BookmarkDragData read_data;
- EXPECT_TRUE(read_data.Read(*data2));
+ EXPECT_TRUE(read_data.Read(data2));
EXPECT_TRUE(read_data.is_valid());
ASSERT_EQ(2, read_data.elements.size());
ASSERT_EQ(1, read_data.elements[0].children.size());
diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc
index 0d9b5a9..23f47c7 100644
--- a/chrome/browser/download/download_util.cc
+++ b/chrome/browser/download/download_util.cc
@@ -29,6 +29,7 @@
#endif
#if defined(OS_WIN)
+#include "app/os_exchange_data_provider_win.h"
#include "base/base_drag_source.h"
#include "views/drag_utils.h"
#endif
@@ -242,14 +243,15 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) {
DCHECK(download);
// Set up our OLE machinery
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
+ OSExchangeData data;
const FilePath::StringType file_name = download->file_name().value();
if (icon)
- drag_utils::CreateDragImageForFile(file_name, icon, data);
+ drag_utils::CreateDragImageForFile(file_name, icon, &data);
+ data.SetFilename(download->full_path().ToWStringHack());
const FilePath full_path = download->full_path();
- data->SetFilename(full_path.value());
+ data.SetFilename(full_path.value());
std::string mime_type = download->mime_type();
if (mime_type.empty())
@@ -257,14 +259,14 @@ void DragDownload(const DownloadItem* download, SkBitmap* icon) {
// Add URL so that we can load supported files when dragged to TabContents.
if (net::IsSupportedMimeType(mime_type))
- data->SetURL(GURL(full_path.value()), file_name);
+ data.SetURL(GURL(full_path.value()), file_name);
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
// Run the drag and drop loop
DWORD effects;
- DoDragDrop(data.get(), drag_source.get(), DROPEFFECT_COPY | DROPEFFECT_LINK,
- &effects);
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source.get(),
+ DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
#else
NOTIMPLEMENTED();
#endif
diff --git a/chrome/browser/tab_contents/web_drop_target.cc b/chrome/browser/tab_contents/web_drop_target.cc
index bad7e1d..af39273 100644
--- a/chrome/browser/tab_contents/web_drop_target.cc
+++ b/chrome/browser/tab_contents/web_drop_target.cc
@@ -8,6 +8,7 @@
#include "chrome/browser/tab_contents/web_drop_target.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/clipboard_util.h"
#include "base/gfx/point.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -104,7 +105,7 @@ DWORD WebDropTarget::OnDragEnter(IDataObject* data_object,
WebDropData::PopulateWebDropData(data_object, &drop_data);
if (drop_data.url.is_empty())
- OSExchangeData::GetPlainTextURL(data_object, &drop_data.url);
+ OSExchangeDataProviderWin::GetPlainTextURL(data_object, &drop_data.url);
is_drop_target_ = true;
diff --git a/chrome/browser/views/bookmark_folder_tree_view.cc b/chrome/browser/views/bookmark_folder_tree_view.cc
index bd464c8..74a6dea 100644
--- a/chrome/browser/views/bookmark_folder_tree_view.cc
+++ b/chrome/browser/views/bookmark_folder_tree_view.cc
@@ -8,6 +8,7 @@
#include "app/drag_drop_types.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/base_drag_source.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
@@ -125,12 +126,12 @@ void BookmarkFolderTreeView::BeginDrag(const BookmarkNode* node) {
std::vector<const BookmarkNode*> nodes_to_drag;
nodes_to_drag.push_back(node);
- scoped_refptr<OSExchangeData> data = new OSExchangeData;
- BookmarkDragData(nodes_to_drag).Write(profile_, data);
+ OSExchangeData data;
+ BookmarkDragData(nodes_to_drag).Write(profile_, &data);
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
DWORD effects;
is_dragging_ = true;
- DoDragDrop(data, drag_source,
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &effects);
is_dragging_ = false;
}
diff --git a/chrome/browser/views/bookmark_table_view.cc b/chrome/browser/views/bookmark_table_view.cc
index 3eaa2f3..1ea3aa6 100644
--- a/chrome/browser/views/bookmark_table_view.cc
+++ b/chrome/browser/views/bookmark_table_view.cc
@@ -11,6 +11,7 @@
#include "app/gfx/font.h"
#include "app/l10n_util.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "app/resource_bundle.h"
#include "base/base_drag_source.h"
#include "chrome/browser/bookmarks/bookmark_utils.h"
@@ -197,11 +198,11 @@ void BookmarkTableView::BeginDrag() {
// We do this as SelectionBegin starts at the end of the visual order.
std::reverse(nodes_to_drag.begin(), nodes_to_drag.end());
- scoped_refptr<OSExchangeData> data = new OSExchangeData;
- BookmarkDragData(nodes_to_drag).Write(profile_, data);
+ OSExchangeData data;
+ BookmarkDragData(nodes_to_drag).Write(profile_, &data);
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
DWORD effects;
- DoDragDrop(data, drag_source,
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
DROPEFFECT_LINK | DROPEFFECT_COPY | DROPEFFECT_MOVE, &effects);
}
diff --git a/chrome/browser/views/tab_contents/tab_contents_view_win.cc b/chrome/browser/views/tab_contents/tab_contents_view_win.cc
index 570df67..47a73e3 100644
--- a/chrome/browser/views/tab_contents/tab_contents_view_win.cc
+++ b/chrome/browser/views/tab_contents/tab_contents_view_win.cc
@@ -8,6 +8,7 @@
#include "app/gfx/canvas_paint.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/time.h"
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful.
@@ -132,7 +133,7 @@ void TabContentsViewWin::GetContainerBounds(gfx::Rect* out) const {
}
void TabContentsViewWin::StartDragging(const WebDropData& drop_data) {
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
+ OSExchangeData data;
// TODO(tc): Generate an appropriate drag image.
@@ -150,10 +151,10 @@ void TabContentsViewWin::StartDragging(const WebDropData& drop_data) {
net::GetSuggestedFilename(drop_data.url, "", "", L""));
}
file_name = file_name.ReplaceExtension(drop_data.file_extension);
- data->SetFileContents(file_name.value(), drop_data.file_contents);
+ data.SetFileContents(file_name.value(), drop_data.file_contents);
}
if (!drop_data.text_html.empty())
- data->SetHtml(drop_data.text_html, drop_data.html_base_url);
+ data.SetHtml(drop_data.text_html, drop_data.html_base_url);
if (drop_data.url.is_valid()) {
if (drop_data.url.SchemeIs(chrome::kJavaScriptScheme)) {
// We don't want to allow javascript URLs to be dragged to the desktop,
@@ -170,13 +171,13 @@ void TabContentsViewWin::StartDragging(const WebDropData& drop_data) {
// Pass in NULL as the profile so that the bookmark always adds the url
// rather than trying to move an existing url.
- bm_drag_data.Write(NULL, data);
+ bm_drag_data.Write(NULL, &data);
} else {
- data->SetURL(drop_data.url, drop_data.url_title);
+ data.SetURL(drop_data.url, drop_data.url_title);
}
}
if (!drop_data.plain_text.empty())
- data->SetString(drop_data.plain_text);
+ data.SetString(drop_data.plain_text);
drag_source_ = new WebDragSource(GetNativeView(), tab_contents());
@@ -186,7 +187,8 @@ void TabContentsViewWin::StartDragging(const WebDropData& drop_data) {
// updates while in the system DoDragDrop loop.
bool old_state = MessageLoop::current()->NestableTasksAllowed();
MessageLoop::current()->SetNestableTasksAllowed(true);
- DoDragDrop(data, drag_source_, DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source_,
+ DROPEFFECT_COPY | DROPEFFECT_LINK, &effects);
MessageLoop::current()->SetNestableTasksAllowed(old_state);
drag_source_ = NULL;
diff --git a/views/controls/menu/chrome_menu.cc b/views/controls/menu/chrome_menu.cc
index 1bd7b53..351e082 100644
--- a/views/controls/menu/chrome_menu.cc
+++ b/views/controls/menu/chrome_menu.cc
@@ -13,6 +13,7 @@
#include "app/l10n_util.h"
#include "app/l10n_util_win.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/base_drag_source.h"
#include "base/gfx/native_theme.h"
#include "base/message_loop.h"
@@ -892,6 +893,8 @@ void SubmenuView::PaintChildren(gfx::Canvas* canvas) {
PaintDropIndicator(canvas, drop_item_, drop_position_);
}
+// TODO(sky): need to add support for new dnd methods for Linux.
+
bool SubmenuView::CanDrop(const OSExchangeData& data) {
DCHECK(GetMenuItem()->GetMenuController());
return GetMenuItem()->GetMenuController()->CanDrop(this, data);
@@ -1835,17 +1838,17 @@ void MenuController::OnMouseDragged(SubmenuView* source,
gfx::Canvas canvas(item->width(), item->height(), false);
item->Paint(&canvas, true);
- scoped_refptr<OSExchangeData> data(new OSExchangeData);
- item->GetDelegate()->WriteDragData(item, data.get());
+ OSExchangeData data;
+ item->GetDelegate()->WriteDragData(item, &data);
drag_utils::SetDragImageOnDataObject(canvas, item->width(),
item->height(), press_loc.x(),
- press_loc.y(), data);
+ press_loc.y(), &data);
scoped_refptr<BaseDragSource> drag_source(new BaseDragSource);
int drag_ops = item->GetDelegate()->GetDragOperations(item);
DWORD effects;
StopScrolling();
- DoDragDrop(data, drag_source,
+ DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source,
DragDropTypes::DragOperationToDropEffect(drag_ops),
&effects);
if (GetActiveInstance() == this) {
diff --git a/views/drag_utils_win.cc b/views/drag_utils_win.cc
index ed01386..b2d35f2 100644
--- a/views/drag_utils_win.cc
+++ b/views/drag_utils_win.cc
@@ -10,6 +10,7 @@
#include "app/gfx/canvas.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/gfx/gdi_util.h"
namespace drag_utils {
@@ -69,10 +70,9 @@ void SetDragImageOnDataObject(const gfx::Canvas& canvas,
HBITMAP bitmap = CreateBitmapFromCanvas(canvas, width, height);
// Attach 'bitmap' to the data_object.
- SetDragImageOnDataObject(bitmap, width, height,
- cursor_x_offset,
- cursor_y_offset,
- data_object);
+ SetDragImageOnDataObject(
+ bitmap, width, height, cursor_x_offset, cursor_y_offset,
+ OSExchangeDataProviderWin::GetIDataObject(*data_object));
}
} // namespace drag_utils
diff --git a/views/view_win.cc b/views/view_win.cc
index bf265f9..f0d71c4 100644
--- a/views/view_win.cc
+++ b/views/view_win.cc
@@ -8,6 +8,7 @@
#include "app/gfx/canvas.h"
#include "app/gfx/path.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/scoped_handle.h"
#include "base/string_util.h"
#include "views/accessibility/view_accessibility_wrapper.h"
@@ -22,13 +23,14 @@ void View::DoDrag(const MouseEvent& e, int press_x, int press_y) {
if (drag_operations == DragDropTypes::DRAG_NONE)
return;
- scoped_refptr<OSExchangeData> data = new OSExchangeData;
- WriteDragData(press_x, press_y, data.get());
+ OSExchangeData data;
+ WriteDragData(press_x, press_y, &data);
// Message the RootView to do the drag and drop. That way if we're removed
// the RootView can detect it and avoid calling us back.
RootView* root_view = GetRootView();
- root_view->StartDragForViewFromMouseEvent(this, data, drag_operations);
+ root_view->StartDragForViewFromMouseEvent(
+ this, OSExchangeDataProviderWin::GetIDataObject(data), drag_operations);
}
ViewAccessibilityWrapper* View::GetViewAccessibilityWrapper() {
diff --git a/views/widget/drop_target_win.cc b/views/widget/drop_target_win.cc
index 69800ca..7a90a64 100644
--- a/views/widget/drop_target_win.cc
+++ b/views/widget/drop_target_win.cc
@@ -6,6 +6,7 @@
#include "app/drag_drop_types.h"
#include "app/os_exchange_data.h"
+#include "app/os_exchange_data_provider_win.h"
#include "base/gfx/point.h"
#include "views/widget/root_view.h"
#include "views/widget/widget.h"
@@ -30,9 +31,9 @@ DWORD DropTargetWin::OnDragOver(IDataObject* data_object,
DWORD effect) {
gfx::Point root_view_location(cursor_position.x, cursor_position.y);
View::ConvertPointToView(NULL, helper_.root_view(), &root_view_location);
+ OSExchangeData data(new OSExchangeDataProviderWin(data_object));
int drop_operation =
- helper_.OnDragOver(OSExchangeData(data_object),
- root_view_location,
+ helper_.OnDragOver(data, root_view_location,
DragDropTypes::DropEffectToDragOperation(effect));
return DragDropTypes::DragOperationToDropEffect(drop_operation);
}
@@ -48,7 +49,7 @@ DWORD DropTargetWin::OnDrop(IDataObject* data_object,
gfx::Point root_view_location(cursor_position.x, cursor_position.y);
View::ConvertPointToView(NULL, helper_.root_view(), &root_view_location);
- OSExchangeData data(data_object);
+ OSExchangeData data(new OSExchangeDataProviderWin(data_object));
int drop_operation = DragDropTypes::DropEffectToDragOperation(effect);
drop_operation = helper_.OnDragOver(data, root_view_location,
drop_operation);