diff options
Diffstat (limited to 'chrome/browser/gtk')
20 files changed, 525 insertions, 608 deletions
diff --git a/chrome/browser/gtk/accelerators_gtk.cc b/chrome/browser/gtk/accelerators_gtk.cc index 21ffe03..c93d8f0 100644 --- a/chrome/browser/gtk/accelerators_gtk.cc +++ b/chrome/browser/gtk/accelerators_gtk.cc @@ -151,8 +151,7 @@ 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_CONTROL_MASK }, - { GDK_b, IDC_SHOW_BOOKMARK_MANAGER, + { GDK_b, IDC_SHOW_BOOKMARK_BAR, 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 524c9c3..2bf86e2 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 a4e79b0..bfe25fc 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_toolbar_gtk.cc @@ -35,7 +35,6 @@ #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" @@ -66,17 +65,13 @@ 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(this, browser)), + location_bar_(new LocationBarViewGtk(browser)), model_(browser->toolbar_model()), page_menu_model_(this, browser), app_menu_model_(this, browser), @@ -160,11 +155,6 @@ 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), @@ -172,23 +162,25 @@ 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); - 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_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(), @@ -227,17 +219,16 @@ 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(star_->widget()); + gtk_widget_show_all(location_hbox_); + gtk_widget_hide(reload_->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()); @@ -248,6 +239,7 @@ void BrowserToolbarGtk::Init(Profile* profile, location_bar_->UpdateContentSettingsIcons(); SetViewIDs(); + theme_provider_->InitThemesFor(this); } void BrowserToolbarGtk::SetViewIDs() { @@ -256,7 +248,6 @@ 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); @@ -312,9 +303,6 @@ 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) { @@ -410,6 +398,19 @@ 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. @@ -445,38 +446,6 @@ 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( @@ -498,18 +467,6 @@ 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) { @@ -579,42 +536,9 @@ 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, - &rec); + &location_hbox->allocation); } return FALSE; @@ -639,8 +563,6 @@ 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 1ece0db..9c5f2c8 100644 --- a/chrome/browser/gtk/browser_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_toolbar_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -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,7 +35,6 @@ 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. @@ -44,7 +43,6 @@ 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); @@ -113,11 +111,6 @@ 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, @@ -135,9 +128,6 @@ 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, @@ -191,14 +181,16 @@ 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> reload_; scoped_ptr<CustomDrawButton> home_; - scoped_ptr<ToolbarStarToggleGtk> star_; + scoped_ptr<CustomDrawButton> reload_; 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 3eba2c5..5bdb347 100644 --- a/chrome/browser/gtk/browser_window_gtk.cc +++ b/chrome/browser/gtk/browser_window_gtk.cc @@ -57,6 +57,7 @@ #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" @@ -65,7 +66,6 @@ #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_->star()->SetStarred(is_starred); + toolbar_->GetLocationBarView()->SetStarred(is_starred); } gfx::Rect BrowserWindowGtk::GetRestoredBounds() const { @@ -845,7 +845,7 @@ void BrowserWindowGtk::ShowBookmarkManager() { void BrowserWindowGtk::ShowBookmarkBubble(const GURL& url, bool already_bookmarked) { - toolbar_->star()->ShowStarBubble(url, !already_bookmarked); + toolbar_->GetLocationBarView()->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 e3bc7ff..b8785da 100644 --- a/chrome/browser/gtk/find_bar_gtk.cc +++ b/chrome/browser/gtk/find_bar_gtk.cc @@ -456,6 +456,7 @@ 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); @@ -482,6 +483,7 @@ 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 2f0f142..24e7266 100644 --- a/chrome/browser/gtk/gtk_theme_provider.cc +++ b/chrome/browser/gtk/gtk_theme_provider.cc @@ -91,10 +91,30 @@ 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(); @@ -738,15 +758,49 @@ 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 new SkBitmap(SkBitmapOperations::CreateHSLShiftedBitmap( - *button, it->second)); + return GenerateTintedIcon(id, it->second); } } } @@ -768,6 +822,20 @@ 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 23c0a57..227bbbe 100644 --- a/chrome/browser/gtk/gtk_theme_provider.h +++ b/chrome/browser/gtk/gtk_theme_provider.h @@ -163,6 +163,13 @@ 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 3013b12..4d5796a 100644 --- a/chrome/browser/gtk/gtk_util.cc +++ b/chrome/browser/gtk/gtk_util.cc @@ -17,11 +17,13 @@ #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" @@ -869,4 +871,32 @@ 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 e28778a..1d8b6d3 100644 --- a/chrome/browser/gtk/gtk_util.h +++ b/chrome/browser/gtk/gtk_util.h @@ -17,6 +17,8 @@ typedef struct _GtkWidget GtkWidget; class GtkThemeProvider; +class GURL; +class Profile; struct RendererPreferences; // from common/renderer_preferences.h namespace event_utils { @@ -270,6 +272,11 @@ 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 7c0685c..18eda70 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.cc +++ b/chrome/browser/gtk/location_bar_view_gtk.cc @@ -6,6 +6,7 @@ #include <string> +#include "app/gtk_dnd_util.h" #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/basictypes.h" @@ -26,6 +27,7 @@ #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" @@ -33,6 +35,7 @@ #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" @@ -73,10 +76,12 @@ const int kHboxBorder = 4; // Padding between the elements in the bar. static const int kInnerPadding = 4; -// 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. +// 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. const GdkColor kKeywordBackgroundColor = GDK_COLOR_RGB(0xf0, 0xf4, 0xfa); const GdkColor kKeywordBorderColor = GDK_COLOR_RGB(0xcb, 0xde, 0xf7); @@ -131,19 +136,22 @@ std::wstring CalculateMinString(const std::wstring& description) { // LocationBarViewGtk // static -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), +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), security_warning_icon_image_(NULL), - info_label_(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), tab_to_search_box_(NULL), tab_to_search_full_label_(NULL), tab_to_search_partial_label_(NULL), @@ -151,12 +159,10 @@ LocationBarViewGtk::LocationBarViewGtk( 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), @@ -164,12 +170,12 @@ LocationBarViewGtk::LocationBarViewGtk( theme_provider_(NULL), entry_box_width_(0), show_selected_keyword_(false), - show_keyword_hint_(false), - show_search_hint_(false) { + show_keyword_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(); @@ -177,14 +183,8 @@ 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,30 +193,23 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { // the home button on/off. gtk_widget_set_redraw_on_allocate(hbox_.get(), TRUE); - 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"); + // Now initialize the AutocompleteEditViewGtk. + location_entry_.reset(new AutocompleteEditViewGtk(this, + toolbar_model_, + profile_, + command_updater_, + popup_window_mode_, + hbox_.get())); + location_entry_->Init(); g_signal_connect(hbox_.get(), "expose-event", G_CALLBACK(&HandleExposeThunk), this); - // 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. + 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. GtkWidget* entry_box = gtk_hbox_new(FALSE, kInnerPadding); gtk_widget_show(entry_box); gtk_widget_set_size_request(entry_box, 0, -1); @@ -237,13 +230,22 @@ 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_label_fixed, NULL, 1, 1, 2, 2); + tab_to_search_hbox, NULL, 1, 1, 1, 3); gtk_widget_set_name(tab_to_search_box_, "chrome-tab-to-search-box"); - gtk_util::ActAsRoundedWindow(tab_to_search_box_, kBorderColor, kCornerSize, + gtk_util::ActAsRoundedWindow(tab_to_search_box_, kKeywordBorderColor, + 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_|. @@ -269,7 +271,7 @@ void LocationBarViewGtk::Init(bool popup_window_mode) { kBottomMargin + kBorderThickness, 0, 0); } - gtk_container_add(GTK_CONTAINER(align), location_entry_->widget()); + gtk_container_add(GTK_CONTAINER(align), location_entry_->GetNativeView()); gtk_box_pack_start(GTK_BOX(entry_box), align, TRUE, TRUE, 0); // Tab to search notification (the hint on the right hand side). @@ -297,36 +299,11 @@ 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); - // 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); + // 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); + } content_setting_hbox_.Own(gtk_hbox_new(FALSE, kInnerPadding)); gtk_widget_set_name(content_setting_hbox_.get(), @@ -350,9 +327,7 @@ 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(type_to_search_hint_, - browser_defaults::kAutocompleteEditFontPixelSize); - gtk_util::ForceFontSizePixels(info_label_, + gtk_util::ForceFontSizePixels(security_info_label_, browser_defaults::kAutocompleteEditFontPixelSize); gtk_util::ForceFontSizePixels(tab_to_search_full_label_, browser_defaults::kAutocompleteEditFontPixelSize); @@ -362,8 +337,6 @@ 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, @@ -372,6 +345,71 @@ 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; } @@ -410,10 +448,9 @@ GtkWidget* LocationBarViewGtk::GetPageActionWidget( } void LocationBarViewGtk::Update(const TabContents* contents) { - SetSecurityIcon(toolbar_model_->GetIcon()); + UpdateSiteTypeArea(); UpdateContentSettingsIcons(); UpdatePageActions(); - SetInfoText(); location_entry_->Update(contents); // The security level (background color) could have changed, etc. if (theme_provider_->UseGtkTheme()) { @@ -461,12 +498,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); @@ -477,6 +514,20 @@ 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. @@ -612,7 +663,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()) + if (PageActionVisibleCount() && !ShouldOnlyShowLocation()) gtk_widget_show(page_action_hbox_.get()); else gtk_widget_hide(page_action_hbox_.get()); @@ -691,11 +742,6 @@ 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); @@ -708,12 +754,11 @@ void LocationBarViewGtk::Observe(NotificationType type, &kHintTextColor); gtk_util::SetLabelColor(tab_to_search_hint_trailing_label_, &kHintTextColor); - gtk_util::SetLabelColor(type_to_search_hint_, &kHintTextColor); - - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - gtk_image_set_from_pixbuf(GTK_IMAGE(security_warning_icon_image_), - rb.GetPixbufNamed(IDR_WARNING)); } + + UpdateStarIcon(); + UpdateSiteTypeArea(); + UpdateContentSettingsIcons(); } gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, @@ -746,8 +791,7 @@ gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, alloc_rect->width, alloc_rect->height - kTopMargin - kBottomMargin - 2 * kBorderThickness); - gdk_cairo_set_source_color(cr, const_cast<GdkColor*>( - &kBackgroundColorByLevel[toolbar_model_->GetSchemeSecurityLevel()])); + gdk_cairo_set_source_color(cr, const_cast<GdkColor*>(&kBackgroundColor)); cairo_fill(cr); cairo_destroy(cr); @@ -756,45 +800,52 @@ gboolean LocationBarViewGtk::HandleExpose(GtkWidget* widget, return FALSE; // Continue propagating the expose. } -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; +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::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_)); + 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_)); } else { - 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_)); + 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_)); } - 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()); + + gtk_widget_show(site_type_area()); + + SetSiteTypeDragSource(); } void LocationBarViewGtk::SetKeywordLabel(const std::wstring& keyword) { @@ -865,46 +916,114 @@ void LocationBarViewGtk::ShowFirstRunBubbleInternal( FirstRunBubble::Show(profile_, anchor, rect, bubble_type); } -// 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; +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; } - tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true); - 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); } -void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkAllocation* allocation) { +void LocationBarViewGtk::OnEntryBoxSizeAllocate(GtkWidget* sender, + 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_|, |tab_to_search_hint_| and - // |type_to_search_hint_| can be visible at the same time. + // Only one of |tab_to_search_box_| and |tab_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); @@ -953,13 +1072,6 @@ 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_); } } @@ -997,14 +1109,12 @@ 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()) { - if (old_icon != content_setting_image_model_->get_icon()) { - gtk_image_set_from_pixbuf(GTK_IMAGE(image_.get()), - ResourceBundle::GetSharedInstance().GetPixbufNamed( + gtk_image_set_from_pixbuf(GTK_IMAGE(image_.get()), + GtkThemeProvider::GetFrom(profile_)->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 97ac60c6..fe9d26c 100644 --- a/chrome/browser/gtk/location_bar_view_gtk.h +++ b/chrome/browser/gtk/location_bar_view_gtk.h @@ -10,6 +10,7 @@ #include <map> #include <string> +#include "app/gtk_signal.h" #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "base/scoped_vector.h" @@ -30,7 +31,6 @@ #include "webkit/glue/window_open_disposition.h" class AutocompleteEditViewGtk; -class BubblePositioner; class Browser; class CommandUpdater; class ContentSettingImageModel; @@ -47,8 +47,7 @@ class LocationBarViewGtk : public AutocompleteEditController, public LocationBarTesting, public NotificationObserver { public: - LocationBarViewGtk(const BubblePositioner* bubble_positioner, - Browser* browser_); + explicit LocationBarViewGtk(Browser* browser); virtual ~LocationBarViewGtk(); void Init(bool popup_window_mode); @@ -78,6 +77,12 @@ 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, @@ -104,6 +109,9 @@ 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(); } @@ -121,9 +129,8 @@ class LocationBarViewGtk : public AutocompleteEditController, const NotificationSource& source, const NotificationDetails& details); - // 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]; + // Edit background color. + static const GdkColor kBackgroundColor; private: class ContentSettingImageViewGtk : public InfoBubbleGtkDelegate { @@ -141,12 +148,8 @@ class LocationBarViewGtk : public AutocompleteEditController, void UpdateFromTabContents(const TabContents* tab_contents); private: - static gboolean OnButtonPressedThunk(GtkWidget* sender, - GdkEvent* event, - ContentSettingImageViewGtk* view) { - return view->OnButtonPressed(sender, event); - } - gboolean OnButtonPressed(GtkWidget* sender, GdkEvent* event); + CHROMEGTK_CALLBACK_1(ContentSettingImageViewGtk, gboolean, OnButtonPressed, + GdkEvent*); // InfoBubbleDelegate overrides: virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble, @@ -208,19 +211,10 @@ class LocationBarViewGtk : public AutocompleteEditController, // with a debugger window attached. Returns true if a popup was shown. bool ShowPopup(bool devtools); - 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); + CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnButtonPressed, + GdkEvent*); + CHROMEGTK_CALLBACK_1(PageActionViewGtk, gboolean, OnExposeEvent, + GdkEventExpose*); // The location bar view that owns us. LocationBarViewGtk* owner_; @@ -268,20 +262,30 @@ class LocationBarViewGtk : public AutocompleteEditController, }; friend class PageActionViewGtk; - static gboolean HandleExposeThunk(GtkWidget* widget, GdkEventExpose* event, - gpointer userdata) { - return reinterpret_cast<LocationBarViewGtk*>(userdata)-> - HandleExpose(widget, event); - } + // 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(); - gboolean HandleExpose(GtkWidget* widget, GdkEventExpose* event); + GtkWidget* site_type_area() { return site_type_alignment_; } - static gboolean OnSecurityIconPressed(GtkWidget* sender, - GdkEventButton* event, - LocationBarViewGtk* location_bar); + 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*); - // Set the SSL icon we should be showing. - void SetSecurityIcon(ToolbarModel::Icon icon); + // Updates the site type area: changes the icon and shows/hides the EV + // certificate information. + void UpdateSiteTypeArea(); // 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 @@ -296,29 +300,43 @@ class LocationBarViewGtk : public AutocompleteEditController, void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type); - static void OnEntryBoxSizeAllocateThunk(GtkWidget* widget, - GtkAllocation* allocation, - gpointer userdata) { - reinterpret_cast<LocationBarViewGtk*>(userdata)-> - OnEntryBoxSizeAllocate(allocation); - } - void OnEntryBoxSizeAllocate(GtkAllocation* allocation); - - // 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. + // 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(); + + // Returns true if we should only show the URL and none of the extras like + // the star button or page actions. + bool ShouldOnlyShowLocation(); + // The outermost widget we want to be hosted. OwnedWidgetGtk hbox_; - // SSL icons. + // Star button. + OwnedWidgetGtk star_; + GtkWidget* star_image_; + bool starred_; + + // SSL state. GtkWidget* security_icon_event_box_; - GtkWidget* security_lock_icon_image_; + GtkWidget* ev_secure_icon_image_; + GtkWidget* secure_icon_image_; GtkWidget* security_warning_icon_image_; - // Toolbar info text (EV cert info). - GtkWidget* info_label_; + 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_; // Content setting icons. OwnedWidgetGtk content_setting_hbox_; @@ -339,9 +357,6 @@ 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_; @@ -349,9 +364,6 @@ 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(). @@ -385,9 +397,6 @@ 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 5488e4f..8162610 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, - false, UnescapeRule::NONE, NULL, NULL, NULL); + net::kFormatUrlOmitAll, 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 0de0403..9ecf89f 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) 2009 The Chromium Authors. All rights reserved. +// 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. @@ -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, - false, UnescapeRule::NONE, NULL, NULL, NULL); + net::kFormatUrlOmitAll, 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 df45b14..b5e5a5b 100644 --- a/chrome/browser/gtk/options/url_picker_dialog_gtk.cc +++ b/chrome/browser/gtk/options/url_picker_dialog_gtk.cc @@ -198,7 +198,8 @@ 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, false, UnescapeRule::NONE, NULL, NULL, NULL); + languages, net::kFormatUrlOmitNothing, 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 540a465..52bedc9 100644 --- a/chrome/browser/gtk/rounded_window.cc +++ b/chrome/browser/gtk/rounded_window.cc @@ -287,6 +287,10 @@ 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 95f91d9..cd98e71 100644 --- a/chrome/browser/gtk/rounded_window.h +++ b/chrome/browser/gtk/rounded_window.h @@ -42,6 +42,9 @@ 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 25a02c3..8d1d1c8 100644 --- a/chrome/browser/gtk/tabs/tab_strip_gtk.cc +++ b/chrome/browser/gtk/tabs/tab_strip_gtk.cc @@ -1980,28 +1980,8 @@ 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. - 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()) + GURL url; + if (!gtk_util::URLFromPrimarySelection(tabstrip->model_->profile(), &url)) return; TabContents* contents = diff --git a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc b/chrome/browser/gtk/toolbar_star_toggle_gtk.cc deleted file mode 100644 index b688b00..0000000 --- a/chrome/browser/gtk/toolbar_star_toggle_gtk.cc +++ /dev/null @@ -1,141 +0,0 @@ -// 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(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 deleted file mode 100644 index faa025a..0000000 --- a/chrome/browser/gtk/toolbar_star_toggle_gtk.h +++ /dev/null @@ -1,76 +0,0 @@ -// 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_ |