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_MENU_DELEGATE_H_
      6 #define CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_DELEGATE_H_
      7 
      8 #include <map>
      9 #include <set>
     10 
     11 #include "base/compiler_specific.h"
     12 #include "chrome/browser/bookmarks/bookmark_stats.h"
     13 #include "chrome/browser/ui/views/bookmarks/bookmark_context_menu.h"
     14 #include "components/bookmarks/browser/base_bookmark_model_observer.h"
     15 #include "components/bookmarks/browser/bookmark_node_data.h"
     16 #include "ui/views/controls/menu/menu_delegate.h"
     17 
     18 class BookmarkNode;
     19 class Browser;
     20 class ChromeBookmarkClient;
     21 class Profile;
     22 
     23 namespace content {
     24 class PageNavigator;
     25 }
     26 
     27 namespace ui {
     28 class OSExchangeData;
     29 }
     30 
     31 namespace views {
     32 class MenuItemView;
     33 class Widget;
     34 }
     35 
     36 // BookmarkMenuDelegate acts as the (informal) views::MenuDelegate for showing
     37 // bookmarks in a MenuItemView. BookmarkMenuDelegate informally implements
     38 // MenuDelegate as its assumed another class is going to forward the appropriate
     39 // methods to this class. Doing so allows this class to be used for both menus
     40 // on the bookmark bar and the bookmarks in the wrench menu.
     41 class BookmarkMenuDelegate : public BaseBookmarkModelObserver,
     42                              public BookmarkContextMenuObserver {
     43  public:
     44   enum ShowOptions {
     45     // Indicates a menu should be added containing the permanent folders (other
     46     // than then bookmark bar folder). This only makes sense when showing the
     47     // contents of the bookmark bar folder.
     48     SHOW_PERMANENT_FOLDERS,
     49 
     50     // Don't show any additional folders.
     51     HIDE_PERMANENT_FOLDERS
     52   };
     53 
     54   BookmarkMenuDelegate(Browser* browser,
     55                        content::PageNavigator* navigator,
     56                        views::Widget* parent,
     57                        int first_menu_id,
     58                        int max_menu_id);
     59   virtual ~BookmarkMenuDelegate();
     60 
     61   // Creates the menus from the model.
     62   void Init(views::MenuDelegate* real_delegate,
     63             views::MenuItemView* parent,
     64             const BookmarkNode* node,
     65             int start_child_index,
     66             ShowOptions show_options,
     67             BookmarkLaunchLocation location);
     68 
     69   // Sets the PageNavigator.
     70   void SetPageNavigator(content::PageNavigator* navigator);
     71 
     72   // Returns the id given to the next menu.
     73   int next_menu_id() const { return next_menu_id_; }
     74 
     75   // Makes the menu for |node| the active menu. |start_index| is the index of
     76   // the first child of |node| to show in the menu.
     77   void SetActiveMenu(const BookmarkNode* node, int start_index);
     78 
     79   BookmarkModel* GetBookmarkModel();
     80   ChromeBookmarkClient* GetChromeBookmarkClient();
     81 
     82   // Returns the menu.
     83   views::MenuItemView* menu() { return menu_; }
     84 
     85   // Returns the context menu, or NULL if the context menu isn't showing.
     86   views::MenuItemView* context_menu() {
     87     return context_menu_.get() ? context_menu_->menu() : NULL;
     88   }
     89 
     90   views::Widget* parent() { return parent_; }
     91   const views::Widget* parent() const { return parent_; }
     92 
     93   // Returns true if we're in the process of mutating the model. This happens
     94   // when the user deletes menu items using the context menu.
     95   bool is_mutating_model() const { return is_mutating_model_; }
     96 
     97   // MenuDelegate like methods (see class description for details).
     98   base::string16 GetTooltipText(int id, const gfx::Point& p) const;
     99   bool IsTriggerableEvent(views::MenuItemView* menu,
    100                           const ui::Event& e);
    101   void ExecuteCommand(int id, int mouse_event_flags);
    102   bool ShouldExecuteCommandWithoutClosingMenu(int id, const ui::Event& e);
    103   bool GetDropFormats(
    104       views::MenuItemView* menu,
    105       int* formats,
    106       std::set<ui::OSExchangeData::CustomFormat>* custom_formats);
    107   bool AreDropTypesRequired(views::MenuItemView* menu);
    108   bool CanDrop(views::MenuItemView* menu, const ui::OSExchangeData& data);
    109   int GetDropOperation(views::MenuItemView* item,
    110                        const ui::DropTargetEvent& event,
    111                        views::MenuDelegate::DropPosition* position);
    112   int OnPerformDrop(views::MenuItemView* menu,
    113                     views::MenuDelegate::DropPosition position,
    114                     const ui::DropTargetEvent& event);
    115   bool ShowContextMenu(views::MenuItemView* source,
    116                        int id,
    117                        const gfx::Point& p,
    118                        ui::MenuSourceType source_type);
    119   bool CanDrag(views::MenuItemView* menu);
    120   void WriteDragData(views::MenuItemView* sender, ui::OSExchangeData* data);
    121   int GetDragOperations(views::MenuItemView* sender);
    122   int GetMaxWidthForMenu(views::MenuItemView* menu);
    123 
    124   // BookmarkModelObserver methods.
    125   virtual void BookmarkModelChanged() OVERRIDE;
    126   virtual void BookmarkNodeFaviconChanged(BookmarkModel* model,
    127                                           const BookmarkNode* node) OVERRIDE;
    128 
    129   // BookmarkContextMenu::Observer methods.
    130   virtual void WillRemoveBookmarks(
    131       const std::vector<const BookmarkNode*>& bookmarks) OVERRIDE;
    132   virtual void DidRemoveBookmarks() OVERRIDE;
    133 
    134  private:
    135   typedef std::map<int, const BookmarkNode*> MenuIDToNodeMap;
    136   typedef std::map<const BookmarkNode*, views::MenuItemView*> NodeToMenuMap;
    137 
    138   // Creates a menu. This uses BuildMenu() to recursively populate the menu.
    139   views::MenuItemView* CreateMenu(const BookmarkNode* parent,
    140                                   int start_child_index,
    141                                   ShowOptions show_options);
    142 
    143   // Invokes BuildMenuForPermanentNode() for the permanent nodes (excluding
    144   // 'other bookmarks' folder).
    145   void BuildMenusForPermanentNodes(views::MenuItemView* menu,
    146                                    int* next_menu_id);
    147 
    148   // If |node| has children a new menu is created and added to |menu| to
    149   // represent it. If |node| is not empty and |added_separator| is false, a
    150   // separator is added before the new menu items and |added_separator| is set
    151   // to true.
    152   void BuildMenuForPermanentNode(const BookmarkNode* node,
    153                                  int icon_resource_id,
    154                                  views::MenuItemView* menu,
    155                                  int* next_menu_id,
    156                                  bool* added_separator);
    157 
    158   void BuildMenuForManagedNode(views::MenuItemView* menu,
    159                                int* next_menu_id);
    160 
    161   // Creates an entry in menu for each child node of |parent| starting at
    162   // |start_child_index|.
    163   void BuildMenu(const BookmarkNode* parent,
    164                  int start_child_index,
    165                  views::MenuItemView* menu,
    166                  int* next_menu_id);
    167 
    168   // Returns true if |menu_id_| is outside the range of minimum and maximum menu
    169   // ID's allowed.
    170   bool IsOutsideMenuIdRange(int menu_id) const;
    171 
    172   Browser* browser_;
    173   Profile* profile_;
    174 
    175   content::PageNavigator* page_navigator_;
    176 
    177   // Parent of menus.
    178   views::Widget* parent_;
    179 
    180   // Maps from menu id to BookmarkNode.
    181   MenuIDToNodeMap menu_id_to_node_map_;
    182 
    183   // Current menu.
    184   views::MenuItemView* menu_;
    185 
    186   // Data for the drop.
    187   bookmarks::BookmarkNodeData drop_data_;
    188 
    189   // Used when a context menu is shown.
    190   scoped_ptr<BookmarkContextMenu> context_menu_;
    191 
    192   // If non-NULL this is the |parent| passed to Init and is NOT owned by us.
    193   views::MenuItemView* parent_menu_item_;
    194 
    195   // Maps from node to menu.
    196   NodeToMenuMap node_to_menu_map_;
    197 
    198   // ID of the next menu item.
    199   int next_menu_id_;
    200 
    201   // Minimum and maximum ID's to use for menu items.
    202   const int min_menu_id_;
    203   const int max_menu_id_;
    204 
    205   views::MenuDelegate* real_delegate_;
    206 
    207   // Is the model being changed?
    208   bool is_mutating_model_;
    209 
    210   // The location where this bookmark menu will be displayed (for UMA).
    211   BookmarkLaunchLocation location_;
    212 
    213   DISALLOW_COPY_AND_ASSIGN(BookmarkMenuDelegate);
    214 };
    215 
    216 #endif  // CHROME_BROWSER_UI_VIEWS_BOOKMARKS_BOOKMARK_MENU_DELEGATE_H_
    217