Home | History | Annotate | Download | only in bookmarks
      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