From 41d2e4af3daa1d1ca8f8cbfa6788604a4c9913b9 Mon Sep 17 00:00:00 2001 From: "ben@chromium.org" Date: Wed, 12 Jan 2011 19:00:48 +0000 Subject: Move OSExchangeData from src/app to src/ui/base/dragdrop BUG=none TEST=none TBR=brettw Review URL: http://codereview.chromium.org/6200005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71205 0039d316-1c4b-4281-b951-d872f2087c98 --- app/app.gyp | 10 +- app/app_base.gypi | 50 +- app/os_exchange_data.cc | 144 ------ app/os_exchange_data.h | 195 -------- app/os_exchange_data_provider_gtk.cc | 244 --------- app/os_exchange_data_provider_gtk.h | 116 ----- app/os_exchange_data_provider_win.cc | 923 ----------------------------------- app/os_exchange_data_provider_win.h | 176 ------- app/os_exchange_data_win_unittest.cc | 373 -------------- 9 files changed, 45 insertions(+), 2186 deletions(-) delete mode 100644 app/os_exchange_data.cc delete mode 100644 app/os_exchange_data.h delete mode 100644 app/os_exchange_data_provider_gtk.cc delete mode 100644 app/os_exchange_data_provider_gtk.h delete mode 100644 app/os_exchange_data_provider_win.cc delete mode 100644 app/os_exchange_data_provider_win.h delete mode 100644 app/os_exchange_data_win_unittest.cc (limited to 'app') diff --git a/app/app.gyp b/app/app.gyp index a0435f8..62c7634 100644 --- a/app/app.gyp +++ b/app/app.gyp @@ -36,14 +36,18 @@ '../third_party/icu/icu.gyp:icuuc', '../third_party/libpng/libpng.gyp:libpng', '../third_party/zlib/zlib.gyp:zlib', - '../ui/ui.gyp:ui_base', '<(libjpeg_gyp_path):libjpeg', ], 'sources': [ + '../ui/base/animation/animation_container_unittest.cc', + '../ui/base/animation/animation_unittest.cc', + '../ui/base/animation/multi_animation_unittest.cc', + '../ui/base/animation/slide_animation_unittest.cc', + '../ui/base/clipboard/clipboard_unittest.cc', + '../ui/base/dragdrop/os_exchange_data_win_unittest.cc', 'data_pack_unittest.cc', 'l10n_util_mac_unittest.mm', 'l10n_util_unittest.cc', - 'os_exchange_data_win_unittest.cc', 'run_all_unittests.cc', 'sql/connection_unittest.cc', 'sql/statement_unittest.cc', @@ -73,7 +77,7 @@ }], ['OS!="win"', { 'sources!': [ - 'os_exchange_data_win_unittest.cc', + '../ui/base/dragdrop/os_exchange_data_win_unittest.cc', 'view_prop_unittest.cc', 'win_util_unittest.cc', ], diff --git a/app/app_base.gypi b/app/app_base.gypi index 1431ce1..2614bb4 100644 --- a/app/app_base.gypi +++ b/app/app_base.gypi @@ -89,6 +89,38 @@ }, 'sources': [ # Files that are not required for Win64 Native Client loader + '../ui/base/animation/animation.cc', + '../ui/base/animation/animation.h', + '../ui/base/animation/animation_container.cc', + '../ui/base/animation/animation_container.h', + '../ui/base/animation/animation_container_element.h', + '../ui/base/animation/animation_container_observer.h', + '../ui/base/animation/animation_delegate.h', + '../ui/base/animation/linear_animation.cc', + '../ui/base/animation/linear_animation.h', + '../ui/base/animation/multi_animation.cc', + '../ui/base/animation/multi_animation.h', + '../ui/base/animation/slide_animation.cc', + '../ui/base/animation/slide_animation.h', + '../ui/base/animation/throb_animation.cc', + '../ui/base/animation/throb_animation.h', + '../ui/base/animation/tween.cc', + '../ui/base/animation/tween.h', + '../ui/base/clipboard/clipboard.cc', + '../ui/base/clipboard/clipboard.h', + '../ui/base/clipboard/clipboard_linux.cc', + '../ui/base/clipboard/clipboard_mac.mm', + '../ui/base/clipboard/clipboard_util_win.cc', + '../ui/base/clipboard/clipboard_util_win.h', + '../ui/base/clipboard/clipboard_win.cc', + '../ui/base/clipboard/scoped_clipboard_writer.cc', + '../ui/base/clipboard/scoped_clipboard_writer.h', + '../ui/base/dragdrop/os_exchange_data_provider_gtk.cc', + '../ui/base/dragdrop/os_exchange_data_provider_gtk.h', + '../ui/base/dragdrop/os_exchange_data_provider_win.cc', + '../ui/base/dragdrop/os_exchange_data_provider_win.h', + '../ui/base/dragdrop/os_exchange_data.cc', + '../ui/base/dragdrop/os_exchange_data.h', 'active_window_watcher_x.cc', 'active_window_watcher_x.h', 'bidi_line_iterator.cc', @@ -159,12 +191,6 @@ 'menus/simple_menu_model.cc', 'menus/simple_menu_model.h', 'message_box_flags.h', - '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', 'resource_bundle_linux.cc', @@ -276,10 +302,10 @@ # Note: because of gyp predence rules this has to be defined as # 'sources/' rather than 'sources!'. 'sources/': [ - ['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', '^../ui/base/dragdrop/os_exchange_data.cc'], + ['exclude', '^../ui/base/dragdrop/os_exchange_data.h'], + ['exclude', '^../ui/base/dragdrop/os_exchange_data_provider_gtk.cc'], + ['exclude', '^../ui/base/dragdrop/os_exchange_data_provider_gtk.h'], ['exclude', '^drag_drop_types_gtk.cc'], ], }], @@ -287,13 +313,14 @@ # Note: because of gyp predence rules this has to be defined as # 'sources/' rather than 'sources!'. 'sources/': [ - ['include', '^os_exchange_data.cc'], + ['include', '^../ui/base/dragdrop/os_exchange_data.cc'], ], }], ], }], ['OS!="win"', { 'sources!': [ + '../ui/base/dragdrop/os_exchange_data.cc', 'drag_drop_types.h', 'gfx/gdi_util.cc', 'gfx/gdi_util.h', @@ -301,7 +328,6 @@ 'gfx/icon_util.h', 'gfx/native_theme_win.cc', 'gfx/native_theme_win.h', - 'os_exchange_data.cc', 'view_prop.cc', 'view_prop.h', 'win/iat_patch_function.cc', diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc deleted file mode 100644 index a09bb83..0000000 --- a/app/os_exchange_data.cc +++ /dev/null @@ -1,144 +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. - -#include "app/os_exchange_data.h" - -#include "base/pickle.h" -#include "googleurl/src/gurl.h" - -OSExchangeData::DownloadFileInfo::DownloadFileInfo( - const FilePath& filename, - DownloadFileProvider* downloader) - : filename(filename), - downloader(downloader) { -} - -OSExchangeData::DownloadFileInfo::~DownloadFileInfo() {} - -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); -} - -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::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& custom_formats) const { - if ((formats & STRING) != 0 && !HasString()) - return false; - if ((formats & URL) != 0 && !HasURL()) - return false; -#if defined(OS_WIN) - if ((formats & FILE_CONTENTS) != 0 && !provider_->HasFileContents()) - return false; - if ((formats & HTML) != 0 && !provider_->HasHtml()) - return false; -#endif - if ((formats & FILE_NAME) != 0 && !provider_->HasFile()) - return false; - for (std::set::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& custom_formats) const { - if ((formats & STRING) != 0 && HasString()) - return true; - if ((formats & URL) != 0 && HasURL()) - return true; -#if defined(OS_WIN) - if ((formats & FILE_CONTENTS) != 0 && provider_->HasFileContents()) - return true; - if ((formats & HTML) != 0 && provider_->HasHtml()) - return true; -#endif - if ((formats & FILE_NAME) != 0 && provider_->HasFile()) - return true; - for (std::set::const_iterator i = custom_formats.begin(); - i != custom_formats.end(); ++i) { - if (HasCustomFormat(*i)) - return true; - } - return false; -} - -#if defined(OS_WIN) -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::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); -} - -void OSExchangeData::SetDownloadFileInfo(const DownloadFileInfo& download) { - return provider_->SetDownloadFileInfo(download); -} -#endif diff --git a/app/os_exchange_data.h b/app/os_exchange_data.h deleted file mode 100644 index e2b06cc..0000000 --- a/app/os_exchange_data.h +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (c) 2010 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_H_ -#define APP_OS_EXCHANGE_DATA_H_ -#pragma once - -#include "build/build_config.h" - -#include -#include - -#if defined(OS_WIN) -#include -#elif !defined(OS_MACOSX) -#include -#endif - -#include "app/download_file_interface.h" -#include "base/basictypes.h" -#include "base/file_path.h" -#include "base/scoped_ptr.h" - -class GURL; -class Pickle; - -/////////////////////////////////////////////////////////////////////////////// -// -// OSExchangeData -// An object that holds interchange data to be sent out to OS services like -// clipboard, drag and drop, etc. This object exposes an API that clients can -// use to specify raw data and its high level type. This object takes care of -// translating that into something the OS can understand. -// -/////////////////////////////////////////////////////////////////////////////// - -// NOTE: Support for html and file contents is required by TabContentViewWin. -// TabContentsViewGtk uses a different class to handle drag support that does -// not use OSExchangeData. As such, file contents and html support is only -// compiled on windows. -class OSExchangeData { - public: - // CustomFormats are used for non-standard data types. For example, bookmark - // nodes are written using a CustomFormat. -#if defined(OS_WIN) - typedef CLIPFORMAT CustomFormat; -#elif !defined(OS_MACOSX) - typedef GdkAtom CustomFormat; -#endif - - // Enumeration of the known formats. - enum Format { - STRING = 1 << 0, - URL = 1 << 1, - FILE_NAME = 1 << 2, - PICKLED_DATA = 1 << 3, -#if defined(OS_WIN) - FILE_CONTENTS = 1 << 4, - HTML = 1 << 5, -#endif - }; - - // Encapsulates the info about a file to be downloaded. - struct DownloadFileInfo { - DownloadFileInfo(const FilePath& filename, - DownloadFileProvider* downloader); - ~DownloadFileInfo(); - - FilePath filename; - scoped_refptr downloader; - }; - - // 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 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 HasString() const = 0; - virtual bool HasURL() const = 0; - virtual bool HasFile() const = 0; - virtual bool HasCustomFormat( - OSExchangeData::CustomFormat format) const = 0; - -#if defined(OS_WIN) - 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 GetFileContents(std::wstring* filename, - std::string* file_contents) const = 0; - virtual bool GetHtml(std::wstring* html, GURL* base_url) const = 0; - virtual bool HasFileContents() const = 0; - virtual bool HasHtml() const = 0; - virtual void SetDownloadFileInfo(const DownloadFileInfo& download) = 0; -#endif - }; - - 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 - // a format suitable for exchange with the OS. - // NOTE WELL: Typically, a data object like this will contain only one of the - // following types of data. In cases where more data is held, the - // order in which these functions are called is _important_! - // ---> The order types are added to an OSExchangeData object controls - // the order of enumeration in our IEnumFORMATETC implementation! - // This comes into play when selecting the best (most preferable) - // data type for insertion into a DropTarget. - void SetString(const std::wstring& data); - // A URL can have an optional title in some exchange formats. - void SetURL(const GURL& url, const std::wstring& title); - // A full path to a file. - // TODO: convert to Filepath. - void SetFilename(const std::wstring& full_path); - // Adds pickled data of the specified format. - void SetPickledData(CustomFormat format, const Pickle& data); - - // These functions retrieve data of the specified type. If data exists, the - // functions return and the result is in the out parameter. If the data does - // not exist, the out parameter is not touched. The out parameter cannot be - // NULL. - bool GetString(std::wstring* data) const; - bool GetURLAndTitle(GURL* url, std::wstring* title) const; - // Return the path of a file, if available. - bool GetFilename(std::wstring* full_path) const; - bool GetPickledData(CustomFormat format, Pickle* data) const; - - // Test whether or not data of certain types is present, without actually - // returning anything. - bool HasString() const; - bool HasURL() const; - bool HasFile() const; - bool HasCustomFormat(CustomFormat format) const; - - // 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& custom_formats) const; - - // 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& custom_formats) const; - -#if defined(OS_WIN) - // Adds the bytes of a file (CFSTR_FILECONTENTS and CFSTR_FILEDESCRIPTOR). - void SetFileContents(const std::wstring& filename, - const std::string& file_contents); - // Adds a snippet of HTML. |html| is just raw html but this sets both - // text/html and CF_HTML. - void SetHtml(const std::wstring& html, const GURL& base_url); - bool GetFileContents(std::wstring* filename, - std::string* file_contents) const; - bool GetHtml(std::wstring* html, GURL* base_url) const; - - // Adds a download file with full path (CF_HDROP). - void SetDownloadFileInfo(const DownloadFileInfo& download); -#endif - - private: - // Creates the platform specific Provider. - static Provider* CreateProvider(); - - // Provides the actual data. - scoped_ptr provider_; - - DISALLOW_COPY_AND_ASSIGN(OSExchangeData); -}; - -#endif // APP_OS_EXCHANGE_DATA_H_ diff --git a/app/os_exchange_data_provider_gtk.cc b/app/os_exchange_data_provider_gtk.cc deleted file mode 100644 index 1375860..0000000 --- a/app/os_exchange_data_provider_gtk.cc +++ /dev/null @@ -1,244 +0,0 @@ -// Copyright (c) 2010 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 - -#include "app/gtk_dnd_util.h" -#include "base/file_path.h" -#include "base/utf_string_conversions.h" -#include "net/base/net_util.h" - -OSExchangeDataProviderGtk::OSExchangeDataProviderGtk( - int known_formats, - const std::set& known_custom_formats) - : known_formats_(known_formats), - known_custom_formats_(known_custom_formats), - formats_(0), - drag_image_(NULL) { -} - -OSExchangeDataProviderGtk::OSExchangeDataProviderGtk() - : known_formats_(0), - formats_(0), - drag_image_(NULL) { -} - -OSExchangeDataProviderGtk::~OSExchangeDataProviderGtk() { - if (drag_image_) - g_object_unref(drag_image_); -} - -bool OSExchangeDataProviderGtk::HasDataForAllFormats( - int formats, - const std::set& custom_formats) const { - if ((formats_ & formats) != formats) - return false; - for (std::set::iterator i = custom_formats.begin(); - i != custom_formats.end(); ++i) { - if (pickle_data_.find(*i) == pickle_data_.end()) - return false; - } - return true; -} - -GtkTargetList* OSExchangeDataProviderGtk::GetTargetList() const { - GtkTargetList* targets = gtk_target_list_new(NULL, 0); - - if ((formats_ & OSExchangeData::STRING) != 0) - gtk_target_list_add_text_targets(targets, OSExchangeData::STRING); - - if ((formats_ & OSExchangeData::URL) != 0) { - gtk_target_list_add_uri_targets(targets, OSExchangeData::URL); - gtk_target_list_add( - targets, - gtk_dnd_util::GetAtomForTarget(gtk_dnd_util::CHROME_NAMED_URL), - 0, - OSExchangeData::URL); - } - - if ((formats_ & OSExchangeData::FILE_NAME) != 0) - gtk_target_list_add_uri_targets(targets, OSExchangeData::FILE_NAME); - - for (PickleData::const_iterator i = pickle_data_.begin(); - i != pickle_data_.end(); ++i) { - gtk_target_list_add(targets, i->first, 0, OSExchangeData::PICKLED_DATA); - } - - return targets; -} - -void OSExchangeDataProviderGtk::WriteFormatToSelection( - int format, - GtkSelectionData* selection) const { - if ((format & OSExchangeData::STRING) != 0) { - gtk_selection_data_set_text( - selection, - reinterpret_cast(string_.c_str()), - -1); - } - - if ((format & OSExchangeData::URL) != 0) { - // TODO: this should be pulled out of TabContentsDragSource into a common - // place. - Pickle pickle; - pickle.WriteString(UTF16ToUTF8(title_)); - pickle.WriteString(url_.spec()); - gtk_selection_data_set( - selection, - gtk_dnd_util::GetAtomForTarget(gtk_dnd_util::CHROME_NAMED_URL), - 8, - reinterpret_cast(pickle.data()), - pickle.size()); - - gchar* uri_array[2]; - uri_array[0] = strdup(url_.spec().c_str()); - uri_array[1] = NULL; - gtk_selection_data_set_uris(selection, uri_array); - free(uri_array[0]); - } - - if ((format & OSExchangeData::FILE_NAME) != 0) { - gchar* uri_array[2]; - uri_array[0] = - strdup(net::FilePathToFileURL(FilePath(filename_)).spec().c_str()); - uri_array[1] = NULL; - gtk_selection_data_set_uris(selection, uri_array); - free(uri_array[0]); - } - - if ((format & OSExchangeData::PICKLED_DATA) != 0) { - for (PickleData::const_iterator i = pickle_data_.begin(); - i != pickle_data_.end(); ++i) { - const Pickle& data = i->second; - gtk_selection_data_set( - selection, - i->first, - 8, - reinterpret_cast(data.data()), - data.size()); - } - } -} - -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_ = WideToUTF8(full_path); - formats_ |= OSExchangeData::FILE_NAME; -} - -void OSExchangeDataProviderGtk::SetPickledData(GdkAtom format, - const Pickle& data) { - pickle_data_[format] = data; - formats_ |= OSExchangeData::PICKLED_DATA; -} - -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) { - title->clear(); - return GetPlainTextURL(url); - } - - 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 = UTF8ToWide(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::HasString() const { - return (known_formats_ & OSExchangeData::STRING) != 0 || - (formats_ & OSExchangeData::STRING) != 0; -} - -bool OSExchangeDataProviderGtk::HasURL() const { - if ((known_formats_ & OSExchangeData::URL) != 0 || - (formats_ & OSExchangeData::URL) != 0) { - return true; - } - // No URL, see if we have plain text that can be parsed as a URL. - return GetPlainTextURL(NULL); -} - -bool OSExchangeDataProviderGtk::HasFile() const { - return (known_formats_ & OSExchangeData::FILE_NAME) != 0 || - (formats_ & OSExchangeData::FILE_NAME) != 0; - } - -bool OSExchangeDataProviderGtk::HasCustomFormat(GdkAtom format) const { - return known_custom_formats_.find(format) != known_custom_formats_.end() || - pickle_data_.find(format) != pickle_data_.end(); -} - -bool OSExchangeDataProviderGtk::GetPlainTextURL(GURL* url) const { - if ((formats_ & OSExchangeData::STRING) == 0) - return false; - - GURL test_url(string_); - if (!test_url.is_valid()) - return false; - - if (url) - *url = test_url; - return true; -} - -void OSExchangeDataProviderGtk::SetDragImage(GdkPixbuf* drag_image, - const gfx::Point& cursor_offset) { - if (drag_image_) - g_object_unref(drag_image_); - g_object_ref(drag_image); - drag_image_ = drag_image; - cursor_offset_ = cursor_offset; -} - -/////////////////////////////////////////////////////////////////////////////// -// 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 deleted file mode 100644 index 276bf90..0000000 --- a/app/os_exchange_data_provider_gtk.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright (c) 2010 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_ -#pragma once - -#include -#include -#include -#include - -#include "app/os_exchange_data.h" -#include "base/pickle.h" -#include "base/string16.h" -#include "gfx/point.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& known_custom_formats_); - OSExchangeDataProviderGtk(); - - virtual ~OSExchangeDataProviderGtk(); - - int known_formats() const { return known_formats_; } - const std::set& 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& custom_formats) const; - - // Returns the set of formats available as a GtkTargetList. It is up to the - // caller to free (gtk_target_list_unref) the returned list. - GtkTargetList* GetTargetList() const; - - // Writes the data to |selection|. |format| is any combination of - // OSExchangeData::Formats. - void WriteFormatToSelection(int format, - GtkSelectionData* selection) 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 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 HasString() const; - virtual bool HasURL() const; - virtual bool HasFile() const; - virtual bool HasCustomFormat(OSExchangeData::CustomFormat format) const; - - // Set the image and cursor offset data for this drag. Will - // increment the ref count of pixbuf. - void SetDragImage(GdkPixbuf* pixbuf, const gfx::Point& cursor_offset); - GdkPixbuf* drag_image() const { return drag_image_; } - gfx::Point cursor_offset() const { return cursor_offset_; } - - private: - typedef std::map PickleData; - - // Returns true if |formats_| contains a string format and the string can be - // parsed as a URL. - bool GetPlainTextURL(GURL* url) const; - - // 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 known_custom_formats_; - - // Actual formats that have been set. See comment above |known_formats_| - // for details. - int formats_; - - // String contents. - string16 string_; - - // URL contents. - GURL url_; - string16 title_; - - // File name. - std::string filename_; - - // PICKLED_DATA contents. - PickleData pickle_data_; - - // Drag image and offset data. - GdkPixbuf* drag_image_; - gfx::Point cursor_offset_; - - DISALLOW_COPY_AND_ASSIGN(OSExchangeDataProviderGtk); -}; - -#endif // APP_OS_EXCHANGE_DATA_PROVIDER_GTK_H_ diff --git a/app/os_exchange_data_provider_win.cc b/app/os_exchange_data_provider_win.cc deleted file mode 100644 index 8dbd7e3..0000000 --- a/app/os_exchange_data_provider_win.cc +++ /dev/null @@ -1,923 +0,0 @@ -// Copyright (c) 2010 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_win.h" - -#include "app/l10n_util.h" -#include "base/file_path.h" -#include "base/i18n/file_util_icu.h" -#include "base/logging.h" -#include "base/pickle.h" -#include "base/scoped_handle.h" -#include "base/stl_util-inl.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_hglobal.h" -#include "googleurl/src/gurl.h" -#include "grit/app_strings.h" -#include "net/base/net_util.h" -#include "ui/base/clipboard/clipboard_util_win.h" - -using ui::ClipboardUtil; - -// Creates a new STGMEDIUM object to hold the specified text. The caller -// owns the resulting object. The "Bytes" version does not NULL terminate, the -// string version does. -static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes); -static STGMEDIUM* GetStorageForWString(const std::wstring& data); -static STGMEDIUM* GetStorageForString(const std::string& data); -// Creates the contents of an Internet Shortcut file for the given URL. -static void GetInternetShortcutFileContents(const GURL& url, std::string* data); -// Creates a valid file name given a suggested title and URL. -static void CreateValidFileNameFromTitle(const GURL& url, - const std::wstring& title, - std::wstring* validated); -// Creates a new STGMEDIUM object to hold a file. -static STGMEDIUM* GetStorageForFileName(const std::wstring& full_path); -// Creates a File Descriptor for the creation of a file to the given URL and -// returns a handle to it. -static STGMEDIUM* GetStorageForFileDescriptor( - const std::wstring& valid_file_name); - -/////////////////////////////////////////////////////////////////////////////// -// FormatEtcEnumerator - -// -// This object implements an enumeration interface. The existence of an -// implementation of this interface is exposed to clients through -// OSExchangeData's EnumFormatEtc method. Our implementation is nobody's -// business but our own, so it lives in this file. -// -// This Windows API is truly a gem. It wants to be an enumerator but assumes -// some sort of sequential data (why not just use an array?). See comments -// throughout. -// -class FormatEtcEnumerator : public IEnumFORMATETC { - public: - FormatEtcEnumerator(DataObjectImpl::StoredData::const_iterator begin, - DataObjectImpl::StoredData::const_iterator end); - ~FormatEtcEnumerator(); - - // IEnumFORMATETC implementation: - HRESULT __stdcall Next( - ULONG count, FORMATETC* elements_array, ULONG* elements_fetched); - HRESULT __stdcall Skip(ULONG skip_count); - HRESULT __stdcall Reset(); - HRESULT __stdcall Clone(IEnumFORMATETC** clone); - - // IUnknown implementation: - HRESULT __stdcall QueryInterface(const IID& iid, void** object); - ULONG __stdcall AddRef(); - ULONG __stdcall Release(); - - private: - // This can only be called from |CloneFromOther|, since it initializes the - // contents_ from the other enumerator's contents. - FormatEtcEnumerator() : ref_count_(0) { - } - - // Clone a new FormatEtc from another instance of this enumeration. - static FormatEtcEnumerator* CloneFromOther(const FormatEtcEnumerator* other); - - private: - // We are _forced_ to use a vector as our internal data model as Windows' - // retarded IEnumFORMATETC API assumes a deterministic ordering of elements - // through methods like Next and Skip. This exposes the underlying data - // structure to the user. Bah. - std::vector contents_; - - // The cursor of the active enumeration - an index into |contents_|. - size_t cursor_; - - LONG ref_count_; - - DISALLOW_COPY_AND_ASSIGN(FormatEtcEnumerator); -}; - -// Safely makes a copy of all of the relevant bits of a FORMATETC object. -static void CloneFormatEtc(FORMATETC* source, FORMATETC* clone) { - *clone = *source; - if (source->ptd) { - source->ptd = - static_cast(CoTaskMemAlloc(sizeof(DVTARGETDEVICE))); - *(clone->ptd) = *(source->ptd); - } -} - -FormatEtcEnumerator::FormatEtcEnumerator( - 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) { - FORMATETC* format_etc = new FORMATETC; - CloneFormatEtc(&(*start)->format_etc, format_etc); - contents_.push_back(format_etc); - ++start; - } -} - -FormatEtcEnumerator::~FormatEtcEnumerator() { - STLDeleteContainerPointers(contents_.begin(), contents_.end()); -} - -STDMETHODIMP FormatEtcEnumerator::Next( - ULONG count, FORMATETC* elements_array, ULONG* elements_fetched) { - // MSDN says |elements_fetched| is allowed to be NULL if count is 1. - if (!elements_fetched) - DCHECK(count == 1); - - // This method copies count elements into |elements_array|. - ULONG index = 0; - while (cursor_ < contents_.size() && index < count) { - CloneFormatEtc(contents_[cursor_], &elements_array[index]); - ++cursor_; - ++index; - } - // The out param is for how many we actually copied. - if (elements_fetched) - *elements_fetched = index; - - // If the two don't agree, then we fail. - return index == count ? S_OK : S_FALSE; -} - -STDMETHODIMP FormatEtcEnumerator::Skip(ULONG skip_count) { - cursor_ += skip_count; - // MSDN implies it's OK to leave the enumerator trashed. - // "Whatever you say, boss" - return cursor_ <= contents_.size() ? S_OK : S_FALSE; -} - -STDMETHODIMP FormatEtcEnumerator::Reset() { - cursor_ = 0; - return S_OK; -} - -STDMETHODIMP FormatEtcEnumerator::Clone(IEnumFORMATETC** clone) { - // Clone the current enumerator in its exact state, including cursor. - FormatEtcEnumerator* e = CloneFromOther(this); - e->AddRef(); - *clone = e; - return S_OK; -} - -STDMETHODIMP FormatEtcEnumerator::QueryInterface(const IID& iid, - void** object) { - *object = NULL; - if (IsEqualIID(iid, IID_IUnknown) || IsEqualIID(iid, IID_IEnumFORMATETC)) { - *object = this; - } else { - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG FormatEtcEnumerator::AddRef() { - return InterlockedIncrement(&ref_count_); -} - -ULONG FormatEtcEnumerator::Release() { - if (InterlockedDecrement(&ref_count_) == 0) { - ULONG copied_refcnt = ref_count_; - delete this; - return copied_refcnt; - } - return ref_count_; -} - -// static -FormatEtcEnumerator* FormatEtcEnumerator::CloneFromOther( - const FormatEtcEnumerator* other) { - FormatEtcEnumerator* e = new FormatEtcEnumerator; - // Copy FORMATETC data from our source into ourselves. - std::vector::const_iterator start = other->contents_.begin(); - while (start != other->contents_.end()) { - FORMATETC* format_etc = new FORMATETC; - CloneFormatEtc(*start, format_etc); - e->contents_.push_back(format_etc); - ++start; - } - // Carry over - e->cursor_ = other->cursor_; - return e; -} - -/////////////////////////////////////////////////////////////////////////////// -// OSExchangeDataProviderWin, public: - -// static -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 OSExchangeDataProviderWin::GetPlainTextURL(IDataObject* source, - GURL* url) { - std::wstring plain_text; - if (ClipboardUtil::GetPlainText(source, &plain_text) && - !plain_text.empty()) { - GURL gurl(plain_text); - if (gurl.is_valid()) { - *url = gurl; - return true; - } - } - return false; -} - -// static -DataObjectImpl* OSExchangeDataProviderWin::GetDataObjectImpl( - const OSExchangeData& data) { - return static_cast(&data.provider())-> - data_.get(); -} - -// static -IDataObject* OSExchangeDataProviderWin::GetIDataObject( - const OSExchangeData& data) { - return static_cast(&data.provider())-> - data_object(); -} - -// static -IAsyncOperation* OSExchangeDataProviderWin::GetIAsyncOperation( - const OSExchangeData& data) { - return static_cast(&data.provider())-> - async_operation(); -} - -OSExchangeDataProviderWin::OSExchangeDataProviderWin(IDataObject* source) - : data_(new DataObjectImpl()), - source_object_(source) { -} - -OSExchangeDataProviderWin::OSExchangeDataProviderWin() - : data_(new DataObjectImpl()), - source_object_(data_.get()) { -} - -OSExchangeDataProviderWin::~OSExchangeDataProviderWin() { -} - -void OSExchangeDataProviderWin::SetString(const std::wstring& data) { - STGMEDIUM* storage = GetStorageForWString(data); - data_->contents_.push_back( - new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage)); - - // Also add plain text. - storage = GetStorageForString(WideToUTF8(data)); - data_->contents_.push_back( - new DataObjectImpl::StoredDataInfo(CF_TEXT, storage)); -} - -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 - // the _unittest.cc file to reflect the new arrangement otherwise that test - // will fail! It assumes an insertion order. - - // Add text/x-moz-url for drags from Firefox - std::wstring x_moz_url_str = UTF8ToWide(url.spec()); - x_moz_url_str += '\n'; - x_moz_url_str += title; - STGMEDIUM* storage = GetStorageForWString(x_moz_url_str); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetMozUrlFormat()->cfFormat, storage)); - - // Add a .URL shortcut file for dragging to Explorer. - std::wstring valid_file_name; - CreateValidFileNameFromTitle(url, title, &valid_file_name); - std::string shortcut_url_file_contents; - GetInternetShortcutFileContents(url, &shortcut_url_file_contents); - SetFileContents(valid_file_name, shortcut_url_file_contents); - - // Add a UniformResourceLocator link for apps like IE and Word. - storage = GetStorageForWString(UTF8ToWide(url.spec())); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetUrlWFormat()->cfFormat, storage)); - storage = GetStorageForString(url.spec()); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetUrlFormat()->cfFormat, storage)); - - // TODO(beng): add CF_HTML. - // http://code.google.com/p/chromium/issues/detail?id=6767 - - // Also add text representations (these should be last since they're the - // least preferable). - storage = GetStorageForWString(UTF8ToWide(url.spec())); - data_->contents_.push_back( - new DataObjectImpl::StoredDataInfo(CF_UNICODETEXT, storage)); - storage = GetStorageForString(url.spec()); - data_->contents_.push_back( - new DataObjectImpl::StoredDataInfo(CF_TEXT, storage)); -} - -void OSExchangeDataProviderWin::SetFilename(const std::wstring& full_path) { - STGMEDIUM* storage = GetStorageForFileName(full_path); - DataObjectImpl::StoredDataInfo* info = - new DataObjectImpl::StoredDataInfo(CF_HDROP, storage); - data_->contents_.push_back(info); -} - -void OSExchangeDataProviderWin::SetPickledData(CLIPFORMAT format, - const Pickle& data) { - STGMEDIUM* storage = GetStorageForString( - std::string(static_cast(data.data()), - static_cast(data.size()))); - data_->contents_.push_back( - new DataObjectImpl::StoredDataInfo(format, storage)); -} - -void OSExchangeDataProviderWin::SetFileContents( - const std::wstring& filename, - const std::string& file_contents) { - // Add CFSTR_FILEDESCRIPTOR - STGMEDIUM* storage = GetStorageForFileDescriptor(filename); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetFileDescriptorFormat()->cfFormat, storage)); - - // Add CFSTR_FILECONTENTS - storage = GetStorageForBytes(file_contents.data(), file_contents.length()); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetFileContentFormatZero(), storage)); -} - -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()); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetHtmlFormat()->cfFormat, storage)); - - STGMEDIUM* storage_plain = GetStorageForBytes(utf8_html.c_str(), - utf8_html.size()); - data_->contents_.push_back(new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetTextHtmlFormat()->cfFormat, storage_plain)); -} - -bool OSExchangeDataProviderWin::GetString(std::wstring* data) const { - return ClipboardUtil::GetPlainText(source_object_, data); -} - -bool OSExchangeDataProviderWin::GetURLAndTitle(GURL* url, - std::wstring* title) const { - std::wstring url_str; - bool success = ClipboardUtil::GetUrl(source_object_, &url_str, title, true); - if (success) { - GURL test_url(url_str); - if (test_url.is_valid()) { - *url = test_url; - return true; - } - } else if (GetPlainTextURL(source_object_, url)) { - title->clear(); - return true; - } - return false; -} - -bool OSExchangeDataProviderWin::GetFilename(std::wstring* full_path) const { - std::vector filenames; - bool success = ClipboardUtil::GetFilenames(source_object_, &filenames); - if (success) - full_path->assign(filenames[0]); - return success; -} - -bool OSExchangeDataProviderWin::GetPickledData(CLIPFORMAT format, - Pickle* data) const { - DCHECK(data); - FORMATETC format_etc = - { format, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - bool success = false; - STGMEDIUM medium; - if (SUCCEEDED(source_object_->GetData(&format_etc, &medium))) { - if (medium.tymed & TYMED_HGLOBAL) { - base::win::ScopedHGlobal c_data(medium.hGlobal); - DCHECK(c_data.Size() > 0); - // Need to subtract 1 as SetPickledData adds an extra byte to the end. - *data = Pickle(c_data.get(), static_cast(c_data.Size() - 1)); - success = true; - } - ReleaseStgMedium(&medium); - } - return success; -} - -bool OSExchangeDataProviderWin::GetFileContents( - std::wstring* filename, - std::string* file_contents) const { - return ClipboardUtil::GetFileContents(source_object_, filename, - file_contents); -} - -bool OSExchangeDataProviderWin::GetHtml(std::wstring* html, - GURL* base_url) const { - std::string url; - bool success = ClipboardUtil::GetHtml(source_object_, html, &url); - if (success) - *base_url = GURL(url); - return success; -} - -bool OSExchangeDataProviderWin::HasString() const { - return ClipboardUtil::HasPlainText(source_object_); -} - -bool OSExchangeDataProviderWin::HasURL() const { - return (ClipboardUtil::HasUrl(source_object_) || - HasPlainTextURL(source_object_)); -} - -bool OSExchangeDataProviderWin::HasFile() const { - return ClipboardUtil::HasFilenames(source_object_); -} - -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); -} - -void OSExchangeDataProviderWin::SetDownloadFileInfo( - const OSExchangeData::DownloadFileInfo& download) { - // If the filename is not provided, set stoarge to NULL to indicate that - // the delay rendering will be used. - STGMEDIUM* storage = NULL; - if (!download.filename.empty()) - storage = GetStorageForFileName(download.filename.value()); - - // Add CF_HDROP. - DataObjectImpl::StoredDataInfo* info = new DataObjectImpl::StoredDataInfo( - ClipboardUtil::GetCFHDropFormat()->cfFormat, storage); - info->downloader = download.downloader; - data_->contents_.push_back(info); -} - -/////////////////////////////////////////////////////////////////////////////// -// 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: -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -static void DuplicateMedium(CLIPFORMAT source_clipformat, - STGMEDIUM* source, - STGMEDIUM* destination) { - switch (source->tymed) { - case TYMED_HGLOBAL: - destination->hGlobal = - static_cast(OleDuplicateData( - source->hGlobal, source_clipformat, 0)); - break; - case TYMED_MFPICT: - destination->hMetaFilePict = - static_cast(OleDuplicateData( - source->hMetaFilePict, source_clipformat, 0)); - break; - case TYMED_GDI: - destination->hBitmap = - static_cast(OleDuplicateData( - source->hBitmap, source_clipformat, 0)); - break; - case TYMED_ENHMF: - destination->hEnhMetaFile = - static_cast(OleDuplicateData( - source->hEnhMetaFile, source_clipformat, 0)); - break; - case TYMED_FILE: - destination->lpszFileName = - static_cast(OleDuplicateData( - source->lpszFileName, source_clipformat, 0)); - break; - case TYMED_ISTREAM: - destination->pstm = source->pstm; - destination->pstm->AddRef(); - break; - case TYMED_ISTORAGE: - destination->pstg = source->pstg; - destination->pstg->AddRef(); - break; - } - - destination->tymed = source->tymed; - destination->pUnkForRelease = source->pUnkForRelease; - if (destination->pUnkForRelease) - destination->pUnkForRelease->AddRef(); -} - -DataObjectImpl::DataObjectImpl() - : is_aborting_(false), - in_async_mode_(false), - async_operation_started_(false), - observer_(NULL) { -} - -DataObjectImpl::~DataObjectImpl() { - StopDownloads(); - STLDeleteContainerPointers(contents_.begin(), contents_.end()); - if (observer_) - observer_->OnDataObjectDisposed(); -} - -void DataObjectImpl::StopDownloads() { - for (StoredData::iterator iter = contents_.begin(); - iter != contents_.end(); ++iter) { - if ((*iter)->downloader.get()) { - (*iter)->downloader->Stop(); - (*iter)->downloader = 0; - } - } -} - -void DataObjectImpl::OnDownloadCompleted(const FilePath& file_path) { - CLIPFORMAT hdrop_format = ClipboardUtil::GetCFHDropFormat()->cfFormat; - DataObjectImpl::StoredData::iterator iter = contents_.begin(); - for (; iter != contents_.end(); ++iter) { - if ((*iter)->format_etc.cfFormat == hdrop_format) { - // Release the old storage. - if ((*iter)->owns_medium) { - ReleaseStgMedium((*iter)->medium); - delete (*iter)->medium; - } - - // Update the storage. - (*iter)->owns_medium = true; - (*iter)->medium = GetStorageForFileName(file_path.value()); - - break; - } - } - DCHECK(iter != contents_.end()); -} - -void DataObjectImpl::OnDownloadAborted() { -} - -HRESULT DataObjectImpl::GetData(FORMATETC* format_etc, STGMEDIUM* medium) { - if (is_aborting_) - return DV_E_FORMATETC; - - StoredData::iterator iter = contents_.begin(); - while (iter != contents_.end()) { - if ((*iter)->format_etc.cfFormat == format_etc->cfFormat && - (*iter)->format_etc.lindex == format_etc->lindex && - ((*iter)->format_etc.tymed & format_etc->tymed)) { - // If medium is NULL, delay-rendering will be used. - if ((*iter)->medium) { - DuplicateMedium((*iter)->format_etc.cfFormat, (*iter)->medium, medium); - } else { - // Check if the left button is down. - bool is_left_button_down = (GetKeyState(VK_LBUTTON) & 0x8000) != 0; - - bool wait_for_data = false; - if ((*iter)->in_delay_rendering) { - // Make sure the left button is up. Sometimes the drop target, like - // Shell, might be too aggresive in calling GetData when the left - // button is not released. - if (is_left_button_down) - return DV_E_FORMATETC; - - // In async mode, we do not want to start waiting for the data before - // the async operation is started. This is because we want to postpone - // until Shell kicks off a background thread to do the work so that - // we do not block the UI thread. - if (!in_async_mode_ || async_operation_started_) - wait_for_data = true; - } else { - // If the left button is up and the target has not requested the data - // yet, it probably means that the target does not support delay- - // rendering. So instead, we wait for the data. - if (is_left_button_down) { - (*iter)->in_delay_rendering = true; - memset(medium, 0, sizeof(STGMEDIUM)); - } else { - wait_for_data = true; - } - } - - if (!wait_for_data) - return DV_E_FORMATETC; - - // Notify the observer we start waiting for the data. This gives - // an observer a chance to end the drag and drop. - if (observer_) - observer_->OnWaitForData(); - - // Now we can start the download. - if ((*iter)->downloader.get()) { - if (!(*iter)->downloader->Start(this)) { - is_aborting_ = true; - return DV_E_FORMATETC; - } - } - - // The stored data should have been updated with the final version. - // So we just need to call this function again to retrieve it. - return GetData(format_etc, medium); - } - return S_OK; - } - ++iter; - } - - return DV_E_FORMATETC; -} - -HRESULT DataObjectImpl::GetDataHere(FORMATETC* format_etc, - STGMEDIUM* medium) { - return DATA_E_FORMATETC; -} - -HRESULT DataObjectImpl::QueryGetData(FORMATETC* format_etc) { - StoredData::const_iterator iter = contents_.begin(); - while (iter != contents_.end()) { - if ((*iter)->format_etc.cfFormat == format_etc->cfFormat) - return S_OK; - ++iter; - } - return DV_E_FORMATETC; -} - -HRESULT DataObjectImpl::GetCanonicalFormatEtc( - FORMATETC* format_etc, FORMATETC* result) { - format_etc->ptd = NULL; - return E_NOTIMPL; -} - -HRESULT DataObjectImpl::SetData( - FORMATETC* format_etc, STGMEDIUM* medium, BOOL should_release) { - STGMEDIUM* local_medium = new STGMEDIUM; - if (should_release) { - *local_medium = *medium; - } else { - DuplicateMedium(format_etc->cfFormat, medium, 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); - - return S_OK; -} - -HRESULT DataObjectImpl::EnumFormatEtc( - DWORD direction, IEnumFORMATETC** enumerator) { - if (direction == DATADIR_GET) { - FormatEtcEnumerator* e = - new FormatEtcEnumerator(contents_.begin(), contents_.end()); - e->AddRef(); - *enumerator = e; - return S_OK; - } - return E_NOTIMPL; -} - -HRESULT DataObjectImpl::DAdvise( - FORMATETC* format_etc, DWORD advf, IAdviseSink* sink, DWORD* connection) { - return OLE_E_ADVISENOTSUPPORTED; -} - -HRESULT DataObjectImpl::DUnadvise(DWORD connection) { - return OLE_E_ADVISENOTSUPPORTED; -} - -HRESULT DataObjectImpl::EnumDAdvise(IEnumSTATDATA** enumerator) { - return OLE_E_ADVISENOTSUPPORTED; -} - -/////////////////////////////////////////////////////////////////////////////// -// DataObjectImpl, IAsyncOperation implementation: - -HRESULT DataObjectImpl::EndOperation( - HRESULT result, IBindCtx* reserved, DWORD effects) { - async_operation_started_ = false; - return S_OK; -} - -HRESULT DataObjectImpl::GetAsyncMode(BOOL* is_op_async) { - *is_op_async = in_async_mode_ ? TRUE : FALSE; - return S_OK; -} - -HRESULT DataObjectImpl::InOperation(BOOL* in_async_op) { - *in_async_op = async_operation_started_ ? TRUE : FALSE; - return S_OK; -} - -HRESULT DataObjectImpl::SetAsyncMode(BOOL do_op_async) { - in_async_mode_ = (do_op_async == TRUE); - return S_OK; -} - -HRESULT DataObjectImpl::StartOperation(IBindCtx* reserved) { - async_operation_started_ = true; - return S_OK; -} - -/////////////////////////////////////////////////////////////////////////////// -// DataObjectImpl, IUnknown implementation: - -HRESULT DataObjectImpl::QueryInterface(const IID& iid, void** object) { - if (!object) - return E_POINTER; - if (IsEqualIID(iid, IID_IDataObject) || IsEqualIID(iid, IID_IUnknown)) { - *object = static_cast(this); - } else if (in_async_mode_ && IsEqualIID(iid, IID_IAsyncOperation)) { - *object = static_cast(this); - } else { - *object = NULL; - return E_NOINTERFACE; - } - AddRef(); - return S_OK; -} - -ULONG DataObjectImpl::AddRef() { - base::RefCountedThreadSafe::AddRef(); - return 0; -} - -ULONG DataObjectImpl::Release() { - base::RefCountedThreadSafe::Release(); - return 0; -} - -/////////////////////////////////////////////////////////////////////////////// -// DataObjectImpl, private: - -static STGMEDIUM* GetStorageForBytes(const char* data, size_t bytes) { - HANDLE handle = GlobalAlloc(GPTR, static_cast(bytes)); - base::win::ScopedHGlobal scoped(handle); - size_t allocated = static_cast(GlobalSize(handle)); - memcpy(scoped.get(), data, allocated); - - STGMEDIUM* storage = new STGMEDIUM; - storage->hGlobal = handle; - storage->tymed = TYMED_HGLOBAL; - storage->pUnkForRelease = NULL; - return storage; -} - -template -static HGLOBAL CopyStringToGlobalHandle(const T& payload) { - int bytes = static_cast(payload.size() + 1) * sizeof(T::value_type); - HANDLE handle = GlobalAlloc(GPTR, bytes); - void* data = GlobalLock(handle); - size_t allocated = static_cast(GlobalSize(handle)); - memcpy(data, payload.c_str(), allocated); - static_cast(data)[payload.size()] = '\0'; - GlobalUnlock(handle); - return handle; -} - -static STGMEDIUM* GetStorageForWString(const std::wstring& data) { - STGMEDIUM* storage = new STGMEDIUM; - storage->hGlobal = CopyStringToGlobalHandle(data); - storage->tymed = TYMED_HGLOBAL; - storage->pUnkForRelease = NULL; - return storage; -} - -static STGMEDIUM* GetStorageForString(const std::string& data) { - STGMEDIUM* storage = new STGMEDIUM; - storage->hGlobal = CopyStringToGlobalHandle(data); - storage->tymed = TYMED_HGLOBAL; - storage->pUnkForRelease = NULL; - return storage; -} - -static void GetInternetShortcutFileContents(const GURL& url, - std::string* data) { - DCHECK(data); - static const std::string kInternetShortcutFileStart = - "[InternetShortcut]\r\nURL="; - static const std::string kInternetShortcutFileEnd = - "\r\n"; - *data = kInternetShortcutFileStart + url.spec() + kInternetShortcutFileEnd; -} - -static void CreateValidFileNameFromTitle(const GURL& url, - const std::wstring& title, - std::wstring* validated) { - if (title.empty()) { - if (url.is_valid()) { - *validated = net::GetSuggestedFilename( - url, std::string(), std::string(), FilePath()).ToWStringHack(); - } else { - // Nothing else can be done, just use a default. - *validated = - l10n_util::GetStringUTF16(IDS_APP_UNTITLED_SHORTCUT_FILE_NAME); - } - } else { - *validated = title; - file_util::ReplaceIllegalCharactersInPath(validated, '-'); - } - static const wchar_t extension[] = L".url"; - static const size_t max_length = MAX_PATH - arraysize(extension); - if (validated->size() > max_length) - validated->erase(max_length); - *validated += extension; -} - -static STGMEDIUM* GetStorageForFileName(const std::wstring& full_path) { - const size_t kDropSize = sizeof(DROPFILES); - const size_t kTotalBytes = - kDropSize + (full_path.length() + 2) * sizeof(wchar_t); - HANDLE hdata = GlobalAlloc(GMEM_MOVEABLE, kTotalBytes); - - base::win::ScopedHGlobal locked_mem(hdata); - DROPFILES* drop_files = locked_mem.get(); - drop_files->pFiles = sizeof(DROPFILES); - drop_files->fWide = TRUE; - wchar_t* data = reinterpret_cast( - reinterpret_cast(drop_files) + kDropSize); - const size_t copy_size = (full_path.length() + 1) * sizeof(wchar_t); - memcpy(data, full_path.c_str(), copy_size); - data[full_path.length() + 1] = L'\0'; // Double NULL - - STGMEDIUM* storage = new STGMEDIUM; - storage->tymed = TYMED_HGLOBAL; - storage->hGlobal = drop_files; - storage->pUnkForRelease = NULL; - return storage; -} - -static STGMEDIUM* GetStorageForFileDescriptor( - const std::wstring& valid_file_name) { - DCHECK(!valid_file_name.empty() && valid_file_name.size() + 1 <= MAX_PATH); - HANDLE handle = GlobalAlloc(GPTR, sizeof(FILEGROUPDESCRIPTOR)); - FILEGROUPDESCRIPTOR* descriptor = - reinterpret_cast(GlobalLock(handle)); - - descriptor->cItems = 1; - wcscpy_s(descriptor->fgd[0].cFileName, - valid_file_name.size() + 1, - valid_file_name.c_str()); - descriptor->fgd[0].dwFlags = FD_LINKUI; - - GlobalUnlock(handle); - - STGMEDIUM* storage = new STGMEDIUM; - storage->hGlobal = handle; - storage->tymed = TYMED_HGLOBAL; - 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 deleted file mode 100644 index b4cc522..0000000 --- a/app/os_exchange_data_provider_win.h +++ /dev/null @@ -1,176 +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. - -#ifndef APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ -#define APP_OS_EXCHANGE_DATA_PROVIDER_WIN_H_ -#pragma once - -#include -#include -#include - -#include "app/os_exchange_data.h" -#include "base/scoped_comptr_win.h" - -class DataObjectImpl : public DownloadFileObserver, - public IDataObject, - public IAsyncOperation { - public: - class Observer { - public: - virtual void OnWaitForData() = 0; - virtual void OnDataObjectDisposed() = 0; - protected: - virtual ~Observer() { } - }; - - DataObjectImpl(); - - // Accessors. - void set_observer(Observer* observer) { observer_ = observer; } - - // DownloadFileObserver implementation: - virtual void OnDownloadCompleted(const FilePath& file_path); - virtual void OnDownloadAborted(); - - // 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); - - // IAsyncOperation implementation: - HRESULT __stdcall EndOperation( - HRESULT result, IBindCtx* reserved, DWORD effects); - HRESULT __stdcall GetAsyncMode(BOOL* is_op_async); - HRESULT __stdcall InOperation(BOOL* in_async_op); - HRESULT __stdcall SetAsyncMode(BOOL do_op_async); - HRESULT __stdcall StartOperation(IBindCtx* reserved); - - // 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; - - virtual ~DataObjectImpl(); - - void StopDownloads(); - - // Our internal representation of stored data & type info. - struct StoredDataInfo { - FORMATETC format_etc; - STGMEDIUM* medium; - bool owns_medium; - bool in_delay_rendering; - scoped_refptr downloader; - - StoredDataInfo(CLIPFORMAT cf, STGMEDIUM* medium) - : medium(medium), - owns_medium(true), - in_delay_rendering(false) { - format_etc.cfFormat = cf; - format_etc.dwAspect = DVASPECT_CONTENT; - format_etc.lindex = -1; - format_etc.ptd = NULL; - format_etc.tymed = medium ? medium->tymed : TYMED_HGLOBAL; - } - - StoredDataInfo(FORMATETC* format_etc, STGMEDIUM* medium) - : format_etc(*format_etc), - medium(medium), - owns_medium(true), - in_delay_rendering(false) { - } - - ~StoredDataInfo() { - if (owns_medium) { - ReleaseStgMedium(medium); - delete medium; - } - if (downloader.get()) - downloader->Stop(); - } - }; - - typedef std::vector StoredData; - StoredData contents_; - - ScopedComPtr source_object_; - - bool is_aborting_; - bool in_async_mode_; - bool async_operation_started_; - Observer* observer_; -}; - -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 DataObjectImpl* GetDataObjectImpl(const OSExchangeData& data); - static IDataObject* GetIDataObject(const OSExchangeData& data); - static IAsyncOperation* GetIAsyncOperation(const OSExchangeData& data); - - explicit OSExchangeDataProviderWin(IDataObject* source); - OSExchangeDataProviderWin(); - - virtual ~OSExchangeDataProviderWin(); - - IDataObject* data_object() const { return data_.get(); } - IAsyncOperation* async_operation() 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; - virtual void SetDownloadFileInfo( - const OSExchangeData::DownloadFileInfo& download_info); - - private: - scoped_refptr data_; - ScopedComPtr 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 deleted file mode 100644 index 39fe2a6..0000000 --- a/app/os_exchange_data_win_unittest.cc +++ /dev/null @@ -1,373 +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. - -#include "app/os_exchange_data.h" -#include "app/os_exchange_data_provider_win.h" -#include "base/pickle.h" -#include "base/ref_counted.h" -#include "base/scoped_handle.h" -#include "base/scoped_ptr.h" -#include "base/utf_string_conversions.h" -#include "base/win/scoped_hglobal.h" -#include "googleurl/src/gurl.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/base/clipboard/clipboard_util_win.h" - -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; - std::wstring input = L"I can has cheezburger?"; - data.SetString(input); - - OSExchangeData data2(CloneProvider(data)); - std::wstring 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)); - // No URLs in |data|, so url should be untouched. - EXPECT_EQ(url_spec, url.spec()); -} - -// Test getting using the IDataObject COM API -TEST(OSExchangeDataTest, StringDataAccessViaCOM) { - OSExchangeData data; - std::wstring input = L"O hai googlz."; - data.SetString(input); - ScopedComPtr com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - - FORMATETC format_etc = - { CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - EXPECT_EQ(S_OK, com_data->QueryGetData(&format_etc)); - - STGMEDIUM medium; - EXPECT_EQ(S_OK, com_data->GetData(&format_etc, &medium)); - std::wstring output = - base::win::ScopedHGlobal(medium.hGlobal).get(); - EXPECT_EQ(input, output); - ReleaseStgMedium(&medium); -} - -// Test setting using the IDataObject COM API -TEST(OSExchangeDataTest, StringDataWritingViaCOM) { - OSExchangeData data; - std::wstring input = L"http://www.google.com/"; - - ScopedComPtr com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - - // Store data in the object using the COM SetData API. - CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); - FORMATETC format_etc = - { cfstr_ineturl, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - STGMEDIUM medium; - medium.tymed = TYMED_HGLOBAL; - HGLOBAL glob = GlobalAlloc(GPTR, sizeof(wchar_t) * (input.size() + 1)); - size_t stringsz = input.size(); - SIZE_T sz = GlobalSize(glob); - base::win::ScopedHGlobal global_lock(glob); - wchar_t* buffer_handle = global_lock.get(); - wcscpy_s(buffer_handle, input.size() + 1, input.c_str()); - medium.hGlobal = glob; - medium.pUnkForRelease = NULL; - EXPECT_EQ(S_OK, com_data->SetData(&format_etc, &medium, TRUE)); - - // Construct a new object with the old object so that we can use our access - // APIs. - OSExchangeData data2(CloneProvider(data)); - EXPECT_TRUE(data2.HasURL()); - GURL url_from_data; - std::wstring title; - EXPECT_TRUE(data2.GetURLAndTitle(&url_from_data, &title)); - GURL reference_url(input); - EXPECT_EQ(reference_url.spec(), url_from_data.spec()); -} - -TEST(OSExchangeDataTest, URLDataAccessViaCOM) { - OSExchangeData data; - GURL url("http://www.google.com/"); - data.SetURL(url, L""); - ScopedComPtr com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - - CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); - FORMATETC format_etc = - { cfstr_ineturl, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - EXPECT_EQ(S_OK, com_data->QueryGetData(&format_etc)); - - STGMEDIUM medium; - EXPECT_EQ(S_OK, com_data->GetData(&format_etc, &medium)); - std::wstring output = - base::win::ScopedHGlobal(medium.hGlobal).get(); - EXPECT_EQ(url.spec(), WideToUTF8(output)); - ReleaseStgMedium(&medium); -} - -TEST(OSExchangeDataTest, MultipleFormatsViaCOM) { - 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); - - ScopedComPtr com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - - CLIPFORMAT cfstr_ineturl = RegisterClipboardFormat(CFSTR_INETURL); - FORMATETC url_format_etc = - { cfstr_ineturl, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - EXPECT_EQ(S_OK, com_data->QueryGetData(&url_format_etc)); - FORMATETC text_format_etc = - { CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL }; - EXPECT_EQ(S_OK, com_data->QueryGetData(&text_format_etc)); - - STGMEDIUM medium; - EXPECT_EQ(S_OK, com_data->GetData(&url_format_etc, &medium)); - std::wstring output_url = - base::win::ScopedHGlobal(medium.hGlobal).get(); - EXPECT_EQ(url.spec(), WideToUTF8(output_url)); - ReleaseStgMedium(&medium); - - // The text is supposed to be the raw text of the URL, _NOT_ the value of - // |text|! This is because the URL is added first and thus takes precedence! - EXPECT_EQ(S_OK, com_data->GetData(&text_format_etc, &medium)); - std::wstring output_text = - base::win::ScopedHGlobal(medium.hGlobal).get(); - EXPECT_EQ(url_spec, WideToUTF8(output_text)); - ReleaseStgMedium(&medium); -} - -TEST(OSExchangeDataTest, EnumerationViaCOM) { - 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 com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - ScopedComPtr enumerator; - EXPECT_EQ(S_OK, com_data.get()->EnumFormatEtc(DATADIR_GET, - enumerator.Receive())); - - // Test that we can get one item. - { - // Explictly don't reset the first time, to verify the creation state is - // OK. - ULONG retrieved = 0; - FORMATETC elements_array[1]; - EXPECT_EQ(S_OK, enumerator->Next(1, - reinterpret_cast(&elements_array), &retrieved)); - EXPECT_EQ(1, retrieved); - EXPECT_EQ(text_x_moz_url, elements_array[0].cfFormat); - } - - // Test that we can get one item with a NULL retrieved value. - { - EXPECT_EQ(S_OK, enumerator->Reset()); - FORMATETC elements_array[1]; - EXPECT_EQ(S_OK, enumerator->Next(1, - reinterpret_cast(&elements_array), NULL)); - EXPECT_EQ(text_x_moz_url, elements_array[0].cfFormat); - } - - // Test that we can get two items. - { - EXPECT_EQ(S_OK, enumerator->Reset()); - ULONG retrieved = 0; - FORMATETC elements_array[2]; - EXPECT_EQ(S_OK, enumerator->Next(2, - reinterpret_cast(&elements_array), &retrieved)); - EXPECT_EQ(2, retrieved); - EXPECT_EQ(text_x_moz_url, elements_array[0].cfFormat); - EXPECT_EQ(cfstr_file_group_descriptor, elements_array[1].cfFormat); - } - - // Test that we can skip the first item. - { - EXPECT_EQ(S_OK, enumerator->Reset()); - EXPECT_EQ(S_OK, enumerator->Skip(1)); - ULONG retrieved = 0; - FORMATETC elements_array[1]; - EXPECT_EQ(S_OK, enumerator->Next(1, - reinterpret_cast(&elements_array), &retrieved)); - EXPECT_EQ(1, retrieved); - EXPECT_EQ(cfstr_file_group_descriptor, elements_array[0].cfFormat); - } - - // Test that we can skip the first item, and create a clone that matches in - // this state, and modify the original without affecting the clone. - { - EXPECT_EQ(S_OK, enumerator->Reset()); - EXPECT_EQ(S_OK, enumerator->Skip(1)); - ScopedComPtr cloned_enumerator; - EXPECT_EQ(S_OK, enumerator.get()->Clone(cloned_enumerator.Receive())); - EXPECT_EQ(S_OK, enumerator.get()->Reset()); - - { - ULONG retrieved = 0; - FORMATETC elements_array[1]; - EXPECT_EQ(S_OK, cloned_enumerator->Next(1, - reinterpret_cast(&elements_array), &retrieved)); - EXPECT_EQ(1, retrieved); - EXPECT_EQ(cfstr_file_group_descriptor, elements_array[0].cfFormat); - } - - { - ULONG retrieved = 0; - FORMATETC elements_array[1]; - EXPECT_EQ(S_OK, enumerator->Next(1, - reinterpret_cast(&elements_array), &retrieved)); - EXPECT_EQ(1, retrieved); - EXPECT_EQ(text_x_moz_url, elements_array[0].cfFormat); - } - } -} - -TEST(OSExchangeDataTest, TestURLExchangeFormats) { - 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); - std::wstring output; - - 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_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_EQ(url_spec, WideToUTF8(output_string)); - - // File contents access via COM - ScopedComPtr com_data( - OSExchangeDataProviderWin::GetIDataObject(data)); - { - CLIPFORMAT cfstr_file_contents = - RegisterClipboardFormat(CFSTR_FILECONTENTS); - FORMATETC format_etc = - { cfstr_file_contents, NULL, DVASPECT_CONTENT, 0, TYMED_HGLOBAL }; - EXPECT_EQ(S_OK, com_data->QueryGetData(&format_etc)); - - STGMEDIUM medium; - EXPECT_EQ(S_OK, com_data->GetData(&format_etc, &medium)); - base::win::ScopedHGlobal glob(medium.hGlobal); - std::string output(glob.get(), glob.Size()); - std::string file_contents = "[InternetShortcut]\r\nURL="; - file_contents += url_spec; - file_contents += "\r\n"; - EXPECT_EQ(file_contents, output); - ReleaseStgMedium(&medium); - } -} - -TEST(OSExchangeDataTest, TestPickledData) { - CLIPFORMAT test_cf = RegisterClipboardFormat(L"chrome/test"); - - Pickle saved_pickle; - saved_pickle.WriteInt(1); - saved_pickle.WriteInt(2); - OSExchangeData data; - data.SetPickledData(test_cf, saved_pickle); - - OSExchangeData copy(CloneProvider(data)); - EXPECT_TRUE(copy.HasCustomFormat(test_cf)); - - Pickle restored_pickle; - EXPECT_TRUE(copy.GetPickledData(test_cf, &restored_pickle)); - void* p_iterator = NULL; - int value; - EXPECT_TRUE(restored_pickle.ReadInt(&p_iterator, &value)); - EXPECT_EQ(1, value); - EXPECT_TRUE(restored_pickle.ReadInt(&p_iterator, &value)); - EXPECT_EQ(2, value); -} - -TEST(OSExchangeDataTest, FileContents) { - OSExchangeData data; - std::string file_contents("data\0with\0nulls", 15); - data.SetFileContents(L"filename.txt", file_contents); - - OSExchangeData copy(CloneProvider(data)); - std::wstring filename; - std::string read_contents; - EXPECT_TRUE(copy.GetFileContents(&filename, &read_contents)); - EXPECT_EQ(L"filename.txt", filename); - EXPECT_EQ(file_contents, read_contents); -} - -TEST(OSExchangeDataTest, Html) { - OSExchangeData data; - GURL url("http://www.google.com/"); - std::wstring html( - L"\n\n" - L"bold. This is bold italic.\n" - L"\n"); - data.SetHtml(html, url); - - OSExchangeData copy(CloneProvider(data)); - std::wstring read_html; - EXPECT_TRUE(copy.GetHtml(&read_html, &url)); - EXPECT_EQ(html, read_html); - - // Check the CF_HTML too. - std::string expected_cf_html( - "Version:0.9\r\nStartHTML:0000000139\r\nEndHTML:0000000292\r\n" - "StartFragment:0000000177\r\nEndFragment:0000000254\r\n" - "SourceURL:http://www.google.com/\r\n\r\n\r\n" - "\r\n"); - expected_cf_html += WideToUTF8(html); - expected_cf_html.append("\r\n\r\n\r\n"); - - STGMEDIUM medium; - IDataObject* data_object = OSExchangeDataProviderWin::GetIDataObject(data); - EXPECT_EQ(S_OK, - data_object->GetData(ui::ClipboardUtil::GetHtmlFormat(), &medium)); - base::win::ScopedHGlobal glob(medium.hGlobal); - std::string output(glob.get(), glob.Size()); - EXPECT_EQ(expected_cf_html, output); - ReleaseStgMedium(&medium); -} - -TEST(OSExchangeDataTest, SetURLWithMaxPath) { - OSExchangeData data; - std::wstring long_title(L'a', MAX_PATH + 1); - data.SetURL(GURL("http://google.com"), long_title); -} - -TEST(OSExchangeDataTest, ProvideURLForPlainTextURL) { - OSExchangeData data; - data.SetString(L"http://google.com"); - - OSExchangeData data2(CloneProvider(data)); - ASSERT_TRUE(data2.HasURL()); - GURL read_url; - std::wstring title; - EXPECT_TRUE(data2.GetURLAndTitle(&read_url, &title)); - EXPECT_EQ(GURL("http://google.com"), read_url); -} -- cgit v1.1