diff options
author | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 21:42:58 +0000 |
---|---|---|
committer | sky@chromium.org <sky@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-09-23 21:42:58 +0000 |
commit | b6d432335f59500e092de2be4fcf42ed303ae1c5 (patch) | |
tree | 0dae24ec6c0f89442ee37d18aeb17f5dcf48d6e0 | |
parent | 599ea9fd7f5f029661916c191ff89b7358719f81 (diff) | |
download | chromium_src-b6d432335f59500e092de2be4fcf42ed303ae1c5.zip chromium_src-b6d432335f59500e092de2be4fcf42ed303ae1c5.tar.gz chromium_src-b6d432335f59500e092de2be4fcf42ed303ae1c5.tar.bz2 |
Implements file contents support in OSExchangeData and DropTarget
for gtk. Makes html and file contents support in OSExchangeData only
for windows (as that is the only place we need it), and makes dragging
files work.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/232002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26995 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | app/os_exchange_data.cc | 50 | ||||
-rw-r--r-- | app/os_exchange_data.h | 58 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.cc | 104 | ||||
-rw-r--r-- | app/os_exchange_data_provider_gtk.h | 21 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 48 | ||||
-rw-r--r-- | chrome/browser/download/download_util.h | 8 | ||||
-rw-r--r-- | chrome/browser/views/download_item_view.cc | 7 | ||||
-rw-r--r-- | views/DEPS | 1 | ||||
-rw-r--r-- | views/drag_utils.cc | 11 | ||||
-rw-r--r-- | views/drag_utils.h | 4 | ||||
-rw-r--r-- | views/widget/drop_target_gtk.cc | 48 |
11 files changed, 184 insertions, 176 deletions
diff --git a/app/os_exchange_data.cc b/app/os_exchange_data.cc index 9361466..8f647c2 100644 --- a/app/os_exchange_data.cc +++ b/app/os_exchange_data.cc @@ -32,15 +32,6 @@ 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); } @@ -57,15 +48,6 @@ 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(); } @@ -89,12 +71,14 @@ bool OSExchangeData::HasAllFormats( return false; if ((formats & URL) != 0 && !HasURL()) return false; +#if defined(OS_WIN) 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; +#endif + if ((formats & FILE_NAME) != 0 && !provider_->HasFile()) + return false; for (std::set<CustomFormat>::const_iterator i = custom_formats.begin(); i != custom_formats.end(); ++i) { if (!HasCustomFormat(*i)) @@ -110,12 +94,14 @@ bool OSExchangeData::HasAnyFormat( return true; if ((formats & URL) != 0 && HasURL()) return true; +#if defined(OS_WIN) 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; +#endif + if ((formats & FILE_NAME) != 0 && provider_->HasFile()) + return true; for (std::set<CustomFormat>::const_iterator i = custom_formats.begin(); i != custom_formats.end(); ++i) { if (HasCustomFormat(*i)) @@ -123,3 +109,23 @@ bool OSExchangeData::HasAnyFormat( } 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); +} +#endif diff --git a/app/os_exchange_data.h b/app/os_exchange_data.h index a956b80..7efea43 100644 --- a/app/os_exchange_data.h +++ b/app/os_exchange_data.h @@ -32,6 +32,11 @@ class Pickle; // 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 @@ -46,10 +51,12 @@ class OSExchangeData { enum Format { STRING = 1 << 0, URL = 1 << 1, - FILE_CONTENTS = 1 << 2, - FILE_NAME = 1 << 3, - PICKLED_DATA = 1 << 4, - HTML = 1 << 5 + FILE_NAME = 1 << 2, + PICKLED_DATA = 1 << 3, +#if defined(OS_WIN) + FILE_CONTENTS = 1 << 4, + HTML = 1 << 5, +#endif }; // Provider defines the platform specific part of OSExchangeData that @@ -63,25 +70,28 @@ class OSExchangeData { 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; + +#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; +#endif }; OSExchangeData(); @@ -111,16 +121,11 @@ class OSExchangeData { 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 + // 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); - // 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); // 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 @@ -131,9 +136,6 @@ class OSExchangeData { // Return the path of a file, if available. bool GetFilename(std::wstring* full_path) const; 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; // Test whether or not data of certain types is present, without actually // returning anything. @@ -152,6 +154,18 @@ class OSExchangeData { bool HasAnyFormat(int formats, const std::set<CustomFormat>& 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; +#endif + private: // Creates the platform specific Provider. static Provider* CreateProvider(); diff --git a/app/os_exchange_data_provider_gtk.cc b/app/os_exchange_data_provider_gtk.cc index 5b32907..597a5ae 100644 --- a/app/os_exchange_data_provider_gtk.cc +++ b/app/os_exchange_data_provider_gtk.cc @@ -7,7 +7,9 @@ #include <algorithm> #include "app/gtk_dnd_util.h" +#include "base/file_path.h" #include "base/string_util.h" +#include "net/base/net_util.h" OSExchangeDataProviderGtk::OSExchangeDataProviderGtk( int known_formats, @@ -53,15 +55,8 @@ GtkTargetList* OSExchangeDataProviderGtk::GetTargetList() const { OSExchangeData::URL); } - if ((formats_ & OSExchangeData::FILE_CONTENTS) != 0) - NOTIMPLEMENTED(); - if ((formats_ & OSExchangeData::FILE_NAME) != 0) - NOTIMPLEMENTED(); - - if ((formats_ & OSExchangeData::HTML) != 0) - NOTIMPLEMENTED(); - + gtk_target_list_add_uri_targets(targets, OSExchangeData::FILE_NAME); for (PickleData::const_iterator i = pickle_data_.begin(); i != pickle_data_.end(); ++i) { @@ -101,15 +96,14 @@ void OSExchangeDataProviderGtk::WriteFormatToSelection( free(uri_array[0]); } - if ((format & OSExchangeData::FILE_CONTENTS) != 0) - NOTIMPLEMENTED(); - - if ((format & OSExchangeData::FILE_NAME) != 0) - NOTIMPLEMENTED(); - - if ((format & OSExchangeData::HTML) != 0) - NOTIMPLEMENTED(); - + 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(); @@ -138,7 +132,7 @@ void OSExchangeDataProviderGtk::SetURL(const GURL& url, } void OSExchangeDataProviderGtk::SetFilename(const std::wstring& full_path) { - filename_ = WideToUTF16Hack(full_path); + filename_ = WideToUTF8(full_path); formats_ |= OSExchangeData::FILE_NAME; } @@ -148,21 +142,6 @@ void OSExchangeDataProviderGtk::SetPickledData(GdkAtom format, 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; @@ -172,8 +151,11 @@ bool OSExchangeDataProviderGtk::GetString(std::wstring* data) const { bool OSExchangeDataProviderGtk::GetURLAndTitle(GURL* url, std::wstring* title) const { - if ((formats_ & OSExchangeData::URL) == 0) - return false; + if ((formats_ & OSExchangeData::URL) == 0) { + title->clear(); + return GetPlainTextURL(url); + } + if (!url_.is_valid()) return false; @@ -185,7 +167,7 @@ bool OSExchangeDataProviderGtk::GetURLAndTitle(GURL* url, bool OSExchangeDataProviderGtk::GetFilename(std::wstring* full_path) const { if ((formats_ & OSExchangeData::FILE_NAME) == 0) return false; - *full_path = UTF16ToWideHack(filename_); + *full_path = UTF8ToWide(filename_); return true; } @@ -199,33 +181,18 @@ bool OSExchangeDataProviderGtk::GetPickledData(GdkAtom format, 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; + 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 { @@ -233,21 +200,24 @@ bool OSExchangeDataProviderGtk::HasFile() const { (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() || 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; +} + /////////////////////////////////////////////////////////////////////////////// // OSExchangeData, public: diff --git a/app/os_exchange_data_provider_gtk.h b/app/os_exchange_data_provider_gtk.h index 5974cde..ffbb182 100644 --- a/app/os_exchange_data_provider_gtk.h +++ b/app/os_exchange_data_provider_gtk.h @@ -59,27 +59,23 @@ class OSExchangeDataProviderGtk : public OSExchangeData::Provider { 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; + // 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_|. @@ -97,13 +93,8 @@ class OSExchangeDataProviderGtk : public OSExchangeData::Provider { GURL url_; string16 title_; - // File contents. - string16 filename_; - std::string file_contents_; - - // HTML contents. - string16 html_; - GURL base_url_; + // File name. + std::string filename_; // PICKLED_DATA contents. PickleData pickle_data_; diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 9a3f943..6b3b2f1 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -24,14 +24,19 @@ #include "third_party/skia/include/core/SkPath.h" #include "third_party/skia/include/core/SkShader.h" -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) #include "app/os_exchange_data.h" +#include "views/drag_utils.h" +#endif + +#if defined(TOOLKIT_VIEWS) && defined(OS_LINUX) +#include "app/drag_drop_types.h" +#include "views/widget/widget_gtk.h" #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 namespace download_util { @@ -72,7 +77,7 @@ SkBitmap* g_foreground_32 = NULL; SkBitmap* g_background_32 = NULL; void PaintDownloadProgress(gfx::Canvas* canvas, -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) views::View* containing_view, #endif int origin_x, @@ -102,7 +107,7 @@ void PaintDownloadProgress(gfx::Canvas* canvas, gfx::Rect foreground_bounds(origin_x, origin_y, foreground->width(), foreground->height()); -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) // Mirror the positions if necessary. int mirrored_x = containing_view->MirroredLeftPointForRect(background_bounds); background_bounds.set_x(mirrored_x); @@ -171,7 +176,7 @@ void PaintDownloadProgress(gfx::Canvas* canvas, } void PaintDownloadComplete(gfx::Canvas* canvas, -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) views::View* containing_view, #endif int origin_x, @@ -189,7 +194,7 @@ void PaintDownloadComplete(gfx::Canvas* canvas, gfx::Rect complete_bounds(origin_x, origin_y, complete->width(), complete->height()); -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) // Mirror the positions if necessary. complete_bounds.set_x( containing_view->MirroredLeftPointForRect(complete_bounds)); @@ -235,41 +240,50 @@ int GetBigProgressIconOffset() { return (GetBigProgressIconSize() - kBigIconSize) / 2; } -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) // Download dragging void DragDownload(const DownloadItem* download, SkBitmap* icon, gfx::NativeView view) { -#if defined(OS_WIN) DCHECK(download); // Set up our OLE machinery OSExchangeData data; - const FilePath::StringType file_name = download->file_name().value(); - if (icon) - drag_utils::CreateDragImageForFile(file_name, icon, &data); - data.SetFilename(download->full_path().ToWStringHack()); + if (icon) { + drag_utils::CreateDragImageForFile(download->file_name().value(), icon, + &data); + } const FilePath full_path = download->full_path(); - data.SetFilename(full_path.value()); + data.SetFilename(full_path.ToWStringHack()); std::string mime_type = download->mime_type(); if (mime_type.empty()) net::GetMimeTypeFromFile(full_path, &mime_type); // 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); + if (net::IsSupportedMimeType(mime_type)) { + data.SetURL(GURL(WideToUTF8(full_path.ToWStringHack())), + download->file_name().ToWStringHack()); + } +#if defined(OS_WIN) scoped_refptr<BaseDragSource> drag_source(new BaseDragSource); // Run the drag and drop loop DWORD effects; DoDragDrop(OSExchangeDataProviderWin::GetIDataObject(data), drag_source.get(), DROPEFFECT_COPY | DROPEFFECT_LINK, &effects); -#else - NOTIMPLEMENTED(); +#elif defined(OS_LINUX) + GtkWidget* root = gtk_widget_get_toplevel(view); + if (!root) + return; + views::WidgetGtk* widget = views::WidgetGtk::GetViewForNative(root); + if (!widget) + return; + + widget->DoDrag(data, DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK); #endif // OS_WIN } #endif diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h index 2093f34..0a320db 100644 --- a/chrome/browser/download/download_util.h +++ b/chrome/browser/download/download_util.h @@ -14,7 +14,7 @@ #include "base/gfx/native_widget_types.h" #include "base/task.h" -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) #include "views/view.h" #endif @@ -102,7 +102,7 @@ enum PaintDownloadProgressSize { // drawing in a right-to-left locale, we need to mirror the position of the // progress animation within the containing View. void PaintDownloadProgress(gfx::Canvas* canvas, -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) views::View* containing_view, #endif int origin_x, @@ -112,7 +112,7 @@ void PaintDownloadProgress(gfx::Canvas* canvas, PaintDownloadProgressSize size); void PaintDownloadComplete(gfx::Canvas* canvas, -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) +#if defined(TOOLKIT_VIEWS) views::View* containing_view, #endif int origin_x, @@ -120,12 +120,12 @@ void PaintDownloadComplete(gfx::Canvas* canvas, double animation_progress, PaintDownloadProgressSize size); -#if defined(OS_WIN) || defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) // Drag support ---------------------------------------------------------------- // Helper function for download views to use when acting as a drag source for a // DownloadItem. If |icon| is NULL, no image will be accompany the drag. |view| // is only required for Mac OS X, elsewhere it can be NULL. +#if defined(TOOLKIT_VIEWS) || defined(OS_MACOSX) void DragDownload(const DownloadItem* download, SkBitmap* icon, gfx::NativeView view); diff --git a/chrome/browser/views/download_item_view.cc b/chrome/browser/views/download_item_view.cc index 65fa198..61650b3 100644 --- a/chrome/browser/views/download_item_view.cc +++ b/chrome/browser/views/download_item_view.cc @@ -910,8 +910,11 @@ bool DownloadItemView::OnMouseDragged(const views::MouseEvent& event) { IconManager* im = g_browser_process->icon_manager(); SkBitmap* icon = im->LookupIcon(download_->full_path(), IconLoader::SMALL); - if (icon) - download_util::DragDownload(download_, icon, NULL); + if (icon) { + views::Widget* widget = GetWidget(); + download_util::DragDownload(download_, icon, + widget ? widget->GetNativeView() : NULL); + } } } else if (ExceededDragThreshold( event.location().x() - drag_start_point_.x(), @@ -3,4 +3,5 @@ include_rules = [ "+grit/app_strings.h", "+grit/app_resources.h", "+skia/ext", + "+net", ] diff --git a/views/drag_utils.cc b/views/drag_utils.cc index 7ba6a86..f1d9717 100644 --- a/views/drag_utils.cc +++ b/views/drag_utils.cc @@ -55,7 +55,7 @@ void SetURLAndDragImage(const GURL& url, data); } -void CreateDragImageForFile(const std::wstring& file_name, +void CreateDragImageForFile(const FilePath::StringType& file_name, SkBitmap* icon, OSExchangeData* data_object) { DCHECK(icon); @@ -74,15 +74,18 @@ void CreateDragImageForFile(const std::wstring& file_name, // Paint the icon. canvas.DrawBitmapInt(*icon, (width - icon->width()) / 2, 0); - // Paint the file name. We inset it one pixel to allow room for the halo. #if defined(OS_WIN) - const std::wstring& name = file_util::GetFilenameFromPath(file_name); + // Paint the file name. We inset it one pixel to allow room for the halo. + std::wstring name = file_util::GetFilenameFromPath(file_name); canvas.DrawStringWithHalo(name, font, kFileDragImageTextColor, SK_ColorWHITE, 1, icon->height() + kLinkDragImageVPadding + 1, width - 2, font.height(), gfx::Canvas::TEXT_ALIGN_CENTER); #else - NOTIMPLEMENTED(); + std::wstring name = file_util::GetFilenameFromPath(UTF8ToWide(file_name)); + canvas.DrawStringInt(name, font, kFileDragImageTextColor, + 0, icon->height() + kLinkDragImageVPadding, + width, font.height(), gfx::Canvas::TEXT_ALIGN_CENTER); #endif SetDragImageOnDataObject(canvas, width, height, width / 2, diff --git a/views/drag_utils.h b/views/drag_utils.h index e04e37e..5ce4def 100644 --- a/views/drag_utils.h +++ b/views/drag_utils.h @@ -7,6 +7,8 @@ #include <string> +#include "base/file_path.h" + namespace gfx { class Canvas; } @@ -27,7 +29,7 @@ void SetURLAndDragImage(const GURL& url, // Chrome (via the download manager, for example). The drag image is set into // the supplied data_object. 'file_name' can be a full path, but the directory // portion will be truncated in the drag image. -void CreateDragImageForFile(const std::wstring& file_name, +void CreateDragImageForFile(const FilePath::StringType& file_name, SkBitmap* icon, OSExchangeData* data_object); diff --git a/views/widget/drop_target_gtk.cc b/views/widget/drop_target_gtk.cc index 2947e63..62fc1a8 100644 --- a/views/widget/drop_target_gtk.cc +++ b/views/widget/drop_target_gtk.cc @@ -10,8 +10,10 @@ #include "app/drag_drop_types.h" #include "app/gtk_dnd_util.h" #include "app/os_exchange_data_provider_gtk.h" +#include "base/file_path.h" #include "base/gfx/point.h" #include "base/string_util.h" +#include "net/base/net_util.h" #include "views/widget/root_view.h" #include "views/widget/widget_gtk.h" @@ -27,14 +29,14 @@ std::string GdkAtomToString(GdkAtom atom) { // Returns true if |name| is a known name of plain text. bool IsTextType(const std::string& name) { return name == "text/plain" || name == "TEXT" || - name == "STRING" || name == "UTF8_STRING"; + name == "STRING" || name == "UTF8_STRING" || + name == "text/plain;charset=utf-8"; } // Returns the OSExchangeData::Formats in |targets| and all the // OSExchangeData::CustomFormats in |type_set|. int CalculateTypes(GList* targets, std::set<GdkAtom>* type_set) { int types = 0; - NOTIMPLEMENTED(); // Need to support FILE_NAME, FILE_CONTENTS for (GList* element = targets; element; element = g_list_next(element)) { GdkAtom atom = static_cast<GdkAtom>(element->data); @@ -42,15 +44,15 @@ int CalculateTypes(GList* targets, std::set<GdkAtom>* type_set) { if (atom == GDK_TARGET_STRING) { types |= OSExchangeData::STRING; } else if (atom == GtkDndUtil::GetAtomForTarget( - GtkDndUtil::CHROME_NAMED_URL) || - atom == GtkDndUtil::GetAtomForTarget( - GtkDndUtil::TEXT_URI_LIST)) { + GtkDndUtil::CHROME_NAMED_URL)) { types |= OSExchangeData::URL; + } else if (atom == GtkDndUtil::GetAtomForTarget( + GtkDndUtil::TEXT_URI_LIST)) { + // TEXT_URI_LIST is used for files as well as urls. + types |= OSExchangeData::URL | OSExchangeData::FILE_NAME; } else { std::string target_name = GdkAtomToString(atom); - if (target_name == "text/html") { - types |= OSExchangeData::HTML; - } else if (IsTextType(target_name)) { + if (IsTextType(target_name)) { types |= OSExchangeData::STRING; } else { // Assume any unknown data is pickled. @@ -117,16 +119,21 @@ void DropTargetGtk::OnDragDataReceived(GdkDragContext* context, GtkDndUtil::TEXT_URI_LIST)) { std::vector<GURL> urls; GtkDndUtil::ExtractURIList(data, &urls); - if (urls.size() == 1) { + if (urls.size() == 1 && urls[0].is_valid()) { data_provider().SetURL(urls[0], std::wstring()); + + // TEXT_URI_LIST is used for files as well as urls. + if (urls[0].SchemeIsFile()) { + FilePath file_path; + if (net::FileURLToFilePath(urls[0], &file_path)) + data_provider().SetFilename(file_path.ToWStringHack()); + } } else { // Consumers of OSExchangeData will see this as an invalid URL. That is, // when GetURL is invoked on the OSExchangeData this triggers false to // be returned. data_provider().SetURL(GURL(), std::wstring()); } - } else { - NOTIMPLEMENTED(); // Need to support FILE_NAME, FILE_CONTENTS, HTML. } if (!data_->HasAllFormats(requested_formats_, requested_custom_formats_)) @@ -271,6 +278,11 @@ void DropTargetGtk::RequestFormats(GdkDragContext* context, } else if (known_formats.count(gdk_atom_intern("text/plain", false))) { gtk_drag_get_data(widget, context, gdk_atom_intern("text/plain", false), time); + } else if (known_formats.count(gdk_atom_intern("text/plain;charset=utf-8", + false))) { + gtk_drag_get_data(widget, context, + gdk_atom_intern("text/plain;charset=utf-8", false), + time); } else if (known_formats.count(gdk_atom_intern("TEXT", false))) { gtk_drag_get_data(widget, context, gdk_atom_intern("TEXT", false), time); @@ -297,20 +309,12 @@ void DropTargetGtk::RequestFormats(GdkDragContext* context, GtkDndUtil::TEXT_URI_LIST), time); } } - if ((formats & OSExchangeData::FILE_CONTENTS) != 0 && - (requested_formats_ & OSExchangeData::FILE_CONTENTS) == 0) { - requested_formats_ |= OSExchangeData::FILE_CONTENTS; - NOTIMPLEMENTED(); - } if (((formats & OSExchangeData::FILE_NAME) != 0) && (requested_formats_ & OSExchangeData::FILE_NAME) == 0) { requested_formats_ |= OSExchangeData::FILE_NAME; - NOTIMPLEMENTED(); - } - if ((formats & OSExchangeData::HTML) != 0 && - (requested_formats_ & OSExchangeData::HTML) == 0) { - requested_formats_ |= OSExchangeData::HTML; - NOTIMPLEMENTED(); + gtk_drag_get_data(widget, context, + GtkDndUtil::GetAtomForTarget( + GtkDndUtil::TEXT_URI_LIST), time); } for (std::set<GdkAtom>::const_iterator i = custom_formats.begin(); i != custom_formats.end(); ++i) { |