| Index: chrome/browser/ui/gtk/global_history_menu.cc
|
| diff --git a/chrome/browser/ui/gtk/global_history_menu.cc b/chrome/browser/ui/gtk/global_history_menu.cc
|
| deleted file mode 100644
|
| index 525bbdf387c8f3bb02e98126a3e7d39d7e694cfd..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/gtk/global_history_menu.cc
|
| +++ /dev/null
|
| @@ -1,418 +0,0 @@
|
| -// Copyright (c) 2012 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.
|
| -
|
| -#include "chrome/browser/ui/gtk/global_history_menu.h"
|
| -
|
| -#include <gtk/gtk.h>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/memory/weak_ptr.h"
|
| -#include "base/stl_util.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "chrome/browser/chrome_notification_types.h"
|
| -#include "chrome/browser/history/top_sites.h"
|
| -#include "chrome/browser/profiles/profile.h"
|
| -#include "chrome/browser/sessions/tab_restore_service.h"
|
| -#include "chrome/browser/sessions/tab_restore_service_factory.h"
|
| -#include "chrome/browser/themes/theme_service_factory.h"
|
| -#include "chrome/browser/ui/browser.h"
|
| -#include "chrome/browser/ui/browser_tab_restore_service_delegate.h"
|
| -#include "chrome/browser/ui/gtk/event_utils.h"
|
| -#include "chrome/browser/ui/gtk/global_menu_bar.h"
|
| -#include "chrome/browser/ui/gtk/gtk_theme_service.h"
|
| -#include "chrome/browser/ui/gtk/gtk_util.h"
|
| -#include "chrome/common/url_constants.h"
|
| -#include "content/public/browser/notification_source.h"
|
| -#include "grit/generated_resources.h"
|
| -#include "ui/base/gtk/owned_widget_gtk.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/gfx/codec/png_codec.h"
|
| -#include "ui/gfx/gtk_util.h"
|
| -#include "ui/gfx/text_elider.h"
|
| -
|
| -using content::OpenURLParams;
|
| -
|
| -namespace {
|
| -
|
| -// The maximum number of most visited items to display.
|
| -const unsigned int kMostVisitedCount = 8;
|
| -
|
| -// The number of recently closed items to get.
|
| -const unsigned int kRecentlyClosedCount = 8;
|
| -
|
| -// Menus more than this many chars long will get trimmed.
|
| -const int kMaximumMenuWidthInChars = 50;
|
| -
|
| -} // namespace
|
| -
|
| -struct GlobalHistoryMenu::ClearMenuClosure {
|
| - GtkWidget* container;
|
| - GlobalHistoryMenu* menu_bar;
|
| - int tag;
|
| -};
|
| -
|
| -struct GlobalHistoryMenu::GetIndexClosure {
|
| - bool found;
|
| - int current_index;
|
| - int tag;
|
| -};
|
| -
|
| -class GlobalHistoryMenu::HistoryItem {
|
| - public:
|
| - HistoryItem()
|
| - : menu_item(NULL),
|
| - session_id(0) {}
|
| -
|
| - // The title for the menu item.
|
| - base::string16 title;
|
| - // The URL that will be navigated to if the user selects this item.
|
| - GURL url;
|
| -
|
| - // A pointer to the menu_item. This is a weak reference in the GTK+ version
|
| - // because the GtkMenu must sink the reference.
|
| - GtkWidget* menu_item;
|
| -
|
| - // This ID is unique for a browser session and can be passed to the
|
| - // TabRestoreService to re-open the closed window or tab that this
|
| - // references. A non-0 session ID indicates that this is an entry can be
|
| - // restored that way. Otherwise, the URL will be used to open the item and
|
| - // this ID will be 0.
|
| - SessionID::id_type session_id;
|
| -
|
| - // If the HistoryItem is a window, this will be the vector of tabs. Note
|
| - // that this is a list of weak references. The |menu_item_map_| is the owner
|
| - // of all items. If it is not a window, then the entry is a single page and
|
| - // the vector will be empty.
|
| - std::vector<HistoryItem*> tabs;
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(HistoryItem);
|
| -};
|
| -
|
| -GlobalHistoryMenu::GlobalHistoryMenu(Browser* browser)
|
| - : browser_(browser),
|
| - profile_(browser_->profile()),
|
| - history_menu_(NULL),
|
| - top_sites_(NULL),
|
| - tab_restore_service_(NULL),
|
| - weak_ptr_factory_(this) {
|
| -}
|
| -
|
| -GlobalHistoryMenu::~GlobalHistoryMenu() {
|
| - if (tab_restore_service_)
|
| - tab_restore_service_->RemoveObserver(this);
|
| -
|
| - STLDeleteContainerPairSecondPointers(menu_item_history_map_.begin(),
|
| - menu_item_history_map_.end());
|
| - menu_item_history_map_.clear();
|
| -
|
| - if (history_menu_) {
|
| - gtk_widget_destroy(history_menu_);
|
| - g_object_unref(history_menu_);
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::Init(GtkWidget* history_menu,
|
| - GtkWidget* history_menu_item) {
|
| - history_menu_ = history_menu;
|
| - g_object_ref_sink(history_menu_);
|
| -
|
| - // We have to connect to |history_menu_item|'s "activate" signal instead of
|
| - // |history_menu|'s "show" signal because we are not supposed to modify the
|
| - // menu during "show"
|
| - g_signal_connect(history_menu_item, "activate",
|
| - G_CALLBACK(OnMenuActivateThunk), this);
|
| -
|
| - if (profile_) {
|
| - top_sites_ = profile_->GetTopSites();
|
| - if (top_sites_) {
|
| - GetTopSitesData();
|
| -
|
| - // Register for notification when TopSites changes so that we can update
|
| - // ourself.
|
| - registrar_.Add(this, chrome::NOTIFICATION_TOP_SITES_CHANGED,
|
| - content::Source<history::TopSites>(top_sites_));
|
| - }
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::GetTopSitesData() {
|
| - DCHECK(top_sites_);
|
| -
|
| - top_sites_->GetMostVisitedURLs(
|
| - base::Bind(&GlobalHistoryMenu::OnTopSitesReceived,
|
| - weak_ptr_factory_.GetWeakPtr()), false);
|
| -}
|
| -
|
| -void GlobalHistoryMenu::OnTopSitesReceived(
|
| - const history::MostVisitedURLList& visited_list) {
|
| - ClearMenuSection(history_menu_, GlobalMenuBar::TAG_MOST_VISITED);
|
| -
|
| - int index = GetIndexOfMenuItemWithTag(
|
| - history_menu_,
|
| - GlobalMenuBar::TAG_MOST_VISITED_HEADER) + 1;
|
| -
|
| - for (size_t i = 0; i < visited_list.size() && i < kMostVisitedCount; ++i) {
|
| - const history::MostVisitedURL& visited = visited_list[i];
|
| - if (visited.url.spec().empty())
|
| - break; // This is the signal that there are no more real visited sites.
|
| -
|
| - HistoryItem* item = new HistoryItem();
|
| - item->title = visited.title;
|
| - item->url = visited.url;
|
| -
|
| - AddHistoryItemToMenu(item,
|
| - history_menu_,
|
| - GlobalMenuBar::TAG_MOST_VISITED,
|
| - index++);
|
| - }
|
| -}
|
| -
|
| -GlobalHistoryMenu::HistoryItem* GlobalHistoryMenu::HistoryItemForMenuItem(
|
| - GtkWidget* menu_item) {
|
| - MenuItemToHistoryMap::iterator it = menu_item_history_map_.find(menu_item);
|
| - return it != menu_item_history_map_.end() ? it->second : NULL;
|
| -}
|
| -
|
| -GlobalHistoryMenu::HistoryItem* GlobalHistoryMenu::HistoryItemForTab(
|
| - const TabRestoreService::Tab& entry) {
|
| - const sessions::SerializedNavigationEntry& current_navigation =
|
| - entry.navigations.at(entry.current_navigation_index);
|
| - HistoryItem* item = new HistoryItem();
|
| - item->title = current_navigation.title();
|
| - item->url = current_navigation.virtual_url();
|
| - item->session_id = entry.id;
|
| -
|
| - return item;
|
| -}
|
| -
|
| -GtkWidget* GlobalHistoryMenu::AddHistoryItemToMenu(HistoryItem* item,
|
| - GtkWidget* menu,
|
| - int tag,
|
| - int index) {
|
| - base::string16 title = item->title;
|
| - std::string url_string = item->url.possibly_invalid_spec();
|
| -
|
| - if (title.empty())
|
| - title = base::UTF8ToUTF16(url_string);
|
| - gfx::ElideString(title, kMaximumMenuWidthInChars, &title);
|
| -
|
| - GtkWidget* menu_item = gtk_menu_item_new_with_label(
|
| - base::UTF16ToUTF8(title).c_str());
|
| -
|
| - item->menu_item = menu_item;
|
| - gtk_widget_show(menu_item);
|
| - g_object_set_data(G_OBJECT(menu_item), "type-tag", GINT_TO_POINTER(tag));
|
| - g_signal_connect(menu_item, "activate",
|
| - G_CALLBACK(OnRecentlyClosedItemActivatedThunk), this);
|
| -
|
| - std::string tooltip = gtk_util::BuildTooltipTitleFor(item->title, item->url);
|
| - gtk_widget_set_tooltip_markup(menu_item, tooltip.c_str());
|
| -
|
| - menu_item_history_map_.insert(std::make_pair(menu_item, item));
|
| - gtk_menu_shell_insert(GTK_MENU_SHELL(menu), menu_item, index);
|
| -
|
| - return menu_item;
|
| -}
|
| -
|
| -int GlobalHistoryMenu::GetIndexOfMenuItemWithTag(GtkWidget* menu, int tag_id) {
|
| - GetIndexClosure closure;
|
| - closure.found = false;
|
| - closure.current_index = 0;
|
| - closure.tag = tag_id;
|
| -
|
| - gtk_container_foreach(
|
| - GTK_CONTAINER(menu),
|
| - reinterpret_cast<void (*)(GtkWidget*, void*)>(GetIndexCallback),
|
| - &closure);
|
| -
|
| - return closure.current_index;
|
| -}
|
| -
|
| -void GlobalHistoryMenu::ClearMenuSection(GtkWidget* menu, int tag) {
|
| - ClearMenuClosure closure;
|
| - closure.container = menu;
|
| - closure.menu_bar = this;
|
| - closure.tag = tag;
|
| -
|
| - gtk_container_foreach(
|
| - GTK_CONTAINER(menu),
|
| - reinterpret_cast<void (*)(GtkWidget*, void*)>(ClearMenuCallback),
|
| - &closure);
|
| -}
|
| -
|
| -// static
|
| -void GlobalHistoryMenu::GetIndexCallback(GtkWidget* menu_item,
|
| - GetIndexClosure* closure) {
|
| - int tag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu_item), "type-tag"));
|
| - if (tag == closure->tag)
|
| - closure->found = true;
|
| -
|
| - if (!closure->found)
|
| - closure->current_index++;
|
| -}
|
| -
|
| -// static
|
| -void GlobalHistoryMenu::ClearMenuCallback(GtkWidget* menu_item,
|
| - ClearMenuClosure* closure) {
|
| - DCHECK_NE(closure->tag, 0);
|
| -
|
| - int tag = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(menu_item), "type-tag"));
|
| - if (closure->tag == tag) {
|
| - HistoryItem* item = closure->menu_bar->HistoryItemForMenuItem(menu_item);
|
| -
|
| - if (item) {
|
| - closure->menu_bar->menu_item_history_map_.erase(menu_item);
|
| - delete item;
|
| - }
|
| -
|
| - GtkWidget* submenu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menu_item));
|
| - if (submenu)
|
| - closure->menu_bar->ClearMenuSection(submenu, closure->tag);
|
| -
|
| - gtk_container_remove(GTK_CONTAINER(closure->container), menu_item);
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::Observe(int type,
|
| - const content::NotificationSource& source,
|
| - const content::NotificationDetails& details) {
|
| - if (type == chrome::NOTIFICATION_TOP_SITES_CHANGED) {
|
| - GetTopSitesData();
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::TabRestoreServiceChanged(TabRestoreService* service) {
|
| - const TabRestoreService::Entries& entries = service->entries();
|
| -
|
| - ClearMenuSection(history_menu_, GlobalMenuBar::TAG_RECENTLY_CLOSED);
|
| -
|
| - // We'll get the index the "Recently Closed" header. (This can vary depending
|
| - // on the number of "Most Visited" items.
|
| - int index = GetIndexOfMenuItemWithTag(
|
| - history_menu_,
|
| - GlobalMenuBar::TAG_RECENTLY_CLOSED_HEADER) + 1;
|
| -
|
| - unsigned int added_count = 0;
|
| - for (TabRestoreService::Entries::const_iterator it = entries.begin();
|
| - it != entries.end() && added_count < kRecentlyClosedCount; ++it) {
|
| - TabRestoreService::Entry* entry = *it;
|
| -
|
| - if (entry->type == TabRestoreService::WINDOW) {
|
| - TabRestoreService::Window* entry_win =
|
| - static_cast<TabRestoreService::Window*>(entry);
|
| - std::vector<TabRestoreService::Tab>& tabs = entry_win->tabs;
|
| - if (tabs.empty())
|
| - continue;
|
| -
|
| - // Create the item for the parent/window.
|
| - HistoryItem* item = new HistoryItem();
|
| - item->session_id = entry_win->id;
|
| -
|
| - GtkWidget* submenu = gtk_menu_new();
|
| - GtkWidget* restore_item = gtk_menu_item_new_with_label(
|
| - l10n_util::GetStringUTF8(
|
| - IDS_HISTORY_CLOSED_RESTORE_WINDOW_LINUX).c_str());
|
| - g_object_set_data(G_OBJECT(restore_item), "type-tag",
|
| - GINT_TO_POINTER(GlobalMenuBar::TAG_RECENTLY_CLOSED));
|
| - g_signal_connect(restore_item, "activate",
|
| - G_CALLBACK(OnRecentlyClosedItemActivatedThunk), this);
|
| - gtk_widget_show(restore_item);
|
| -
|
| - // The mac version of this code allows the user to click on the parent
|
| - // menu item to have the same effect as clicking the restore window
|
| - // submenu item. GTK+ helpfully activates a menu item when it shows a
|
| - // submenu so toss that feature out.
|
| - menu_item_history_map_.insert(std::make_pair(restore_item, item));
|
| - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), restore_item);
|
| -
|
| - GtkWidget* separator = gtk_separator_menu_item_new();
|
| - gtk_widget_show(separator);
|
| - gtk_menu_shell_append(GTK_MENU_SHELL(submenu), separator);
|
| -
|
| - // Loop over the window's tabs and add them to the submenu.
|
| - int subindex = 2;
|
| - std::vector<TabRestoreService::Tab>::const_iterator iter;
|
| - for (iter = tabs.begin(); iter != tabs.end(); ++iter) {
|
| - TabRestoreService::Tab tab = *iter;
|
| - HistoryItem* tab_item = HistoryItemForTab(tab);
|
| - item->tabs.push_back(tab_item);
|
| - AddHistoryItemToMenu(tab_item,
|
| - submenu,
|
| - GlobalMenuBar::TAG_RECENTLY_CLOSED,
|
| - subindex++);
|
| - }
|
| -
|
| - std::string title = item->tabs.size() == 1 ?
|
| - l10n_util::GetStringUTF8(
|
| - IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_SINGLE) :
|
| - l10n_util::GetStringFUTF8(
|
| - IDS_NEW_TAB_RECENTLY_CLOSED_WINDOW_MULTIPLE,
|
| - base::IntToString16(item->tabs.size()));
|
| -
|
| - // Create the menu item parent. Unlike mac, it's can't be activated.
|
| - GtkWidget* parent_item = gtk_menu_item_new_with_label(title.c_str());
|
| - gtk_widget_show(parent_item);
|
| - g_object_set_data(G_OBJECT(parent_item), "type-tag",
|
| - GINT_TO_POINTER(GlobalMenuBar::TAG_RECENTLY_CLOSED));
|
| - gtk_menu_item_set_submenu(GTK_MENU_ITEM(parent_item), submenu);
|
| -
|
| - gtk_menu_shell_insert(GTK_MENU_SHELL(history_menu_), parent_item,
|
| - index++);
|
| - ++added_count;
|
| - } else if (entry->type == TabRestoreService::TAB) {
|
| - TabRestoreService::Tab* tab = static_cast<TabRestoreService::Tab*>(entry);
|
| - HistoryItem* item = HistoryItemForTab(*tab);
|
| - AddHistoryItemToMenu(item,
|
| - history_menu_,
|
| - GlobalMenuBar::TAG_RECENTLY_CLOSED,
|
| - index++);
|
| - ++added_count;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::TabRestoreServiceDestroyed(
|
| - TabRestoreService* service) {
|
| - tab_restore_service_ = NULL;
|
| -}
|
| -
|
| -void GlobalHistoryMenu::OnRecentlyClosedItemActivated(GtkWidget* sender) {
|
| - WindowOpenDisposition disposition =
|
| - event_utils::DispositionForCurrentButtonPressEvent();
|
| - HistoryItem* item = HistoryItemForMenuItem(sender);
|
| -
|
| - // If this item can be restored using TabRestoreService, do so. Otherwise,
|
| - // just load the URL.
|
| - TabRestoreService* service =
|
| - TabRestoreServiceFactory::GetForProfile(browser_->profile());
|
| - if (item->session_id && service) {
|
| - service->RestoreEntryById(browser_->tab_restore_service_delegate(),
|
| - item->session_id, browser_->host_desktop_type(),
|
| - UNKNOWN);
|
| - } else {
|
| - DCHECK(item->url.is_valid());
|
| - browser_->OpenURL(OpenURLParams(item->url, content::Referrer(), disposition,
|
| - content::PAGE_TRANSITION_AUTO_BOOKMARK, false));
|
| - }
|
| -}
|
| -
|
| -void GlobalHistoryMenu::OnMenuActivate(GtkWidget* sender) {
|
| - if (!tab_restore_service_) {
|
| - tab_restore_service_ = TabRestoreServiceFactory::GetForProfile(profile_);
|
| - if (tab_restore_service_) {
|
| - tab_restore_service_->LoadTabsFromLastSession();
|
| - tab_restore_service_->AddObserver(this);
|
| -
|
| - // If LoadTabsFromLastSession doesn't load tabs, it won't call
|
| - // TabRestoreServiceChanged(). This ensures that all new windows after
|
| - // the first one will have their menus populated correctly.
|
| - TabRestoreServiceChanged(tab_restore_service_);
|
| - }
|
| - }
|
| -}
|
|
|