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 #ifndef CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_ 6 #define CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_ 7 8 #include <map> 9 10 #include "base/compiler_specific.h" 11 #include "chrome/browser/common/cancelable_request.h" 12 #include "chrome/browser/history/history_types.h" 13 #include "chrome/browser/sessions/tab_restore_service.h" 14 #include "chrome/browser/sessions/tab_restore_service_observer.h" 15 #include "chrome/browser/ui/gtk/global_menu_owner.h" 16 #include "content/public/browser/notification_observer.h" 17 #include "content/public/browser/notification_registrar.h" 18 #include "ui/base/gtk/gtk_signal.h" 19 20 class Browser; 21 class Profile; 22 23 namespace history { 24 class TopSites; 25 } 26 27 typedef struct _GdkPixbuf GdkPixbuf; 28 29 // Controls the History menu. 30 class GlobalHistoryMenu : public GlobalMenuOwner, 31 public content::NotificationObserver, 32 public TabRestoreServiceObserver { 33 public: 34 explicit GlobalHistoryMenu(Browser* browser); 35 virtual ~GlobalHistoryMenu(); 36 37 // Takes the history menu we need to modify based on the tab restore/most 38 // visited state. 39 virtual void Init(GtkWidget* history_menu, 40 GtkWidget* history_menu_item) OVERRIDE; 41 42 private: 43 class HistoryItem; 44 struct ClearMenuClosure; 45 struct GetIndexClosure; 46 47 typedef std::map<GtkWidget*, HistoryItem*> MenuItemToHistoryMap; 48 49 // Sends a message off to History for data. 50 void GetTopSitesData(); 51 52 // Callback to receive data requested from GetTopSitesData(). 53 void OnTopSitesReceived(const history::MostVisitedURLList& visited_list); 54 55 // Returns the currently existing HistoryItem associated with 56 // |menu_item|. Can return NULL. 57 HistoryItem* HistoryItemForMenuItem(GtkWidget* menu_item); 58 59 // Returns whether there's a valid HistoryItem representation of |entry|. 60 bool HasValidHistoryItemForTab(const TabRestoreService::Tab& entry); 61 62 // Creates a HistoryItem from the data in |entry|. 63 HistoryItem* HistoryItemForTab(const TabRestoreService::Tab& entry); 64 65 // Creates a menu item form |item| and inserts it in |menu| at |index|. 66 GtkWidget* AddHistoryItemToMenu(HistoryItem* item, 67 GtkWidget* menu, 68 int tag, 69 int index); 70 71 // Find the first index of the item in |menu| with the tag |tag_id|. 72 int GetIndexOfMenuItemWithTag(GtkWidget* menu, int tag_id); 73 74 // This will remove all menu items in |menu| with |tag| as their tag. This 75 // clears state about HistoryItems* that we keep to prevent that data from 76 // going stale. That's why this method recurses into its child menus. 77 void ClearMenuSection(GtkWidget* menu, int tag); 78 79 // Implementation detail of GetIndexOfMenuItemWithTag. 80 static void GetIndexCallback(GtkWidget* widget, GetIndexClosure* closure); 81 82 // Implementation detail of ClearMenuSection. 83 static void ClearMenuCallback(GtkWidget* widget, ClearMenuClosure* closure); 84 85 // content::NotificationObserver: 86 virtual void Observe(int type, 87 const content::NotificationSource& source, 88 const content::NotificationDetails& details) OVERRIDE; 89 90 // For TabRestoreServiceObserver 91 virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE; 92 virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE; 93 94 CHROMEGTK_CALLBACK_0(GlobalHistoryMenu, void, OnRecentlyClosedItemActivated); 95 96 // Listen for the first menu show command so we can then connect to the 97 // TabRestoreService. With how the global menus work, I'd prefer to register 98 // with the TabRestoreService as soon as we're constructed, but this breaks 99 // unit tests which test the service (because they force different 100 // construction ordering while us connecting to the TabRestoreService loads 101 // data now!) 102 CHROMEGTK_CALLBACK_0(GlobalHistoryMenu, void, OnMenuActivate); 103 104 Browser* browser_; 105 Profile* profile_; 106 107 // The history menu. We keep this since we need to rewrite parts of it 108 // periodically. 109 GtkWidget* history_menu_; 110 111 history::TopSites* top_sites_; 112 113 // For callbacks may be run after destruction. 114 base::WeakPtrFactory<GlobalHistoryMenu> weak_ptr_factory_; 115 116 TabRestoreService* tab_restore_service_; // weak 117 118 // A mapping from GtkMenuItems to HistoryItems that maintain data. 119 MenuItemToHistoryMap menu_item_history_map_; 120 121 content::NotificationRegistrar registrar_; 122 }; 123 124 #endif // CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_ 125