// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_ #define CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_ #include #include "base/compiler_specific.h" #include "chrome/browser/cancelable_request.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/sessions/tab_restore_service_observer.h" #include "chrome/browser/ui/gtk/global_menu_owner.h" #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "ui/base/gtk/gtk_signal.h" #include "ui/base/gtk/owned_widget_gtk.h" class Browser; namespace history { class TopSites; } typedef struct _GdkPixbuf GdkPixbuf; // Controls the History menu. class GlobalHistoryMenu : public GlobalMenuOwner, public content::NotificationObserver, public TabRestoreServiceObserver { public: explicit GlobalHistoryMenu(Browser* browser); virtual ~GlobalHistoryMenu(); // Takes the history menu we need to modify based on the tab restore/most // visited state. virtual void Init(GtkWidget* history_menu, GtkWidget* history_menu_item) OVERRIDE; private: class HistoryItem; struct ClearMenuClosure; struct GetIndexClosure; typedef std::map MenuItemToHistoryMap; // Sends a message off to History for data. void GetTopSitesData(); // Callback to receive data requested from GetTopSitesData(). void OnTopSitesReceived(const history::MostVisitedURLList& visited_list); // Returns the currently existing HistoryItem associated with // |menu_item|. Can return NULL. HistoryItem* HistoryItemForMenuItem(GtkWidget* menu_item); // Returns whether there's a valid HistoryItem representation of |entry|. bool HasValidHistoryItemForTab(const TabRestoreService::Tab& entry); // Creates a HistoryItem from the data in |entry|. HistoryItem* HistoryItemForTab(const TabRestoreService::Tab& entry); // Creates a menu item form |item| and inserts it in |menu| at |index|. GtkWidget* AddHistoryItemToMenu(HistoryItem* item, GtkWidget* menu, int tag, int index); // Find the first index of the item in |menu| with the tag |tag_id|. int GetIndexOfMenuItemWithTag(GtkWidget* menu, int tag_id); // This will remove all menu items in |menu| with |tag| as their tag. This // clears state about HistoryItems* that we keep to prevent that data from // going stale. That's why this method recurses into its child menus. void ClearMenuSection(GtkWidget* menu, int tag); // Implementation detail of GetIndexOfMenuItemWithTag. static void GetIndexCallback(GtkWidget* widget, GetIndexClosure* closure); // Implementation detail of ClearMenuSection. static void ClearMenuCallback(GtkWidget* widget, ClearMenuClosure* closure); // content::NotificationObserver: virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE; // For TabRestoreServiceObserver virtual void TabRestoreServiceChanged(TabRestoreService* service) OVERRIDE; virtual void TabRestoreServiceDestroyed(TabRestoreService* service) OVERRIDE; CHROMEGTK_CALLBACK_0(GlobalHistoryMenu, void, OnRecentlyClosedItemActivated); // Listen for the first menu show command so we can then connect to the // TabRestoreService. With how the global menus work, I'd prefer to register // with the TabRestoreService as soon as we're constructed, but this breaks // unit tests which test the service (because they force different // construction ordering while us connecting to the TabRestoreService loads // data now!) CHROMEGTK_CALLBACK_0(GlobalHistoryMenu, void, OnMenuActivate); Browser* browser_; Profile* profile_; // The history menu. We keep this since we need to rewrite parts of it // periodically. ui::OwnedWidgetGtk history_menu_; history::TopSites* top_sites_; CancelableRequestConsumer top_sites_consumer_; TabRestoreService* tab_restore_service_; // weak // A mapping from GtkMenuItems to HistoryItems that maintain data. MenuItemToHistoryMap menu_item_history_map_; content::NotificationRegistrar registrar_; }; #endif // CHROME_BROWSER_UI_GTK_GLOBAL_HISTORY_MENU_H_