OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/autocomplete/autocomplete_edit_view_gtk.h" | 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" |
6 | 6 |
7 #include <gtk/gtk.h> | 7 #include <gtk/gtk.h> |
8 #include <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 25 matching lines...) Expand all Loading... |
36 #include "chrome/browser/views/location_bar_view.h" | 36 #include "chrome/browser/views/location_bar_view.h" |
37 #include "gfx/skia_utils_gtk.h" | 37 #include "gfx/skia_utils_gtk.h" |
38 #else | 38 #else |
39 #include "chrome/browser/gtk/gtk_theme_provider.h" | 39 #include "chrome/browser/gtk/gtk_theme_provider.h" |
40 #include "chrome/browser/gtk/location_bar_view_gtk.h" | 40 #include "chrome/browser/gtk/location_bar_view_gtk.h" |
41 #endif | 41 #endif |
42 | 42 |
43 namespace { | 43 namespace { |
44 | 44 |
45 const char kTextBaseColor[] = "#808080"; | 45 const char kTextBaseColor[] = "#808080"; |
46 const char kSecureSchemeColor[] = "#009614"; | 46 const char kEVSecureSchemeColor[] = "#079500"; |
47 const char kInsecureSchemeColor[] = "#c80000"; | 47 const char kSecureSchemeColor[] = "#000e95"; |
| 48 const char kSecurityErrorSchemeColor[] = "#a20000"; |
48 | 49 |
49 const double kStrikethroughStrokeRed = 210.0 / 256.0; | 50 const double kStrikethroughStrokeRed = 162.0 / 256.0; |
50 const double kStrikethroughStrokeWidth = 2.0; | 51 const double kStrikethroughStrokeWidth = 2.0; |
51 | 52 |
52 size_t GetUTF8Offset(const std::wstring& wide_text, size_t wide_text_offset) { | 53 size_t GetUTF8Offset(const std::wstring& wide_text, size_t wide_text_offset) { |
53 return WideToUTF8(wide_text.substr(0, wide_text_offset)).size(); | 54 return WideToUTF8(wide_text.substr(0, wide_text_offset)).size(); |
54 } | 55 } |
55 | 56 |
56 // Stores GTK+-specific state so it can be restored after switching tabs. | 57 // Stores GTK+-specific state so it can be restored after switching tabs. |
57 struct ViewState { | 58 struct ViewState { |
58 explicit ViewState(const AutocompleteEditViewGtk::CharRange& selection_range) | 59 explicit ViewState(const AutocompleteEditViewGtk::CharRange& selection_range) |
59 : selection_range(selection_range) { | 60 : selection_range(selection_range) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 AutocompleteEditController* controller, | 112 AutocompleteEditController* controller, |
112 ToolbarModel* toolbar_model, | 113 ToolbarModel* toolbar_model, |
113 Profile* profile, | 114 Profile* profile, |
114 CommandUpdater* command_updater, | 115 CommandUpdater* command_updater, |
115 bool popup_window_mode, | 116 bool popup_window_mode, |
116 const BubblePositioner* bubble_positioner) | 117 const BubblePositioner* bubble_positioner) |
117 : text_view_(NULL), | 118 : text_view_(NULL), |
118 tag_table_(NULL), | 119 tag_table_(NULL), |
119 text_buffer_(NULL), | 120 text_buffer_(NULL), |
120 faded_text_tag_(NULL), | 121 faded_text_tag_(NULL), |
| 122 ev_secure_scheme_tag_(NULL), |
121 secure_scheme_tag_(NULL), | 123 secure_scheme_tag_(NULL), |
122 insecure_scheme_tag_(NULL), | 124 security_error_scheme_tag_(NULL), |
123 model_(new AutocompleteEditModel(this, controller, profile)), | 125 model_(new AutocompleteEditModel(this, controller, profile)), |
124 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, | 126 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, |
125 model_.get(), | 127 model_.get(), |
126 profile, | 128 profile, |
127 bubble_positioner)), | 129 bubble_positioner)), |
128 controller_(controller), | 130 controller_(controller), |
129 toolbar_model_(toolbar_model), | 131 toolbar_model_(toolbar_model), |
130 command_updater_(command_updater), | 132 command_updater_(command_updater), |
131 popup_window_mode_(popup_window_mode), | 133 popup_window_mode_(popup_window_mode), |
132 scheme_security_level_(ToolbarModel::NORMAL), | 134 security_level_(ToolbarModel::NONE), |
133 mark_set_handler_id_(0), | 135 mark_set_handler_id_(0), |
134 #if defined(OS_CHROMEOS) | 136 #if defined(OS_CHROMEOS) |
135 button_1_pressed_(false), | 137 button_1_pressed_(false), |
136 text_selected_during_click_(false), | 138 text_selected_during_click_(false), |
137 text_view_focused_before_button_press_(false), | 139 text_view_focused_before_button_press_(false), |
138 #endif | 140 #endif |
139 #if !defined(TOOLKIT_VIEWS) | 141 #if !defined(TOOLKIT_VIEWS) |
140 theme_provider_(GtkThemeProvider::GetFrom(profile)), | 142 theme_provider_(GtkThemeProvider::GetFrom(profile)), |
141 #endif | 143 #endif |
142 enter_was_pressed_(false), | 144 enter_was_pressed_(false), |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view_); | 205 gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view_); |
204 | 206 |
205 // Do not allow inserting tab characters when pressing Tab key, so that when | 207 // Do not allow inserting tab characters when pressing Tab key, so that when |
206 // Tab key is pressed, |text_view_| will emit "move-focus" signal, which will | 208 // Tab key is pressed, |text_view_| will emit "move-focus" signal, which will |
207 // be intercepted by our own handler to trigger Tab to search feature when | 209 // be intercepted by our own handler to trigger Tab to search feature when |
208 // necessary. | 210 // necessary. |
209 gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), FALSE); | 211 gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), FALSE); |
210 | 212 |
211 faded_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, | 213 faded_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, |
212 NULL, "foreground", kTextBaseColor, NULL); | 214 NULL, "foreground", kTextBaseColor, NULL); |
| 215 ev_secure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, |
| 216 NULL, "foreground", kEVSecureSchemeColor, NULL); |
213 secure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, | 217 secure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, |
214 NULL, "foreground", kSecureSchemeColor, NULL); | 218 NULL, "foreground", kSecureSchemeColor, NULL); |
215 insecure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, | 219 security_error_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, |
216 NULL, "foreground", kInsecureSchemeColor, NULL); | 220 NULL, "foreground", kSecurityErrorSchemeColor, NULL); |
217 normal_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, | 221 normal_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, |
218 NULL, "foreground", "#000000", NULL); | 222 NULL, "foreground", "#000000", NULL); |
219 | 223 |
220 // NOTE: This code used to connect to "changed", however this was fired too | 224 // NOTE: This code used to connect to "changed", however this was fired too |
221 // often and during bad times (our own buffer changes?). It works out much | 225 // often and during bad times (our own buffer changes?). It works out much |
222 // better to listen to end-user-action, which should be fired whenever the | 226 // better to listen to end-user-action, which should be fired whenever the |
223 // user makes some sort of change to the buffer. | 227 // user makes some sort of change to the buffer. |
224 g_signal_connect(text_buffer_, "begin-user-action", | 228 g_signal_connect(text_buffer_, "begin-user-action", |
225 G_CALLBACK(&HandleBeginUserActionThunk), this); | 229 G_CALLBACK(&HandleBeginUserActionThunk), this); |
226 g_signal_connect(text_buffer_, "end-user-action", | 230 g_signal_connect(text_buffer_, "end-user-action", |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 registrar_.Add(this, | 278 registrar_.Add(this, |
275 NotificationType::BROWSER_THEME_CHANGED, | 279 NotificationType::BROWSER_THEME_CHANGED, |
276 NotificationService::AllSources()); | 280 NotificationService::AllSources()); |
277 theme_provider_->InitThemesFor(this); | 281 theme_provider_->InitThemesFor(this); |
278 #else | 282 #else |
279 // Manually invoke SetBaseColor() because TOOLKIT_VIEWS doesn't observe | 283 // Manually invoke SetBaseColor() because TOOLKIT_VIEWS doesn't observe |
280 // themes. | 284 // themes. |
281 SetBaseColor(); | 285 SetBaseColor(); |
282 #endif | 286 #endif |
283 | 287 |
284 ViewIDUtil::SetID(widget(), VIEW_ID_AUTOCOMPLETE); | 288 ViewIDUtil::SetID(GetNativeView(), VIEW_ID_AUTOCOMPLETE); |
285 } | 289 } |
286 | 290 |
287 void AutocompleteEditViewGtk::SetFocus() { | 291 void AutocompleteEditViewGtk::SetFocus() { |
288 gtk_widget_grab_focus(text_view_); | 292 gtk_widget_grab_focus(text_view_); |
289 } | 293 } |
290 | 294 |
291 int AutocompleteEditViewGtk::TextWidth() { | 295 int AutocompleteEditViewGtk::TextWidth() { |
292 int horizontal_border_size = | 296 int horizontal_border_size = |
293 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), | 297 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), |
294 GTK_TEXT_WINDOW_LEFT) + | 298 GTK_TEXT_WINDOW_LEFT) + |
(...skipping 29 matching lines...) Expand all Loading... |
324 tab->property_bag(), | 328 tab->property_bag(), |
325 AutocompleteEditState(model_state, ViewState(GetSelection()))); | 329 AutocompleteEditState(model_state, ViewState(GetSelection()))); |
326 } | 330 } |
327 | 331 |
328 void AutocompleteEditViewGtk::Update(const TabContents* contents) { | 332 void AutocompleteEditViewGtk::Update(const TabContents* contents) { |
329 // NOTE: We're getting the URL text here from the ToolbarModel. | 333 // NOTE: We're getting the URL text here from the ToolbarModel. |
330 bool visibly_changed_permanent_text = | 334 bool visibly_changed_permanent_text = |
331 model_->UpdatePermanentText(toolbar_model_->GetText()); | 335 model_->UpdatePermanentText(toolbar_model_->GetText()); |
332 | 336 |
333 ToolbarModel::SecurityLevel security_level = | 337 ToolbarModel::SecurityLevel security_level = |
334 toolbar_model_->GetSchemeSecurityLevel(); | 338 toolbar_model_->GetSecurityLevel(); |
335 bool changed_security_level = (security_level != scheme_security_level_); | 339 bool changed_security_level = (security_level != security_level_); |
336 scheme_security_level_ = security_level; | 340 security_level_ = security_level; |
337 | |
338 // TODO(deanm): This doesn't exactly match Windows. There there is a member | |
339 // background_color_. I think we can get away with just the level though. | |
340 if (changed_security_level) { | |
341 SetBaseColor(); | |
342 } | |
343 | 341 |
344 if (contents) { | 342 if (contents) { |
345 selected_text_.clear(); | 343 selected_text_.clear(); |
346 RevertAll(); | 344 RevertAll(); |
347 const AutocompleteEditState* state = | 345 const AutocompleteEditState* state = |
348 GetStateAccessor()->GetProperty(contents->property_bag()); | 346 GetStateAccessor()->GetProperty(contents->property_bag()); |
349 if (state) { | 347 if (state) { |
350 model_->RestoreState(state->model_state); | 348 model_->RestoreState(state->model_state); |
351 | 349 |
352 // Move the marks for the cursor and the other end of the selection to | 350 // Move the marks for the cursor and the other end of the selection to |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 SetBaseColor(); | 570 SetBaseColor(); |
573 } | 571 } |
574 | 572 |
575 void AutocompleteEditViewGtk::SetBaseColor() { | 573 void AutocompleteEditViewGtk::SetBaseColor() { |
576 #if defined(TOOLKIT_VIEWS) | 574 #if defined(TOOLKIT_VIEWS) |
577 bool use_gtk = false; | 575 bool use_gtk = false; |
578 #else | 576 #else |
579 bool use_gtk = theme_provider_->UseGtkTheme(); | 577 bool use_gtk = theme_provider_->UseGtkTheme(); |
580 #endif | 578 #endif |
581 | 579 |
582 // If we're on a secure connection, ignore what the theme wants us to do | 580 if (use_gtk) { |
583 // and use a yellow background. | |
584 bool is_secure = (scheme_security_level_ == ToolbarModel::SECURE); | |
585 if (use_gtk && !is_secure) { | |
586 gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, NULL); | 581 gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, NULL); |
587 | 582 |
588 // Grab the text colors out of the style and set our tags to use them. | 583 // Grab the text colors out of the style and set our tags to use them. |
589 GtkStyle* style = gtk_rc_get_style(text_view_); | 584 GtkStyle* style = gtk_rc_get_style(text_view_); |
590 | 585 |
591 // style may be unrealized at this point, so calculate the halfway point | 586 // style may be unrealized at this point, so calculate the halfway point |
592 // between text[] and base[] manually instead of just using text_aa[]. | 587 // between text[] and base[] manually instead of just using text_aa[]. |
593 GdkColor average_color = gtk_util::AverageColors( | 588 GdkColor average_color = gtk_util::AverageColors( |
594 style->text[GTK_STATE_NORMAL], style->base[GTK_STATE_NORMAL]); | 589 style->text[GTK_STATE_NORMAL], style->base[GTK_STATE_NORMAL]); |
595 | 590 |
596 g_object_set(faded_text_tag_, "foreground-gdk", | 591 g_object_set(faded_text_tag_, "foreground-gdk", &average_color, NULL); |
597 &average_color, NULL); | |
598 g_object_set(normal_text_tag_, "foreground-gdk", | 592 g_object_set(normal_text_tag_, "foreground-gdk", |
599 &style->text[GTK_STATE_NORMAL], NULL); | 593 &style->text[GTK_STATE_NORMAL], NULL); |
600 } else { | 594 } else { |
| 595 const GdkColor* background_color_ptr; |
601 #if defined(TOOLKIT_VIEWS) | 596 #if defined(TOOLKIT_VIEWS) |
602 const GdkColor background_color = gfx::SkColorToGdkColor( | 597 const GdkColor background_color = gfx::SkColorToGdkColor( |
603 LocationBarView::GetColor(is_secure, LocationBarView::BACKGROUND)); | 598 LocationBarView::GetColor(ToolbarModel::NONE, |
604 gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, | 599 LocationBarView::BACKGROUND)); |
605 &background_color); | 600 background_color_ptr = &background_color; |
606 #else | 601 #else |
607 gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, | 602 background_color_ptr = &LocationBarViewGtk::kBackgroundColor; |
608 &LocationBarViewGtk::kBackgroundColorByLevel[scheme_security_level_]); | |
609 #endif | 603 #endif |
| 604 gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, background_color_ptr); |
610 | 605 |
611 g_object_set(faded_text_tag_, "foreground", kTextBaseColor, NULL); | 606 g_object_set(faded_text_tag_, "foreground", kTextBaseColor, NULL); |
612 g_object_set(normal_text_tag_, "foreground", "#000000", NULL); | 607 g_object_set(normal_text_tag_, "foreground", "#000000", NULL); |
613 } | 608 } |
614 } | 609 } |
615 | 610 |
616 void AutocompleteEditViewGtk::HandleBeginUserAction() { | 611 void AutocompleteEditViewGtk::HandleBeginUserAction() { |
617 OnBeforePossibleChange(); | 612 OnBeforePossibleChange(); |
618 } | 613 } |
619 | 614 |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1335 host.end())); | 1330 host.end())); |
1336 | 1331 |
1337 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); | 1332 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); |
1338 } else { | 1333 } else { |
1339 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); | 1334 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); |
1340 } | 1335 } |
1341 | 1336 |
1342 strikethrough_ = CharRange(); | 1337 strikethrough_ = CharRange(); |
1343 // Emphasize the scheme for security UI display purposes (if necessary). | 1338 // Emphasize the scheme for security UI display purposes (if necessary). |
1344 if (!model_->user_input_in_progress() && scheme.is_nonempty() && | 1339 if (!model_->user_input_in_progress() && scheme.is_nonempty() && |
1345 (scheme_security_level_ != ToolbarModel::NORMAL)) { | 1340 (security_level_ != ToolbarModel::NONE)) { |
1346 CharRange scheme_range = CharRange(GetUTF8Offset(text, scheme.begin), | 1341 CharRange scheme_range = CharRange(GetUTF8Offset(text, scheme.begin), |
1347 GetUTF8Offset(text, scheme.end())); | 1342 GetUTF8Offset(text, scheme.end())); |
1348 ItersFromCharRange(scheme_range, &start, &end); | 1343 ItersFromCharRange(scheme_range, &start, &end); |
1349 | 1344 |
1350 if (scheme_security_level_ == ToolbarModel::SECURE) { | 1345 if (security_level_ == ToolbarModel::SECURITY_ERROR) { |
1351 gtk_text_buffer_apply_tag(text_buffer_, secure_scheme_tag_, | |
1352 &start, &end); | |
1353 } else { | |
1354 strikethrough_ = scheme_range; | 1346 strikethrough_ = scheme_range; |
1355 // When we draw the strikethrough, we don't want to include the ':' at the | 1347 // When we draw the strikethrough, we don't want to include the ':' at the |
1356 // end of the scheme. | 1348 // end of the scheme. |
1357 strikethrough_.cp_max--; | 1349 strikethrough_.cp_max--; |
1358 | 1350 |
1359 gtk_text_buffer_apply_tag(text_buffer_, insecure_scheme_tag_, | 1351 gtk_text_buffer_apply_tag(text_buffer_, security_error_scheme_tag_, |
1360 &start, &end); | 1352 &start, &end); |
| 1353 } else { |
| 1354 gtk_text_buffer_apply_tag(text_buffer_, |
| 1355 (security_level_ == ToolbarModel::EV_SECURE) ? |
| 1356 ev_secure_scheme_tag_ : secure_scheme_tag_, &start, &end); |
1361 } | 1357 } |
1362 } | 1358 } |
1363 } | 1359 } |
1364 | 1360 |
1365 void AutocompleteEditViewGtk::TextChanged() { | 1361 void AutocompleteEditViewGtk::TextChanged() { |
1366 EmphasizeURLComponents(); | 1362 EmphasizeURLComponents(); |
1367 controller_->OnChanged(); | 1363 controller_->OnChanged(); |
1368 } | 1364 } |
1369 | 1365 |
1370 void AutocompleteEditViewGtk::SavePrimarySelection( | 1366 void AutocompleteEditViewGtk::SavePrimarySelection( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1421 | 1417 |
1422 PangoDirection dir = PANGO_DIRECTION_NEUTRAL; | 1418 PangoDirection dir = PANGO_DIRECTION_NEUTRAL; |
1423 do { | 1419 do { |
1424 dir = pango_unichar_direction(gtk_text_iter_get_char(&iter)); | 1420 dir = pango_unichar_direction(gtk_text_iter_get_char(&iter)); |
1425 if (dir != PANGO_DIRECTION_NEUTRAL) | 1421 if (dir != PANGO_DIRECTION_NEUTRAL) |
1426 break; | 1422 break; |
1427 } while (gtk_text_iter_forward_char(&iter)); | 1423 } while (gtk_text_iter_forward_char(&iter)); |
1428 | 1424 |
1429 return dir; | 1425 return dir; |
1430 } | 1426 } |
OLD | NEW |