OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
772 ) { | 772 ) { |
773 instant_animation_->set_delegate(this); | 773 instant_animation_->set_delegate(this); |
774 instant_animation_->Start(); | 774 instant_animation_->Start(); |
775 } | 775 } |
776 | 776 |
777 gtk_widget_show(instant_view_); | 777 gtk_widget_show(instant_view_); |
778 AdjustVerticalAlignmentOfInstantView(); | 778 AdjustVerticalAlignmentOfInstantView(); |
779 UpdateInstantViewColors(); | 779 UpdateInstantViewColors(); |
780 } | 780 } |
781 | 781 |
782 string16 AutocompleteEditViewGtk::GetInstantSuggestion() const { | |
783 const gchar* suggestion = gtk_label_get_text(GTK_LABEL(instant_view_)); | |
784 return suggestion ? UTF8ToUTF16(suggestion) : string16(); | |
785 } | |
786 | |
782 int AutocompleteEditViewGtk::TextWidth() const { | 787 int AutocompleteEditViewGtk::TextWidth() const { |
783 int horizontal_border_size = | 788 int horizontal_border_size = |
784 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), | 789 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), |
785 GTK_TEXT_WINDOW_LEFT) + | 790 GTK_TEXT_WINDOW_LEFT) + |
786 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), | 791 gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), |
787 GTK_TEXT_WINDOW_RIGHT) + | 792 GTK_TEXT_WINDOW_RIGHT) + |
788 gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + | 793 gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + |
789 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); | 794 gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); |
790 | 795 |
791 GtkTextIter start, end; | 796 GtkTextIter start, end; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
827 | 832 |
828 #if defined(TOOLKIT_VIEWS) | 833 #if defined(TOOLKIT_VIEWS) |
829 views::View* AutocompleteEditViewGtk::AddToView(views::View* parent) { | 834 views::View* AutocompleteEditViewGtk::AddToView(views::View* parent) { |
830 views::NativeViewHost* host = new views::NativeViewHost; | 835 views::NativeViewHost* host = new views::NativeViewHost; |
831 parent->AddChildView(host); | 836 parent->AddChildView(host); |
832 host->set_focus_view(parent); | 837 host->set_focus_view(parent); |
833 host->Attach(GetNativeView()); | 838 host->Attach(GetNativeView()); |
834 return host; | 839 return host; |
835 } | 840 } |
836 | 841 |
837 bool AutocompleteEditViewGtk::CommitInstantSuggestion( | |
838 const string16& typed_text, | |
839 const string16& suggestion) { | |
840 return CommitInstantSuggestion(); | |
841 } | |
842 | |
843 void AutocompleteEditViewGtk::EnableAccessibility() { | 842 void AutocompleteEditViewGtk::EnableAccessibility() { |
844 accessible_widget_helper_.reset( | 843 accessible_widget_helper_.reset( |
845 new AccessibleWidgetHelper(text_view(), model_->profile())); | 844 new AccessibleWidgetHelper(text_view(), model_->profile())); |
846 accessible_widget_helper_->SetWidgetName( | 845 accessible_widget_helper_->SetWidgetName( |
847 text_view(), l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); | 846 text_view(), l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); |
848 } | 847 } |
849 | 848 |
850 // static | 849 // static |
851 AutocompleteEditView* AutocompleteEditViewGtk::Create( | 850 AutocompleteEditView* AutocompleteEditViewGtk::Create( |
852 AutocompleteEditController* controller, | 851 AutocompleteEditController* controller, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
891 | 890 |
892 void AutocompleteEditViewGtk::Observe(NotificationType type, | 891 void AutocompleteEditViewGtk::Observe(NotificationType type, |
893 const NotificationSource& source, | 892 const NotificationSource& source, |
894 const NotificationDetails& details) { | 893 const NotificationDetails& details) { |
895 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); | 894 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); |
896 | 895 |
897 SetBaseColor(); | 896 SetBaseColor(); |
898 } | 897 } |
899 | 898 |
900 void AutocompleteEditViewGtk::AnimationEnded(const ui::Animation* animation) { | 899 void AutocompleteEditViewGtk::AnimationEnded(const ui::Animation* animation) { |
901 controller_->OnCommitSuggestedText(GetText()); | 900 controller_->OnCommitSuggestedText(false); |
902 } | 901 } |
903 | 902 |
904 void AutocompleteEditViewGtk::AnimationProgressed( | 903 void AutocompleteEditViewGtk::AnimationProgressed( |
905 const ui::Animation* animation) { | 904 const ui::Animation* animation) { |
906 UpdateInstantViewColors(); | 905 UpdateInstantViewColors(); |
907 } | 906 } |
908 | 907 |
909 void AutocompleteEditViewGtk::AnimationCanceled( | 908 void AutocompleteEditViewGtk::AnimationCanceled( |
910 const ui::Animation* animation) { | 909 const ui::Animation* animation) { |
911 UpdateInstantViewColors(); | 910 UpdateInstantViewColors(); |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1337 GtkMovementStep step, | 1336 GtkMovementStep step, |
1338 gint count, | 1337 gint count, |
1339 gboolean extend_selection) { | 1338 gboolean extend_selection) { |
1340 GtkTextIter sel_start, sel_end; | 1339 GtkTextIter sel_start, sel_end; |
1341 gboolean has_selection = | 1340 gboolean has_selection = |
1342 gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end); | 1341 gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end); |
1343 bool handled = false; | 1342 bool handled = false; |
1344 | 1343 |
1345 if (step == GTK_MOVEMENT_VISUAL_POSITIONS && !extend_selection && | 1344 if (step == GTK_MOVEMENT_VISUAL_POSITIONS && !extend_selection && |
1346 (count == 1 || count == -1)) { | 1345 (count == 1 || count == -1)) { |
1347 gint cursor_pos; | |
1348 g_object_get(G_OBJECT(text_buffer_), "cursor-position", &cursor_pos, NULL); | |
1349 | |
1350 // We need to take the content direction into account when handling cursor | 1346 // We need to take the content direction into account when handling cursor |
1351 // movement, because the behavior of Left and Right key will be inverted if | 1347 // movement, because the behavior of Left and Right key will be inverted if |
1352 // the direction is RTL. Although we should check the direction around the | 1348 // the direction is RTL. Although we should check the direction around the |
1353 // input caret, it's much simpler and good enough to check whole content's | 1349 // input caret, it's much simpler and good enough to check whole content's |
1354 // direction. | 1350 // direction. |
1355 PangoDirection content_dir = GetContentDirection(); | 1351 PangoDirection content_dir = GetContentDirection(); |
1356 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1; | 1352 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1; |
1357 | 1353 |
1358 // We want the GtkEntry behavior when you move the cursor while you have a | 1354 // We want the GtkEntry behavior when you move the cursor while you have a |
1359 // selection. GtkTextView just drops the selection and moves the cursor, | 1355 // selection. GtkTextView just drops the selection and moves the cursor, |
1360 // but instead we want to move the cursor to the appropiate end of the | 1356 // but instead we want to move the cursor to the appropiate end of the |
1361 // selection. | 1357 // selection. |
1362 if (has_selection) { | 1358 if (has_selection) { |
1363 // We have a selection and start / end are in ascending order. | 1359 // We have a selection and start / end are in ascending order. |
1364 // Cursor placement will remove the selection, so we need inform | 1360 // Cursor placement will remove the selection, so we need inform |
1365 // |model_| about this change by | 1361 // |model_| about this change by |
1366 // calling On{Before|After}PossibleChange() methods. | 1362 // calling On{Before|After}PossibleChange() methods. |
1367 OnBeforePossibleChange(); | 1363 OnBeforePossibleChange(); |
1368 gtk_text_buffer_place_cursor( | 1364 gtk_text_buffer_place_cursor( |
1369 text_buffer_, count == count_towards_end ? &sel_end : &sel_start); | 1365 text_buffer_, count == count_towards_end ? &sel_end : &sel_start); |
1370 OnAfterPossibleChange(); | 1366 OnAfterPossibleChange(); |
1371 handled = true; | 1367 handled = true; |
1372 } else if (count == count_towards_end && cursor_pos == GetTextLength()) { | 1368 } else if (count == count_towards_end && |
1373 handled = controller_->OnCommitSuggestedText(GetText()); | 1369 GetCursorPosition() == GetTextLength()) { |
1370 handled = controller_->OnCommitSuggestedText(true); | |
1374 } | 1371 } |
1375 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down. | 1372 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down. |
1376 // Multiply by count for the direction (if we move too much that's ok). | 1373 // Multiply by count for the direction (if we move too much that's ok). |
1377 model_->OnUpOrDownKeyPressed(model_->result().size() * count); | 1374 model_->OnUpOrDownKeyPressed(model_->result().size() * count); |
1378 handled = true; | 1375 handled = true; |
1379 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down. | 1376 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down. |
1380 model_->OnUpOrDownKeyPressed(count); | 1377 model_->OnUpOrDownKeyPressed(count); |
1381 handled = true; | 1378 handled = true; |
1382 } | 1379 } |
1383 | 1380 |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1631 void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget, | 1628 void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget, |
1632 GtkDirectionType direction) { | 1629 GtkDirectionType direction) { |
1633 if (!tab_was_pressed_) | 1630 if (!tab_was_pressed_) |
1634 return; | 1631 return; |
1635 | 1632 |
1636 // If special behavior is triggered, then stop the signal emission to | 1633 // If special behavior is triggered, then stop the signal emission to |
1637 // prevent the focus from being moved. | 1634 // prevent the focus from being moved. |
1638 bool handled = false; | 1635 bool handled = false; |
1639 | 1636 |
1640 // Trigger Tab to search behavior only when Tab key is pressed. | 1637 // Trigger Tab to search behavior only when Tab key is pressed. |
1641 if (model_->is_keyword_hint()) { | 1638 if (model_->is_keyword_hint()) |
1642 handled = model_->AcceptKeyword(); | 1639 handled = model_->AcceptKeyword(); |
1643 } else if (GTK_WIDGET_VISIBLE(instant_view_)) { | 1640 |
1644 controller_->OnCommitSuggestedText(GetText()); | 1641 #if GTK_CHECK_VERSION(2, 20, 0) |
1642 if (!handled && !preedit_.empty()) | |
1645 handled = true; | 1643 handled = true; |
1646 } else { | 1644 #endif |
1645 | |
1646 if (!handled && GTK_WIDGET_VISIBLE(instant_view_)) | |
1647 handled = controller_->OnCommitSuggestedText(true); | |
1648 | |
1649 if (!handled) { | |
1650 CharRange selection = GetSelection(); | |
1651 int length = GetTextLength(); | |
1652 if (selection.cp_min != selection.cp_max || selection.cp_min < length) { | |
1653 OnBeforePossibleChange(); | |
sky
2011/01/27 19:55:31
Do we need the OnBefore/after here?
James Su
2011/01/27 20:07:16
Yes we need it to inform the model possible select
| |
1654 SetCursorPosition(length); | |
1655 OnAfterPossibleChange(); | |
1656 handled = true; | |
1657 } | |
1658 } | |
1659 | |
1660 if (!handled) | |
1647 handled = controller_->AcceptCurrentInstantPreview(); | 1661 handled = controller_->AcceptCurrentInstantPreview(); |
1648 } | |
1649 | 1662 |
1650 if (handled) { | 1663 if (handled) { |
1651 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); | 1664 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); |
1652 g_signal_stop_emission(widget, signal_id, 0); | 1665 g_signal_stop_emission(widget, signal_id, 0); |
1653 } | 1666 } |
1654 } | 1667 } |
1655 | 1668 |
1656 void AutocompleteEditViewGtk::HandleCopyClipboard(GtkWidget* sender) { | 1669 void AutocompleteEditViewGtk::HandleCopyClipboard(GtkWidget* sender) { |
1657 HandleCopyOrCutClipboard(true); | 1670 HandleCopyOrCutClipboard(true); |
1658 } | 1671 } |
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1864 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); | 1877 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); |
1865 #if GTK_CHECK_VERSION(2, 20, 0) | 1878 #if GTK_CHECK_VERSION(2, 20, 0) |
1866 // We need to count the length of the text being composed, because we treat | 1879 // We need to count the length of the text being composed, because we treat |
1867 // it as part of the content in GetText(). | 1880 // it as part of the content in GetText(). |
1868 return gtk_text_iter_get_offset(&end) + preedit_.size(); | 1881 return gtk_text_iter_get_offset(&end) + preedit_.size(); |
1869 #else | 1882 #else |
1870 return gtk_text_iter_get_offset(&end); | 1883 return gtk_text_iter_get_offset(&end); |
1871 #endif | 1884 #endif |
1872 } | 1885 } |
1873 | 1886 |
1887 int AutocompleteEditViewGtk::GetCursorPosition() const { | |
1888 gint cursor_pos; | |
sky
2011/01/27 19:55:31
Can this be implemented in terms of GetSelection?
James Su
2011/01/27 20:07:16
I'll recheck this part to see how we can do it bet
| |
1889 g_object_get(G_OBJECT(text_buffer_), "cursor-position", &cursor_pos, NULL); | |
1890 return cursor_pos; | |
1891 } | |
1892 | |
1893 void AutocompleteEditViewGtk::SetCursorPosition(int cursor_position) { | |
1894 GtkTextIter cursor; | |
1895 gtk_text_buffer_get_iter_at_offset(text_buffer_, &cursor, cursor_position); | |
1896 gtk_text_buffer_place_cursor(text_buffer_, &cursor); | |
1897 } | |
1898 | |
1874 void AutocompleteEditViewGtk::EmphasizeURLComponents() { | 1899 void AutocompleteEditViewGtk::EmphasizeURLComponents() { |
1875 #if GTK_CHECK_VERSION(2, 20, 0) | 1900 #if GTK_CHECK_VERSION(2, 20, 0) |
1876 // We can't change the text style easily, if the preedit string (the text | 1901 // We can't change the text style easily, if the preedit string (the text |
1877 // being composed by the input method) is not empty, which is not treated as | 1902 // being composed by the input method) is not empty, which is not treated as |
1878 // a part of the text content inside GtkTextView. And it's ok to simply return | 1903 // a part of the text content inside GtkTextView. And it's ok to simply return |
1879 // in this case, as this method will be called again when the preedit string | 1904 // in this case, as this method will be called again when the preedit string |
1880 // gets committed. | 1905 // gets committed. |
1881 if (preedit_.size()) { | 1906 if (preedit_.size()) { |
1882 strikethrough_ = CharRange(); | 1907 strikethrough_ = CharRange(); |
1883 return; | 1908 return; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1939 } | 1964 } |
1940 } | 1965 } |
1941 | 1966 |
1942 void AutocompleteEditViewGtk::StopAnimation() { | 1967 void AutocompleteEditViewGtk::StopAnimation() { |
1943 // Clear the animation delegate so we don't get an AnimationEnded() callback. | 1968 // Clear the animation delegate so we don't get an AnimationEnded() callback. |
1944 instant_animation_->set_delegate(NULL); | 1969 instant_animation_->set_delegate(NULL); |
1945 instant_animation_->Stop(); | 1970 instant_animation_->Stop(); |
1946 UpdateInstantViewColors(); | 1971 UpdateInstantViewColors(); |
1947 } | 1972 } |
1948 | 1973 |
1949 bool AutocompleteEditViewGtk::CommitInstantSuggestion() { | |
1950 const gchar* suggestion = gtk_label_get_text(GTK_LABEL(instant_view_)); | |
1951 if (!suggestion || !*suggestion) | |
1952 return false; | |
1953 | |
1954 model()->FinalizeInstantQuery(GetText(), | |
1955 UTF8ToUTF16(suggestion)); | |
1956 return true; | |
1957 } | |
1958 | |
1959 void AutocompleteEditViewGtk::TextChanged() { | 1974 void AutocompleteEditViewGtk::TextChanged() { |
1960 EmphasizeURLComponents(); | 1975 EmphasizeURLComponents(); |
1961 controller_->OnChanged(); | 1976 controller_->OnChanged(); |
1962 } | 1977 } |
1963 | 1978 |
1964 void AutocompleteEditViewGtk::SavePrimarySelection( | 1979 void AutocompleteEditViewGtk::SavePrimarySelection( |
1965 const std::string& selected_text) { | 1980 const std::string& selected_text) { |
1966 GtkClipboard* clipboard = | 1981 GtkClipboard* clipboard = |
1967 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); | 1982 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); |
1968 DCHECK(clipboard); | 1983 DCHECK(clipboard); |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2217 // baseline, so we need to move the |instant_view_| down to make sure it | 2232 // baseline, so we need to move the |instant_view_| down to make sure it |
2218 // has the same baseline as the |text_view_|. | 2233 // has the same baseline as the |text_view_|. |
2219 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); | 2234 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); |
2220 int height; | 2235 int height; |
2221 pango_layout_get_size(layout, NULL, &height); | 2236 pango_layout_get_size(layout, NULL, &height); |
2222 PangoLayoutIter* iter = pango_layout_get_iter(layout); | 2237 PangoLayoutIter* iter = pango_layout_get_iter(layout); |
2223 int baseline = pango_layout_iter_get_baseline(iter); | 2238 int baseline = pango_layout_iter_get_baseline(iter); |
2224 pango_layout_iter_free(iter); | 2239 pango_layout_iter_free(iter); |
2225 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); | 2240 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); |
2226 } | 2241 } |
OLD | NEW |