1// Copyright 2013 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#include "chrome/browser/ui/bookmarks/bookmark_editor.h"
6
7#include "base/logging.h"
8#include "chrome/grit/generated_resources.h"
9
10namespace {
11
12const BookmarkNode* CreateNewNode(BookmarkModel* model,
13                                  const BookmarkNode* parent,
14                                  const BookmarkEditor::EditDetails& details,
15                                  const base::string16& new_title,
16                                  const GURL& new_url) {
17  const BookmarkNode* node;
18  // When create the new one to right-clicked folder, add it to the next to the
19  // folder's position. Because |details.index| has a index of the folder when
20  // it was right-clicked, it might cause out of range exception when another
21  // bookmark manager edits contents of the folder.
22  // So we must check the range.
23  int child_count = parent->child_count();
24  int insert_index = (parent == details.parent_node && details.index >= 0 &&
25                      details.index <= child_count) ?
26                      details.index : child_count;
27  if (details.type == BookmarkEditor::EditDetails::NEW_URL) {
28    node = model->AddURL(parent, insert_index, new_title, new_url);
29  } else if (details.type == BookmarkEditor::EditDetails::NEW_FOLDER) {
30    node = model->AddFolder(parent, insert_index, new_title);
31    for (size_t i = 0; i < details.urls.size(); ++i) {
32      model->AddURL(node, node->child_count(), details.urls[i].second,
33                    details.urls[i].first);
34    }
35    model->SetDateFolderModified(parent, base::Time::Now());
36  } else {
37    NOTREACHED();
38    return NULL;
39  }
40
41  return node;
42}
43
44}  // namespace
45
46BookmarkEditor::EditDetails::EditDetails(Type node_type)
47    : type(node_type), existing_node(NULL), parent_node(NULL), index(-1) {
48}
49
50BookmarkNode::Type BookmarkEditor::EditDetails::GetNodeType() const {
51  BookmarkNode::Type node_type = BookmarkNode::URL;
52  switch (type) {
53    case EXISTING_NODE:
54      node_type = existing_node->type();
55      break;
56    case NEW_URL:
57      node_type = BookmarkNode::URL;
58      break;
59    case NEW_FOLDER:
60      node_type = BookmarkNode::FOLDER;
61      break;
62    default:
63      NOTREACHED();
64  }
65  return node_type;
66}
67
68int BookmarkEditor::EditDetails::GetWindowTitleId() const {
69  int dialog_title = IDS_BOOKMARK_EDITOR_TITLE;
70  switch (type) {
71    case EditDetails::EXISTING_NODE:
72    case EditDetails::NEW_URL:
73      dialog_title = (type == EditDetails::EXISTING_NODE &&
74                      existing_node->type() == BookmarkNode::FOLDER) ?
75          IDS_BOOKMARK_FOLDER_EDITOR_WINDOW_TITLE :
76          IDS_BOOKMARK_EDITOR_TITLE;
77      break;
78    case EditDetails::NEW_FOLDER:
79      dialog_title = urls.empty() ?
80          IDS_BOOKMARK_FOLDER_EDITOR_WINDOW_TITLE_NEW :
81          IDS_BOOKMARK_ALL_TABS_DIALOG_TITLE;
82      break;
83    default:
84      NOTREACHED();
85  }
86  return dialog_title;
87}
88
89BookmarkEditor::EditDetails BookmarkEditor::EditDetails::EditNode(
90    const BookmarkNode* node) {
91  EditDetails details(EXISTING_NODE);
92  details.existing_node = node;
93  if (node)
94    details.parent_node = node->parent();
95  return details;
96}
97
98BookmarkEditor::EditDetails BookmarkEditor::EditDetails::AddNodeInFolder(
99    const BookmarkNode* parent_node,
100    int index,
101    const GURL& url,
102    const base::string16& title) {
103  EditDetails details(NEW_URL);
104  details.parent_node = parent_node;
105  details.index = index;
106  details.url = url;
107  details.title = title;
108  return details;
109}
110
111BookmarkEditor::EditDetails BookmarkEditor::EditDetails::AddFolder(
112    const BookmarkNode* parent_node,
113    int index) {
114  EditDetails details(NEW_FOLDER);
115  details.parent_node = parent_node;
116  details.index = index;
117  return details;
118}
119
120BookmarkEditor::EditDetails::~EditDetails() {}
121
122// static
123const BookmarkNode* BookmarkEditor::ApplyEditsWithNoFolderChange(
124    BookmarkModel* model,
125    const BookmarkNode* parent,
126    const EditDetails& details,
127    const base::string16& new_title,
128    const GURL& new_url) {
129  if (details.type == EditDetails::NEW_URL ||
130      details.type == EditDetails::NEW_FOLDER) {
131    return CreateNewNode(model, parent, details, new_title, new_url);
132  }
133
134  const BookmarkNode* node = details.existing_node;
135  DCHECK(node);
136
137  if (node->is_url())
138    model->SetURL(node, new_url);
139  model->SetTitle(node, new_title);
140
141  return node;
142}
143
144// static
145const BookmarkNode* BookmarkEditor::ApplyEditsWithPossibleFolderChange(
146    BookmarkModel* model,
147    const BookmarkNode* new_parent,
148    const EditDetails& details,
149    const base::string16& new_title,
150    const GURL& new_url) {
151  if (details.type == EditDetails::NEW_URL ||
152      details.type == EditDetails::NEW_FOLDER) {
153    return CreateNewNode(model, new_parent, details, new_title, new_url);
154  }
155
156  const BookmarkNode* node = details.existing_node;
157  DCHECK(node);
158
159  if (new_parent != node->parent())
160    model->Move(node, new_parent, new_parent->child_count());
161  if (node->is_url())
162    model->SetURL(node, new_url);
163  model->SetTitle(node, new_title);
164
165  return node;
166}
167