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