| 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/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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, | 96 popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, |
| 97 model_.get(), | 97 model_.get(), |
| 98 profile, | 98 profile, |
| 99 bubble_positioner)), | 99 bubble_positioner)), |
| 100 controller_(controller), | 100 controller_(controller), |
| 101 toolbar_model_(toolbar_model), | 101 toolbar_model_(toolbar_model), |
| 102 command_updater_(command_updater), | 102 command_updater_(command_updater), |
| 103 popup_window_mode_(popup_window_mode), | 103 popup_window_mode_(popup_window_mode), |
| 104 scheme_security_level_(ToolbarModel::NORMAL), | 104 scheme_security_level_(ToolbarModel::NORMAL), |
| 105 mark_set_handler_id_(0), | 105 mark_set_handler_id_(0), |
| 106 #if defined(OS_CHROMEOS) |
| 107 button_1_pressed_(false), |
| 108 text_selected_during_click_(false), |
| 109 text_view_focused_before_button_press_(false), |
| 110 #endif |
| 106 #if !defined(TOOLKIT_VIEWS) | 111 #if !defined(TOOLKIT_VIEWS) |
| 107 theme_provider_(GtkThemeProvider::GetFrom(profile)), | 112 theme_provider_(GtkThemeProvider::GetFrom(profile)), |
| 108 #endif | 113 #endif |
| 109 enter_was_pressed_(false), | 114 enter_was_pressed_(false), |
| 110 tab_was_pressed_(false), | 115 tab_was_pressed_(false), |
| 111 paste_clipboard_requested_(false), | 116 paste_clipboard_requested_(false), |
| 112 enter_was_inserted_(false) { | 117 enter_was_inserted_(false) { |
| 113 model_->SetPopupModel(popup_view_->GetModel()); | 118 model_->SetPopupModel(popup_view_->GetModel()); |
| 114 } | 119 } |
| 115 | 120 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 G_CALLBACK(&HandleBeginUserActionThunk), this); | 187 G_CALLBACK(&HandleBeginUserActionThunk), this); |
| 183 g_signal_connect(text_buffer_, "end-user-action", | 188 g_signal_connect(text_buffer_, "end-user-action", |
| 184 G_CALLBACK(&HandleEndUserActionThunk), this); | 189 G_CALLBACK(&HandleEndUserActionThunk), this); |
| 185 g_signal_connect(text_buffer_, "insert-text", | 190 g_signal_connect(text_buffer_, "insert-text", |
| 186 G_CALLBACK(&HandleInsertTextThunk), this); | 191 G_CALLBACK(&HandleInsertTextThunk), this); |
| 187 // We connect to key press and release for special handling of a few keys. | 192 // We connect to key press and release for special handling of a few keys. |
| 188 g_signal_connect(text_view_, "key-press-event", | 193 g_signal_connect(text_view_, "key-press-event", |
| 189 G_CALLBACK(&HandleKeyPressThunk), this); | 194 G_CALLBACK(&HandleKeyPressThunk), this); |
| 190 g_signal_connect(text_view_, "key-release-event", | 195 g_signal_connect(text_view_, "key-release-event", |
| 191 G_CALLBACK(&HandleKeyReleaseThunk), this); | 196 G_CALLBACK(&HandleKeyReleaseThunk), this); |
| 197 #if defined(OS_CHROMEOS) |
| 198 g_signal_connect(text_view_, "button-press-event", |
| 199 G_CALLBACK(&HandleViewButtonPressThunk), this); |
| 200 g_signal_connect(text_view_, "button-release-event", |
| 201 G_CALLBACK(&HandleViewButtonReleaseThunk), this); |
| 202 #endif |
| 192 g_signal_connect(text_view_, "focus-in-event", | 203 g_signal_connect(text_view_, "focus-in-event", |
| 193 G_CALLBACK(&HandleViewFocusInThunk), this); | 204 G_CALLBACK(&HandleViewFocusInThunk), this); |
| 194 g_signal_connect(text_view_, "focus-out-event", | 205 g_signal_connect(text_view_, "focus-out-event", |
| 195 G_CALLBACK(&HandleViewFocusOutThunk), this); | 206 G_CALLBACK(&HandleViewFocusOutThunk), this); |
| 196 // NOTE: The GtkTextView documentation asks you not to connect to this | 207 // NOTE: The GtkTextView documentation asks you not to connect to this |
| 197 // signal, but it is very convenient and clean for catching up/down. | 208 // signal, but it is very convenient and clean for catching up/down. |
| 198 g_signal_connect(text_view_, "move-cursor", | 209 g_signal_connect(text_view_, "move-cursor", |
| 199 G_CALLBACK(&HandleViewMoveCursorThunk), this); | 210 G_CALLBACK(&HandleViewMoveCursorThunk), this); |
| 200 g_signal_connect(text_view_, "move-focus", | 211 g_signal_connect(text_view_, "move-focus", |
| 201 G_CALLBACK(&HandleViewMoveFocusThunk), this); | 212 G_CALLBACK(&HandleViewMoveFocusThunk), this); |
| (...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 if (!(mod & GDK_CONTROL_MASK)) | 719 if (!(mod & GDK_CONTROL_MASK)) |
| 709 model_->OnControlKeyChanged(false); | 720 model_->OnControlKeyChanged(false); |
| 710 } | 721 } |
| 711 | 722 |
| 712 // Even though we handled the press ourselves, let GtkTextView handle the | 723 // Even though we handled the press ourselves, let GtkTextView handle the |
| 713 // release. It shouldn't do anything particularly interesting, but it will | 724 // release. It shouldn't do anything particularly interesting, but it will |
| 714 // handle the IME work for us. | 725 // handle the IME work for us. |
| 715 return FALSE; // Propagate into GtkTextView. | 726 return FALSE; // Propagate into GtkTextView. |
| 716 } | 727 } |
| 717 | 728 |
| 729 #if defined(OS_CHROMEOS) |
| 730 gboolean AutocompleteEditViewGtk::HandleViewButtonPress(GdkEventButton* event) { |
| 731 // We don't need to care about double and triple clicks. |
| 732 if (event->type != GDK_BUTTON_PRESS) |
| 733 return FALSE; |
| 734 |
| 735 if (event->button == 1) { |
| 736 // When the first button is pressed, track some stuff that will help us |
| 737 // determine whether we should select all of the text when the button is |
| 738 // released. |
| 739 button_1_pressed_ = true; |
| 740 text_view_focused_before_button_press_ = GTK_WIDGET_HAS_FOCUS(text_view_); |
| 741 text_selected_during_click_ = false; |
| 742 |
| 743 // Button press event may change the selection, we need to record the change |
| 744 // and report it to |model_| later when button is released. |
| 745 OnBeforePossibleChange(); |
| 746 } else if (event->button == 2) { |
| 747 // GtkTextView pastes PRIMARY selection with middle click. |
| 748 // We can't call model_->on_paste_replacing_all() here, because the actual |
| 749 // paste clipboard action may not be performed if the clipboard is empty. |
| 750 paste_clipboard_requested_ = true; |
| 751 } |
| 752 return FALSE; |
| 753 } |
| 754 |
| 755 gboolean AutocompleteEditViewGtk::HandleViewButtonRelease( |
| 756 GdkEventButton* event) { |
| 757 if (event->button != 1) |
| 758 return FALSE; |
| 759 |
| 760 button_1_pressed_ = false; |
| 761 |
| 762 // Call the GtkTextView default handler, ignoring the fact that it will |
| 763 // likely have told us to stop propagating. We want to handle selection. |
| 764 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); |
| 765 klass->button_release_event(text_view_, event); |
| 766 |
| 767 if (!text_view_focused_before_button_press_ && !text_selected_during_click_) { |
| 768 // If this was a focusing click and the user didn't drag to highlight any |
| 769 // text, select the full input and update the PRIMARY selection. |
| 770 SelectAllInternal(false, true); |
| 771 |
| 772 // So we told the buffer where the cursor should be, but make sure to tell |
| 773 // the view so it can scroll it to be visible if needed. |
| 774 // NOTE: This function doesn't seem to like a count of 0, looking at the |
| 775 // code it will skip an important loop. Use -1 to achieve the same. |
| 776 GtkTextIter start, end; |
| 777 gtk_text_buffer_get_bounds(text_buffer_, &start, &end); |
| 778 gtk_text_view_move_visually(GTK_TEXT_VIEW(text_view_), &start, -1); |
| 779 } |
| 780 |
| 781 // Inform |model_| about possible text selection change. |
| 782 OnAfterPossibleChange(); |
| 783 |
| 784 return TRUE; // Don't continue, we called the default handler already. |
| 785 } |
| 786 #endif |
| 787 |
| 718 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() { | 788 gboolean AutocompleteEditViewGtk::HandleViewFocusIn() { |
| 719 GdkModifierType modifiers; | 789 GdkModifierType modifiers; |
| 720 gdk_window_get_pointer(text_view_->window, NULL, NULL, &modifiers); | 790 gdk_window_get_pointer(text_view_->window, NULL, NULL, &modifiers); |
| 721 model_->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); | 791 model_->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); |
| 722 controller_->OnSetFocus(); | 792 controller_->OnSetFocus(); |
| 723 // TODO(deanm): Some keyword hit business, etc here. | 793 // TODO(deanm): Some keyword hit business, etc here. |
| 724 | 794 |
| 725 return FALSE; // Continue propagation. | 795 return FALSE; // Continue propagation. |
| 726 } | 796 } |
| 727 | 797 |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 845 std::string new_selected_text; | 915 std::string new_selected_text; |
| 846 GtkTextIter start, end; | 916 GtkTextIter start, end; |
| 847 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &start, &end)) { | 917 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &start, &end)) { |
| 848 gchar* text = gtk_text_iter_get_text(&start, &end); | 918 gchar* text = gtk_text_iter_get_text(&start, &end); |
| 849 size_t text_len = strlen(text); | 919 size_t text_len = strlen(text); |
| 850 if (text_len) | 920 if (text_len) |
| 851 new_selected_text = std::string(text, text_len); | 921 new_selected_text = std::string(text, text_len); |
| 852 g_free(text); | 922 g_free(text); |
| 853 } | 923 } |
| 854 | 924 |
| 925 #if defined(OS_CHROMEOS) |
| 926 // If the user just selected some text with the mouse (or at least while the |
| 927 // mouse button was down), make sure that we won't blow their selection away |
| 928 // later by selecting all of the text when the button is released. |
| 929 if (button_1_pressed_ && !new_selected_text.empty()) |
| 930 text_selected_during_click_ = true; |
| 931 #endif |
| 932 |
| 855 // If we had some text selected earlier but it's no longer highlighted, we | 933 // If we had some text selected earlier but it's no longer highlighted, we |
| 856 // might need to save it now... | 934 // might need to save it now... |
| 857 if (!selected_text_.empty() && new_selected_text.empty()) { | 935 if (!selected_text_.empty() && new_selected_text.empty()) { |
| 858 // ... but only if we currently own the selection. We want to manually | 936 // ... but only if we currently own the selection. We want to manually |
| 859 // update the selection when the text is unhighlighted because the user | 937 // update the selection when the text is unhighlighted because the user |
| 860 // clicked in a blank area of the text view, but not when it's unhighlighted | 938 // clicked in a blank area of the text view, but not when it's unhighlighted |
| 861 // because another client or widget took the selection. (This handler gets | 939 // because another client or widget took the selection. (This handler gets |
| 862 // called before the default handler, so as long as nobody else took the | 940 // called before the default handler, so as long as nobody else took the |
| 863 // selection, the text buffer still owns it even if GTK is about to take it | 941 // selection, the text buffer still owns it even if GTK is about to take it |
| 864 // away in the default handler.) | 942 // away in the default handler.) |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1207 std::string utf8 = WideToUTF8(text); | 1285 std::string utf8 = WideToUTF8(text); |
| 1208 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length()); | 1286 gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length()); |
| 1209 SetSelectedRange(range); | 1287 SetSelectedRange(range); |
| 1210 } | 1288 } |
| 1211 | 1289 |
| 1212 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { | 1290 void AutocompleteEditViewGtk::SetSelectedRange(const CharRange& range) { |
| 1213 GtkTextIter insert, bound; | 1291 GtkTextIter insert, bound; |
| 1214 ItersFromCharRange(range, &bound, &insert); | 1292 ItersFromCharRange(range, &bound, &insert); |
| 1215 gtk_text_buffer_select_range(text_buffer_, &insert, &bound); | 1293 gtk_text_buffer_select_range(text_buffer_, &insert, &bound); |
| 1216 } | 1294 } |
| OLD | NEW |