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 25 namespace views { 26 class Label; 27 class LabelButton; 28 class MenuRunner; 29 class TreeView; 30 } 31 32 class BookmarkEditorViewTest; 33 class GURL; 34 class Menu; 35 class 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 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 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