• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
InvalidateMenu()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