OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/gtk/location_bar_view_gtk.h" | 5 #include "chrome/browser/gtk/location_bar_view_gtk.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
| 9 #include "app/l10n_util.h" |
9 #include "app/resource_bundle.h" | 10 #include "app/resource_bundle.h" |
10 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
11 #include "base/gfx/gtk_util.h" | 12 #include "base/gfx/gtk_util.h" |
12 #include "base/logging.h" | 13 #include "base/logging.h" |
13 #include "base/string_util.h" | 14 #include "base/string_util.h" |
14 #include "chrome/app/chrome_dll_resource.h" | 15 #include "chrome/app/chrome_dll_resource.h" |
15 #include "chrome/browser/alternate_nav_url_fetcher.h" | 16 #include "chrome/browser/alternate_nav_url_fetcher.h" |
16 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" | 17 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" |
17 #include "chrome/browser/command_updater.h" | 18 #include "chrome/browser/command_updater.h" |
18 #include "chrome/browser/gtk/gtk_theme_provider.h" | 19 #include "chrome/browser/gtk/gtk_theme_provider.h" |
| 20 #include "chrome/browser/profile.h" |
| 21 #include "chrome/browser/search_engines/template_url.h" |
| 22 #include "chrome/browser/search_engines/template_url_model.h" |
19 #include "chrome/browser/tab_contents/tab_contents.h" | 23 #include "chrome/browser/tab_contents/tab_contents.h" |
20 #include "chrome/common/gtk_util.h" | 24 #include "chrome/common/gtk_util.h" |
21 #include "chrome/common/page_transition_types.h" | 25 #include "chrome/common/page_transition_types.h" |
| 26 #include "grit/generated_resources.h" |
22 #include "third_party/skia/include/core/SkBitmap.h" | 27 #include "third_party/skia/include/core/SkBitmap.h" |
23 #include "webkit/glue/window_open_disposition.h" | 28 #include "webkit/glue/window_open_disposition.h" |
24 | 29 |
25 namespace { | 30 namespace { |
26 | 31 |
27 // Top and bottom padding/margin | 32 // Top and bottom padding/margin |
28 // We are positioned with a little bit of extra space that we don't use now. | 33 // We are positioned with a little bit of extra space that we don't use now. |
29 const int kTopMargin = 1; | 34 const int kTopMargin = 1; |
30 const int kBottomMargin = 1; | 35 const int kBottomMargin = 1; |
31 // We draw a border on the top and bottom (but not on left or right). | 36 // We draw a border on the top and bottom (but not on left or right). |
32 const int kBorderThickness = 1; | 37 const int kBorderThickness = 1; |
33 | 38 |
34 // Left and right padding/margin. | 39 // Left and right padding/margin. |
35 // no icon/text : 4px url_text 4px | 40 // no icon/text : 4px url_text 4px |
36 // [4px|url text|4px] <hide ssl icon> <hide ev text> | 41 // [4px|url text|4px] <hide ssl icon> <hide ev text> |
37 // with icon : 4px url_text 6px ssl_icon 8px | 42 // with icon : 4px url_text 6px ssl_icon 8px |
38 // [4px|url text|4px] [2px|ssl icon|8px] <hide ev text> | 43 // [4px|url text|4px] [2px|ssl icon|8px] <hide ev text> |
39 // with icon/text: 4px url_text 6px ssl_icon 8px ev_text 4px] | 44 // with icon/text: 4px url_text 6px ssl_icon 8px ev_text 4px] |
40 // [4px|url text|4px] [2px|ssl icon|8px] [ev text|4px] | 45 // [4px|url text|4px] [2px|ssl icon|8px] [ev text|4px] |
41 | 46 |
42 // We don't want to edit control's text to be right against the edge. | 47 // We don't want to edit control's text to be right against the edge. |
43 const int kEditLeftRightPadding = 4; | 48 const int kEditLeftRightPadding = 4; |
44 | 49 |
45 // Padding around the security icon. | 50 // Padding around the security icon. |
46 const int kSecurityIconPaddingLeft = 0; | 51 const int kSecurityIconPaddingLeft = 0; |
47 const int kSecurityIconPaddingRight = 6; | 52 const int kSecurityIconPaddingRight = 6; |
48 | 53 |
49 const int kEvTextPaddingRight = 4; | 54 const int kEvTextPaddingRight = 4; |
50 | 55 |
| 56 const int kKeywordTopBottomPadding = 4; |
| 57 const int kKeywordLeftRightPadding = 4; |
| 58 |
51 // TODO(deanm): Eventually this should be painted with the background png | 59 // TODO(deanm): Eventually this should be painted with the background png |
52 // image, but for now we get pretty close by just drawing a solid border. | 60 // image, but for now we get pretty close by just drawing a solid border. |
53 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); | 61 const GdkColor kBorderColor = GDK_COLOR_RGB(0xbe, 0xc8, 0xd4); |
| 62 const GdkColor kEvTextColor = GDK_COLOR_RGB(0x00, 0x96, 0x14); // Green. |
| 63 const GdkColor kKeywordBackgroundColor = GDK_COLOR_RGB(0xf0, 0xf4, 0xfa); |
| 64 const GdkColor kKeywordBorderColor = GDK_COLOR_RGB(0xcb, 0xde, 0xf7); |
54 | 65 |
55 const GdkColor kEvTextColor = GDK_COLOR_RGB(0x00, 0x96, 0x14); // Green. | 66 // Returns the short name for a keyword. |
| 67 std::wstring GetKeywordName(Profile* profile, |
| 68 const std::wstring& keyword) { |
| 69 // Make sure the TemplateURL still exists. |
| 70 // TODO(sky): Once LocationBarView adds a listener to the TemplateURLModel |
| 71 // to track changes to the model, this should become a DCHECK. |
| 72 const TemplateURL* template_url = |
| 73 profile->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword); |
| 74 if (template_url) |
| 75 return template_url->AdjustedShortNameForLocaleDirection(); |
| 76 return std::wstring(); |
| 77 } |
56 | 78 |
57 } // namespace | 79 } // namespace |
58 | 80 |
59 // static | 81 // static |
60 const GdkColor LocationBarViewGtk::kBackgroundColorByLevel[3] = { | 82 const GdkColor LocationBarViewGtk::kBackgroundColorByLevel[3] = { |
61 GDK_COLOR_RGB(255, 245, 195), // SecurityLevel SECURE: Yellow. | 83 GDK_COLOR_RGB(255, 245, 195), // SecurityLevel SECURE: Yellow. |
62 GDK_COLOR_RGB(255, 255, 255), // SecurityLevel NORMAL: White. | 84 GDK_COLOR_RGB(255, 255, 255), // SecurityLevel NORMAL: White. |
63 GDK_COLOR_RGB(255, 255, 255), // SecurityLevel INSECURE: White. | 85 GDK_COLOR_RGB(255, 255, 255), // SecurityLevel INSECURE: White. |
64 }; | 86 }; |
65 | 87 |
66 LocationBarViewGtk::LocationBarViewGtk(CommandUpdater* command_updater, | 88 LocationBarViewGtk::LocationBarViewGtk(CommandUpdater* command_updater, |
67 ToolbarModel* toolbar_model, AutocompletePopupPositioner* popup_positioner) | 89 ToolbarModel* toolbar_model, AutocompletePopupPositioner* popup_positioner) |
68 : security_icon_align_(NULL), | 90 : security_icon_align_(NULL), |
69 security_lock_icon_image_(NULL), | 91 security_lock_icon_image_(NULL), |
70 security_warning_icon_image_(NULL), | 92 security_warning_icon_image_(NULL), |
71 info_label_align_(NULL), | 93 info_label_align_(NULL), |
72 info_label_(NULL), | 94 info_label_(NULL), |
| 95 tab_to_search_(NULL), |
| 96 tab_to_search_label_(NULL), |
| 97 tab_to_search_hint_(NULL), |
| 98 tab_to_search_hint_leading_label_(NULL), |
| 99 tab_to_search_hint_icon_(NULL), |
| 100 tab_to_search_hint_trailing_label_(NULL), |
73 profile_(NULL), | 101 profile_(NULL), |
74 command_updater_(command_updater), | 102 command_updater_(command_updater), |
75 toolbar_model_(toolbar_model), | 103 toolbar_model_(toolbar_model), |
76 popup_positioner_(popup_positioner), | 104 popup_positioner_(popup_positioner), |
77 disposition_(CURRENT_TAB), | 105 disposition_(CURRENT_TAB), |
78 transition_(PageTransition::TYPED) { | 106 transition_(PageTransition::TYPED) { |
79 } | 107 } |
80 | 108 |
81 LocationBarViewGtk::~LocationBarViewGtk() { | 109 LocationBarViewGtk::~LocationBarViewGtk() { |
82 // All of our widgets should have be children of / owned by the alignment. | 110 // All of our widgets should have be children of / owned by the alignment. |
(...skipping 26 matching lines...) Expand all Loading... |
109 gtk_widget_hide(GTK_WIDGET(security_warning_icon_image_)); | 137 gtk_widget_hide(GTK_WIDGET(security_warning_icon_image_)); |
110 | 138 |
111 info_label_ = gtk_label_new(NULL); | 139 info_label_ = gtk_label_new(NULL); |
112 gtk_widget_modify_base(info_label_, GTK_STATE_NORMAL, | 140 gtk_widget_modify_base(info_label_, GTK_STATE_NORMAL, |
113 &LocationBarViewGtk::kBackgroundColorByLevel[0]); | 141 &LocationBarViewGtk::kBackgroundColorByLevel[0]); |
114 gtk_widget_hide(GTK_WIDGET(info_label_)); | 142 gtk_widget_hide(GTK_WIDGET(info_label_)); |
115 | 143 |
116 g_signal_connect(hbox_.get(), "expose-event", | 144 g_signal_connect(hbox_.get(), "expose-event", |
117 G_CALLBACK(&HandleExposeThunk), this); | 145 G_CALLBACK(&HandleExposeThunk), this); |
118 | 146 |
| 147 // Tab to search (the keyword box on the left hand side). |
| 148 tab_to_search_label_ = gtk_label_new(NULL); |
| 149 // We need an alignment to pad our box inside the edit area. |
| 150 tab_to_search_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
| 151 gtk_alignment_set_padding(GTK_ALIGNMENT(tab_to_search_), |
| 152 kKeywordTopBottomPadding, kKeywordTopBottomPadding, |
| 153 kKeywordLeftRightPadding, kKeywordLeftRightPadding); |
| 154 |
| 155 // This crazy stack of alignments and event boxes creates a box around the |
| 156 // keyword text with a border, background color, and padding around the text. |
| 157 gtk_container_add(GTK_CONTAINER(tab_to_search_), |
| 158 gtk_util::CreateGtkBorderBin( |
| 159 gtk_util::CreateGtkBorderBin( |
| 160 tab_to_search_label_, &kKeywordBackgroundColor, 1, 1, 2, 2), |
| 161 &kKeywordBorderColor, 1, 1, 1, 1)); |
| 162 |
| 163 gtk_box_pack_start(GTK_BOX(hbox_.get()), tab_to_search_, FALSE, FALSE, 0); |
| 164 |
119 GtkWidget* align = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | 165 GtkWidget* align = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
120 // TODO(erg): Redo this so that it adjusts during theme changes. | 166 // TODO(erg): Redo this so that it adjusts during theme changes. |
121 if (GtkThemeProvider::UseSystemThemeGraphics(profile_)) { | 167 if (GtkThemeProvider::UseSystemThemeGraphics(profile_)) { |
122 gtk_alignment_set_padding(GTK_ALIGNMENT(align), | 168 gtk_alignment_set_padding(GTK_ALIGNMENT(align), |
123 0, 0, | 169 0, 0, |
124 kEditLeftRightPadding, kEditLeftRightPadding); | 170 kEditLeftRightPadding, kEditLeftRightPadding); |
125 } else { | 171 } else { |
126 gtk_alignment_set_padding(GTK_ALIGNMENT(align), | 172 gtk_alignment_set_padding(GTK_ALIGNMENT(align), |
127 kTopMargin + kBorderThickness, | 173 kTopMargin + kBorderThickness, |
128 kBottomMargin + kBorderThickness, | 174 kBottomMargin + kBorderThickness, |
129 kEditLeftRightPadding, kEditLeftRightPadding); | 175 kEditLeftRightPadding, kEditLeftRightPadding); |
130 } | 176 } |
131 gtk_container_add(GTK_CONTAINER(align), location_entry_->widget()); | 177 gtk_container_add(GTK_CONTAINER(align), location_entry_->widget()); |
132 gtk_box_pack_start(GTK_BOX(hbox_.get()), align, TRUE, TRUE, 0); | 178 gtk_box_pack_start(GTK_BOX(hbox_.get()), align, TRUE, TRUE, 0); |
133 | 179 |
| 180 // Tab to search notification (the hint on the right hand side). |
| 181 tab_to_search_hint_ = gtk_hbox_new(FALSE, 0); |
| 182 tab_to_search_hint_leading_label_ = gtk_label_new(NULL); |
| 183 tab_to_search_hint_icon_ = gtk_image_new_from_pixbuf( |
| 184 rb.GetPixbufNamed(IDR_LOCATION_BAR_KEYWORD_HINT_TAB)); |
| 185 tab_to_search_hint_trailing_label_ = gtk_label_new(NULL); |
| 186 gtk_box_pack_start(GTK_BOX(tab_to_search_hint_), |
| 187 tab_to_search_hint_leading_label_, |
| 188 FALSE, FALSE, 0); |
| 189 gtk_box_pack_start(GTK_BOX(tab_to_search_hint_), |
| 190 tab_to_search_hint_icon_, |
| 191 FALSE, FALSE, 0); |
| 192 gtk_box_pack_start(GTK_BOX(tab_to_search_hint_), |
| 193 tab_to_search_hint_trailing_label_, |
| 194 FALSE, FALSE, 0); |
| 195 // tab_to_search_hint_ gets hidden initially in OnChanged. Hiding it here |
| 196 // doesn't work, someone is probably calling show_all on our parent box. |
| 197 gtk_box_pack_end(GTK_BOX(hbox_.get()), tab_to_search_hint_, FALSE, FALSE, 4); |
| 198 |
134 // Pack info_label_ and security icons in hbox. We hide/show them | 199 // Pack info_label_ and security icons in hbox. We hide/show them |
135 // by SetSecurityIcon() and SetInfoText(). | 200 // by SetSecurityIcon() and SetInfoText(). |
136 info_label_align_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | 201 info_label_align_ = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
137 gtk_alignment_set_padding(GTK_ALIGNMENT(info_label_align_), | 202 gtk_alignment_set_padding(GTK_ALIGNMENT(info_label_align_), |
138 kTopMargin + kBorderThickness, | 203 kTopMargin + kBorderThickness, |
139 kBottomMargin + kBorderThickness, | 204 kBottomMargin + kBorderThickness, |
140 0, kEvTextPaddingRight); | 205 0, kEvTextPaddingRight); |
141 gtk_container_add(GTK_CONTAINER(info_label_align_), info_label_); | 206 gtk_container_add(GTK_CONTAINER(info_label_align_), info_label_); |
142 gtk_box_pack_end(GTK_BOX(hbox_.get()), info_label_align_, FALSE, FALSE, 0); | 207 gtk_box_pack_end(GTK_BOX(hbox_.get()), info_label_align_, FALSE, FALSE, 0); |
143 | 208 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 // I'm not sure this should be reachable, but I'm not also sure enough | 263 // I'm not sure this should be reachable, but I'm not also sure enough |
199 // that it shouldn't to stick in a NOTREACHED(). In any case, this is | 264 // that it shouldn't to stick in a NOTREACHED(). In any case, this is |
200 // harmless; we can simply let the fetcher get deleted here and it will | 265 // harmless; we can simply let the fetcher get deleted here and it will |
201 // clean itself up properly. | 266 // clean itself up properly. |
202 } else { | 267 } else { |
203 fetcher.release(); // The navigation controller will delete the fetcher. | 268 fetcher.release(); // The navigation controller will delete the fetcher. |
204 } | 269 } |
205 } | 270 } |
206 | 271 |
207 void LocationBarViewGtk::OnChanged() { | 272 void LocationBarViewGtk::OnChanged() { |
208 // TODO(deanm): Here is where we would do layout when we have things like | 273 const std::wstring keyword(location_entry_->model()->keyword()); |
209 // the keyword display, ssl icons, etc. | 274 const bool is_keyword_hint = location_entry_->model()->is_keyword_hint(); |
| 275 const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint; |
| 276 const bool show_keyword_hint = !keyword.empty() && is_keyword_hint; |
| 277 |
| 278 if (show_selected_keyword) { |
| 279 SetKeywordLabel(keyword); |
| 280 gtk_widget_show_all(tab_to_search_); |
| 281 } else { |
| 282 gtk_widget_hide_all(tab_to_search_); |
| 283 } |
| 284 |
| 285 if (show_keyword_hint) { |
| 286 SetKeywordHintLabel(keyword); |
| 287 gtk_widget_show_all(tab_to_search_hint_); |
| 288 } else { |
| 289 gtk_widget_hide_all(tab_to_search_hint_); |
| 290 } |
210 } | 291 } |
211 | 292 |
212 void LocationBarViewGtk::OnInputInProgress(bool in_progress) { | 293 void LocationBarViewGtk::OnInputInProgress(bool in_progress) { |
213 // This is identical to the Windows code, except that we don't proxy the call | 294 // This is identical to the Windows code, except that we don't proxy the call |
214 // back through the Toolbar, and just access the model here. | 295 // back through the Toolbar, and just access the model here. |
215 // The edit should make sure we're only notified when something changes. | 296 // The edit should make sure we're only notified when something changes. |
216 DCHECK(toolbar_model_->input_in_progress() != in_progress); | 297 DCHECK(toolbar_model_->input_in_progress() != in_progress); |
217 | 298 |
218 toolbar_model_->set_input_in_progress(in_progress); | 299 toolbar_model_->set_input_in_progress(in_progress); |
219 Update(NULL); | 300 Update(NULL); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 } else { | 436 } else { |
356 DCHECK_EQ(info_text_type, ToolbarModel::INFO_NO_INFO); | 437 DCHECK_EQ(info_text_type, ToolbarModel::INFO_NO_INFO); |
357 DCHECK(info_text.empty()); | 438 DCHECK(info_text.empty()); |
358 // Clear info_text. Should we reset the fg here? | 439 // Clear info_text. Should we reset the fg here? |
359 gtk_widget_hide(GTK_WIDGET(info_label_align_)); | 440 gtk_widget_hide(GTK_WIDGET(info_label_align_)); |
360 } | 441 } |
361 gtk_label_set_text(GTK_LABEL(info_label_), WideToUTF8(info_text).c_str()); | 442 gtk_label_set_text(GTK_LABEL(info_label_), WideToUTF8(info_text).c_str()); |
362 gtk_widget_set_tooltip_text(GTK_WIDGET(info_label_), | 443 gtk_widget_set_tooltip_text(GTK_WIDGET(info_label_), |
363 WideToUTF8(info_tooltip).c_str()); | 444 WideToUTF8(info_tooltip).c_str()); |
364 } | 445 } |
| 446 |
| 447 void LocationBarViewGtk::SetKeywordLabel(const std::wstring& keyword) { |
| 448 if (keyword.empty()) |
| 449 return; |
| 450 |
| 451 DCHECK(profile_); |
| 452 if (!profile_->GetTemplateURLModel()) |
| 453 return; |
| 454 |
| 455 const std::wstring short_name = GetKeywordName(profile_, keyword); |
| 456 // TODO(deanm): Windows does some measuring of the text here and truncates |
| 457 // it if it's too long? |
| 458 std::wstring full_name(l10n_util::GetStringF(IDS_OMNIBOX_KEYWORD_TEXT, |
| 459 short_name)); |
| 460 gtk_label_set_text(GTK_LABEL(tab_to_search_label_), |
| 461 WideToUTF8(full_name).c_str()); |
| 462 } |
| 463 |
| 464 void LocationBarViewGtk::SetKeywordHintLabel(const std::wstring& keyword) { |
| 465 if (keyword.empty()) |
| 466 return; |
| 467 |
| 468 DCHECK(profile_); |
| 469 if (!profile_->GetTemplateURLModel()) |
| 470 return; |
| 471 |
| 472 std::vector<size_t> content_param_offsets; |
| 473 const std::wstring keyword_hint(l10n_util::GetStringF( |
| 474 IDS_OMNIBOX_KEYWORD_HINT, std::wstring(), |
| 475 GetKeywordName(profile_, keyword), &content_param_offsets)); |
| 476 |
| 477 if (content_param_offsets.size() != 2) { |
| 478 // See comments on an identical NOTREACHED() in search_provider.cc. |
| 479 NOTREACHED(); |
| 480 return; |
| 481 } |
| 482 |
| 483 std::string leading(WideToUTF8( |
| 484 keyword_hint.substr(0, content_param_offsets.front()))); |
| 485 std::string trailing(WideToUTF8( |
| 486 keyword_hint.substr(content_param_offsets.front()))); |
| 487 gtk_label_set_text(GTK_LABEL(tab_to_search_hint_leading_label_), |
| 488 leading.c_str()); |
| 489 gtk_label_set_text(GTK_LABEL(tab_to_search_hint_trailing_label_), |
| 490 trailing.c_str()); |
| 491 } |
OLD | NEW |