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.
4
5#ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_NODE_DATA_H_
6#define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_NODE_DATA_H_
7
8#include <vector>
9
10#include "base/files/file_path.h"
11#include "base/strings/string16.h"
12#include "base/time/time.h"
13#include "components/bookmarks/browser/bookmark_node.h"
14#include "ui/base/clipboard/clipboard_types.h"
15
16#include "url/gurl.h"
17#if defined(TOOLKIT_VIEWS)
18#include "ui/base/dragdrop/os_exchange_data.h"
19#endif
20
21class BookmarkModel;
22class Pickle;
23class PickleIterator;
24
25// BookmarkNodeData is used to represent the following:
26//
27// . A single URL.
28// . A single node from the bookmark model.
29// . A set of nodes from the bookmark model.
30//
31// BookmarkNodeData is used by bookmark related views to represent a dragged
32// bookmark or bookmarks.
33//
34// Typical usage when writing data for a drag is:
35//   BookmarkNodeData data(node_user_is_dragging);
36//   data.Write(os_exchange_data_for_drag);
37//
38// Typical usage to read is:
39//   BookmarkNodeData data;
40//   if (data.Read(os_exchange_data))
41//     // data is valid, contents are in elements.
42
43struct BookmarkNodeData {
44  // Element represents a single node.
45  struct Element {
46    Element();
47    explicit Element(const BookmarkNode* node);
48    ~Element();
49
50    // If true, this element represents a URL.
51    bool is_url;
52
53    // The URL, only valid if is_url is true.
54    GURL url;
55
56    // Title of the entry, used for both urls and folders.
57    base::string16 title;
58
59    // Date of when this node was created.
60    base::Time date_added;
61
62    // Date of the last modification. Only used for folders.
63    base::Time date_folder_modified;
64
65    // Children, only used for non-URL nodes.
66    std::vector<Element> children;
67
68    // Meta info for the bookmark node.
69    BookmarkNode::MetaInfoMap meta_info_map;
70
71    int64 id() const { return id_; }
72
73   private:
74    friend struct BookmarkNodeData;
75
76    // For reading/writing this Element.
77    void WriteToPickle(Pickle* pickle) const;
78    bool ReadFromPickle(Pickle* pickle, PickleIterator* iterator);
79
80    // ID of the node.
81    int64 id_;
82  };
83
84  // The MIME type for the clipboard format for BookmarkNodeData.
85  static const char* kClipboardFormatString;
86
87  BookmarkNodeData();
88
89  // Created a BookmarkNodeData populated from the arguments.
90  explicit BookmarkNodeData(const BookmarkNode* node);
91  explicit BookmarkNodeData(const std::vector<const BookmarkNode*>& nodes);
92
93  ~BookmarkNodeData();
94
95#if defined(TOOLKIT_VIEWS)
96  static const ui::OSExchangeData::CustomFormat& GetBookmarkCustomFormat();
97#endif
98
99  static bool ClipboardContainsBookmarks();
100
101  // Reads bookmarks from the given vector.
102  bool ReadFromVector(const std::vector<const BookmarkNode*>& nodes);
103
104  // Creates a single-bookmark DragData from url/title pair.
105  bool ReadFromTuple(const GURL& url, const base::string16& title);
106
107  // Writes bookmarks to the specified clipboard.
108  void WriteToClipboard(ui::ClipboardType type);
109
110  // Reads bookmarks from the specified clipboard. Prefers data written via
111  // WriteToClipboard() but will also attempt to read a plain bookmark.
112  bool ReadFromClipboard(ui::ClipboardType type);
113
114#if defined(TOOLKIT_VIEWS)
115  // Writes elements to data. If there is only one element and it is a URL
116  // the URL and title are written to the clipboard in a format other apps can
117  // use.
118  // |profile_path| is used to identify which profile the data came from. Use an
119  // empty path to indicate that the data is not associated with any profile.
120  void Write(const base::FilePath& profile_path,
121             ui::OSExchangeData* data) const;
122
123  // Restores this data from the clipboard, returning true on success.
124  bool Read(const ui::OSExchangeData& data);
125#endif
126
127  // Writes the data for a drag to |pickle|.
128  void WriteToPickle(const base::FilePath& profile_path, Pickle* pickle) const;
129
130  // Reads the data for a drag from a |pickle|.
131  bool ReadFromPickle(Pickle* pickle);
132
133  // Returns the nodes represented by this DragData. If this DragData was
134  // created from the same profile then the nodes from the model are returned.
135  // If the nodes can't be found (may have been deleted), an empty vector is
136  // returned.
137  std::vector<const BookmarkNode*> GetNodes(
138      BookmarkModel* model,
139      const base::FilePath& profile_path) const;
140
141  // Convenience for getting the first node. Returns NULL if the data doesn't
142  // match any nodes or there is more than one node.
143  const BookmarkNode* GetFirstNode(BookmarkModel* model,
144                                   const base::FilePath& profile_path) const;
145
146  // Do we contain valid data?
147  bool is_valid() const { return !elements.empty(); }
148
149  // Returns true if there is a single url.
150  bool has_single_url() const { return is_valid() && elements[0].is_url; }
151
152  // Number of elements.
153  size_t size() const { return elements.size(); }
154
155  // Clears the data.
156  void Clear();
157
158  // Sets |profile_path_|. This is useful for the constructors/readers that
159  // don't set it. This should only be called if the profile path is not
160  // already set.
161  void SetOriginatingProfilePath(const base::FilePath& profile_path);
162
163  // Returns true if this data is from the specified profile path.
164  bool IsFromProfilePath(const base::FilePath& profile_path) const;
165
166  // The actual elements written to the clipboard.
167  std::vector<Element> elements;
168
169 private:
170  // Path of the profile we originated from.
171  base::FilePath profile_path_;
172};
173
174#endif  // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_NODE_DATA_H_
175