[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / ui / views / bookmarks / bookmark_editor_view.cc
blob4d4f36373a164403d6e391ee319c5e0b23cb8b80
1 // Copyright (c) 2012 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 "chrome/browser/ui/views/bookmarks/bookmark_editor_view.h"
7 #include <string>
9 #include "base/basictypes.h"
10 #include "base/logging.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
15 #include "chrome/browser/history/history_service.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
18 #include "chrome/browser/ui/views/constrained_window_views.h"
19 #include "chrome/common/net/url_fixer_upper.h"
20 #include "components/bookmarks/browser/bookmark_model.h"
21 #include "components/bookmarks/browser/bookmark_utils.h"
22 #include "components/user_prefs/user_prefs.h"
23 #include "grit/chromium_strings.h"
24 #include "grit/generated_resources.h"
25 #include "grit/locale_settings.h"
26 #include "ui/accessibility/ax_view_state.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "ui/events/event.h"
29 #include "ui/views/background.h"
30 #include "ui/views/controls/button/label_button.h"
31 #include "ui/views/controls/label.h"
32 #include "ui/views/controls/menu/menu_runner.h"
33 #include "ui/views/controls/textfield/textfield.h"
34 #include "ui/views/controls/tree/tree_view.h"
35 #include "ui/views/focus/focus_manager.h"
36 #include "ui/views/layout/grid_layout.h"
37 #include "ui/views/layout/layout_constants.h"
38 #include "ui/views/widget/widget.h"
39 #include "ui/views/window/dialog_client_view.h"
40 #include "url/gurl.h"
42 using views::GridLayout;
44 namespace {
46 // Background color of text field when URL is invalid.
47 const SkColor kErrorColor = SkColorSetRGB(0xFF, 0xBC, 0xBC);
49 } // namespace
51 // static
52 void BookmarkEditor::Show(gfx::NativeWindow parent_window,
53 Profile* profile,
54 const EditDetails& details,
55 Configuration configuration) {
56 DCHECK(profile);
57 BookmarkEditorView* editor = new BookmarkEditorView(profile,
58 details.parent_node, details, configuration);
59 editor->Show(parent_window);
62 BookmarkEditorView::BookmarkEditorView(
63 Profile* profile,
64 const BookmarkNode* parent,
65 const EditDetails& details,
66 BookmarkEditor::Configuration configuration)
67 : profile_(profile),
68 tree_view_(NULL),
69 url_label_(NULL),
70 url_tf_(NULL),
71 title_label_(NULL),
72 title_tf_(NULL),
73 parent_(parent),
74 details_(details),
75 running_menu_for_root_(false),
76 show_tree_(configuration == SHOW_TREE) {
77 DCHECK(profile);
78 Init();
81 BookmarkEditorView::~BookmarkEditorView() {
82 // The tree model is deleted before the view. Reset the model otherwise the
83 // tree will reference a deleted model.
84 if (tree_view_)
85 tree_view_->SetModel(NULL);
86 bb_model_->RemoveObserver(this);
89 base::string16 BookmarkEditorView::GetDialogButtonLabel(
90 ui::DialogButton button) const {
91 if (button == ui::DIALOG_BUTTON_OK)
92 return l10n_util::GetStringUTF16(IDS_SAVE);
93 return views::DialogDelegateView::GetDialogButtonLabel(button);
96 bool BookmarkEditorView::IsDialogButtonEnabled(ui::DialogButton button) const {
97 if (button == ui::DIALOG_BUTTON_OK) {
98 if (!bb_model_->loaded())
99 return false;
101 if (details_.GetNodeType() != BookmarkNode::FOLDER)
102 return GetInputURL().is_valid();
104 return true;
107 views::View* BookmarkEditorView::CreateExtraView() {
108 return new_folder_button_.get();
111 ui::ModalType BookmarkEditorView::GetModalType() const {
112 return ui::MODAL_TYPE_WINDOW;
115 bool BookmarkEditorView::CanResize() const {
116 return true;
119 base::string16 BookmarkEditorView::GetWindowTitle() const {
120 return l10n_util::GetStringUTF16(details_.GetWindowTitleId());
123 bool BookmarkEditorView::Accept() {
124 if (!IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)) {
125 if (details_.GetNodeType() != BookmarkNode::FOLDER) {
126 // The url is invalid, focus the url field.
127 url_tf_->SelectAll(true);
128 url_tf_->RequestFocus();
130 return false;
132 // Otherwise save changes and close the dialog box.
133 ApplyEdits();
134 return true;
137 gfx::Size BookmarkEditorView::GetPreferredSize() const {
138 if (!show_tree_)
139 return views::View::GetPreferredSize();
141 return gfx::Size(views::Widget::GetLocalizedContentsSize(
142 IDS_EDITBOOKMARK_DIALOG_WIDTH_CHARS,
143 IDS_EDITBOOKMARK_DIALOG_HEIGHT_LINES));
146 void BookmarkEditorView::OnTreeViewSelectionChanged(
147 views::TreeView* tree_view) {
150 bool BookmarkEditorView::CanEdit(views::TreeView* tree_view,
151 ui::TreeModelNode* node) {
152 // Only allow editting of children of the bookmark bar node and other node.
153 EditorNode* bb_node = tree_model_->AsNode(node);
154 return (bb_node->parent() && bb_node->parent()->parent());
157 void BookmarkEditorView::ContentsChanged(views::Textfield* sender,
158 const base::string16& new_contents) {
159 UserInputChanged();
162 bool BookmarkEditorView::HandleKeyEvent(views::Textfield* sender,
163 const ui::KeyEvent& key_event) {
164 return false;
167 void BookmarkEditorView::GetAccessibleState(ui::AXViewState* state) {
168 state->name =
169 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_TITLE);
170 state->role = ui::AX_ROLE_DIALOG;
173 void BookmarkEditorView::ButtonPressed(views::Button* sender,
174 const ui::Event& event) {
175 DCHECK_EQ(new_folder_button_.get(), sender);
176 NewFolder();
179 bool BookmarkEditorView::IsCommandIdChecked(int command_id) const {
180 return false;
183 bool BookmarkEditorView::IsCommandIdEnabled(int command_id) const {
184 switch (command_id) {
185 case IDS_EDIT:
186 case IDS_DELETE:
187 return !running_menu_for_root_;
188 case IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM:
189 return true;
190 default:
191 NOTREACHED();
192 return false;
196 bool BookmarkEditorView::GetAcceleratorForCommandId(
197 int command_id,
198 ui::Accelerator* accelerator) {
199 return GetWidget()->GetAccelerator(command_id, accelerator);
202 void BookmarkEditorView::ExecuteCommand(int command_id, int event_flags) {
203 DCHECK(tree_view_->GetSelectedNode());
204 if (command_id == IDS_EDIT) {
205 tree_view_->StartEditing(tree_view_->GetSelectedNode());
206 } else if (command_id == IDS_DELETE) {
207 EditorNode* node = tree_model_->AsNode(tree_view_->GetSelectedNode());
208 if (!node)
209 return;
210 if (node->value != 0) {
211 const BookmarkNode* b_node = GetBookmarkNodeByID(bb_model_, node->value);
212 if (!b_node->empty() &&
213 !chrome::ConfirmDeleteBookmarkNode(b_node,
214 GetWidget()->GetNativeWindow())) {
215 // The folder is not empty and the user didn't confirm.
216 return;
218 deletes_.push_back(node->value);
220 tree_model_->Remove(node->parent(), node);
221 } else {
222 DCHECK_EQ(IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM, command_id);
223 NewFolder();
227 void BookmarkEditorView::Show(gfx::NativeWindow parent) {
228 CreateBrowserModalDialogViews(this, parent);
229 UserInputChanged();
230 if (show_tree_ && bb_model_->loaded())
231 ExpandAndSelect();
232 GetWidget()->Show();
233 // Select all the text in the name Textfield.
234 title_tf_->SelectAll(true);
235 // Give focus to the name Textfield.
236 title_tf_->RequestFocus();
239 void BookmarkEditorView::ShowContextMenuForView(
240 views::View* source,
241 const gfx::Point& point,
242 ui::MenuSourceType source_type) {
243 DCHECK_EQ(tree_view_, source);
244 if (!tree_view_->GetSelectedNode())
245 return;
246 running_menu_for_root_ =
247 (tree_model_->GetParent(tree_view_->GetSelectedNode()) ==
248 tree_model_->GetRoot());
250 context_menu_runner_.reset(new views::MenuRunner(GetMenuModel()));
252 if (context_menu_runner_->RunMenuAt(
253 source->GetWidget()->GetTopLevelWidget(),
254 NULL,
255 gfx::Rect(point, gfx::Size()),
256 views::MENU_ANCHOR_TOPRIGHT,
257 source_type,
258 views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) ==
259 views::MenuRunner::MENU_DELETED) {
260 return;
264 void BookmarkEditorView::Init() {
265 bb_model_ = BookmarkModelFactory::GetForProfile(profile_);
266 DCHECK(bb_model_);
267 bb_model_->AddObserver(this);
269 title_label_ = new views::Label(
270 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NAME_LABEL));
272 base::string16 title;
273 GURL url;
274 if (details_.type == EditDetails::EXISTING_NODE) {
275 title = details_.existing_node->GetTitle();
276 url = details_.existing_node->url();
277 } else if (details_.type == EditDetails::NEW_FOLDER) {
278 title = l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME);
279 } else if (details_.type == EditDetails::NEW_URL) {
280 url = details_.url;
281 title = details_.title;
283 title_tf_ = new views::Textfield;
284 title_tf_->SetAccessibleName(
285 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_EDITOR_NAME_LABEL));
286 title_tf_->SetText(title);
287 title_tf_->set_controller(this);
289 if (show_tree_) {
290 tree_view_ = new views::TreeView;
291 tree_view_->SetRootShown(false);
292 tree_view_->set_context_menu_controller(this);
294 new_folder_button_.reset(new views::LabelButton(this,
295 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_BUTTON)));
296 new_folder_button_->SetStyle(views::Button::STYLE_BUTTON);
297 new_folder_button_->set_owned_by_client();
298 new_folder_button_->SetEnabled(false);
301 GridLayout* layout = GridLayout::CreatePanel(this);
302 SetLayoutManager(layout);
304 const int labels_column_set_id = 0;
305 const int single_column_view_set_id = 1;
306 const int buttons_column_set_id = 2;
308 views::ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id);
309 column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
310 GridLayout::USE_PREF, 0, 0);
311 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
312 column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
313 GridLayout::USE_PREF, 0, 0);
315 column_set = layout->AddColumnSet(single_column_view_set_id);
316 column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1,
317 GridLayout::USE_PREF, 0, 0);
319 column_set = layout->AddColumnSet(buttons_column_set_id);
320 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
321 GridLayout::USE_PREF, 0, 0);
322 column_set->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing);
323 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
324 GridLayout::USE_PREF, 0, 0);
325 column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
326 column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0,
327 GridLayout::USE_PREF, 0, 0);
328 column_set->LinkColumnSizes(0, 2, 4, -1);
330 layout->StartRow(0, labels_column_set_id);
331 layout->AddView(title_label_);
332 layout->AddView(title_tf_);
334 if (details_.GetNodeType() != BookmarkNode::FOLDER) {
335 url_label_ = new views::Label(
336 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_URL_LABEL));
338 url_tf_ = new views::Textfield;
339 PrefService* prefs =
340 profile_ ? user_prefs::UserPrefs::Get(profile_) : NULL;
341 url_tf_->SetText(chrome::FormatBookmarkURLForDisplay(url, prefs));
342 url_tf_->set_controller(this);
343 url_tf_->SetAccessibleName(
344 l10n_util::GetStringUTF16(IDS_BOOKMARK_AX_EDITOR_URL_LABEL));
346 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
348 layout->StartRow(0, labels_column_set_id);
349 layout->AddView(url_label_);
350 layout->AddView(url_tf_);
353 if (show_tree_) {
354 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
355 layout->StartRow(1, single_column_view_set_id);
356 layout->AddView(tree_view_->CreateParentIfNecessary());
359 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
361 if (!show_tree_ || bb_model_->loaded())
362 Reset();
365 void BookmarkEditorView::BookmarkNodeMoved(BookmarkModel* model,
366 const BookmarkNode* old_parent,
367 int old_index,
368 const BookmarkNode* new_parent,
369 int new_index) {
370 Reset();
373 void BookmarkEditorView::BookmarkNodeAdded(BookmarkModel* model,
374 const BookmarkNode* parent,
375 int index) {
376 Reset();
379 void BookmarkEditorView::BookmarkNodeRemoved(
380 BookmarkModel* model,
381 const BookmarkNode* parent,
382 int index,
383 const BookmarkNode* node,
384 const std::set<GURL>& removed_urls) {
385 if ((details_.type == EditDetails::EXISTING_NODE &&
386 details_.existing_node->HasAncestor(node)) ||
387 (parent_ && parent_->HasAncestor(node))) {
388 // The node, or its parent was removed. Close the dialog.
389 GetWidget()->Close();
390 } else {
391 Reset();
395 void BookmarkEditorView::BookmarkAllNodesRemoved(
396 BookmarkModel* model,
397 const std::set<GURL>& removed_urls) {
398 Reset();
401 void BookmarkEditorView::BookmarkNodeChildrenReordered(
402 BookmarkModel* model,
403 const BookmarkNode* node) {
404 Reset();
407 void BookmarkEditorView::Reset() {
408 if (!show_tree_) {
409 if (parent())
410 UserInputChanged();
411 return;
414 new_folder_button_->SetEnabled(true);
416 // Do this first, otherwise when we invoke SetModel with the real one
417 // tree_view will try to invoke something on the model we just deleted.
418 tree_view_->SetModel(NULL);
420 EditorNode* root_node = CreateRootNode();
421 tree_model_.reset(new EditorTreeModel(root_node));
423 tree_view_->SetModel(tree_model_.get());
424 tree_view_->SetController(this);
426 context_menu_runner_.reset();
428 if (parent())
429 ExpandAndSelect();
432 GURL BookmarkEditorView::GetInputURL() const {
433 if (details_.GetNodeType() == BookmarkNode::FOLDER)
434 return GURL();
435 return URLFixerUpper::FixupURL(
436 base::UTF16ToUTF8(url_tf_->text()), std::string());
439 void BookmarkEditorView::UserInputChanged() {
440 if (details_.GetNodeType() != BookmarkNode::FOLDER) {
441 const GURL url(GetInputURL());
442 if (!url.is_valid())
443 url_tf_->SetBackgroundColor(kErrorColor);
444 else
445 url_tf_->UseDefaultBackgroundColor();
447 GetDialogClientView()->UpdateDialogButtons();
450 void BookmarkEditorView::NewFolder() {
451 // Create a new entry parented to the selected item, or the bookmark
452 // bar if nothing is selected.
453 EditorNode* parent = tree_model_->AsNode(tree_view_->GetSelectedNode());
454 if (!parent) {
455 NOTREACHED();
456 return;
459 tree_view_->StartEditing(AddNewFolder(parent));
462 BookmarkEditorView::EditorNode* BookmarkEditorView::AddNewFolder(
463 EditorNode* parent) {
464 EditorNode* new_node = new EditorNode(
465 l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME), 0);
466 // |new_node| is now owned by |parent|.
467 tree_model_->Add(parent, new_node, parent->child_count());
468 return new_node;
471 void BookmarkEditorView::ExpandAndSelect() {
472 BookmarkExpandedStateTracker::Nodes expanded_nodes =
473 bb_model_->expanded_state_tracker()->GetExpandedNodes();
474 for (BookmarkExpandedStateTracker::Nodes::const_iterator i(
475 expanded_nodes.begin()); i != expanded_nodes.end(); ++i) {
476 EditorNode* editor_node =
477 FindNodeWithID(tree_model_->GetRoot(), (*i)->id());
478 if (editor_node)
479 tree_view_->Expand(editor_node);
482 const BookmarkNode* to_select = parent_;
483 if (details_.type == EditDetails::EXISTING_NODE)
484 to_select = details_.existing_node->parent();
485 int64 folder_id_to_select = to_select->id();
486 EditorNode* b_node =
487 FindNodeWithID(tree_model_->GetRoot(), folder_id_to_select);
488 if (!b_node)
489 b_node = tree_model_->GetRoot()->GetChild(0); // Bookmark bar node.
491 tree_view_->SetSelectedNode(b_node);
494 BookmarkEditorView::EditorNode* BookmarkEditorView::CreateRootNode() {
495 EditorNode* root_node = new EditorNode(base::string16(), 0);
496 const BookmarkNode* bb_root_node = bb_model_->root_node();
497 CreateNodes(bb_root_node, root_node);
498 DCHECK(root_node->child_count() >= 2 && root_node->child_count() <= 3);
499 DCHECK_EQ(BookmarkNode::BOOKMARK_BAR, bb_root_node->GetChild(0)->type());
500 DCHECK_EQ(BookmarkNode::OTHER_NODE, bb_root_node->GetChild(1)->type());
501 if (root_node->child_count() == 3)
502 DCHECK_EQ(BookmarkNode::MOBILE, bb_root_node->GetChild(2)->type());
503 return root_node;
506 void BookmarkEditorView::CreateNodes(const BookmarkNode* bb_node,
507 BookmarkEditorView::EditorNode* b_node) {
508 for (int i = 0; i < bb_node->child_count(); ++i) {
509 const BookmarkNode* child_bb_node = bb_node->GetChild(i);
510 if (child_bb_node->IsVisible() && child_bb_node->is_folder()) {
511 EditorNode* new_b_node = new EditorNode(child_bb_node->GetTitle(),
512 child_bb_node->id());
513 b_node->Add(new_b_node, b_node->child_count());
514 CreateNodes(child_bb_node, new_b_node);
519 BookmarkEditorView::EditorNode* BookmarkEditorView::FindNodeWithID(
520 BookmarkEditorView::EditorNode* node,
521 int64 id) {
522 if (node->value == id)
523 return node;
524 for (int i = 0; i < node->child_count(); ++i) {
525 EditorNode* result = FindNodeWithID(node->GetChild(i), id);
526 if (result)
527 return result;
529 return NULL;
532 void BookmarkEditorView::ApplyEdits() {
533 DCHECK(bb_model_->loaded());
535 if (tree_view_)
536 tree_view_->CommitEdit();
538 EditorNode* parent = show_tree_ ?
539 tree_model_->AsNode(tree_view_->GetSelectedNode()) : NULL;
540 if (show_tree_ && !parent) {
541 NOTREACHED();
542 return;
544 ApplyEdits(parent);
547 void BookmarkEditorView::ApplyEdits(EditorNode* parent) {
548 DCHECK(!show_tree_ || parent);
550 // We're going to apply edits to the bookmark bar model, which will call us
551 // back. Normally when a structural edit occurs we reset the tree model.
552 // We don't want to do that here, so we remove ourselves as an observer.
553 bb_model_->RemoveObserver(this);
555 GURL new_url(GetInputURL());
556 base::string16 new_title(title_tf_->text());
558 if (!show_tree_) {
559 BookmarkEditor::ApplyEditsWithNoFolderChange(
560 bb_model_, parent_, details_, new_title, new_url);
561 return;
564 // Create the new folders and update the titles.
565 const BookmarkNode* new_parent = NULL;
566 ApplyNameChangesAndCreateNewFolders(
567 bb_model_->root_node(), tree_model_->GetRoot(), parent, &new_parent);
569 BookmarkEditor::ApplyEditsWithPossibleFolderChange(
570 bb_model_, new_parent, details_, new_title, new_url);
572 BookmarkExpandedStateTracker::Nodes expanded_nodes;
573 UpdateExpandedNodes(tree_model_->GetRoot(), &expanded_nodes);
574 bb_model_->expanded_state_tracker()->SetExpandedNodes(expanded_nodes);
576 // Remove the folders that were removed. This has to be done after all the
577 // other changes have been committed.
578 bookmark_utils::DeleteBookmarkFolders(bb_model_, deletes_);
581 void BookmarkEditorView::ApplyNameChangesAndCreateNewFolders(
582 const BookmarkNode* bb_node,
583 BookmarkEditorView::EditorNode* b_node,
584 BookmarkEditorView::EditorNode* parent_b_node,
585 const BookmarkNode** parent_bb_node) {
586 if (parent_b_node == b_node)
587 *parent_bb_node = bb_node;
588 for (int i = 0; i < b_node->child_count(); ++i) {
589 EditorNode* child_b_node = b_node->GetChild(i);
590 const BookmarkNode* child_bb_node = NULL;
591 if (child_b_node->value == 0) {
592 // New folder.
593 child_bb_node = bb_model_->AddFolder(bb_node,
594 bb_node->child_count(), child_b_node->GetTitle());
595 child_b_node->value = child_bb_node->id();
596 } else {
597 // Existing node, reset the title (BookmarkModel ignores changes if the
598 // title is the same).
599 for (int j = 0; j < bb_node->child_count(); ++j) {
600 const BookmarkNode* node = bb_node->GetChild(j);
601 if (node->is_folder() && node->id() == child_b_node->value) {
602 child_bb_node = node;
603 break;
606 DCHECK(child_bb_node);
607 bb_model_->SetTitle(child_bb_node, child_b_node->GetTitle());
609 ApplyNameChangesAndCreateNewFolders(child_bb_node, child_b_node,
610 parent_b_node, parent_bb_node);
614 void BookmarkEditorView::UpdateExpandedNodes(
615 EditorNode* editor_node,
616 BookmarkExpandedStateTracker::Nodes* expanded_nodes) {
617 if (!tree_view_->IsExpanded(editor_node))
618 return;
620 if (editor_node->value != 0) // The root is 0.
621 expanded_nodes->insert(GetBookmarkNodeByID(bb_model_, editor_node->value));
623 for (int i = 0; i < editor_node->child_count(); ++i)
624 UpdateExpandedNodes(editor_node->GetChild(i), expanded_nodes);
627 ui::SimpleMenuModel* BookmarkEditorView::GetMenuModel() {
628 if (!context_menu_model_.get()) {
629 context_menu_model_.reset(new ui::SimpleMenuModel(this));
630 context_menu_model_->AddItemWithStringId(IDS_EDIT, IDS_EDIT);
631 context_menu_model_->AddItemWithStringId(IDS_DELETE, IDS_DELETE);
632 context_menu_model_->AddItemWithStringId(
633 IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM,
634 IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM);
636 return context_menu_model_.get();
639 void BookmarkEditorView::EditorTreeModel::SetTitle(
640 ui::TreeModelNode* node,
641 const base::string16& title) {
642 if (!title.empty())
643 ui::TreeNodeModel<EditorNode>::SetTitle(node, title);