closure: fix compile error by adding missing externs
[chromium-blink-merge.git] / components / bookmarks / browser / bookmark_node_data.cc
bloba781516fbf9c4440d4fde98d85272b17ec5b58f8
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/bookmarks/browser/bookmark_node_data.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/pickle.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "components/bookmarks/browser/bookmark_utils.h"
14 #include "ui/base/clipboard/scoped_clipboard_writer.h"
16 namespace bookmarks {
18 const char* BookmarkNodeData::kClipboardFormatString =
19 "chromium/x-bookmark-entries";
21 BookmarkNodeData::Element::Element() : is_url(false), id_(0) {
24 BookmarkNodeData::Element::Element(const BookmarkNode* node)
25 : is_url(node->is_url()),
26 url(node->url()),
27 title(node->GetTitle()),
28 date_added(node->date_added()),
29 date_folder_modified(node->date_folder_modified()),
30 id_(node->id()) {
31 if (node->GetMetaInfoMap())
32 meta_info_map = *node->GetMetaInfoMap();
33 for (int i = 0; i < node->child_count(); ++i)
34 children.push_back(Element(node->GetChild(i)));
37 BookmarkNodeData::Element::~Element() {
40 void BookmarkNodeData::Element::WriteToPickle(Pickle* pickle) const {
41 pickle->WriteBool(is_url);
42 pickle->WriteString(url.spec());
43 pickle->WriteString16(title);
44 pickle->WriteInt64(id_);
45 pickle->WriteSizeT(meta_info_map.size());
46 for (BookmarkNode::MetaInfoMap::const_iterator it = meta_info_map.begin();
47 it != meta_info_map.end(); ++it) {
48 pickle->WriteString(it->first);
49 pickle->WriteString(it->second);
51 if (!is_url) {
52 pickle->WriteSizeT(children.size());
53 for (std::vector<Element>::const_iterator i = children.begin();
54 i != children.end(); ++i) {
55 i->WriteToPickle(pickle);
60 bool BookmarkNodeData::Element::ReadFromPickle(PickleIterator* iterator) {
61 std::string url_spec;
62 if (!iterator->ReadBool(&is_url) ||
63 !iterator->ReadString(&url_spec) ||
64 !iterator->ReadString16(&title) ||
65 !iterator->ReadInt64(&id_)) {
66 return false;
68 url = GURL(url_spec);
69 date_added = base::Time();
70 date_folder_modified = base::Time();
71 meta_info_map.clear();
72 size_t meta_field_count;
73 if (!iterator->ReadSizeT(&meta_field_count))
74 return false;
75 for (size_t i = 0; i < meta_field_count; ++i) {
76 std::string key;
77 std::string value;
78 if (!iterator->ReadString(&key) ||
79 !iterator->ReadString(&value)) {
80 return false;
82 meta_info_map[key] = value;
84 children.clear();
85 if (!is_url) {
86 size_t children_count;
87 if (!iterator->ReadSizeT(&children_count))
88 return false;
89 children.reserve(children_count);
90 for (size_t i = 0; i < children_count; ++i) {
91 children.push_back(Element());
92 if (!children.back().ReadFromPickle(iterator))
93 return false;
96 return true;
99 // BookmarkNodeData -----------------------------------------------------------
101 BookmarkNodeData::BookmarkNodeData() {
104 BookmarkNodeData::BookmarkNodeData(const BookmarkNode* node) {
105 elements.push_back(Element(node));
108 BookmarkNodeData::BookmarkNodeData(
109 const std::vector<const BookmarkNode*>& nodes) {
110 ReadFromVector(nodes);
113 BookmarkNodeData::~BookmarkNodeData() {
116 #if !defined(OS_MACOSX)
117 // static
118 bool BookmarkNodeData::ClipboardContainsBookmarks() {
119 return ui::Clipboard::GetForCurrentThread()->IsFormatAvailable(
120 ui::Clipboard::GetFormatType(kClipboardFormatString),
121 ui::CLIPBOARD_TYPE_COPY_PASTE);
123 #endif
125 bool BookmarkNodeData::ReadFromVector(
126 const std::vector<const BookmarkNode*>& nodes) {
127 Clear();
129 if (nodes.empty())
130 return false;
132 for (size_t i = 0; i < nodes.size(); ++i)
133 elements.push_back(Element(nodes[i]));
135 return true;
138 bool BookmarkNodeData::ReadFromTuple(const GURL& url,
139 const base::string16& title) {
140 Clear();
142 if (!url.is_valid())
143 return false;
145 Element element;
146 element.title = title;
147 element.url = url;
148 element.is_url = true;
150 elements.push_back(element);
152 return true;
155 #if !defined(OS_MACOSX)
156 void BookmarkNodeData::WriteToClipboard(ui::ClipboardType clipboard_type) {
157 DCHECK(clipboard_type == ui::CLIPBOARD_TYPE_COPY_PASTE ||
158 clipboard_type == ui::CLIPBOARD_TYPE_SELECTION);
159 ui::ScopedClipboardWriter scw(clipboard_type);
161 // If there is only one element and it is a URL, write the URL to the
162 // clipboard.
163 if (has_single_url()) {
164 const base::string16& title = elements[0].title;
165 const std::string url = elements[0].url.spec();
167 scw.WriteBookmark(title, url);
169 // Don't call scw.WriteHyperlink() here, since some rich text editors will
170 // change fonts when such data is pasted in; besides, most such editors
171 // auto-linkify at some point anyway.
173 // Also write the URL to the clipboard as text so that it can be pasted
174 // into text fields. We use WriteText instead of WriteURL because we don't
175 // want to clobber the X clipboard when the user copies out of the omnibox
176 // on Linux (on Windows and Mac, there is no difference between these
177 // functions).
178 scw.WriteText(base::UTF8ToUTF16(url));
179 } else {
180 // We have either more than one URL, a folder, or a combination of URLs
181 // and folders.
182 base::string16 text;
183 for (size_t i = 0; i < size(); i++) {
184 text += i == 0 ? base::ASCIIToUTF16("") : base::ASCIIToUTF16("\n");
185 if (!elements[i].is_url) {
186 // Then it's a folder. Only copy the name of the folder.
187 const base::string16 title = elements[i].title;
188 text += title;
189 } else {
190 const base::string16 url = base::UTF8ToUTF16(elements[i].url.spec());
191 text += url;
194 scw.WriteText(text);
197 Pickle pickle;
198 WriteToPickle(base::FilePath(), &pickle);
199 scw.WritePickledData(pickle,
200 ui::Clipboard::GetFormatType(kClipboardFormatString));
203 bool BookmarkNodeData::ReadFromClipboard(ui::ClipboardType type) {
204 DCHECK_EQ(type, ui::CLIPBOARD_TYPE_COPY_PASTE);
205 std::string data;
206 ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
207 clipboard->ReadData(ui::Clipboard::GetFormatType(kClipboardFormatString),
208 &data);
210 if (!data.empty()) {
211 Pickle pickle(data.data(), static_cast<int>(data.size()));
212 if (ReadFromPickle(&pickle))
213 return true;
216 base::string16 title;
217 std::string url;
218 clipboard->ReadBookmark(&title, &url);
219 if (!url.empty()) {
220 Element element;
221 element.is_url = true;
222 element.url = GURL(url);
223 element.title = title;
225 elements.clear();
226 elements.push_back(element);
227 return true;
230 return false;
232 #endif
234 void BookmarkNodeData::WriteToPickle(const base::FilePath& profile_path,
235 Pickle* pickle) const {
236 profile_path.WriteToPickle(pickle);
237 pickle->WriteSizeT(size());
239 for (size_t i = 0; i < size(); ++i)
240 elements[i].WriteToPickle(pickle);
243 bool BookmarkNodeData::ReadFromPickle(Pickle* pickle) {
244 PickleIterator data_iterator(*pickle);
245 size_t element_count;
246 if (profile_path_.ReadFromPickle(&data_iterator) &&
247 data_iterator.ReadSizeT(&element_count)) {
248 std::vector<Element> tmp_elements;
249 tmp_elements.resize(element_count);
250 for (size_t i = 0; i < element_count; ++i) {
251 if (!tmp_elements[i].ReadFromPickle(&data_iterator)) {
252 return false;
255 elements.swap(tmp_elements);
258 return true;
261 std::vector<const BookmarkNode*> BookmarkNodeData::GetNodes(
262 BookmarkModel* model,
263 const base::FilePath& profile_path) const {
264 std::vector<const BookmarkNode*> nodes;
266 if (!IsFromProfilePath(profile_path))
267 return nodes;
269 for (size_t i = 0; i < size(); ++i) {
270 const BookmarkNode* node = GetBookmarkNodeByID(model, elements[i].id_);
271 if (!node) {
272 nodes.clear();
273 return nodes;
275 nodes.push_back(node);
277 return nodes;
280 const BookmarkNode* BookmarkNodeData::GetFirstNode(
281 BookmarkModel* model,
282 const base::FilePath& profile_path) const {
283 std::vector<const BookmarkNode*> nodes = GetNodes(model, profile_path);
284 return nodes.size() == 1 ? nodes[0] : NULL;
287 void BookmarkNodeData::Clear() {
288 profile_path_.clear();
289 elements.clear();
292 void BookmarkNodeData::SetOriginatingProfilePath(
293 const base::FilePath& profile_path) {
294 DCHECK(profile_path_.empty());
295 profile_path_ = profile_path;
298 bool BookmarkNodeData::IsFromProfilePath(
299 const base::FilePath& profile_path) const {
300 // An empty path means the data is not associated with any profile.
301 return !profile_path_.empty() && profile_path_ == profile_path;
304 } // namespace bookmarks