diff options
Diffstat (limited to 'chrome/browser/gtk')
20 files changed, 609 insertions, 525 deletions
diff --git a/chrome/browser/gtk/accelerators_gtk.cc b/chrome/browser/gtk/accelerators_gtk.cc index c93d8f0..21ffe03 100644 --- a/chrome/browser/gtk/accelerators_gtk.cc +++ b/chrome/browser/gtk/accelerators_gtk.cc @@ -151,7 +151,8 @@ const struct AcceleratorMapping { { GDK_o, IDC_OPEN_FILE, GDK_CONTROL_MASK }, { GDK_f, IDC_FIND, GDK_CONTROL_MASK }, { GDK_p, IDC_PRINT, GDK_CONTROL_MASK }, - { GDK_b, IDC_SHOW_BOOKMARK_BAR, + { GDK_b, IDC_SHOW_BOOKMARK_BAR, GDK_CONTROL_MASK }, + { GDK_b, IDC_SHOW_BOOKMARK_MANAGER, GdkModifierType(GDK_CONTROL_MASK | GDK_SHIFT_MASK) }, { GDK_F11, IDC_FULLSCREEN, GdkModifierType(0) }, { GDK_Delete, IDC_CLEAR_BROWSING_DATA, diff --git a/chrome/browser/gtk/bookmark_bubble_gtk.cc b/chrome/browser/gtk/bookmark_bubble_gtk.cc index 2bf86e2..524c9c3 100644 --- a/chrome/browser/gtk/bookmark_bubble_gtk.cc +++ b/chrome/browser/gtk/bookmark_bubble_gtk.cc @@ -219,7 +219,7 @@ BookmarkBubbleGtk::BookmarkBubbleGtk(GtkWidget* anchor, gtk_container_set_focus_child(GTK_CONTAINER(content), table); InfoBubbleGtk::ArrowLocationGtk arrow_location = - base::i18n::IsRTL() ? + !base::i18n::IsRTL() ? InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT : InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT; bubble_ = InfoBubbleGtk::Show(anchor_, diff --git a/chrome/browser/gtk/browser_toolbar_gtk.cc b/chrome/browser/gtk/browser_toolbar_gtk.cc index bfe25fc..a4e79b0 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -35,6 +35,7 @@ #include "chrome/browser/gtk/location_bar_view_gtk.h" #include "chrome/browser/gtk/standard_menus.h" #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" +#include "chrome/browser/gtk/toolbar_star_toggle_gtk.h" #include "chrome/browser/gtk/view_id_util.h" #include "chrome/browser/net/url_fixer_upper.h" #include "chrome/browser/pref_service.h" @@ -65,13 +66,17 @@ const int kToolbarHeightLocationBarOnly = kToolbarHeight - 2; // Interior spacing between toolbar widgets. const int kToolbarWidgetSpacing = 2; +// The color used as the base[] color of the location entry during a secure +// connection. +const GdkColor kSecureColor = GDK_COLOR_RGB(255, 245, 195); + } // namespace // BrowserToolbarGtk, public --------------------------------------------------- BrowserToolbarGtk::BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window) : toolbar_(NULL), - location_bar_(new LocationBarViewGtk(browser)), + location_bar_(new LocationBarViewGtk(this, browser)), model_(browser->toolbar_model()), page_menu_model_(this, browser), app_menu_model_(this, browser), @@ -155,6 +160,11 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_box_pack_start(GTK_BOX(toolbar_), back_forward_hbox_, FALSE, FALSE, kToolbarWidgetSpacing); + reload_.reset(BuildToolbarButton(IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0, + IDR_BUTTON_MASK, + l10n_util::GetStringUTF8(IDS_TOOLTIP_RELOAD), + GTK_STOCK_REFRESH)); + home_.reset(BuildToolbarButton(IDR_HOME, IDR_HOME_P, IDR_HOME_H, 0, IDR_BUTTON_MASK, l10n_util::GetStringUTF8(IDS_TOOLTIP_HOME), @@ -162,25 +172,23 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_util::SetButtonTriggersNavigation(home_->widget()); SetUpDragForHomeButton(); + // Group the start, omnibox, and go button into an hbox. + GtkWidget* location_hbox = gtk_hbox_new(FALSE, 0); + star_.reset(BuildStarButton(l10n_util::GetStringUTF8(IDS_TOOLTIP_STAR))); + gtk_box_pack_start(GTK_BOX(location_hbox), star_->widget(), FALSE, FALSE, 0); - reload_.reset(BuildToolbarButton(IDR_RELOAD, IDR_RELOAD_P, IDR_RELOAD_H, 0, - IDR_RELOAD_MASK, - l10n_util::GetStringUTF8(IDS_TOOLTIP_RELOAD), - GTK_STOCK_REFRESH)); - - location_hbox_ = gtk_hbox_new(FALSE, 0); location_bar_->Init(ShouldOnlyShowLocation()); - gtk_box_pack_start(GTK_BOX(location_hbox_), location_bar_->widget(), TRUE, + gtk_box_pack_start(GTK_BOX(location_hbox), location_bar_->widget(), TRUE, TRUE, 0); - g_signal_connect(location_hbox_, "expose-event", + go_.reset(new GoButtonGtk(location_bar_.get(), browser_)); + gtk_box_pack_start(GTK_BOX(location_hbox), go_->widget(), FALSE, FALSE, 0); + + g_signal_connect(location_hbox, "expose-event", G_CALLBACK(OnLocationHboxExposeThunk), this); - gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox_, TRUE, TRUE, + gtk_box_pack_start(GTK_BOX(toolbar_), location_hbox, TRUE, TRUE, kToolbarWidgetSpacing + (ShouldOnlyShowLocation() ? 1 : 0)); - go_.reset(new GoButtonGtk(location_bar_.get(), browser_)); - gtk_box_pack_start(GTK_BOX(toolbar_), go_->widget(), FALSE, FALSE, 0); - if (!ShouldOnlyShowLocation()) { actions_toolbar_.reset(new BrowserActionsToolbarGtk(browser_)); gtk_box_pack_start(GTK_BOX(toolbar_), actions_toolbar_->widget(), @@ -219,16 +227,17 @@ void BrowserToolbarGtk::Init(Profile* profile, gtk_widget_show(event_box_); gtk_widget_show(alignment_); gtk_widget_show(toolbar_); - gtk_widget_show_all(location_hbox_); - gtk_widget_hide(reload_->widget()); + gtk_widget_show_all(location_hbox); + gtk_widget_hide(star_->widget()); gtk_widget_hide(go_->widget()); } else { gtk_widget_show_all(event_box_); - if (show_home_button_.GetValue()) + if (show_home_button_.GetValue()) { gtk_widget_show(home_->widget()); - else + } else { gtk_widget_hide(home_->widget()); + } if (actions_toolbar_->button_count() == 0) gtk_widget_hide(actions_toolbar_->widget()); @@ -239,7 +248,6 @@ void BrowserToolbarGtk::Init(Profile* profile, location_bar_->UpdateContentSettingsIcons(); SetViewIDs(); - theme_provider_->InitThemesFor(this); } void BrowserToolbarGtk::SetViewIDs() { @@ -248,6 +256,7 @@ void BrowserToolbarGtk::SetViewIDs() { ViewIDUtil::SetID(forward_->widget(), VIEW_ID_FORWARD_BUTTON); ViewIDUtil::SetID(reload_->widget(), VIEW_ID_RELOAD_BUTTON); ViewIDUtil::SetID(home_->widget(), VIEW_ID_HOME_BUTTON); + ViewIDUtil::SetID(star_->widget(), VIEW_ID_STAR_BUTTON); ViewIDUtil::SetID(location_bar_->widget(), VIEW_ID_LOCATION_BAR); ViewIDUtil::SetID(go_->widget(), VIEW_ID_GO_BUTTON); ViewIDUtil::SetID(page_menu_button_.get(), VIEW_ID_PAGE_MENU); @@ -303,6 +312,9 @@ void BrowserToolbarGtk::EnabledStateChangedForCommand(int id, bool enabled) { if (home_.get()) widget = home_->widget(); break; + case IDC_BOOKMARK_PAGE: + widget = star_->widget(); + break; } if (widget) { if (!enabled && GTK_WIDGET_STATE(widget) == GTK_STATE_PRELIGHT) { @@ -398,19 +410,6 @@ void BrowserToolbarGtk::Observe(NotificationType type, gtk_image_set_from_pixbuf(GTK_IMAGE(app_menu_image_), theme_provider_->GetRTLEnabledPixbufNamed(IDR_MENU_CHROME)); - // Update the spacing between the reload button and the location bar. - gtk_box_set_child_packing( - GTK_BOX(toolbar_), reload_->widget(), - FALSE, FALSE, - theme_provider_->UseGtkTheme() ? kToolbarWidgetSpacing : 0, - GTK_PACK_START); - gtk_box_set_child_packing( - GTK_BOX(toolbar_), location_hbox_, - TRUE, TRUE, - (theme_provider_->UseGtkTheme() ? kToolbarWidgetSpacing : 0) + - (ShouldOnlyShowLocation() ? 1 : 0), - GTK_PACK_START); - // When using the GTK+ theme, we need to have the event box be visible so // buttons don't get a halo color from the background. When using Chromium // themes, we want to let the background show through the toolbar. @@ -446,6 +445,38 @@ void BrowserToolbarGtk::UpdateTabContents(TabContents* contents, actions_toolbar_->Update(); } +gfx::Rect BrowserToolbarGtk::GetLocationStackBounds() const { + // The number of pixels from the left or right edges of the location stack to + // "just inside the visible borders". When the omnibox bubble contents are + // aligned with this, the visible borders tacked on to the outsides will line + // up with the visible borders on the location stack. + const int kLocationStackEdgeWidth = 1; + + GtkWidget* left; + GtkWidget* right; + if (base::i18n::IsRTL()) { + left = go_->widget(); + right = star_->widget(); + } else { + left = star_->widget(); + right = go_->widget(); + } + + gint origin_x, origin_y; + DCHECK_EQ(left->window, right->window); + gdk_window_get_origin(left->window, &origin_x, &origin_y); + + gint right_x = origin_x + right->allocation.x + right->allocation.width; + gint left_x = origin_x + left->allocation.x; + DCHECK_LE(left_x, right_x); + + gfx::Rect stack_bounds(left_x, origin_y + left->allocation.y, + right_x - left_x, left->allocation.height); + // Inset the bounds to just inside the visible edges (see comment above). + stack_bounds.Inset(kLocationStackEdgeWidth, 0); + return stack_bounds; +} + // BrowserToolbarGtk, private -------------------------------------------------- CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton( @@ -467,6 +498,18 @@ CustomDrawButton* BrowserToolbarGtk::BuildToolbarButton( return button; } +ToolbarStarToggleGtk* BrowserToolbarGtk::BuildStarButton( + const std::string& localized_tooltip) { + ToolbarStarToggleGtk* button = new ToolbarStarToggleGtk(this); + + gtk_widget_set_tooltip_text(button->widget(), + localized_tooltip.c_str()); + g_signal_connect(button->widget(), "clicked", + G_CALLBACK(OnButtonClickThunk), this); + + return button; +} + GtkWidget* BrowserToolbarGtk::BuildToolbarMenuButton( const std::string& localized_tooltip, OwnedWidgetGtk* owner) { @@ -536,9 +579,42 @@ gboolean BrowserToolbarGtk::OnAlignmentExpose(GtkWidget* widget, gboolean BrowserToolbarGtk::OnLocationHboxExpose(GtkWidget* location_hbox, GdkEventExpose* e) { if (theme_provider_->UseGtkTheme()) { + // To get the proper look surrounding the location bar, we issue raw gtk + // painting commands to the theme engine. We figure out the region from the + // leftmost widget to the rightmost and then tell GTK to perform the same + // drawing commands that draw a GtkEntry on that region. + GtkWidget* star = star_->widget(); + GtkWidget* left = NULL; + GtkWidget* right = NULL; + if (ShouldOnlyShowLocation()) { + left = location_hbox; + right = location_hbox; + } else if (gtk_widget_get_direction(star) == GTK_TEXT_DIR_LTR) { + left = star_->widget(); + right = go_->widget(); + } else { + left = go_->widget(); + right = star_->widget(); + } + + GdkRectangle rec = { + left->allocation.x, + left->allocation.y, + (right->allocation.x - left->allocation.x) + right->allocation.width, + (right->allocation.y - left->allocation.y) + right->allocation.height + }; + + // Make sure our off screen entry has the correct base color if we're in + // secure mode. + gtk_widget_modify_base( + offscreen_entry_.get(), GTK_STATE_NORMAL, + (browser_->toolbar_model()->GetSchemeSecurityLevel() == + ToolbarModel::SECURE) ? + &kSecureColor : NULL); + gtk_util::DrawTextEntryBackground(offscreen_entry_.get(), location_hbox, &e->area, - &location_hbox->allocation); + &rec); } return FALSE; @@ -563,6 +639,8 @@ void BrowserToolbarGtk::OnButtonClick(GtkWidget* button) { location_bar_->Revert(); } else if (home_.get() && button == home_->widget()) { tag = IDC_HOME; + } else if (button == star_->widget()) { + tag = IDC_BOOKMARK_PAGE; } DCHECK_NE(tag, -1) << "Unexpected button click callback"; diff --git a/chrome/browser/gtk/browser_toolbar_gtk.h b/chrome/browser/gtk/browser_toolbar_gtk.h index 9c5f2c8..1ece0db 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -12,8 +12,8 @@ #include "app/menus/simple_menu_model.h" #include "base/scoped_ptr.h" #include "chrome/browser/app_menu_model.h" +#include "chrome/browser/bubble_positioner.h" #include "chrome/browser/command_updater.h" -#include "chrome/browser/gtk/custom_button.h" #include "chrome/browser/gtk/menu_bar_helper.h" #include "chrome/browser/gtk/menu_gtk.h" #include "chrome/browser/page_menu_model.h" @@ -35,6 +35,7 @@ class LocationBarViewGtk; class Profile; class TabContents; class ToolbarModel; +class ToolbarStarToggleGtk; // View class that displays the GTK version of the toolbar and routes gtk // events back to the Browser. @@ -43,6 +44,7 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, public menus::SimpleMenuModel::Delegate, public MenuGtk::Delegate, public NotificationObserver, + public BubblePositioner, public MenuBarHelper::Delegate { public: explicit BrowserToolbarGtk(Browser* browser, BrowserWindowGtk* window); @@ -111,6 +113,11 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // Message that we should react to a state change. void UpdateTabContents(TabContents* contents, bool should_restore_state); + ToolbarStarToggleGtk* star() { return star_.get(); } + + // BubblePositioner: + virtual gfx::Rect GetLocationStackBounds() const; + // MenuBarHelper::Delegate implementation ------------------------------------ virtual void PopupForButton(GtkWidget* button); virtual void PopupForButtonNextTo(GtkWidget* button, @@ -128,6 +135,9 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, const std::string& localized_tooltip, const char* stock_id); + // Create the star button given the tooltip. Returns the widget created. + ToolbarStarToggleGtk* BuildStarButton(const std::string& localized_tooltip); + // Create a menu for the toolbar given the icon id and tooltip. Returns the // widget created. GtkWidget* BuildToolbarMenuButton(const std::string& localized_tooltip, @@ -181,16 +191,14 @@ class BrowserToolbarGtk : public CommandUpdater::CommandObserver, // toolbar placed side by side. GtkWidget* toolbar_; - // Contains all the widgets of the location bar. - GtkWidget* location_hbox_; - // The location bar view. scoped_ptr<LocationBarViewGtk> location_bar_; // All the buttons in the toolbar. scoped_ptr<BackForwardButtonGtk> back_, forward_; - scoped_ptr<CustomDrawButton> home_; scoped_ptr<CustomDrawButton> reload_; + scoped_ptr<CustomDrawButton> home_; + scoped_ptr<ToolbarStarToggleGtk> star_; scoped_ptr<GoButtonGtk> go_; scoped_ptr<BrowserActionsToolbarGtk> actions_toolbar_; OwnedWidgetGtk page_menu_button_, app_menu_button_; diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc index e31d564..03f9228 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -57,7 +57,6 @@ #include "chrome/browser/gtk/info_bubble_gtk.h" #include "chrome/browser/gtk/infobar_container_gtk.h" #include "chrome/browser/gtk/keyword_editor_view.h" -#include "chrome/browser/gtk/location_bar_view_gtk.h" #include "chrome/browser/gtk/nine_box.h" #include "chrome/browser/gtk/options/content_settings_window_gtk.h" #include "chrome/browser/gtk/repost_form_warning_gtk.h" @@ -66,6 +65,7 @@ #include "chrome/browser/gtk/tabs/tab_strip_gtk.h" #include "chrome/browser/gtk/task_manager_gtk.h" #include "chrome/browser/gtk/theme_install_bubble_view_gtk.h" +#include "chrome/browser/gtk/toolbar_star_toggle_gtk.h" #include "chrome/browser/location_bar.h" #include "chrome/browser/page_info_window.h" #include "chrome/browser/pref_service.h" @@ -742,7 +742,7 @@ void BrowserWindowGtk::LoadingAnimationCallback() { } void BrowserWindowGtk::SetStarredState(bool is_starred) { - toolbar_->GetLocationBarView()->SetStarred(is_starred); + toolbar_->star()->SetStarred(is_starred); } gfx::Rect BrowserWindowGtk::GetRestoredBounds() const { @@ -846,7 +846,7 @@ void BrowserWindowGtk::ShowBookmarkManager() { void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) { - toolbar_->GetLocationBarView()->ShowStarBubble(url, !already_bookmarked); + toolbar_->star()->ShowStarBubble(url, !already_bookmarked); } bool BrowserWindowGtk::IsDownloadShelfVisible() const { diff --git a/chrome/browser/gtk/find_bar_gtk.cc b/chrome/browser/gtk/find_bar_gtk.cc index b8785da..e3bc7ff 100644 --- a/chrome/browser/gtk/find_bar_gtk.cc +++ b/chrome/browser/gtk/find_bar_gtk.cc @@ -456,7 +456,6 @@ void FindBarGtk::Observe(NotificationType type, container_height_ = -1; if (theme_provider_->UseGtkTheme()) { - gtk_widget_modify_cursor(text_entry_, NULL, NULL); gtk_widget_modify_base(text_entry_, GTK_STATE_NORMAL, NULL); gtk_widget_modify_text(text_entry_, GTK_STATE_NORMAL, NULL); @@ -483,7 +482,6 @@ void FindBarGtk::Observe(NotificationType type, gtk_misc_set_alignment(GTK_MISC(match_count_label_), 0.5, 0.5); } else { - gtk_widget_modify_cursor(text_entry_, &gfx::kGdkBlack, &gfx::kGdkGray); gtk_widget_modify_base(text_entry_, GTK_STATE_NORMAL, &kEntryBackgroundColor); gtk_widget_modify_text(text_entry_, GTK_STATE_NORMAL, diff --git a/chrome/browser/gtk/gtk_theme_provider.cc b/chrome/browser/gtk/gtk_theme_provider.cc index ab8cd00..651fdda 100644 --- a/chrome/browser/gtk/gtk_theme_provider.cc +++ b/chrome/browser/gtk/gtk_theme_provider.cc @@ -91,30 +91,10 @@ const int kThemeImages[] = { IDR_THEME_FRAME_INCOGNITO_INACTIVE, }; -// A list of icons used in the autocomplete view that should be tinted to the -// current gtk theme selection color so they stand out against the GtkEntry's -// base color. -const int kAutocompleteImages[] = { - IDR_OMNIBOX_HTTP, - IDR_OMNIBOX_HTTP_DARK, - IDR_OMNIBOX_HISTORY, - IDR_OMNIBOX_HISTORY_DARK, - IDR_OMNIBOX_SEARCH, - IDR_OMNIBOX_SEARCH_DARK, - IDR_OMNIBOX_MORE, - IDR_OMNIBOX_MORE_DARK, - IDR_OMNIBOX_STAR, - IDR_OMNIBOX_STAR_DARK, - IDR_GEOLOCATION_ALLOWED_LOCATIONBAR_ICON, - IDR_GEOLOCATION_DENIED_LOCATIONBAR_ICON -}; - bool IsOverridableImage(int id) { static std::set<int> images; if (images.empty()) { images.insert(kThemeImages, kThemeImages + arraysize(kThemeImages)); - images.insert(kAutocompleteImages, - kAutocompleteImages + arraysize(kAutocompleteImages)); const std::set<int>& buttons = BrowserThemeProvider::GetTintableToolbarButtons(); @@ -758,49 +738,15 @@ SkBitmap* GtkThemeProvider::GenerateGtkThemeBitmap(int id) const { return GenerateFrameImage( BrowserThemeProvider::TINT_FRAME_INCOGNITO_INACTIVE); } - // Two sets of omnibox icons, the one for normal http and the one for - // history, include white backgrounds (and are supposed to, for the windows - // chrome-theme). On linux, where we have all sorts of wacky themes and - // color combinations we need to deal with, switch them out with - // transparent background versions. - case IDR_OMNIBOX_HTTP: { - TintMap::const_iterator it = tints_.find( - BrowserThemeProvider::TINT_BUTTONS); - DCHECK(it != tints_.end()); - return GenerateTintedIcon(IDR_OMNIBOX_HTTP_TRANSPARENT, it->second); - } - case IDR_OMNIBOX_HISTORY: { - TintMap::const_iterator it = tints_.find( - BrowserThemeProvider::TINT_BUTTONS); - DCHECK(it != tints_.end()); - return GenerateTintedIcon(IDR_OMNIBOX_HISTORY_TRANSPARENT, it->second); - } - // In GTK mode, the dark versions of the omnibox icons only ever appear in - // the autocomplete popup and only against the current theme's GtkEntry - // base[GTK_STATE_SELECTED] color, so tint the icons so they won't collide - // with the selected color. - case IDR_OMNIBOX_HTTP_DARK: { - color_utils::HSL tint; - GetEntryForegroundHSL(&tint); - return GenerateTintedIcon(IDR_OMNIBOX_HTTP_DARK_TRANSPARENT, tint); - } - case IDR_OMNIBOX_HISTORY_DARK: { - color_utils::HSL tint; - GetEntryForegroundHSL(&tint); - return GenerateTintedIcon(IDR_OMNIBOX_HISTORY_DARK_TRANSPARENT, tint); - } - case IDR_OMNIBOX_SEARCH_DARK: - case IDR_OMNIBOX_MORE_DARK: - case IDR_OMNIBOX_STAR_DARK: { - color_utils::HSL tint; - GetEntryForegroundHSL(&tint); - return GenerateTintedIcon(id, tint); - } default: { + // This is a tinted button. Tint it and return it. + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + scoped_ptr<SkBitmap> button(new SkBitmap(*rb.GetBitmapNamed(id))); TintMap::const_iterator it = tints_.find( BrowserThemeProvider::TINT_BUTTONS); DCHECK(it != tints_.end()); - return GenerateTintedIcon(id, it->second); + return new SkBitmap(SkBitmapOperations::CreateHSLShiftedBitmap( + *button, it->second)); } } } @@ -822,20 +768,6 @@ SkBitmap* GtkThemeProvider::GenerateTabImage(int base_id) const { bg_tint, 0, 0, bg_tint.width(), bg_tint.height())); } -SkBitmap* GtkThemeProvider::GenerateTintedIcon(int base_id, - color_utils::HSL tint) const { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - scoped_ptr<SkBitmap> button(new SkBitmap(*rb.GetBitmapNamed(base_id))); - return new SkBitmap(SkBitmapOperations::CreateHSLShiftedBitmap( - *button, tint)); -} - -void GtkThemeProvider::GetEntryForegroundHSL(color_utils::HSL* tint) const { - GtkStyle* style = gtk_rc_get_style(fake_entry_.get()); - const GdkColor color = style->text[GTK_STATE_SELECTED]; - color_utils::SkColorToHSL(GdkToSkColor(&color), tint); -} - void GtkThemeProvider::OnDestroyChromeButton(GtkWidget* button) { std::vector<GtkWidget*>::iterator it = find(chrome_buttons_.begin(), chrome_buttons_.end(), button); diff --git a/chrome/browser/gtk/gtk_theme_provider.h b/chrome/browser/gtk/gtk_theme_provider.h index 227bbbe..23c0a57 100644 --- a/chrome/browser/gtk/gtk_theme_provider.h +++ b/chrome/browser/gtk/gtk_theme_provider.h @@ -163,13 +163,6 @@ class GtkThemeProvider : public BrowserThemeProvider, // Takes the base frame image |base_id| and tints it with |tint_id|. SkBitmap* GenerateTabImage(int base_id) const; - // Tints an icon based on tint. - SkBitmap* GenerateTintedIcon(int base_id, color_utils::HSL tint) const; - - // Returns a tint that's the color of the current highlighted text in an - // entry. - void GetEntryForegroundHSL(color_utils::HSL* tint) const; - // A notification from the GtkChromeButton GObject destructor that we should // remove it from our internal list. CHROMEGTK_CALLBACK_0(GtkThemeProvider, void, OnDestroyChromeButton); diff --git a/chrome/browser/gtk/gtk_util.cc b/chrome/browser/gtk/gtk_util.cc index 4d5796a..3013b12 100644 --- a/chrome/browser/gtk/gtk_util.cc +++ b/chrome/browser/gtk/gtk_util.cc @@ -17,13 +17,11 @@ #include "base/i18n/rtl.h" #include "base/linux_util.h" #include "base/logging.h" -#include "chrome/browser/autocomplete/autocomplete.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/common/renderer_preferences.h" -#include "googleurl/src/gurl.h" #include "grit/theme_resources.h" #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" @@ -871,32 +869,4 @@ guint32 XTimeNow() { return ts.tv_sec * 1000 + ts.tv_nsec / 1000000; } -bool URLFromPrimarySelection(Profile* profile, GURL* url) { - GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); - DCHECK(clipboard); - gchar* selection_text = gtk_clipboard_wait_for_text(clipboard); - if (!selection_text) - return false; - - // Use autocomplete to clean up the text, going so far as to turn it into - // a search query if necessary. - AutocompleteController controller(profile); - controller.Start(UTF8ToWide(selection_text), - std::wstring(), // desired_tld - true, // prevent_inline_autocomplete - false, // prefer_keyword - true); // synchronous_only - g_free(selection_text); - const AutocompleteResult& result = controller.result(); - AutocompleteResult::const_iterator it = result.default_match(); - if (it == result.end()) - return false; - - if (!it->destination_url.is_valid()) - return false; - - *url = it->destination_url; - return true; -} - } // namespace gtk_util diff --git a/chrome/browser/gtk/gtk_util.h b/chrome/browser/gtk/gtk_util.h index 1d8b6d3..e28778a 100644 --- a/chrome/browser/gtk/gtk_util.h +++ b/chrome/browser/gtk/gtk_util.h @@ -17,8 +17,6 @@ typedef struct _GtkWidget GtkWidget; class GtkThemeProvider; -class GURL; -class Profile; struct RendererPreferences; // from common/renderer_preferences.h namespace event_utils { @@ -272,11 +270,6 @@ void SetWMLastUserActionTime(GtkWindow* window); // function, instead using the timestamp from the latest GDK event. guint32 XTimeNow(); -// Uses the autocomplete controller for |profile| to convert the contents of the -// PRIMARY selection to a parsed URL. Returns true and sets |url| on success, -// otherwise returns false. -bool URLFromPrimarySelection(Profile* profile, GURL* url); - } // namespace gtk_util #endif // CHROME_BROWSER_GTK_GTK_UTIL_H_ diff --git a/chrome/browser/gtk/location_bar_view_gtk.cc b/chrome/browser/gtk/location_bar_view_gtk.cc index 59da90c..453a8f54 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -6,7 +6,6 @@ #include <string> -#include "app/gtk_dnd_util.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/basictypes.h" @@ -27,7 +26,6 @@ #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_tabs_module.h" #include "chrome/browser/extensions/extensions_service.h" -#include "chrome/browser/gtk/bookmark_bubble_gtk.h" #include "chrome/browser/gtk/cairo_cached_surface.h" #include "chrome/browser/gtk/content_setting_bubble_gtk.h" #include "chrome/browser/gtk/extension_popup_gtk.h" @@ -35,7 +33,6 @@ #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/gtk/rounded_window.h" -#include "chrome/browser/gtk/view_id_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" @@ -76,12 +73,10 @@ const int kHboxBorder = 4; // Padding between the elements in the bar. static const int kInnerPadding = 4; -// Colors used to draw the EV certificate rounded bubble. -const GdkColor kEvSecureTextColor = GDK_COLOR_RGB(0x07, 0x95, 0x00); -const GdkColor kEvSecureBackgroundColor = GDK_COLOR_RGB(0xef, 0xfc, 0xef); -const GdkColor kEvSecureBorderColor = GDK_COLOR_RGB(0x90, 0xc3, 0x90); - -// Colors used to draw the Tab to Search rounded bubble. +// TODO(deanm): Eventually this should be painted with the background png +// image, but for now we get pretty close by just drawing a solid border. +const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); +const GdkColor kEvTextColor = GDK_COLOR_RGB(0x00, 0x96, 0x14); // Green. const GdkColor kKeywordBackgroundColor = GDK_COLOR_RGB(0xf0, 0xf4, 0xfa); const GdkColor kKeywordBorderColor = GDK_COLOR_RGB(0xcb, 0xde, 0xf7); @@ -136,22 +131,19 @@ std::wstring CalculateMinString(const std::wstring& description) { // LocationBarViewGtk // static -const GdkColor LocationBarViewGtk::kBackgroundColor = - GDK_COLOR_RGB(255, 255, 255); - -LocationBarViewGtk::LocationBarViewGtk(Browser* browser) - : star_image_(NULL), - starred_(false), - security_icon_event_box_(NULL), - ev_secure_icon_image_(NULL), - secure_icon_image_(NULL), +const GdkColor LocationBarViewGtk::kBackgroundColorByLevel[3] = { + GDK_COLOR_RGB(255, 245, 195), // SecurityLevel SECURE: Yellow. + GDK_COLOR_RGB(255, 255, 255), // SecurityLevel NORMAL: White. + GDK_COLOR_RGB(255, 255, 255), // SecurityLevel INSECURE: White. +}; + +LocationBarViewGtk::LocationBarViewGtk( + const BubblePositioner* bubble_positioner, + Browser* browser) + : security_icon_event_box_(NULL), + security_lock_icon_image_(NULL), security_warning_icon_image_(NULL), - security_error_icon_image_(NULL), - site_type_alignment_(NULL), - site_type_event_box_(NULL), - location_icon_image_(NULL), - enable_location_drag_(false), - security_info_label_(NULL), + info_label_(NULL), tab_to_search_box_(NULL), tab_to_search_full_label_(NULL), tab_to_search_partial_label_(NULL), @@ -159,10 +151,12 @@ LocationBarViewGtk::LocationBarViewGtk(Browser* browser) tab_to_search_hint_leading_label_(NULL), tab_to_search_hint_icon_(NULL), tab_to_search_hint_trailing_label_(NULL), + type_to_search_hint_(NULL), profile_(NULL), command_updater_(browser->command_updater()), toolbar_model_(browser->toolbar_model()), browser_(browser), + bubble_positioner_(bubble_positioner), disposition_(CURRENT_TAB), transition_(PageTransition::TYPED), first_run_bubble_(this), @@ -170,12 +164,12 @@ LocationBarViewGtk::LocationBarViewGtk(Browser* browser) theme_provider_(NULL), entry_box_width_(0), show_selected_keyword_(false), - show_keyword_hint_(false) { + show_keyword_hint_(false), + show_search_hint_(false) { } LocationBarViewGtk::~LocationBarViewGtk() { // All of our widgets should have be children of / owned by the alignment. - star_.Destroy(); hbox_.Destroy(); content_setting_hbox_.Destroy(); page_action_hbox_.Destroy(); @@ -183,8 +177,14 @@ LocationBarViewGtk::~LocationBarViewGtk() { void LocationBarViewGtk::Init(bool popup_window_mode) { popup_window_mode_ = popup_window_mode; + location_entry_.reset(new AutocompleteEditViewGtk(this, + toolbar_model_, + profile_, + command_updater_, + popup_window_mode_, + bubble_positioner_)); + location_entry_->Init(); - // Create the widget first, so we can pass it to the AutocompleteEditViewGtk. hbox_.Own(gtk_hbox_new(FALSE, kInnerPadding)); gtk_container_set_border_width(GTK_CONTAINER(hbox_.get()), kHboxBorder); // We will paint for the alignment, to paint the background and border. @@ -193,23 +193,30 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { // the home button on/off. gtk_widget_set_redraw_on_allocate(hbox_.get(), TRUE); - // Now initialize the AutocompleteEditViewGtk. - location_entry_.reset(new AutocompleteEditViewGtk(this, - toolbar_model_, - profile_, - command_updater_, - popup_window_mode_, - hbox_.get())); - location_entry_->Init(); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + security_lock_icon_image_ = gtk_image_new_from_pixbuf( + rb.GetPixbufNamed(IDR_LOCK)); + gtk_widget_set_name(security_lock_icon_image_, "chrome-security-lock-icon"); + gtk_widget_hide(GTK_WIDGET(security_lock_icon_image_)); + security_warning_icon_image_ = gtk_image_new(); + gtk_widget_set_name(security_warning_icon_image_, + "chrome-security-warning-icon"); + gtk_widget_hide(GTK_WIDGET(security_warning_icon_image_)); + + info_label_ = gtk_label_new(NULL); + gtk_widget_modify_base(info_label_, GTK_STATE_NORMAL, + &LocationBarViewGtk::kBackgroundColorByLevel[0]); + gtk_widget_hide(GTK_WIDGET(info_label_)); + gtk_widget_set_name(info_label_, + "chrome-location-bar-info-label"); g_signal_connect(hbox_.get(), "expose-event", G_CALLBACK(&HandleExposeThunk), this); - BuildSiteTypeArea(); - - // Put |tab_to_search_box_|, |location_entry_|, and |tab_to_search_hint_| into - // a sub hbox, so that we can make this part horizontally shrinkable without - // affecting other elements in the location bar. + // Put |tab_to_search_box_|, |location_entry_|, |tab_to_search_hint_| and + // |type_to_search_hint_| into a sub hbox, so that we can make this part + // horizontally shrinkable without affecting other elements in the location + // bar. GtkWidget* entry_box = gtk_hbox_new(FALSE, kInnerPadding); gtk_widget_show(entry_box); gtk_widget_set_size_request(entry_box, 0, -1); @@ -230,22 +237,13 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { tab_to_search_full_label_, 0, 0); gtk_fixed_put(GTK_FIXED(tab_to_search_label_fixed), tab_to_search_partial_label_, 0, 0); - GtkWidget* tab_to_search_hbox = gtk_hbox_new(FALSE, 0); - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - GtkWidget* tab_to_search_lens = gtk_image_new_from_pixbuf( - rb.GetPixbufNamed(IDR_OMNIBOX_SEARCH)); - gtk_box_pack_start(GTK_BOX(tab_to_search_hbox), tab_to_search_lens, - FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(tab_to_search_hbox), tab_to_search_label_fixed, - FALSE, FALSE, 0); // This creates a box around the keyword text with a border, background color, // and padding around the text. tab_to_search_box_ = gtk_util::CreateGtkBorderBin( - tab_to_search_hbox, NULL, 1, 1, 1, 3); + tab_to_search_label_fixed, NULL, 1, 1, 2, 2); gtk_widget_set_name(tab_to_search_box_, "chrome-tab-to-search-box"); - gtk_util::ActAsRoundedWindow(tab_to_search_box_, kKeywordBorderColor, - kCornerSize, + gtk_util::ActAsRoundedWindow(tab_to_search_box_, kBorderColor, kCornerSize, gtk_util::ROUNDED_ALL, gtk_util::BORDER_ALL); // Show all children widgets of |tab_to_search_box_| initially, except // |tab_to_search_partial_label_|. @@ -271,7 +269,7 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { kBottomMargin + kBorderThickness, 0, 0); } - gtk_container_add(GTK_CONTAINER(align), location_entry_->GetNativeView()); + gtk_container_add(GTK_CONTAINER(align), location_entry_->widget()); gtk_box_pack_start(GTK_BOX(entry_box), align, TRUE, TRUE, 0); // Tab to search notification (the hint on the right hand side). @@ -299,11 +297,36 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { // doesn't work, someone is probably calling show_all on our parent box. gtk_box_pack_end(GTK_BOX(entry_box), tab_to_search_hint_, FALSE, FALSE, 0); - // We don't show the star in popups, app windows, etc. - if (!ShouldOnlyShowLocation()) { - CreateStarButton(); - gtk_box_pack_end(GTK_BOX(hbox_.get()), star_.get(), FALSE, FALSE, 0); - } + // Type to search hint is on the right hand side. + type_to_search_hint_ = + gtk_label_new(l10n_util::GetStringUTF8(IDS_OMNIBOX_EMPTY_TEXT).c_str()); + gtk_widget_set_sensitive(type_to_search_hint_, FALSE); + gtk_box_pack_end(GTK_BOX(entry_box), type_to_search_hint_, FALSE, FALSE, 0); + + // Pack info_label_ and security icons in hbox. We hide/show them + // by SetSecurityIcon() and SetInfoText(). + gtk_box_pack_end(GTK_BOX(hbox_.get()), info_label_, FALSE, FALSE, 0); + + GtkWidget* security_icon_box = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(security_icon_box), + security_lock_icon_image_, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(security_icon_box), + security_warning_icon_image_, FALSE, FALSE, 0); + + // GtkImage is a "no window" widget and requires a GtkEventBox to receive + // events. + security_icon_event_box_ = gtk_event_box_new(); + // Make the event box not visible so it does not paint a background. + gtk_event_box_set_visible_window(GTK_EVENT_BOX(security_icon_event_box_), + FALSE); + g_signal_connect(security_icon_event_box_, "button-press-event", + G_CALLBACK(&OnSecurityIconPressed), this); + + gtk_container_add(GTK_CONTAINER(security_icon_event_box_), security_icon_box); + gtk_widget_set_name(security_icon_event_box_, + "chrome-security-icon-eventbox"); + gtk_box_pack_end(GTK_BOX(hbox_.get()), security_icon_event_box_, + FALSE, FALSE, 0); content_setting_hbox_.Own(gtk_hbox_new(FALSE, kInnerPadding)); gtk_widget_set_name(content_setting_hbox_.get(), @@ -327,7 +350,9 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { FALSE, FALSE, 0); // Until we switch to vector graphics, force the font size of labels. - gtk_util::ForceFontSizePixels(security_info_label_, + gtk_util::ForceFontSizePixels(type_to_search_hint_, + browser_defaults::kAutocompleteEditFontPixelSize); + gtk_util::ForceFontSizePixels(info_label_, browser_defaults::kAutocompleteEditFontPixelSize); gtk_util::ForceFontSizePixels(tab_to_search_full_label_, browser_defaults::kAutocompleteEditFontPixelSize); @@ -337,6 +362,8 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { browser_defaults::kAutocompleteEditFontPixelSize); gtk_util::ForceFontSizePixels(tab_to_search_hint_trailing_label_, browser_defaults::kAutocompleteEditFontPixelSize); + gtk_util::ForceFontSizePixels(type_to_search_hint_, + browser_defaults::kAutocompleteEditFontPixelSize); registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED, @@ -345,71 +372,6 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { theme_provider_->InitThemesFor(this); } -void LocationBarViewGtk::BuildSiteTypeArea() { - location_icon_image_ = gtk_image_new(); - gtk_widget_set_name(location_icon_image_, "chrome-location-icon"); - gtk_widget_show(location_icon_image_); - - security_info_label_ = gtk_label_new(NULL); - gtk_widget_modify_fg(GTK_WIDGET(security_info_label_), GTK_STATE_NORMAL, - &kEvSecureTextColor); - gtk_widget_set_name(security_info_label_, - "chrome-location-bar-security-info-label"); - - GtkWidget* site_type_hbox = gtk_hbox_new(FALSE, 0); - gtk_box_pack_start(GTK_BOX(site_type_hbox), location_icon_image_, - FALSE, FALSE, 0); - gtk_box_pack_start(GTK_BOX(site_type_hbox), security_info_label_, - FALSE, FALSE, kCornerSize); - - site_type_event_box_ = gtk_event_box_new(); - gtk_widget_modify_bg(site_type_event_box_, GTK_STATE_NORMAL, - &kEvSecureBackgroundColor); - - // Make the event box not visible so it does not paint a background. - gtk_event_box_set_visible_window(GTK_EVENT_BOX(site_type_event_box_), - FALSE); - gtk_widget_set_name(site_type_event_box_, - "chrome-location-icon-eventbox"); - gtk_container_add(GTK_CONTAINER(site_type_event_box_), - site_type_hbox); - - // Put the event box in an alignment to get the padding correct. - site_type_alignment_ = gtk_alignment_new(0, 0, 1, 1); - gtk_alignment_set_padding(GTK_ALIGNMENT(site_type_alignment_), - 0, 0, 1, 0); - gtk_container_add(GTK_CONTAINER(site_type_alignment_), - site_type_event_box_); - gtk_box_pack_start(GTK_BOX(hbox_.get()), site_type_alignment_, - FALSE, FALSE, 0); - - // Set up drags. -} - -void LocationBarViewGtk::SetSiteTypeDragSource() { - bool enable = !location_entry()->IsEditingOrEmpty(); - if (enable_location_drag_ == enable) - return; - enable_location_drag_ = enable; - - if (!enable) { - gtk_drag_source_unset(site_type_event_box_); - return; - } - - gtk_drag_source_set(site_type_event_box_, GDK_BUTTON1_MASK, - NULL, 0, GDK_ACTION_COPY); - gtk_dnd_util::SetSourceTargetListFromCodeMask(site_type_event_box_, - gtk_dnd_util::TEXT_PLAIN | - gtk_dnd_util::TEXT_URI_LIST | - gtk_dnd_util::CHROME_NAMED_URL); - - g_signal_connect(site_type_event_box_, "button-release-event", - G_CALLBACK(&OnIconReleasedThunk), this); - g_signal_connect(site_type_event_box_, "drag-data-get", - G_CALLBACK(&OnIconDragDataThunk), this); -} - void LocationBarViewGtk::SetProfile(Profile* profile) { profile_ = profile; } @@ -448,9 +410,10 @@ GtkWidget* LocationBarViewGtk::GetPageActionWidget( } void LocationBarViewGtk::Update(const TabContents* contents) { - UpdateSiteTypeArea(); + SetSecurityIcon(toolbar_model_->GetIcon()); UpdateContentSettingsIcons(); UpdatePageActions(); + SetInfoText(); location_entry_->Update(contents); // The security level (background color) could have changed, etc. if (theme_provider_->UseGtkTheme()) { @@ -498,12 +461,12 @@ void LocationBarViewGtk::OnAutocompleteAccept(const GURL& url, } void LocationBarViewGtk::OnChanged() { - UpdateSiteTypeArea(); - const std::wstring keyword(location_entry_->model()->keyword()); const bool is_keyword_hint = location_entry_->model()->is_keyword_hint(); show_selected_keyword_ = !keyword.empty() && !is_keyword_hint; show_keyword_hint_ = !keyword.empty() && is_keyword_hint; + show_search_hint_ = location_entry_->model()->show_search_hint(); + DCHECK(keyword.empty() || !show_search_hint_); if (show_selected_keyword_) SetKeywordLabel(keyword); @@ -514,20 +477,6 @@ void LocationBarViewGtk::OnChanged() { AdjustChildrenVisibility(); } -void LocationBarViewGtk::CreateStarButton() { - star_.Own(gtk_event_box_new()); - gtk_event_box_set_visible_window(GTK_EVENT_BOX(star_.get()), FALSE); - star_image_ = gtk_image_new(); - gtk_container_add(GTK_CONTAINER(star_.get()), star_image_); - gtk_widget_show_all(star_.get()); - ViewIDUtil::SetID(star_.get(), VIEW_ID_STAR_BUTTON); - - gtk_widget_set_tooltip_text(star_.get(), - l10n_util::GetStringUTF8(IDS_TOOLTIP_STAR).c_str()); - g_signal_connect(star_.get(), "button-press-event", - G_CALLBACK(OnStarButtonPressThunk), this); -} - void LocationBarViewGtk::OnInputInProgress(bool in_progress) { // This is identical to the Windows code, except that we don't proxy the call // back through the Toolbar, and just access the model here. @@ -662,7 +611,7 @@ void LocationBarViewGtk::UpdatePageActions() { // If there are no visible page actions, hide the hbox too, so that it does // not affect the padding in the location bar. - if (PageActionVisibleCount() && !ShouldOnlyShowLocation()) + if (PageActionVisibleCount()) gtk_widget_show(page_action_hbox_.get()); else gtk_widget_hide(page_action_hbox_.get()); @@ -741,6 +690,11 @@ void LocationBarViewGtk::Observe(NotificationType type, gtk_util::SetLabelColor(tab_to_search_partial_label_, NULL); gtk_util::SetLabelColor(tab_to_search_hint_leading_label_, NULL); gtk_util::SetLabelColor(tab_to_search_hint_trailing_label_, NULL); + gtk_util::SetLabelColor(type_to_search_hint_, NULL); + + gtk_image_set_from_stock(GTK_IMAGE(security_warning_icon_image_), + GTK_STOCK_DIALOG_WARNING, + GTK_ICON_SIZE_SMALL_TOOLBAR); } else { gtk_widget_modify_bg(tab_to_search_box_, GTK_STATE_NORMAL, &kKeywordBackgroundColor); @@ -753,11 +707,12 @@ void LocationBarViewGtk::Observe(NotificationType type, &kHintTextColor); gtk_util::SetLabelColor(tab_to_search_hint_trailing_label_, &kHintTextColor); - } + gtk_util::SetLabelColor(type_to_search_hint_, &kHintTextColor); - UpdateStarIcon(); - UpdateSiteTypeArea(); - UpdateContentSettingsIcons(); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + gtk_image_set_from_pixbuf(GTK_IMAGE(security_warning_icon_image_), + rb.GetPixbufNamed(IDR_WARNING)); + } } gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, @@ -790,7 +745,8 @@ gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, alloc_rect->width, alloc_rect->height - kTopMargin - kBottomMargin - 2 * kBorderThickness); - gdk_cairo_set_source_color(cr, const_cast<GdkColor*>(&kBackgroundColor)); + gdk_cairo_set_source_color(cr, const_cast<GdkColor*>( + &kBackgroundColorByLevel[toolbar_model_->GetSchemeSecurityLevel()])); cairo_fill(cr); cairo_destroy(cr); @@ -799,52 +755,45 @@ gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, return FALSE; // Continue propagating the expose. } -void LocationBarViewGtk::UpdateSiteTypeArea() { - // The icon is always visible except when the |tab_to_search_box_| is visible. - if (!location_entry_->model()->keyword().empty() && - !location_entry_->model()->is_keyword_hint()) { - gtk_widget_hide(site_type_area()); - return; +void LocationBarViewGtk::SetSecurityIcon(ToolbarModel::Icon icon) { + gtk_widget_hide(GTK_WIDGET(security_lock_icon_image_)); + gtk_widget_hide(GTK_WIDGET(security_warning_icon_image_)); + if (icon != ToolbarModel::NO_ICON) + gtk_widget_show(GTK_WIDGET(security_icon_event_box_)); + else + gtk_widget_hide(GTK_WIDGET(security_icon_event_box_)); + switch (icon) { + case ToolbarModel::LOCK_ICON: + gtk_widget_show(GTK_WIDGET(security_lock_icon_image_)); + break; + case ToolbarModel::WARNING_ICON: + gtk_widget_show(GTK_WIDGET(security_warning_icon_image_)); + break; + case ToolbarModel::NO_ICON: + break; + default: + NOTREACHED(); + break; } +} - int resource_id = location_entry_->GetIcon(); - gtk_image_set_from_pixbuf(GTK_IMAGE(location_icon_image_), - theme_provider_->GetPixbufNamed(resource_id)); - - if (toolbar_model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) { - if (!gtk_util::IsActingAsRoundedWindow(site_type_event_box_)) { - // Fun fact: If wee try to make |site_type_event_box_| act as a - // rounded window while it doesn't have a visible window, GTK interprets - // this as a sign that it should paint the skyline texture into the - // omnibox. - gtk_event_box_set_visible_window(GTK_EVENT_BOX(site_type_event_box_), - TRUE); - - gtk_util::ActAsRoundedWindow(site_type_event_box_, - kEvSecureBorderColor, - kCornerSize, - gtk_util::ROUNDED_ALL, - gtk_util::BORDER_ALL); - } - - std::wstring info_text = toolbar_model_->GetEVCertName(); - gtk_label_set_text(GTK_LABEL(security_info_label_), - WideToUTF8(info_text).c_str()); - gtk_widget_show(GTK_WIDGET(security_info_label_)); +void LocationBarViewGtk::SetInfoText() { + std::wstring info_text, info_tooltip; + ToolbarModel::InfoTextType info_text_type = + toolbar_model_->GetInfoText(&info_text, &info_tooltip); + if (info_text_type == ToolbarModel::INFO_EV_TEXT) { + gtk_widget_modify_fg(GTK_WIDGET(info_label_), GTK_STATE_NORMAL, + &kEvTextColor); + gtk_widget_show(GTK_WIDGET(info_label_)); } else { - if (gtk_util::IsActingAsRoundedWindow(site_type_event_box_)) { - gtk_util::StopActingAsRoundedWindow(site_type_event_box_); - - gtk_event_box_set_visible_window(GTK_EVENT_BOX(site_type_event_box_), - FALSE); - } - - gtk_widget_hide(GTK_WIDGET(security_info_label_)); + DCHECK_EQ(info_text_type, ToolbarModel::INFO_NO_INFO); + DCHECK(info_text.empty()); + // Clear info_text. Should we reset the fg here? + gtk_widget_hide(GTK_WIDGET(info_label_)); } - - gtk_widget_show(site_type_area()); - - SetSiteTypeDragSource(); + gtk_label_set_text(GTK_LABEL(info_label_), WideToUTF8(info_text).c_str()); + gtk_widget_set_tooltip_text(GTK_WIDGET(info_label_), + WideToUTF8(info_tooltip).c_str()); } void LocationBarViewGtk::SetKeywordLabel(const std::wstring& keyword) { @@ -915,114 +864,46 @@ void LocationBarViewGtk::ShowFirstRunBubbleInternal( FirstRunBubble::Show(profile_, anchor, rect, bubble_type); } -gboolean LocationBarViewGtk::OnIconReleased(GtkWidget* sender, - GdkEventButton* event) { - TabContents* tab = GetTabContents(); - - if (event->button == 1) { - // Do not show page info if the user has been editing the location - // bar, or the location bar is at the NTP. - if (location_entry()->IsEditingOrEmpty()) - return FALSE; - - // (0,0) event coordinates indicates that the release came at the end of - // a drag. - if (event->x == 0 && event->y == 0) - return FALSE; - - NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); - if (!nav_entry) { - NOTREACHED(); - return FALSE; - } - tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); - return TRUE; - } else if (event->button == 2) { - // When the user middle clicks on the location icon, try to open the - // contents of the PRIMARY selection in the current tab. - // If the click was outside our bounds, do nothing. - if (!gtk_util::WidgetBounds(sender).Contains( - gfx::Point(event->x, event->y))) { - return FALSE; - } - - GURL url; - if (!gtk_util::URLFromPrimarySelection(profile_, &url)) - return FALSE; - - tab->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED); - return TRUE; +// static +gboolean LocationBarViewGtk::OnSecurityIconPressed( + GtkWidget* sender, + GdkEventButton* event, + LocationBarViewGtk* location_bar) { + TabContents* tab = location_bar->GetTabContents(); + NavigationEntry* nav_entry = tab->controller().GetActiveEntry(); + if (!nav_entry) { + NOTREACHED(); + return true; } - - return FALSE; -} - -void LocationBarViewGtk::OnIconDragData(GtkWidget* sender, - GdkDragContext* context, - GtkSelectionData* data, - guint info, guint time) { - TabContents* tab = GetTabContents(); - if (!tab) - return; - gtk_dnd_util::WriteURLWithName(data, tab->GetURL(), tab->GetTitle(), info); + tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); + return true; } -void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkWidget* sender, - GtkAllocation* allocation) { +void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkAllocation* allocation) { if (entry_box_width_ != allocation->width) { entry_box_width_ = allocation->width; AdjustChildrenVisibility(); } } -gboolean LocationBarViewGtk::OnStarButtonPress(GtkWidget* widget, - GdkEventButton* event) { - browser_->ExecuteCommand(IDC_BOOKMARK_PAGE); - return FALSE; -} - -void LocationBarViewGtk::ShowStarBubble(const GURL& url, - bool newly_bookmarked) { - if (!star_.get()) - return; - - BookmarkBubbleGtk::Show(star_.get(), profile_, url, newly_bookmarked); -} - -void LocationBarViewGtk::SetStarred(bool starred) { - if (starred == starred_) - return; - - starred_ = starred; - UpdateStarIcon(); -} - -void LocationBarViewGtk::UpdateStarIcon() { - if (!star_.get()) - return; - - gtk_image_set_from_pixbuf(GTK_IMAGE(star_image_), - theme_provider_->GetPixbufNamed( - starred_ ? IDR_OMNIBOX_STAR_LIT : IDR_OMNIBOX_STAR)); -} - -bool LocationBarViewGtk::ShouldOnlyShowLocation() { - return browser_->type() != Browser::TYPE_NORMAL; -} - void LocationBarViewGtk::AdjustChildrenVisibility() { int text_width = location_entry_->TextWidth(); int available_width = entry_box_width_ - text_width - kInnerPadding; - // Only one of |tab_to_search_box_| and |tab_to_search_hint_| can be visible - // at the same time. + // Only one of |tab_to_search_box_|, |tab_to_search_hint_| and + // |type_to_search_hint_| can be visible at the same time. if (!show_selected_keyword_ && GTK_WIDGET_VISIBLE(tab_to_search_box_)) { gtk_widget_hide(tab_to_search_box_); } else if (!show_keyword_hint_ && GTK_WIDGET_VISIBLE(tab_to_search_hint_)) { gtk_widget_hide(tab_to_search_hint_); location_entry_->set_enable_tab_to_search(false); + } else if (!show_search_hint_ && GTK_WIDGET_VISIBLE(type_to_search_hint_)) { + gtk_widget_hide(type_to_search_hint_); } + if (!show_selected_keyword_ && !show_keyword_hint_ && !show_search_hint_) + return; + if (show_selected_keyword_) { GtkRequisition box, full_label, partial_label; gtk_widget_size_request(tab_to_search_box_, &box); @@ -1071,6 +952,13 @@ void LocationBarViewGtk::AdjustChildrenVisibility() { gtk_widget_show(tab_to_search_hint_); location_entry_->set_enable_tab_to_search(true); } + } else if (show_search_hint_) { + GtkRequisition requisition; + gtk_widget_size_request(type_to_search_hint_, &requisition); + if (requisition.width >= available_width) + gtk_widget_hide(type_to_search_hint_); + else if (requisition.width < available_width) + gtk_widget_show(type_to_search_hint_); } } @@ -1108,12 +996,14 @@ LocationBarViewGtk::ContentSettingImageViewGtk::~ContentSettingImageViewGtk() { void LocationBarViewGtk::ContentSettingImageViewGtk::UpdateFromTabContents( const TabContents* tab_contents) { + int old_icon = content_setting_image_model_->get_icon(); content_setting_image_model_->UpdateFromTabContents(tab_contents); if (content_setting_image_model_->is_visible()) { - gtk_image_set_from_pixbuf(GTK_IMAGE(image_.get()), - GtkThemeProvider::GetFrom(profile_)->GetPixbufNamed( + if (old_icon != content_setting_image_model_->get_icon()) { + gtk_image_set_from_pixbuf(GTK_IMAGE(image_.get()), + ResourceBundle::GetSharedInstance().GetPixbufNamed( content_setting_image_model_->get_icon())); - + } gtk_widget_set_tooltip_text(widget(), content_setting_image_model_->get_tooltip().c_str()); gtk_widget_show(widget()); diff --git a/chrome/browser/gtk/location_bar_view_gtk.h b/chrome/browser/gtk/location_bar_view_gtk.h index dd2db25..d31655b 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -10,7 +10,6 @@ #include <map> #include <string> -#include "app/gtk_signal.h" #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/scoped_vector.h" @@ -31,6 +30,7 @@ #include "webkit/glue/window_open_disposition.h" class AutocompleteEditViewGtk; +class BubblePositioner; class Browser; class CommandUpdater; class ContentSettingImageModel; @@ -47,7 +47,8 @@ class LocationBarViewGtk : public AutocompleteEditController, public LocationBarTesting, public NotificationObserver { public: - explicit LocationBarViewGtk(Browser* browser); + LocationBarViewGtk(const BubblePositioner* bubble_positioner, + Browser* browser_); virtual ~LocationBarViewGtk(); void Init(bool popup_window_mode); @@ -77,12 +78,6 @@ class LocationBarViewGtk : public AutocompleteEditController, // restore saved state that the tab holds. void Update(const TabContents* tab_for_state_restoring); - // Show the bookmark bubble. - void ShowStarBubble(const GURL& url, bool newly_boomkarked); - - // Set the starred state of the bookmark star. - void SetStarred(bool starred); - // Implement the AutocompleteEditController interface. virtual void OnAutocompleteAccept(const GURL& url, WindowOpenDisposition disposition, @@ -109,9 +104,6 @@ class LocationBarViewGtk : public AutocompleteEditController, virtual void InvalidatePageActions(); virtual void SaveStateToContents(TabContents* contents); virtual void Revert(); - virtual const AutocompleteEditView* location_entry() const { - return location_entry_.get(); - } virtual AutocompleteEditView* location_entry() { return location_entry_.get(); } @@ -129,8 +121,9 @@ class LocationBarViewGtk : public AutocompleteEditController, const NotificationSource& source, const NotificationDetails& details); - // Edit background color. - static const GdkColor kBackgroundColor; + // Translation between a security level and the background color. Both the + // location bar and edit have to manage and match the background color. + static const GdkColor kBackgroundColorByLevel[3]; private: class ContentSettingImageViewGtk : public InfoBubbleGtkDelegate { @@ -148,8 +141,12 @@ class LocationBarViewGtk : public AutocompleteEditController, void UpdateFromTabContents(const TabContents* tab_contents); private: - CHROMEGTK_CALLBACK_1(ContentSettingImageViewGtk, gboolean, OnButtonPressed, - GdkEvent*); + static gboolean OnButtonPressedThunk(GtkWidget* sender, + GdkEvent* event, + ContentSettingImageViewGtk* view) { + return view->OnButtonPressed(sender, event); + } + gboolean OnButtonPressed(GtkWidget* sender, GdkEvent* event); // InfoBubbleDelegate overrides: virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble, @@ -211,10 +208,19 @@ class LocationBarViewGtk : public AutocompleteEditController, // with a debugger window attached. Returns true if a popup was shown. bool ShowPopup(bool devtools); - CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, - GdkEvent*); - CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, - GdkEventExpose*); + static gboolean OnButtonPressedThunk(GtkWidget* sender, + GdkEvent* event, + PageActionViewGtk* page_action_view) { + return page_action_view->OnButtonPressed(sender, event); + } + gboolean OnButtonPressed(GtkWidget* sender, GdkEvent* event); + + static gboolean OnExposeEventThunk(GtkWidget* widget, + GdkEventExpose* event, + PageActionViewGtk* page_action_view) { + return page_action_view->OnExposeEvent(widget, event); + } + gboolean OnExposeEvent(GtkWidget* widget, GdkEventExpose* event); // The location bar view that owns us. LocationBarViewGtk* owner_; @@ -262,30 +268,20 @@ class LocationBarViewGtk : public AutocompleteEditController, }; friend class PageActionViewGtk; - // Creates, initializes, and packs the location icon, EV certificate name, - // and optional border. - void BuildSiteTypeArea(); - - // Enable or disable the location icon/EV certificate as a drag source for - // the URL. - void SetSiteTypeDragSource(); + static gboolean HandleExposeThunk(GtkWidget* widget, GdkEventExpose* event, + gpointer userdata) { + return reinterpret_cast<LocationBarViewGtk*>(userdata)-> + HandleExpose(widget, event); + } - GtkWidget* site_type_area() { return site_type_alignment_; } + gboolean HandleExpose(GtkWidget* widget, GdkEventExpose* event); - CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, HandleExpose, - GdkEventExpose*); - CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnIconReleased, - GdkEventButton*); - CHROMEGTK_CALLBACK_4(LocationBarViewGtk, void, OnIconDragData, - GdkDragContext*, GtkSelectionData*, guint, guint); - CHROMEGTK_CALLBACK_1(LocationBarViewGtk, void, OnEntryBoxSizeAllocate, - GtkAllocation*); - CHROMEGTK_CALLBACK_1(LocationBarViewGtk, gboolean, OnStarButtonPress, - GdkEventButton*); + static gboolean OnSecurityIconPressed(GtkWidget* sender, + GdkEventButton* event, + LocationBarViewGtk* location_bar); - // Updates the site type area: changes the icon and shows/hides the EV - // certificate information. - void UpdateSiteTypeArea(); + // Set the SSL icon we should be showing. + void SetSecurityIcon(ToolbarModel::Icon icon); // Sets the text that should be displayed in the info label and its associated // tooltip text. Call with an empty string if the info label should be @@ -300,43 +296,29 @@ class LocationBarViewGtk : public AutocompleteEditController, void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type); - // Show or hide |tab_to_search_box_| and |tab_to_search_hint_| according to - // the value of |show_selected_keyword_|, |show_keyword_hint_|, and the - // available horizontal space in the location bar. - void AdjustChildrenVisibility(); - - // Build the star icon. - void CreateStarButton(); - - // Update the star icon after it is toggled or the theme changes. - void UpdateStarIcon(); + static void OnEntryBoxSizeAllocateThunk(GtkWidget* widget, + GtkAllocation* allocation, + gpointer userdata) { + reinterpret_cast<LocationBarViewGtk*>(userdata)-> + OnEntryBoxSizeAllocate(allocation); + } + void OnEntryBoxSizeAllocate(GtkAllocation* allocation); - // Returns true if we should only show the URL and none of the extras like - // the star button or page actions. - bool ShouldOnlyShowLocation(); + // Show or hide |tab_to_search_box_|, |tab_to_search_hint_| and + // |type_to_search_hint_| according to the value of |show_selected_keyword_|, + // |show_keyword_hint_|, |show_search_hint_| and the available horizontal + // space in the location bar. + void AdjustChildrenVisibility(); // The outermost widget we want to be hosted. OwnedWidgetGtk hbox_; - // Star button. - OwnedWidgetGtk star_; - GtkWidget* star_image_; - bool starred_; - - // SSL state. + // SSL icons. GtkWidget* security_icon_event_box_; - GtkWidget* ev_secure_icon_image_; - GtkWidget* secure_icon_image_; + GtkWidget* security_lock_icon_image_; GtkWidget* security_warning_icon_image_; - GtkWidget* security_error_icon_image_; - // An icon to the left of the address bar. - GtkWidget* site_type_alignment_; - GtkWidget* site_type_event_box_; - GtkWidget* location_icon_image_; - bool enable_location_drag_; - // TODO(pkasting): Split this label off and move the rest of the items to the - // left of the address bar. - GtkWidget* security_info_label_; + // Toolbar info text (EV cert info). + GtkWidget* info_label_; // Content setting icons. OwnedWidgetGtk content_setting_hbox_; @@ -357,6 +339,9 @@ class LocationBarViewGtk : public AutocompleteEditController, GtkWidget* tab_to_search_hint_icon_; GtkWidget* tab_to_search_hint_trailing_label_; + // Hint to user that the inputted text is not a keyword or url. + GtkWidget* type_to_search_hint_; + scoped_ptr<AutocompleteEditViewGtk> location_entry_; Profile* profile_; @@ -364,6 +349,9 @@ class LocationBarViewGtk : public AutocompleteEditController, ToolbarModel* toolbar_model_; Browser* browser_; + // We need to hold on to this just to it pass to the edit. + const BubblePositioner* bubble_positioner_; + // When we get an OnAutocompleteAccept notification from the autocomplete // edit, we save the input string so we can give it back to the browser on // the LocationBar interface via GetInputString(). @@ -397,6 +385,9 @@ class LocationBarViewGtk : public AutocompleteEditController, // Indicate if |tab_to_search_hint_| should be shown. bool show_keyword_hint_; + // Indicate if |type_to_search_hint_| should be shown. + bool show_search_hint_; + DISALLOW_COPY_AND_ASSIGN(LocationBarViewGtk); }; diff --git a/chrome/browser/gtk/options/passwords_exceptions_page_gtk.cc b/chrome/browser/gtk/options/passwords_exceptions_page_gtk.cc index 8162610..5488e4f 100644 --- a/chrome/browser/gtk/options/passwords_exceptions_page_gtk.cc +++ b/chrome/browser/gtk/options/passwords_exceptions_page_gtk.cc @@ -116,7 +116,7 @@ void PasswordsExceptionsPageGtk::SetExceptionList( for (size_t i = 0; i < result.size(); ++i) { exception_list_[i] = *result[i]; std::wstring formatted = net::FormatUrl(result[i]->origin, languages, - net::kFormatUrlOmitAll, UnescapeRule::NONE, NULL, NULL, NULL); + false, UnescapeRule::NONE, NULL, NULL, NULL); std::string site = WideToUTF8(formatted); GtkTreeIter iter; gtk_list_store_insert_with_values(exception_list_store_, &iter, (gint) i, diff --git a/chrome/browser/gtk/options/passwords_page_gtk.cc b/chrome/browser/gtk/options/passwords_page_gtk.cc index 9ecf89f..0de0403 100644 --- a/chrome/browser/gtk/options/passwords_page_gtk.cc +++ b/chrome/browser/gtk/options/passwords_page_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 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. @@ -160,7 +160,7 @@ void PasswordsPageGtk::SetPasswordList( for (size_t i = 0; i < result.size(); ++i) { password_list_[i] = *result[i]; std::wstring formatted = net::FormatUrl(result[i]->origin, languages, - net::kFormatUrlOmitAll, UnescapeRule::NONE, NULL, NULL, NULL); + false, UnescapeRule::NONE, NULL, NULL, NULL); std::string site = WideToUTF8(formatted); std::string user = UTF16ToUTF8(result[i]->username_value); GtkTreeIter iter; diff --git a/chrome/browser/gtk/options/url_picker_dialog_gtk.cc b/chrome/browser/gtk/options/url_picker_dialog_gtk.cc index b5e5a5b..df45b14 100644 --- a/chrome/browser/gtk/options/url_picker_dialog_gtk.cc +++ b/chrome/browser/gtk/options/url_picker_dialog_gtk.cc @@ -198,8 +198,7 @@ std::string UrlPickerDialogGtk::GetURLForPath(GtkTreePath* path) const { // Because the url_field_ is user-editable, we set the URL with // username:password and escaped path and query. std::wstring formatted = net::FormatUrl(url_table_model_->GetURL(row), - languages, net::kFormatUrlOmitNothing, UnescapeRule::NONE, NULL, NULL, - NULL); + languages, false, UnescapeRule::NONE, NULL, NULL, NULL); return WideToUTF8(formatted); } diff --git a/chrome/browser/gtk/rounded_window.cc b/chrome/browser/gtk/rounded_window.cc index 52bedc9..540a465 100644 --- a/chrome/browser/gtk/rounded_window.cc +++ b/chrome/browser/gtk/rounded_window.cc @@ -287,10 +287,6 @@ void StopActingAsRoundedWindow(GtkWidget* widget) { gdk_window_shape_combine_mask(widget->window, NULL, 0, 0); } -bool IsActingAsRoundedWindow(GtkWidget* widget) { - return g_object_get_data(G_OBJECT(widget), kRoundedData) != NULL; -} - void SetRoundedWindowEdgesAndBorders(GtkWidget* widget, int corner_size, int rounded_edges, diff --git a/chrome/browser/gtk/rounded_window.h b/chrome/browser/gtk/rounded_window.h index cd98e71..95f91d9 100644 --- a/chrome/browser/gtk/rounded_window.h +++ b/chrome/browser/gtk/rounded_window.h @@ -42,9 +42,6 @@ void ActAsRoundedWindow( // Undoes most of the actions of ActAsRoundedWindow(). void StopActingAsRoundedWindow(GtkWidget* widget); -// Returns true if the window is rounded. -bool IsActingAsRoundedWindow(GtkWidget* widget); - // Sets edge and border properties on a widget that has already been configured // with ActAsRoundedWindow(). void SetRoundedWindowEdgesAndBorders(GtkWidget* widget, diff --git a/chrome/browser/gtk/tabs/tab_strip_gtk.cc b/chrome/browser/gtk/tabs/tab_strip_gtk.cc index 8d1d1c8..25a02c3 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -1980,8 +1980,28 @@ void TabStripGtk::OnNewTabClicked(GtkWidget* widget, TabStripGtk* tabstrip) { case 2: { // On middle-click, try to parse the PRIMARY selection as a URL and load // it instead of creating a blank page. - GURL url; - if (!gtk_util::URLFromPrimarySelection(tabstrip->model_->profile(), &url)) + GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); + DCHECK(clipboard); + gchar* selection_text = gtk_clipboard_wait_for_text(clipboard); + if (!selection_text) + return; + + // Use autocomplete to clean up the text, going so far as to turn it into + // a search query if necessary. + AutocompleteController controller(tabstrip->model_->profile()); + controller.Start(UTF8ToWide(selection_text), + std::wstring(), // desired_tld + true, // prevent_inline_autocomplete + false, // prefer_keyword + true); // synchronous_only + g_free(selection_text); + const AutocompleteResult& result = controller.result(); + AutocompleteResult::const_iterator it = result.default_match(); + if (it == result.end()) + return; + + GURL url(it->destination_url); + if (!url.is_valid()) return; TabContents* contents = diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc new file mode 100644 index 0000000..a57d79e --- /dev/null +++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2010 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/gtk/toolbar_star_toggle_gtk.h" + +#include "app/gtk_dnd_util.h" +#include "app/resource_bundle.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/gtk/bookmark_bubble_gtk.h" +#include "chrome/browser/gtk/browser_toolbar_gtk.h" +#include "chrome/browser/gtk/gtk_chrome_button.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" +#include "chrome/browser/gtk/gtk_util.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/common/notification_service.h" +#include "gfx/rect.h" +#include "grit/theme_resources.h" + +ToolbarStarToggleGtk::ToolbarStarToggleGtk(BrowserToolbarGtk* host) + : host_(host), + widget_(gtk_chrome_button_new()), + is_starred_(false), + theme_provider_(GtkThemeProvider::GetFrom(host->profile())), + unstarred_(theme_provider_, IDR_STAR, IDR_STAR_P, IDR_STAR_H, IDR_STAR_D, + IDR_STAR_MASK), + starred_(theme_provider_, IDR_STARRED, IDR_STARRED_P, IDR_STARRED_H, 0, + IDR_STAR_MASK) { + gtk_widget_set_size_request(widget_.get(), unstarred_.Width(), + unstarred_.Height()); + + gtk_widget_set_app_paintable(widget_.get(), TRUE); + // We effectively double-buffer by virtue of having only one image... + gtk_widget_set_double_buffered(widget_.get(), FALSE); + + g_signal_connect(widget(), "expose-event", + G_CALLBACK(OnExpose), this); + GTK_WIDGET_UNSET_FLAGS(widget(), GTK_CAN_FOCUS); + + gtk_drag_source_set(widget(), GDK_BUTTON1_MASK, NULL, 0, + static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_LINK)); + gtk_dnd_util::SetSourceTargetListFromCodeMask(widget(), + gtk_dnd_util::TEXT_PLAIN | + gtk_dnd_util::TEXT_URI_LIST | + gtk_dnd_util::CHROME_NAMED_URL | + gtk_dnd_util::NETSCAPE_URL); + g_signal_connect(widget(), "drag-data-get", G_CALLBACK(OnDragDataGet), this); + + theme_provider_->InitThemesFor(this); + registrar_.Add(this, + NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + + hover_controller_.Init(widget()); +} + +ToolbarStarToggleGtk::~ToolbarStarToggleGtk() { + widget_.Destroy(); +} + +void ToolbarStarToggleGtk::Observe(NotificationType type, + const NotificationSource& source, const NotificationDetails& details) { + DCHECK(NotificationType::BROWSER_THEME_CHANGED == type); + + GtkThemeProvider* provider = static_cast<GtkThemeProvider*>( + Source<GtkThemeProvider>(source).ptr()); + DCHECK(provider == theme_provider_); + UpdateGTKButton(); +} + +void ToolbarStarToggleGtk::ShowStarBubble(const GURL& url, + bool newly_bookmarked) { + GtkWidget* widget = widget_.get(); + BookmarkBubbleGtk::Show(GTK_WINDOW(gtk_widget_get_toplevel(widget)), + gtk_util::GetWidgetRectRelativeToToplevel(widget), + host_->profile(), + url, + newly_bookmarked); +} + +void ToolbarStarToggleGtk::SetStarred(bool starred) { + is_starred_ = starred; + gtk_widget_queue_draw(widget_.get()); + UpdateGTKButton(); +} + +// static +gboolean ToolbarStarToggleGtk::OnExpose(GtkWidget* widget, GdkEventExpose* e, + ToolbarStarToggleGtk* button) { + if (button->theme_provider_->UseGtkTheme()) { + return FALSE; + } else { + double hover_state = button->hover_controller_.GetCurrentValue(); + if (button->is_starred_) + return button->starred_.OnExpose(widget, e, hover_state); + else + return button->unstarred_.OnExpose(widget, e, hover_state); + } +} + +// static +void ToolbarStarToggleGtk::OnDragDataGet(GtkWidget* widget, + GdkDragContext* drag_context, GtkSelectionData* data, guint info, + guint time, ToolbarStarToggleGtk* star) { + const TabContents* tab = star->host_->browser()->tabstrip_model()-> + GetSelectedTabContents(); + if (!tab) + return; + gtk_dnd_util::WriteURLWithName(data, tab->GetURL(), tab->GetTitle(), info); +} + +void ToolbarStarToggleGtk::UpdateGTKButton() { + bool use_gtk = theme_provider_ && theme_provider_->UseGtkTheme(); + + if (use_gtk) { + GdkPixbuf* pixbuf = NULL; + if (is_starred_) { + pixbuf = theme_provider_->GetPixbufNamed(IDR_STARRED_NOBORDER_CENTER); + } else { + pixbuf = theme_provider_->GetPixbufNamed(IDR_STAR_NOBORDER_CENTER); + } + + gtk_button_set_image( + GTK_BUTTON(widget_.get()), + gtk_image_new_from_pixbuf(pixbuf)); + + gtk_widget_set_size_request(widget_.get(), -1, -1); + gtk_widget_set_app_paintable(widget_.get(), FALSE); + gtk_widget_set_double_buffered(widget_.get(), TRUE); + } else { + gtk_widget_set_size_request(widget_.get(), unstarred_.Width(), + unstarred_.Height()); + + gtk_widget_set_app_paintable(widget_.get(), TRUE); + // We effectively double-buffer by virtue of having only one image... + gtk_widget_set_double_buffered(widget_.get(), FALSE); + } + + gtk_chrome_button_set_use_gtk_rendering( + GTK_CHROME_BUTTON(widget_.get()), use_gtk); +} diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.h b/chrome/browser/gtk/toolbar_star_toggle_gtk.h new file mode 100644 index 0000000..faa025a --- /dev/null +++ b/chrome/browser/gtk/toolbar_star_toggle_gtk.h @@ -0,0 +1,76 @@ +// Copyright (c) 2010 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_GTK_TOOLBAR_STAR_TOGGLE_GTK_H_ +#define CHROME_BROWSER_GTK_TOOLBAR_STAR_TOGGLE_GTK_H_ + +#include <gtk/gtk.h> + +#include "base/basictypes.h" +#include "chrome/browser/gtk/custom_button.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/owned_widget_gtk.h" + +class BrowserToolbarGtk; +class GtkThemeProvider; +class GURL; + +// Displays the bookmark star button, which toggles between two images. +class ToolbarStarToggleGtk : public NotificationObserver { + public: + explicit ToolbarStarToggleGtk(BrowserToolbarGtk* host); + ~ToolbarStarToggleGtk(); + + // Provide NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // If the bubble isn't showing, shows it above the star button. + void ShowStarBubble(const GURL& url, bool newly_bookmarked); + + void SetStarred(bool starred); + + GtkWidget* widget() const { return widget_.get(); } + + private: + // Updates the properties of |widget_| when we would need to change its + // state. + void UpdateGTKButton(); + + // Callback for expose, used to draw the custom graphics. + static gboolean OnExpose(GtkWidget* widget, GdkEventExpose* e, + ToolbarStarToggleGtk* obj); + + // Callback to get the data associated with a drag. + static void OnDragDataGet(GtkWidget* widget, + GdkDragContext* drag_context, + GtkSelectionData* data, + guint info, + guint time, + ToolbarStarToggleGtk* star); + + // Used to listen for theme change notifications. + NotificationRegistrar registrar_; + + // The browser toolbar hosting this widget, for getting the current profile. + BrowserToolbarGtk* host_; + + // The actual button widget. + OwnedWidgetGtk widget_; + + // Whether we show the yellow star. + bool is_starred_; + + GtkThemeProvider* theme_provider_; + + CustomDrawButtonBase unstarred_; + CustomDrawButtonBase starred_; + CustomDrawHoverController hover_controller_; + + DISALLOW_COPY_AND_ASSIGN(ToolbarStarToggleGtk); +}; + +#endif // CHROME_BROWSER_GTK_TOOLBAR_STAR_TOGGLE_GTK_H_ |