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 #ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_
6 #define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_
10 #include "base/compiler_specific.h"
11 #include "base/gtest_prod_util.h"
12 #include "base/strings/string16.h"
13 #include "chrome/browser/ui/bookmarks/bookmark_editor.h"
14 #include "components/bookmarks/browser/bookmark_expanded_state_tracker.h"
15 #include "components/bookmarks/browser/bookmark_model_observer.h"
16 #include "ui/base/models/simple_menu_model.h"
17 #include "ui/base/models/tree_node_model.h"
18 #include "ui/views/context_menu_controller.h"
19 #include "ui/views/controls/button/button.h"
20 #include "ui/views/controls/textfield/textfield.h"
21 #include "ui/views/controls/textfield/textfield_controller.h"
22 #include "ui/views/controls/tree/tree_view_controller.h"
23 #include "ui/views/window/dialog_delegate.h"
32 class BookmarkEditorViewTest
;
37 // View that allows the user to edit a bookmark/starred URL. The user can
38 // change the URL, title and where the bookmark appears as well as adding
39 // new folders and changing the name of other folders. The editor is used for
40 // both editing a url bookmark, as well as editing a folder bookmark when
41 // created from 'Bookmark all tabs'.
43 // Edits are applied to the BookmarkModel when the user presses 'OK'.
45 // To use BookmarkEditorView invoke the static show method.
47 class BookmarkEditorView
: public BookmarkEditor
,
48 public views::ButtonListener
,
49 public views::TreeViewController
,
50 public views::DialogDelegateView
,
51 public views::TextfieldController
,
52 public views::ContextMenuController
,
53 public ui::SimpleMenuModel::Delegate
,
54 public bookmarks::BookmarkModelObserver
{
56 // Type of node in the tree. Public purely for testing.
57 typedef ui::TreeNodeWithValue
<int64
> EditorNode
;
59 // Model for the TreeView. Trivial subclass that doesn't allow titles with
60 // empty strings. Public purely for testing.
61 class EditorTreeModel
: public ui::TreeNodeModel
<EditorNode
> {
63 explicit EditorTreeModel(EditorNode
* root
)
64 : ui::TreeNodeModel
<EditorNode
>(root
) {}
66 void SetTitle(ui::TreeModelNode
* node
,
67 const base::string16
& title
) override
;
70 DISALLOW_COPY_AND_ASSIGN(EditorTreeModel
);
73 BookmarkEditorView(Profile
* profile
,
74 const bookmarks::BookmarkNode
* parent
,
75 const EditDetails
& details
,
76 BookmarkEditor::Configuration configuration
);
78 ~BookmarkEditorView() override
;
80 // views::DialogDelegateView:
81 base::string16
GetDialogButtonLabel(ui::DialogButton button
) const override
;
82 bool IsDialogButtonEnabled(ui::DialogButton button
) const override
;
83 views::View
* CreateExtraView() override
;
84 ui::ModalType
GetModalType() const override
;
85 bool CanResize() const override
;
86 base::string16
GetWindowTitle() const override
;
87 bool Accept() override
;
90 gfx::Size
GetPreferredSize() const override
;
91 void GetAccessibleState(ui::AXViewState
* state
) override
;
93 // views::TreeViewController:
94 void OnTreeViewSelectionChanged(views::TreeView
* tree_view
) override
;
95 bool CanEdit(views::TreeView
* tree_view
, ui::TreeModelNode
* node
) override
;
97 // views::TextfieldController:
98 void ContentsChanged(views::Textfield
* sender
,
99 const base::string16
& new_contents
) override
;
100 bool HandleKeyEvent(views::Textfield
* sender
,
101 const ui::KeyEvent
& key_event
) override
;
103 // views::ButtonListener:
104 void ButtonPressed(views::Button
* sender
, const ui::Event
& event
) override
;
106 // ui::SimpleMenuModel::Delegate:
107 bool IsCommandIdChecked(int command_id
) const override
;
108 bool IsCommandIdEnabled(int command_id
) const override
;
109 bool GetAcceleratorForCommandId(int command_id
,
110 ui::Accelerator
* accelerator
) override
;
111 void ExecuteCommand(int command_id
, int event_flags
) override
;
113 // Creates a Window and adds the BookmarkEditorView to it. When the window is
114 // closed the BookmarkEditorView is deleted.
115 void Show(gfx::NativeWindow parent
);
117 // views::ContextMenuController:
118 void ShowContextMenuForView(views::View
* source
,
119 const gfx::Point
& point
,
120 ui::MenuSourceType source_type
) override
;
123 friend class BookmarkEditorViewTest
;
125 // views::DialogDelegateView:
126 const char* GetClassName() const override
;
128 // bookmarks::BookmarkModelObserver:
129 // Any structural change results in resetting the tree model.
130 void BookmarkModelLoaded(bookmarks::BookmarkModel
* model
,
131 bool ids_reassigned
) override
{}
132 void BookmarkNodeMoved(bookmarks::BookmarkModel
* model
,
133 const bookmarks::BookmarkNode
* old_parent
,
135 const bookmarks::BookmarkNode
* new_parent
,
136 int new_index
) override
;
137 void BookmarkNodeAdded(bookmarks::BookmarkModel
* model
,
138 const bookmarks::BookmarkNode
* parent
,
140 void BookmarkNodeRemoved(bookmarks::BookmarkModel
* model
,
141 const bookmarks::BookmarkNode
* parent
,
143 const bookmarks::BookmarkNode
* node
,
144 const std::set
<GURL
>& removed_urls
) override
;
145 void BookmarkAllUserNodesRemoved(bookmarks::BookmarkModel
* model
,
146 const std::set
<GURL
>& removed_urls
) override
;
147 void BookmarkNodeChanged(bookmarks::BookmarkModel
* model
,
148 const bookmarks::BookmarkNode
* node
) override
{}
149 void BookmarkNodeChildrenReordered(
150 bookmarks::BookmarkModel
* model
,
151 const bookmarks::BookmarkNode
* node
) override
;
152 void BookmarkNodeFaviconChanged(
153 bookmarks::BookmarkModel
* model
,
154 const bookmarks::BookmarkNode
* node
) override
{}
156 // Creates the necessary sub-views, configures them, adds them to the layout,
157 // and requests the entries to display from the database.
160 // Resets the model of the tree and updates the various buttons appropriately.
163 // Expands all the nodes in the tree and selects the parent node of the
164 // url we're editing or the most recent parent if the url being editted isn't
166 void ExpandAndSelect();
168 // Creates a returns the new root node. This invokes CreateNodes to do
170 EditorNode
* CreateRootNode();
172 // Adds and creates a child node in b_node for all children of bb_node that
174 void CreateNodes(const bookmarks::BookmarkNode
* bb_node
, EditorNode
* b_node
);
176 // Returns the node with the specified id, or NULL if one can't be found.
177 EditorNode
* FindNodeWithID(BookmarkEditorView::EditorNode
* node
, int64 id
);
179 // Invokes ApplyEdits with the selected node.
182 // Applies the edits done by the user. |parent| gives the parent of the URL
184 void ApplyEdits(EditorNode
* parent
);
186 // Recursively adds newly created folders and sets the title of nodes to
187 // match the user edited title.
189 // bb_node gives the BookmarkNode the edits are to be applied to, with b_node
190 // the source of the edits.
192 // If b_node == parent_b_node, parent_bb_node is set to bb_node. This is
193 // used to determine the new BookmarkNode parent based on the EditorNode
195 void ApplyNameChangesAndCreateNewFolders(
196 const bookmarks::BookmarkNode
* bb_node
,
197 BookmarkEditorView::EditorNode
* b_node
,
198 BookmarkEditorView::EditorNode
* parent_b_node
,
199 const bookmarks::BookmarkNode
** parent_bb_node
);
201 // Returns the current url the user has input.
202 GURL
GetInputURL() const;
204 // Invoked when the url or title has possibly changed. Updates the background
205 // of Textfields and ok button appropriately.
206 void UserInputChanged();
208 // Creates a new folder as a child of the selected node. If no node is
209 // selected, the new folder is added as a child of the bookmark node. Starts
210 // editing on the new gorup as well.
213 // Creates a new EditorNode as the last child of parent. The new node is
214 // added to the model and returned. This does NOT start editing. This is used
215 // internally by NewFolder and broken into a separate method for testing.
216 EditorNode
* AddNewFolder(EditorNode
* parent
);
218 // If |editor_node| is expanded it's added to |expanded_nodes| and this is
219 // recursively invoked for all the children.
220 void UpdateExpandedNodes(
221 EditorNode
* editor_node
,
222 bookmarks::BookmarkExpandedStateTracker::Nodes
* expanded_nodes
);
224 ui::SimpleMenuModel
* GetMenuModel();
226 // Profile the entry is from.
229 // Model driving the TreeView.
230 scoped_ptr
<EditorTreeModel
> tree_model_
;
232 // Displays star folder.
233 views::TreeView
* tree_view_
;
235 // Used to create a new folder.
236 scoped_ptr
<views::LabelButton
> new_folder_button_
;
238 // The label for the url text field.
239 views::Label
* url_label_
;
241 // The text field used for editing the URL.
242 views::Textfield
* url_tf_
;
244 // The label for the title text field.
245 views::Label
* title_label_
;
247 // The text field used for editing the title.
248 views::Textfield
* title_tf_
;
250 // Initial parent to select. Is only used if |details_.existing_node| is
252 const bookmarks::BookmarkNode
* parent_
;
254 const EditDetails details_
;
257 scoped_ptr
<ui::SimpleMenuModel
> context_menu_model_
;
258 scoped_ptr
<views::MenuRunner
> context_menu_runner_
;
260 // Mode used to create nodes from.
261 bookmarks::BookmarkModel
* bb_model_
;
263 // If true, we're running the menu for the bookmark bar or other bookmarks
265 bool running_menu_for_root_
;
267 // Is the tree shown?
270 // List of deleted bookmark folders.
271 std::vector
<int64
> deletes_
;
273 DISALLOW_COPY_AND_ASSIGN(BookmarkEditorView
);
276 #endif // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_