| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/views/bookmarks/bookmark_editor_view.h" |
| |
| #include <string> |
| |
| #include "base/basictypes.h" |
| #include "base/logging.h" |
| #include "base/prefs/pref_service.h" |
| #include "base/strings/string_util.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "chrome/browser/bookmarks/bookmark_model.h" |
| #include "chrome/browser/bookmarks/bookmark_model_factory.h" |
| #include "chrome/browser/bookmarks/bookmark_utils.h" |
| #include "chrome/browser/history/history_service.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/bookmarks/bookmark_utils.h" |
| #include "chrome/browser/ui/views/constrained_window_views.h" |
| #include "chrome/common/net/url_fixer_upper.h" |
| #include "components/user_prefs/user_prefs.h" |
| #include "grit/chromium_strings.h" |
| #include "grit/generated_resources.h" |
| #include "grit/locale_settings.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/events/event.h" |
| #include "ui/views/background.h" |
| #include "ui/views/controls/button/label_button.h" |
| #include "ui/views/controls/label.h" |
| #include "ui/views/controls/menu/menu_runner.h" |
| #include "ui/views/controls/textfield/textfield.h" |
| #include "ui/views/controls/tree/tree_view.h" |
| #include "ui/views/focus/focus_manager.h" |
| #include "ui/views/layout/grid_layout.h" |
| #include "ui/views/layout/layout_constants.h" |
| #include "ui/views/widget/widget.h" |
| #include "ui/views/window/dialog_client_view.h" |
| #include "url/gurl.h" |
| |
| using views::GridLayout; |
| |
| namespace { |
| |
| // Background color of text field when URL is invalid. |
| const SkColor kErrorColor = SkColorSetRGB(0xFF, 0xBC, 0xBC); |
| |
| } // namespace |
| |
| // static |
| void BookmarkEditor::Show(gfx::NativeWindow parent_window, |
| Profile* profile, |
| const EditDetails& details, |
| Configuration configuration) { |
| DCHECK(profile); |
| BookmarkEditorView* editor = new BookmarkEditorView(profile, |
| details.parent_node, details, configuration); |
| editor->Show(parent_window); |
| } |
| |
| BookmarkEditorView::BookmarkEditorView( |
| Profile* profile, |
| const BookmarkNode* parent, |
| const EditDetails& details, |
| BookmarkEditor::Configuration configuration) |
| : profile_(profile), |
| tree_view_(NULL), |
| url_label_(NULL), |
| url_tf_(NULL), |
| title_label_(NULL), |
| title_tf_(NULL), |
| parent_(parent), |
| details_(details), |
| running_menu_for_root_(false), |
| show_tree_(configuration == SHOW_TREE) { |
| DCHECK(profile); |
| Init(); |
| } |
| |
| BookmarkEditorView::~BookmarkEditorView() { |
| // The tree model is deleted before the view. Reset the model otherwise the |
| // tree will reference a deleted model. |
| if (tree_view_) |
| tree_view_->SetModel(NULL); |
| bb_model_->RemoveObserver(this); |
| } |
| |
| string16 BookmarkEditorView::GetDialogButtonLabel( |
| ui::DialogButton button) const { |
| if (button == ui::DIALOG_BUTTON_OK) |
| return l10n_util::GetStringUTF16(IDS_SAVE); |
| return views::DialogDelegateView::GetDialogButtonLabel(button); |
| } |
| |
| bool BookmarkEditorView::IsDialogButtonEnabled(ui::DialogButton button) const { |
| if (button == ui::DIALOG_BUTTON_OK) { |
| if (!bb_model_->loaded()) |
| return false; |
| |
| if (details_.GetNodeType() != BookmarkNode::FOLDER) |
| return GetInputURL().is_valid(); |
| } |
| return true; |
| } |
| |
| views::View* BookmarkEditorView::CreateExtraView() { |
| return new_folder_button_.get(); |
| } |
| |
| ui::ModalType BookmarkEditorView::GetModalType() const { |
| return ui::MODAL_TYPE_WINDOW; |
| } |
| |
| bool BookmarkEditorView::CanResize() const { |
| return true; |
| } |
| |
| string16 BookmarkEditorView::GetWindowTitle() const { |
| return l10n_util::GetStringUTF16(details_.GetWindowTitleId()); |
| } |
| |
| bool BookmarkEditorView::Accept() { |
| if (!IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK)) { |
| if (details_.GetNodeType() != BookmarkNode::FOLDER) { |
| // The url is invalid, focus the url field. |
| url_tf_->SelectAll(true); |
| url_tf_->RequestFocus(); |
| } |
| return false; |
| } |
| // Otherwise save changes and close the dialog box. |
| ApplyEdits(); |
| return true; |
| } |
| |
| gfx::Size BookmarkEditorView::GetPreferredSize() { |
| if (!show_tree_) |
| return views::View::GetPreferredSize(); |
| |
| return gfx::Size(views::Widget::GetLocalizedContentsSize( |
| IDS_EDITBOOKMARK_DIALOG_WIDTH_CHARS, |
| IDS_EDITBOOKMARK_DIALOG_HEIGHT_LINES)); |
| } |
| |
| void BookmarkEditorView::OnTreeViewSelectionChanged( |
| views::TreeView* tree_view) { |
| } |
| |
| bool BookmarkEditorView::CanEdit(views::TreeView* tree_view, |
| ui::TreeModelNode* node) { |
| // Only allow editting of children of the bookmark bar node and other node. |
| EditorNode* bb_node = tree_model_->AsNode(node); |
| return (bb_node->parent() && bb_node->parent()->parent()); |
| } |
| |
| void BookmarkEditorView::ContentsChanged(views::Textfield* sender, |
| const string16& new_contents) { |
| UserInputChanged(); |
| } |
| |
| bool BookmarkEditorView::HandleKeyEvent(views::Textfield* sender, |
| const ui::KeyEvent& key_event) { |
| return false; |
| } |
| |
| void BookmarkEditorView::ButtonPressed(views::Button* sender, |
| const ui::Event& event) { |
| DCHECK_EQ(new_folder_button_.get(), sender); |
| NewFolder(); |
| } |
| |
| bool BookmarkEditorView::IsCommandIdChecked(int command_id) const { |
| return false; |
| } |
| |
| bool BookmarkEditorView::IsCommandIdEnabled(int command_id) const { |
| switch (command_id) { |
| case IDS_EDIT: |
| case IDS_DELETE: |
| return !running_menu_for_root_; |
| case IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM: |
| return true; |
| default: |
| NOTREACHED(); |
| return false; |
| } |
| } |
| |
| bool BookmarkEditorView::GetAcceleratorForCommandId( |
| int command_id, |
| ui::Accelerator* accelerator) { |
| return GetWidget()->GetAccelerator(command_id, accelerator); |
| } |
| |
| void BookmarkEditorView::ExecuteCommand(int command_id, int event_flags) { |
| DCHECK(tree_view_->GetSelectedNode()); |
| if (command_id == IDS_EDIT) { |
| tree_view_->StartEditing(tree_view_->GetSelectedNode()); |
| } else if (command_id == IDS_DELETE) { |
| EditorNode* node = tree_model_->AsNode(tree_view_->GetSelectedNode()); |
| if (!node) |
| return; |
| if (node->value != 0) { |
| const BookmarkNode* b_node = bb_model_->GetNodeByID(node->value); |
| if (!b_node->empty() && |
| !chrome::ConfirmDeleteBookmarkNode(b_node, |
| GetWidget()->GetNativeWindow())) { |
| // The folder is not empty and the user didn't confirm. |
| return; |
| } |
| deletes_.push_back(node->value); |
| } |
| tree_model_->Remove(node->parent(), node); |
| } else { |
| DCHECK_EQ(IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM, command_id); |
| NewFolder(); |
| } |
| } |
| |
| void BookmarkEditorView::Show(gfx::NativeWindow parent) { |
| CreateBrowserModalDialogViews(this, parent); |
| UserInputChanged(); |
| if (show_tree_ && bb_model_->loaded()) |
| ExpandAndSelect(); |
| GetWidget()->Show(); |
| // Select all the text in the name Textfield. |
| title_tf_->SelectAll(true); |
| // Give focus to the name Textfield. |
| title_tf_->RequestFocus(); |
| } |
| |
| void BookmarkEditorView::ShowContextMenuForView( |
| views::View* source, |
| const gfx::Point& point, |
| ui::MenuSourceType source_type) { |
| DCHECK_EQ(tree_view_, source); |
| if (!tree_view_->GetSelectedNode()) |
| return; |
| running_menu_for_root_ = |
| (tree_model_->GetParent(tree_view_->GetSelectedNode()) == |
| tree_model_->GetRoot()); |
| |
| context_menu_runner_.reset(new views::MenuRunner(GetMenuModel())); |
| |
| if (context_menu_runner_->RunMenuAt(source->GetWidget()->GetTopLevelWidget(), |
| NULL, gfx::Rect(point, gfx::Size()), views::MenuItemView::TOPRIGHT, |
| source_type, |
| views::MenuRunner::HAS_MNEMONICS | views::MenuRunner::CONTEXT_MENU) == |
| views::MenuRunner::MENU_DELETED) |
| return; |
| } |
| |
| void BookmarkEditorView::Init() { |
| bb_model_ = BookmarkModelFactory::GetForProfile(profile_); |
| DCHECK(bb_model_); |
| bb_model_->AddObserver(this); |
| |
| title_label_ = new views::Label( |
| l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NAME_LABEL)); |
| |
| string16 title; |
| GURL url; |
| if (details_.type == EditDetails::EXISTING_NODE) { |
| title = details_.existing_node->GetTitle(); |
| url = details_.existing_node->url(); |
| } else if (details_.type == EditDetails::NEW_FOLDER) { |
| title = l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME); |
| } else if (details_.type == EditDetails::NEW_URL) { |
| url = details_.url; |
| title = details_.title; |
| } |
| title_tf_ = new views::Textfield; |
| title_tf_->SetText(title); |
| title_tf_->SetController(this); |
| title_tf_->SetAccessibleName(title_label_->text()); |
| |
| if (show_tree_) { |
| tree_view_ = new views::TreeView; |
| tree_view_->SetRootShown(false); |
| tree_view_->set_context_menu_controller(this); |
| |
| new_folder_button_.reset(new views::LabelButton(this, |
| l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_BUTTON))); |
| new_folder_button_->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); |
| new_folder_button_->set_owned_by_client(); |
| new_folder_button_->SetEnabled(false); |
| } |
| |
| GridLayout* layout = GridLayout::CreatePanel(this); |
| SetLayoutManager(layout); |
| |
| const int labels_column_set_id = 0; |
| const int single_column_view_set_id = 1; |
| const int buttons_column_set_id = 2; |
| |
| views::ColumnSet* column_set = layout->AddColumnSet(labels_column_set_id); |
| column_set->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0, |
| GridLayout::USE_PREF, 0, 0); |
| column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); |
| column_set->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1, |
| GridLayout::USE_PREF, 0, 0); |
| |
| column_set = layout->AddColumnSet(single_column_view_set_id); |
| if (views::DialogDelegate::UseNewStyle()) { |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::USE_PREF, 0, 0); |
| } else { |
| column_set->AddColumn(GridLayout::FILL, GridLayout::FILL, 1, |
| GridLayout::FIXED, 300, 0); |
| } |
| |
| column_set = layout->AddColumnSet(buttons_column_set_id); |
| column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, |
| GridLayout::USE_PREF, 0, 0); |
| column_set->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing); |
| column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, |
| GridLayout::USE_PREF, 0, 0); |
| column_set->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); |
| column_set->AddColumn(GridLayout::FILL, GridLayout::LEADING, 0, |
| GridLayout::USE_PREF, 0, 0); |
| column_set->LinkColumnSizes(0, 2, 4, -1); |
| |
| layout->StartRow(0, labels_column_set_id); |
| layout->AddView(title_label_); |
| layout->AddView(title_tf_); |
| |
| if (details_.GetNodeType() != BookmarkNode::FOLDER) { |
| url_label_ = new views::Label( |
| l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_URL_LABEL)); |
| |
| url_tf_ = new views::Textfield; |
| PrefService* prefs = |
| profile_ ? user_prefs::UserPrefs::Get(profile_) : NULL; |
| url_tf_->SetText(chrome::FormatBookmarkURLForDisplay(url, prefs)); |
| url_tf_->SetController(this); |
| url_tf_->SetAccessibleName(url_label_->text()); |
| |
| layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| |
| layout->StartRow(0, labels_column_set_id); |
| layout->AddView(url_label_); |
| layout->AddView(url_tf_); |
| } |
| |
| if (show_tree_) { |
| layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| layout->StartRow(1, single_column_view_set_id); |
| layout->AddView(tree_view_->CreateParentIfNecessary()); |
| } |
| |
| layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); |
| |
| if (!show_tree_ || bb_model_->loaded()) |
| Reset(); |
| } |
| |
| void BookmarkEditorView::BookmarkNodeMoved(BookmarkModel* model, |
| const BookmarkNode* old_parent, |
| int old_index, |
| const BookmarkNode* new_parent, |
| int new_index) { |
| Reset(); |
| } |
| |
| void BookmarkEditorView::BookmarkNodeAdded(BookmarkModel* model, |
| const BookmarkNode* parent, |
| int index) { |
| Reset(); |
| } |
| |
| void BookmarkEditorView::BookmarkNodeRemoved(BookmarkModel* model, |
| const BookmarkNode* parent, |
| int index, |
| const BookmarkNode* node) { |
| if ((details_.type == EditDetails::EXISTING_NODE && |
| details_.existing_node->HasAncestor(node)) || |
| (parent_ && parent_->HasAncestor(node))) { |
| // The node, or its parent was removed. Close the dialog. |
| GetWidget()->Close(); |
| } else { |
| Reset(); |
| } |
| } |
| |
| void BookmarkEditorView::BookmarkAllNodesRemoved(BookmarkModel* model) { |
| Reset(); |
| } |
| |
| void BookmarkEditorView::BookmarkNodeChildrenReordered( |
| BookmarkModel* model, const BookmarkNode* node) { |
| Reset(); |
| } |
| |
| void BookmarkEditorView::Reset() { |
| if (!show_tree_) { |
| if (parent()) |
| UserInputChanged(); |
| return; |
| } |
| |
| new_folder_button_->SetEnabled(true); |
| |
| // Do this first, otherwise when we invoke SetModel with the real one |
| // tree_view will try to invoke something on the model we just deleted. |
| tree_view_->SetModel(NULL); |
| |
| EditorNode* root_node = CreateRootNode(); |
| tree_model_.reset(new EditorTreeModel(root_node)); |
| |
| tree_view_->SetModel(tree_model_.get()); |
| tree_view_->SetController(this); |
| |
| context_menu_runner_.reset(); |
| |
| if (parent()) |
| ExpandAndSelect(); |
| } |
| |
| GURL BookmarkEditorView::GetInputURL() const { |
| if (details_.GetNodeType() == BookmarkNode::FOLDER) |
| return GURL(); |
| return URLFixerUpper::FixupURL(UTF16ToUTF8(url_tf_->text()), std::string()); |
| } |
| |
| void BookmarkEditorView::UserInputChanged() { |
| if (details_.GetNodeType() != BookmarkNode::FOLDER) { |
| const GURL url(GetInputURL()); |
| if (!url.is_valid()) |
| url_tf_->SetBackgroundColor(kErrorColor); |
| else |
| url_tf_->UseDefaultBackgroundColor(); |
| } |
| GetDialogClientView()->UpdateDialogButtons(); |
| } |
| |
| void BookmarkEditorView::NewFolder() { |
| // Create a new entry parented to the selected item, or the bookmark |
| // bar if nothing is selected. |
| EditorNode* parent = tree_model_->AsNode(tree_view_->GetSelectedNode()); |
| if (!parent) { |
| NOTREACHED(); |
| return; |
| } |
| |
| tree_view_->StartEditing(AddNewFolder(parent)); |
| } |
| |
| BookmarkEditorView::EditorNode* BookmarkEditorView::AddNewFolder( |
| EditorNode* parent) { |
| EditorNode* new_node = new EditorNode( |
| l10n_util::GetStringUTF16(IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME), 0); |
| // |new_node| is now owned by |parent|. |
| tree_model_->Add(parent, new_node, parent->child_count()); |
| return new_node; |
| } |
| |
| void BookmarkEditorView::ExpandAndSelect() { |
| BookmarkExpandedStateTracker::Nodes expanded_nodes = |
| bb_model_->expanded_state_tracker()->GetExpandedNodes(); |
| for (BookmarkExpandedStateTracker::Nodes::const_iterator i( |
| expanded_nodes.begin()); i != expanded_nodes.end(); ++i) { |
| EditorNode* editor_node = |
| FindNodeWithID(tree_model_->GetRoot(), (*i)->id()); |
| if (editor_node) |
| tree_view_->Expand(editor_node); |
| } |
| |
| const BookmarkNode* to_select = parent_; |
| if (details_.type == EditDetails::EXISTING_NODE) |
| to_select = details_.existing_node->parent(); |
| int64 folder_id_to_select = to_select->id(); |
| EditorNode* b_node = |
| FindNodeWithID(tree_model_->GetRoot(), folder_id_to_select); |
| if (!b_node) |
| b_node = tree_model_->GetRoot()->GetChild(0); // Bookmark bar node. |
| |
| tree_view_->SetSelectedNode(b_node); |
| } |
| |
| BookmarkEditorView::EditorNode* BookmarkEditorView::CreateRootNode() { |
| EditorNode* root_node = new EditorNode(string16(), 0); |
| const BookmarkNode* bb_root_node = bb_model_->root_node(); |
| CreateNodes(bb_root_node, root_node); |
| DCHECK(root_node->child_count() >= 2 && root_node->child_count() <= 3); |
| DCHECK_EQ(BookmarkNode::BOOKMARK_BAR, bb_root_node->GetChild(0)->type()); |
| DCHECK_EQ(BookmarkNode::OTHER_NODE, bb_root_node->GetChild(1)->type()); |
| if (root_node->child_count() == 3) |
| DCHECK_EQ(BookmarkNode::MOBILE, bb_root_node->GetChild(2)->type()); |
| return root_node; |
| } |
| |
| void BookmarkEditorView::CreateNodes(const BookmarkNode* bb_node, |
| BookmarkEditorView::EditorNode* b_node) { |
| for (int i = 0; i < bb_node->child_count(); ++i) { |
| const BookmarkNode* child_bb_node = bb_node->GetChild(i); |
| if (child_bb_node->IsVisible() && child_bb_node->is_folder()) { |
| EditorNode* new_b_node = new EditorNode(child_bb_node->GetTitle(), |
| child_bb_node->id()); |
| b_node->Add(new_b_node, b_node->child_count()); |
| CreateNodes(child_bb_node, new_b_node); |
| } |
| } |
| } |
| |
| BookmarkEditorView::EditorNode* BookmarkEditorView::FindNodeWithID( |
| BookmarkEditorView::EditorNode* node, |
| int64 id) { |
| if (node->value == id) |
| return node; |
| for (int i = 0; i < node->child_count(); ++i) { |
| EditorNode* result = FindNodeWithID(node->GetChild(i), id); |
| if (result) |
| return result; |
| } |
| return NULL; |
| } |
| |
| void BookmarkEditorView::ApplyEdits() { |
| DCHECK(bb_model_->loaded()); |
| |
| if (tree_view_) |
| tree_view_->CommitEdit(); |
| |
| EditorNode* parent = show_tree_ ? |
| tree_model_->AsNode(tree_view_->GetSelectedNode()) : NULL; |
| if (show_tree_ && !parent) { |
| NOTREACHED(); |
| return; |
| } |
| ApplyEdits(parent); |
| } |
| |
| void BookmarkEditorView::ApplyEdits(EditorNode* parent) { |
| DCHECK(!show_tree_ || parent); |
| |
| // We're going to apply edits to the bookmark bar model, which will call us |
| // back. Normally when a structural edit occurs we reset the tree model. |
| // We don't want to do that here, so we remove ourselves as an observer. |
| bb_model_->RemoveObserver(this); |
| |
| GURL new_url(GetInputURL()); |
| string16 new_title(title_tf_->text()); |
| |
| if (!show_tree_) { |
| BookmarkEditor::ApplyEditsWithNoFolderChange( |
| bb_model_, parent_, details_, new_title, new_url); |
| return; |
| } |
| |
| // Create the new folders and update the titles. |
| const BookmarkNode* new_parent = NULL; |
| ApplyNameChangesAndCreateNewFolders( |
| bb_model_->root_node(), tree_model_->GetRoot(), parent, &new_parent); |
| |
| BookmarkEditor::ApplyEditsWithPossibleFolderChange( |
| bb_model_, new_parent, details_, new_title, new_url); |
| |
| BookmarkExpandedStateTracker::Nodes expanded_nodes; |
| UpdateExpandedNodes(tree_model_->GetRoot(), &expanded_nodes); |
| bb_model_->expanded_state_tracker()->SetExpandedNodes(expanded_nodes); |
| |
| // Remove the folders that were removed. This has to be done after all the |
| // other changes have been committed. |
| bookmark_utils::DeleteBookmarkFolders(bb_model_, deletes_); |
| } |
| |
| void BookmarkEditorView::ApplyNameChangesAndCreateNewFolders( |
| const BookmarkNode* bb_node, |
| BookmarkEditorView::EditorNode* b_node, |
| BookmarkEditorView::EditorNode* parent_b_node, |
| const BookmarkNode** parent_bb_node) { |
| if (parent_b_node == b_node) |
| *parent_bb_node = bb_node; |
| for (int i = 0; i < b_node->child_count(); ++i) { |
| EditorNode* child_b_node = b_node->GetChild(i); |
| const BookmarkNode* child_bb_node = NULL; |
| if (child_b_node->value == 0) { |
| // New folder. |
| child_bb_node = bb_model_->AddFolder(bb_node, |
| bb_node->child_count(), child_b_node->GetTitle()); |
| child_b_node->value = child_bb_node->id(); |
| } else { |
| // Existing node, reset the title (BookmarkModel ignores changes if the |
| // title is the same). |
| for (int j = 0; j < bb_node->child_count(); ++j) { |
| const BookmarkNode* node = bb_node->GetChild(j); |
| if (node->is_folder() && node->id() == child_b_node->value) { |
| child_bb_node = node; |
| break; |
| } |
| } |
| DCHECK(child_bb_node); |
| bb_model_->SetTitle(child_bb_node, child_b_node->GetTitle()); |
| } |
| ApplyNameChangesAndCreateNewFolders(child_bb_node, child_b_node, |
| parent_b_node, parent_bb_node); |
| } |
| } |
| |
| void BookmarkEditorView::UpdateExpandedNodes( |
| EditorNode* editor_node, |
| BookmarkExpandedStateTracker::Nodes* expanded_nodes) { |
| if (!tree_view_->IsExpanded(editor_node)) |
| return; |
| |
| if (editor_node->value != 0) // The root is 0 |
| expanded_nodes->insert(bb_model_->GetNodeByID(editor_node->value)); |
| for (int i = 0; i < editor_node->child_count(); ++i) |
| UpdateExpandedNodes(editor_node->GetChild(i), expanded_nodes); |
| } |
| |
| ui::SimpleMenuModel* BookmarkEditorView::GetMenuModel() { |
| if (!context_menu_model_.get()) { |
| context_menu_model_.reset(new ui::SimpleMenuModel(this)); |
| context_menu_model_->AddItemWithStringId(IDS_EDIT, IDS_EDIT); |
| context_menu_model_->AddItemWithStringId(IDS_DELETE, IDS_DELETE); |
| context_menu_model_->AddItemWithStringId( |
| IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM, |
| IDS_BOOKMARK_EDITOR_NEW_FOLDER_MENU_ITEM); |
| } |
| return context_menu_model_.get(); |
| } |
| |
| void BookmarkEditorView::EditorTreeModel::SetTitle(ui::TreeModelNode* node, |
| const string16& title) { |
| if (!title.empty()) |
| ui::TreeNodeModel<EditorNode>::SetTitle(node, title); |
| } |