// 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); }