Home | History | Annotate | Download | only in bookmarks
      1 // Copyright (c) 2011 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 // C++ controller for the bookmark menu; one per AppController (which
      6 // means there is only one).  When bookmarks are changed, this class
      7 // takes care of updating Cocoa bookmark menus.  This is not named
      8 // BookmarkMenuController to help avoid confusion between languages.
      9 // This class needs to be C++, not ObjC, since it derives from
     10 // BookmarkModelObserver.
     11 //
     12 // Most Chromium Cocoa menu items are static from a nib (e.g. New
     13 // Tab), but may be enabled/disabled under certain circumstances
     14 // (e.g. Cut and Paste).  In addition, most Cocoa menu items have
     15 // firstResponder: as a target.  Unusually, bookmark menu items are
     16 // created dynamically.  They also have a target of
     17 // BookmarkMenuCocoaController instead of firstResponder.
     18 // See BookmarkMenuBridge::AddNodeToMenu()).
     19 
     20 #ifndef CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
     21 #define CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
     22 #pragma once
     23 
     24 #include <map>
     25 
     26 #include "base/memory/scoped_nsobject.h"
     27 #include "chrome/browser/bookmarks/bookmark_model_observer.h"
     28 
     29 class BookmarkNode;
     30 class Profile;
     31 @class NSImage;
     32 @class NSMenu;
     33 @class NSMenuItem;
     34 @class BookmarkMenuCocoaController;
     35 
     36 class BookmarkMenuBridge : public BookmarkModelObserver {
     37  public:
     38   BookmarkMenuBridge(Profile* profile);
     39   virtual ~BookmarkMenuBridge();
     40 
     41   // Overridden from BookmarkModelObserver
     42   virtual void Loaded(BookmarkModel* model);
     43   virtual void BookmarkModelBeingDeleted(BookmarkModel* model);
     44   virtual void BookmarkNodeMoved(BookmarkModel* model,
     45                                  const BookmarkNode* old_parent,
     46                                  int old_index,
     47                                  const BookmarkNode* new_parent,
     48                                  int new_index);
     49   virtual void BookmarkNodeAdded(BookmarkModel* model,
     50                                  const BookmarkNode* parent,
     51                                  int index);
     52   virtual void BookmarkNodeRemoved(BookmarkModel* model,
     53                                    const BookmarkNode* parent,
     54                                    int old_index,
     55                                    const BookmarkNode* node);
     56   virtual void BookmarkNodeChanged(BookmarkModel* model,
     57                                    const BookmarkNode* node);
     58   virtual void BookmarkNodeFaviconLoaded(BookmarkModel* model,
     59                                          const BookmarkNode* node);
     60   virtual void BookmarkNodeChildrenReordered(BookmarkModel* model,
     61                                              const BookmarkNode* node);
     62 
     63   // Rebuilds the bookmark menu, if it has been marked invalid.
     64   void UpdateMenu(NSMenu* bookmark_menu);
     65 
     66   // I wish I had a "friend @class" construct.
     67   BookmarkModel* GetBookmarkModel();
     68   Profile* GetProfile();
     69 
     70  protected:
     71   // Clear all bookmarks from the given bookmark menu.
     72   void ClearBookmarkMenu(NSMenu* menu);
     73 
     74   // Mark the bookmark menu as being invalid.
     75   void InvalidateMenu()  { menuIsValid_ = false; }
     76 
     77   // Helper for adding the node as a submenu to the menu with the
     78   // given title.
     79   void AddNodeAsSubmenu(NSMenu* menu,
     80                         const BookmarkNode* node,
     81                         NSString* title);
     82 
     83   // Helper for recursively adding items to our bookmark menu.
     84   // All children of |node| will be added to |menu|.
     85   // TODO(jrg): add a counter to enforce maximum nodes added
     86   void AddNodeToMenu(const BookmarkNode* node, NSMenu* menu);
     87 
     88   // Helper for adding an item to our bookmark menu. An item which has a
     89   // localized title specified by |message_id| will be added to |menu|.
     90   // The item is also bound to |node| by tag. |command_id| selects the action.
     91   void AddItemToMenu(int command_id,
     92                      int message_id,
     93                      const BookmarkNode* node,
     94                      NSMenu* menu,
     95                      bool enabled);
     96 
     97   // This configures an NSMenuItem with all the data from a BookmarkNode. This
     98   // is used to update existing menu items, as well as to configure newly
     99   // created ones, like in AddNodeToMenu().
    100   // |set_title| is optional since it is only needed when we get a
    101   // node changed notification.  On initial build of the menu we set
    102   // the title as part of alloc/init.
    103   void ConfigureMenuItem(const BookmarkNode* node, NSMenuItem* item,
    104                          bool set_title);
    105 
    106   // Returns the NSMenuItem for a given BookmarkNode.
    107   NSMenuItem* MenuItemForNode(const BookmarkNode* node);
    108 
    109   // Return the Bookmark menu.
    110   virtual NSMenu* BookmarkMenu();
    111 
    112   // Start watching the bookmarks for changes.
    113   void ObserveBookmarkModel();
    114 
    115  private:
    116   friend class BookmarkMenuBridgeTest;
    117 
    118   // True iff the menu is up-to-date with the actual BookmarkModel.
    119   bool menuIsValid_;
    120 
    121   Profile* profile_;  // weak
    122   BookmarkMenuCocoaController* controller_;  // strong
    123 
    124   // The folder image so we can use one copy for all.
    125   scoped_nsobject<NSImage> folder_image_;
    126 
    127   // In order to appropriately update items in the bookmark menu, without
    128   // forcing a rebuild, map the model's nodes to menu items.
    129   std::map<const BookmarkNode*, NSMenuItem*> bookmark_nodes_;
    130 };
    131 
    132 #endif  // CHROME_BROWSER_UI_COCOA_BOOKMARKS_BOOKMARK_MENU_BRIDGE_H_
    133