OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/base/x/selection_utils.h" | 5 #include "ui/base/x/selection_utils.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 | 8 |
| 9 #include "base/i18n/icu_string_conversions.h" |
9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/utf_string_conversions.h" |
| 12 #include "ui/base/clipboard/clipboard.h" |
10 #include "ui/base/x/x11_atom_cache.h" | 13 #include "ui/base/x/x11_atom_cache.h" |
11 | 14 |
12 namespace ui { | 15 namespace ui { |
13 | 16 |
| 17 const char kMimeTypeMozillaURL[] = "text/x-moz-url"; |
| 18 const char kString[] = "STRING"; |
| 19 const char kText[] = "TEXT"; |
| 20 const char kUtf8String[] = "UTF8_STRING"; |
| 21 |
| 22 const char* kSelectionDataAtoms[] = { |
| 23 Clipboard::kMimeTypeHTML, |
| 24 kString, |
| 25 kText, |
| 26 kUtf8String, |
| 27 NULL |
| 28 }; |
| 29 |
14 std::vector< ::Atom> GetTextAtomsFrom(const X11AtomCache* atom_cache) { | 30 std::vector< ::Atom> GetTextAtomsFrom(const X11AtomCache* atom_cache) { |
15 std::vector< ::Atom> atoms; | 31 std::vector< ::Atom> atoms; |
16 atoms.push_back(atom_cache->GetAtom("UTF8_STRING")); | 32 atoms.push_back(atom_cache->GetAtom(kString)); |
17 atoms.push_back(atom_cache->GetAtom("STRING")); | 33 atoms.push_back(atom_cache->GetAtom(kText)); |
18 atoms.push_back(atom_cache->GetAtom("TEXT")); | 34 atoms.push_back(atom_cache->GetAtom(kUtf8String)); |
19 return atoms; | 35 return atoms; |
20 } | 36 } |
21 | 37 |
| 38 std::vector< ::Atom> GetURLAtomsFrom(const X11AtomCache* atom_cache) { |
| 39 std::vector< ::Atom> atoms; |
| 40 atoms.push_back(atom_cache->GetAtom(Clipboard::kMimeTypeURIList)); |
| 41 atoms.push_back(atom_cache->GetAtom(kMimeTypeMozillaURL)); |
| 42 return atoms; |
| 43 } |
| 44 |
| 45 void GetAtomIntersection(const std::vector< ::Atom>& one, |
| 46 const std::vector< ::Atom>& two, |
| 47 std::vector< ::Atom>* output) { |
| 48 for (std::vector< ::Atom>::const_iterator it = one.begin(); it != one.end(); |
| 49 ++it) { |
| 50 for (std::vector< ::Atom>::const_iterator jt = two.begin(); jt != two.end(); |
| 51 ++jt) { |
| 52 if (*it == *jt) { |
| 53 output->push_back(*it); |
| 54 break; |
| 55 } |
| 56 } |
| 57 } |
| 58 } |
| 59 |
22 /////////////////////////////////////////////////////////////////////////////// | 60 /////////////////////////////////////////////////////////////////////////////// |
23 | 61 |
24 SelectionFormatMap::SelectionFormatMap() {} | 62 SelectionFormatMap::SelectionFormatMap() {} |
25 | 63 |
26 SelectionFormatMap::~SelectionFormatMap() { | 64 SelectionFormatMap::~SelectionFormatMap() { |
27 // WriteText() inserts the same pointer multiple times for different | 65 // WriteText() inserts the same pointer multiple times for different |
28 // representations; we need to dedupe it. | 66 // representations; we need to dedupe it. |
29 std::set<char*> to_delete; | 67 std::set<char*> to_delete; |
30 for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) | 68 for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) |
31 to_delete.insert(it->second.first); | 69 to_delete.insert(it->second.first); |
32 | 70 |
33 for (std::set<char*>::iterator it = to_delete.begin(); it != to_delete.end(); | 71 for (std::set<char*>::iterator it = to_delete.begin(); it != to_delete.end(); |
34 ++it) { | 72 ++it) { |
35 delete [] *it; | 73 delete [] *it; |
36 } | 74 } |
37 } | 75 } |
38 | 76 |
39 void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) { | 77 void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) { |
40 DCHECK(data_.find(atom) == data_.end()); | 78 DCHECK(data_.find(atom) == data_.end()); |
41 data_.insert(std::make_pair(atom, std::make_pair(data, size))); | 79 data_.insert(std::make_pair(atom, std::make_pair(data, size))); |
42 } | 80 } |
43 | 81 |
| 82 /////////////////////////////////////////////////////////////////////////////// |
| 83 |
| 84 SelectionData::SelectionData(Display* x_display) |
| 85 : type_(None), |
| 86 data_(NULL), |
| 87 size_(0), |
| 88 owned_(false), |
| 89 atom_cache_(x_display, kSelectionDataAtoms) { |
| 90 } |
| 91 |
| 92 SelectionData::~SelectionData() { |
| 93 if (owned_) |
| 94 XFree(data_); |
| 95 } |
| 96 |
| 97 void SelectionData::Set(::Atom type, char* data, size_t size, bool owned) { |
| 98 if (owned_) |
| 99 XFree(data_); |
| 100 |
| 101 type_ = type; |
| 102 data_ = data; |
| 103 size_ = size; |
| 104 owned_ = owned; |
| 105 } |
| 106 |
| 107 std::string SelectionData::GetText() const { |
| 108 if (type_ == atom_cache_.GetAtom(kUtf8String) || |
| 109 type_ == atom_cache_.GetAtom(kText)) { |
| 110 return std::string(data_, size_); |
| 111 } else if (type_ == atom_cache_.GetAtom(kString)) { |
| 112 std::string result; |
| 113 base::ConvertToUtf8AndNormalize(std::string(data_, size_), |
| 114 base::kCodepageLatin1, |
| 115 &result); |
| 116 return result; |
| 117 } else { |
| 118 // BTW, I looked at COMPOUND_TEXT, and there's no way we're going to |
| 119 // support that. Yuck. |
| 120 NOTREACHED(); |
| 121 return std::string(); |
| 122 } |
| 123 } |
| 124 |
| 125 string16 SelectionData::GetHtml() const { |
| 126 string16 markup; |
| 127 |
| 128 if (type_ == atom_cache_.GetAtom(Clipboard::kMimeTypeHTML)) { |
| 129 // If the data starts with 0xFEFF, i.e., Byte Order Mark, assume it is |
| 130 // UTF-16, otherwise assume UTF-8. |
| 131 if (size_ >= 2 && |
| 132 reinterpret_cast<const uint16_t*>(data_)[0] == 0xFEFF) { |
| 133 markup.assign(reinterpret_cast<const uint16_t*>(data_) + 1, |
| 134 (size_ / 2) - 1); |
| 135 } else { |
| 136 UTF8ToUTF16(reinterpret_cast<const char*>(data_), size_, &markup); |
| 137 } |
| 138 |
| 139 // If there is a terminating NULL, drop it. |
| 140 if (!markup.empty() && markup.at(markup.length() - 1) == '\0') |
| 141 markup.resize(markup.length() - 1); |
| 142 |
| 143 return markup; |
| 144 } else { |
| 145 NOTREACHED(); |
| 146 return markup; |
| 147 } |
| 148 } |
| 149 |
| 150 void SelectionData::AssignTo(std::string* result) const { |
| 151 result->assign(data_, size_); |
| 152 } |
| 153 |
| 154 void SelectionData::AssignTo(string16* result) const { |
| 155 result->assign(reinterpret_cast<base::char16*>(data_), size_ / 2); |
| 156 } |
| 157 |
44 } // namespace ui | 158 } // namespace ui |
OLD | NEW |