bookmark_editor_view.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_
7
8#include <vector>
9
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"
24
25namespace views {
26class Label;
27class LabelButton;
28class MenuRunner;
29class TreeView;
30}
31
32class BookmarkEditorViewTest;
33class GURL;
34class Menu;
35class Profile;
36
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'.
42//
43// Edits are applied to the BookmarkModel when the user presses 'OK'.
44//
45// To use BookmarkEditorView invoke the static show method.
46
47class 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 BookmarkModelObserver {
55 public:
56  // Type of node in the tree. Public purely for testing.
57  typedef ui::TreeNodeWithValue<int64> EditorNode;
58
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> {
62   public:
63    explicit EditorTreeModel(EditorNode* root)
64        : ui::TreeNodeModel<EditorNode>(root) {}
65
66    virtual void SetTitle(ui::TreeModelNode* node,
67                          const base::string16& title) OVERRIDE;
68
69   private:
70    DISALLOW_COPY_AND_ASSIGN(EditorTreeModel);
71  };
72
73  BookmarkEditorView(Profile* profile,
74                     const BookmarkNode* parent,
75                     const EditDetails& details,
76                     BookmarkEditor::Configuration configuration);
77
78  virtual ~BookmarkEditorView();
79
80  // views::DialogDelegateView:
81  virtual base::string16 GetDialogButtonLabel(
82      ui::DialogButton button) const OVERRIDE;
83  virtual bool IsDialogButtonEnabled(ui::DialogButton button) const OVERRIDE;
84  virtual views::View* CreateExtraView() OVERRIDE;
85  virtual ui::ModalType GetModalType() const OVERRIDE;
86  virtual bool CanResize() const  OVERRIDE;
87  virtual base::string16 GetWindowTitle() const  OVERRIDE;
88  virtual bool Accept() OVERRIDE;
89
90  // views::View:
91  virtual gfx::Size GetPreferredSize() const OVERRIDE;
92  virtual void GetAccessibleState(ui::AXViewState* state) OVERRIDE;
93
94  // views::TreeViewController:
95  virtual void OnTreeViewSelectionChanged(views::TreeView* tree_view) OVERRIDE;
96  virtual bool CanEdit(views::TreeView* tree_view,
97                       ui::TreeModelNode* node) OVERRIDE;
98
99  // views::TextfieldController:
100  virtual void ContentsChanged(views::Textfield* sender,
101                               const base::string16& new_contents) OVERRIDE;
102  virtual bool HandleKeyEvent(views::Textfield* sender,
103                              const ui::KeyEvent& key_event) OVERRIDE;
104
105  // views::ButtonListener:
106  virtual void ButtonPressed(views::Button* sender,
107                             const ui::Event& event) OVERRIDE;
108
109  // ui::SimpleMenuModel::Delegate:
110  virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
111  virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
112  virtual bool GetAcceleratorForCommandId(
113      int command_id,
114      ui::Accelerator* accelerator) OVERRIDE;
115  virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE;
116
117  // Creates a Window and adds the BookmarkEditorView to it. When the window is
118  // closed the BookmarkEditorView is deleted.
119  void Show(gfx::NativeWindow parent);
120
121  // views::ContextMenuController:
122  virtual void ShowContextMenuForView(views::View* source,
123                                      const gfx::Point& point,
124                                      ui::MenuSourceType source_type) OVERRIDE;
125
126 private:
127  friend class BookmarkEditorViewTest;
128
129  // Creates the necessary sub-views, configures them, adds them to the layout,
130  // and requests the entries to display from the database.
131  void Init();
132
133  // BookmarkModel observer methods. Any structural change results in
134  // resetting the tree model.
135  virtual void BookmarkModelLoaded(BookmarkModel* model,
136                                   bool ids_reassigned) OVERRIDE {}
137  virtual void BookmarkNodeMoved(BookmarkModel* model,
138                                 const BookmarkNode* old_parent,
139                                 int old_index,
140                                 const BookmarkNode* new_parent,
141                                 int new_index) OVERRIDE;
142  virtual void BookmarkNodeAdded(BookmarkModel* model,
143                                 const BookmarkNode* parent,
144                                 int index) OVERRIDE;
145  virtual void BookmarkNodeRemoved(BookmarkModel* model,
146                                   const BookmarkNode* parent,
147                                   int index,
148                                   const BookmarkNode* node,
149                                   const std::set<GURL>& removed_urls) OVERRIDE;
150  virtual void BookmarkAllUserNodesRemoved(
151      BookmarkModel* model,
152      const std::set<GURL>& removed_urls) OVERRIDE;
153  virtual void BookmarkNodeChanged(BookmarkModel* model,
154                                   const BookmarkNode* node) OVERRIDE {}
155  virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
156                                             const BookmarkNode* node) OVERRIDE;
157  virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
158                                          const BookmarkNode* node) OVERRIDE {}
159
160  // Resets the model of the tree and updates the various buttons appropriately.
161  void Reset();
162
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
165  // starred.
166  void ExpandAndSelect();
167
168  // Creates a returns the new root node. This invokes CreateNodes to do
169  // the real work.
170  EditorNode* CreateRootNode();
171
172  // Adds and creates a child node in b_node for all children of bb_node that
173  // are folders.
174  void CreateNodes(const BookmarkNode* bb_node, EditorNode* b_node);
175
176  // Returns the node with the specified id, or NULL if one can't be found.
177  EditorNode* FindNodeWithID(BookmarkEditorView::EditorNode* node, int64 id);
178
179  // Invokes ApplyEdits with the selected node.
180  void ApplyEdits();
181
182  // Applies the edits done by the user. |parent| gives the parent of the URL
183  // being edited.
184  void ApplyEdits(EditorNode* parent);
185
186  // Recursively adds newly created folders and sets the title of nodes to
187  // match the user edited title.
188  //
189  // bb_node gives the BookmarkNode the edits are to be applied to, with b_node
190  // the source of the edits.
191  //
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
194  // parent.
195  void ApplyNameChangesAndCreateNewFolders(
196      const BookmarkNode* bb_node,
197      BookmarkEditorView::EditorNode* b_node,
198      BookmarkEditorView::EditorNode* parent_b_node,
199      const BookmarkNode** parent_bb_node);
200
201  // Returns the current url the user has input.
202  GURL GetInputURL() const;
203
204  // Invoked when the url or title has possibly changed. Updates the background
205  // of Textfields and ok button appropriately.
206  void UserInputChanged();
207
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.
211  void NewFolder();
212
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);
217
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);
223
224  ui::SimpleMenuModel* GetMenuModel();
225
226  // Profile the entry is from.
227  Profile* profile_;
228
229  // Model driving the TreeView.
230  scoped_ptr<EditorTreeModel> tree_model_;
231
232  // Displays star folder.
233  views::TreeView* tree_view_;
234
235  // Used to create a new folder.
236  scoped_ptr<views::LabelButton> new_folder_button_;
237
238  // The label for the url text field.
239  views::Label* url_label_;
240
241  // The text field used for editing the URL.
242  views::Textfield* url_tf_;
243
244  // The label for the title text field.
245  views::Label* title_label_;
246
247  // The text field used for editing the title.
248  views::Textfield* title_tf_;
249
250  // Initial parent to select. Is only used if |details_.existing_node| is
251  // NULL.
252  const BookmarkNode* parent_;
253
254  const EditDetails details_;
255
256  // The context menu.
257  scoped_ptr<ui::SimpleMenuModel> context_menu_model_;
258  scoped_ptr<views::MenuRunner> context_menu_runner_;
259
260  // Mode used to create nodes from.
261  BookmarkModel* bb_model_;
262
263  // If true, we're running the menu for the bookmark bar or other bookmarks
264  // nodes.
265  bool running_menu_for_root_;
266
267  // Is the tree shown?
268  bool show_tree_;
269
270  // List of deleted bookmark folders.
271  std::vector<int64> deletes_;
272
273  DISALLOW_COPY_AND_ASSIGN(BookmarkEditorView);
274};
275
276#endif  // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_EDITOR_VIEW_H_
277