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/i18n/icu_string_conversions.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
12 #include "ui/base/clipboard/clipboard.h" | 12 #include "ui/base/clipboard/clipboard.h" |
13 #include "ui/base/x/x11_atom_cache.h" | 13 #include "ui/base/x/x11_atom_cache.h" |
14 #include "ui/base/x/x11_util.h" | |
14 | 15 |
15 namespace ui { | 16 namespace ui { |
16 | 17 |
17 const char kMimeTypeMozillaURL[] = "text/x-moz-url"; | 18 const char kMimeTypeMozillaURL[] = "text/x-moz-url"; |
18 const char kString[] = "STRING"; | 19 const char kString[] = "STRING"; |
19 const char kText[] = "TEXT"; | 20 const char kText[] = "TEXT"; |
20 const char kUtf8String[] = "UTF8_STRING"; | 21 const char kUtf8String[] = "UTF8_STRING"; |
21 | 22 |
22 const char* kSelectionDataAtoms[] = { | 23 const char* kSelectionDataAtoms[] = { |
23 Clipboard::kMimeTypeHTML, | 24 Clipboard::kMimeTypeHTML, |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
68 for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) | 69 for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) |
69 to_delete.insert(it->second.first); | 70 to_delete.insert(it->second.first); |
70 | 71 |
71 for (std::set<char*>::iterator it = to_delete.begin(); it != to_delete.end(); | 72 for (std::set<char*>::iterator it = to_delete.begin(); it != to_delete.end(); |
72 ++it) { | 73 ++it) { |
73 delete [] *it; | 74 delete [] *it; |
74 } | 75 } |
75 } | 76 } |
76 | 77 |
77 void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) { | 78 void SelectionFormatMap::Insert(::Atom atom, char* data, size_t size) { |
78 DCHECK(data_.find(atom) == data_.end()); | 79 // Views code often inserts the same content multiple times, so we have to |
80 // free old data. Only call delete when it's the last pointer we have to that | |
81 // data. | |
82 InternalMap::iterator exists_it = data_.find(atom); | |
83 if (exists_it != data_.end()) { | |
84 int count = 0; | |
85 for (InternalMap::iterator it = data_.begin(); it != data_.end(); ++it) { | |
86 if (it->second.first == exists_it->second.first) | |
87 count++; | |
88 } | |
89 | |
90 if (count == 1) | |
91 delete [] exists_it->second.first; | |
92 } | |
93 | |
79 data_.insert(std::make_pair(atom, std::make_pair(data, size))); | 94 data_.insert(std::make_pair(atom, std::make_pair(data, size))); |
80 } | 95 } |
81 | 96 |
97 ui::SelectionData* SelectionFormatMap::GetFirstOf( | |
98 const std::vector< ::Atom>& requested_types) const { | |
99 for (std::vector< ::Atom>::const_iterator it = requested_types.begin(); | |
100 it != requested_types.end(); ++it) { | |
101 const_iterator data_it = data_.find(*it); | |
102 if (data_it != data_.end()) { | |
103 ui::SelectionData* data = new SelectionData; | |
104 data->Set(data_it->first, data_it->second.first, data_it->second.second, | |
105 false); | |
106 return data; | |
107 } | |
108 } | |
109 | |
110 return NULL; | |
111 } | |
112 | |
113 std::vector< ::Atom> SelectionFormatMap::GetTypes() const { | |
114 std::vector< ::Atom> atoms; | |
115 for (const_iterator it = data_.begin(); it != data_.end(); ++it) | |
116 atoms.push_back(it->first); | |
117 | |
118 return atoms; | |
119 } | |
120 | |
121 SelectionFormatMap* SelectionFormatMap::Clone() const { | |
Daniel Erat
2013/06/17 22:09:57
return a scoped_ptr instead?
| |
122 SelectionFormatMap* ret = new SelectionFormatMap; | |
123 | |
124 for (const_iterator it = data_.begin(); it != data_.end(); ++it) { | |
125 char* data_copy = new char[it->second.second]; | |
126 memcpy(data_copy, it->second.first, it->second.second); | |
127 ret->Insert(it->first, data_copy, it->second.second); | |
128 } | |
129 | |
130 return ret; | |
131 } | |
132 | |
82 /////////////////////////////////////////////////////////////////////////////// | 133 /////////////////////////////////////////////////////////////////////////////// |
83 | 134 |
84 SelectionData::SelectionData(Display* x_display) | 135 SelectionData::SelectionData() |
85 : type_(None), | 136 : type_(None), |
86 data_(NULL), | 137 data_(NULL), |
87 size_(0), | 138 size_(0), |
88 owned_(false), | 139 owned_(false), |
89 atom_cache_(x_display, kSelectionDataAtoms) { | 140 atom_cache_(ui::GetXDisplay(), kSelectionDataAtoms) { |
90 } | 141 } |
91 | 142 |
92 SelectionData::~SelectionData() { | 143 SelectionData::~SelectionData() { |
93 if (owned_) | 144 if (owned_) |
94 XFree(data_); | 145 XFree(data_); |
95 } | 146 } |
96 | 147 |
97 void SelectionData::Set(::Atom type, char* data, size_t size, bool owned) { | 148 void SelectionData::Set(::Atom type, char* data, size_t size, bool owned) { |
98 if (owned_) | 149 if (owned_) |
99 XFree(data_); | 150 XFree(data_); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 | 200 |
150 void SelectionData::AssignTo(std::string* result) const { | 201 void SelectionData::AssignTo(std::string* result) const { |
151 result->assign(data_, size_); | 202 result->assign(data_, size_); |
152 } | 203 } |
153 | 204 |
154 void SelectionData::AssignTo(string16* result) const { | 205 void SelectionData::AssignTo(string16* result) const { |
155 result->assign(reinterpret_cast<base::char16*>(data_), size_ / 2); | 206 result->assign(reinterpret_cast<base::char16*>(data_), size_ / 2); |
156 } | 207 } |
157 | 208 |
158 } // namespace ui | 209 } // namespace ui |
OLD | NEW |