Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Unified Diff: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc

Issue 172041: Implements unimplemented methods of AutocompleteEditViewGtk.... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
===================================================================
--- chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc (revision 23948)
+++ chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc (working copy)
@@ -100,12 +100,11 @@
mark_set_handler_id_(0),
button_1_pressed_(false),
text_selected_during_click_(false),
- text_view_focused_before_button_press_(false)
+ text_view_focused_before_button_press_(false),
#if !defined(TOOLKIT_VIEWS)
- ,
- theme_provider_(GtkThemeProvider::GetFrom(profile))
+ theme_provider_(GtkThemeProvider::GetFrom(profile)),
#endif
- {
+ tab_was_pressed_(false) {
model_->set_popup_model(popup_view_->GetModel());
}
@@ -153,13 +152,11 @@
// The text view was floating. It will now be owned by the alignment.
gtk_container_add(GTK_CONTAINER(alignment_.get()), text_view_);
- // Allows inserting tab characters when pressing tab key, to prevent
- // |text_view_| from moving focus.
- // Tab characters will be filtered out by our "insert-text" signal handler
- // attached to |text_buffer_| object.
- // Tab key events will be handled by our "key-press-event" signal handler for
- // tab to search feature.
- gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), TRUE);
+ // Do not allow inserting tab characters when pressing Tab key, so that when
+ // Tab key is pressed, |text_view_| will emit "move-focus" signal, which will
+ // be intercepted by our own handler to trigger Tab to search feature when
+ // necessary.
+ gtk_text_view_set_accepts_tab(GTK_TEXT_VIEW(text_view_), FALSE);
faded_text_tag_ = gtk_text_buffer_create_tag(text_buffer_,
NULL, "foreground", kTextBaseColor, NULL);
@@ -197,6 +194,8 @@
// signal, but it is very convenient and clean for catching up/down.
g_signal_connect(text_view_, "move-cursor",
G_CALLBACK(&HandleViewMoveCursorThunk), this);
+ g_signal_connect(text_view_, "move-focus",
+ G_CALLBACK(&HandleViewMoveFocusThunk), this);
// Override the size request. We want to keep the original height request
// from the widget, since that's font dependent. We want to ignore the width
// so we don't force a minimum width based on the text length.
@@ -331,13 +330,18 @@
void AutocompleteEditViewGtk::SetWindowTextAndCaretPos(const std::wstring& text,
size_t caret_pos) {
+ CharRange range(static_cast<int>(caret_pos), static_cast<int>(caret_pos));
+ SetTextAndSelectedRange(text, range);
+}
+
+void AutocompleteEditViewGtk::SetTextAndSelectedRange(const std::wstring& text,
+ const CharRange& range) {
std::string utf8 = WideToUTF8(text);
gtk_text_buffer_set_text(text_buffer_, utf8.data(), utf8.length());
- EmphasizeURLComponents();
- GtkTextIter cur_pos;
- gtk_text_buffer_get_iter_at_offset(text_buffer_, &cur_pos, caret_pos);
- gtk_text_buffer_place_cursor(text_buffer_, &cur_pos);
+ GtkTextIter insert, bound;
+ ItersFromCharRange(range, &insert, &bound);
+ gtk_text_buffer_select_range(text_buffer_, &insert, &bound);
}
void AutocompleteEditViewGtk::SetForcedQuery() {
@@ -355,8 +359,15 @@
}
bool AutocompleteEditViewGtk::IsSelectAll() {
- NOTIMPLEMENTED();
- return false;
+ GtkTextIter sel_start, sel_end;
+ if (!gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end))
+ return false;
+
+ GtkTextIter start, end;
+ gtk_text_buffer_get_bounds(text_buffer_, &start, &end);
+
+ return gtk_text_iter_equal(&start, &sel_start) &&
+ gtk_text_iter_equal(&end, &sel_end);
}
void AutocompleteEditViewGtk::SelectAll(bool reversed) {
@@ -392,8 +403,14 @@
void AutocompleteEditViewGtk::OnTemporaryTextMaybeChanged(
const std::wstring& display_text,
bool save_original_selection) {
- // TODO(deanm): Ignoring save_original_selection here, etc.
+ if (save_original_selection) {
+ saved_temporary_selection_ = GetSelection();
+ saved_temporary_text_ = GetText();
+ }
+
+ StartUpdatingHighlightedText();
SetWindowTextAndCaretPos(display_text, display_text.length());
+ FinishUpdatingHighlightedText();
TextChanged();
}
@@ -418,7 +435,11 @@
}
void AutocompleteEditViewGtk::OnRevertTemporaryText() {
- NOTIMPLEMENTED();
+ StartUpdatingHighlightedText();
+ SetTextAndSelectedRange(saved_temporary_text_, saved_temporary_selection_);
+ FinishUpdatingHighlightedText();
+ saved_temporary_text_.clear();
+ TextChanged();
}
void AutocompleteEditViewGtk::OnBeforePossibleChange() {
@@ -520,7 +541,7 @@
gboolean AutocompleteEditViewGtk::HandleKeyPress(GtkWidget* widget,
GdkEventKey* event) {
// Background of this piece of complicated code:
- // The omnibox supports several special behavior which may be triggered by
+ // The omnibox supports several special behaviors which may be triggered by
// certain key events:
// Tab to search - triggered by Tab key
// Accept input - triggered by Enter key
@@ -532,114 +553,100 @@
// signal of |text_view_| object and call its default handler to handle the
// key event first.
//
- // Then if the key event is one of Tab, Enter and Escape, we need trigger
- // corresponding special behavior if IME did not handle it.
- // For Escape key if the default signal handler returns FALSE, then we know
+ // Then if the key event is one of Tab, Enter and Escape, we need to trigger
+ // the corresponding special behavior if IME did not handle it.
+ // For Escape key, if the default signal handler returns FALSE, then we know
// it's not handled by IME.
//
- // But for Tab and Enter key, the default signal handler always returns TRUE,
- // and following operation will be performed by GtkTextView if IME did not
- // handle it:
- // Tab key - delete current selection range and insert '\t'
- // Enter key - delete current selection range and insert '\n'
+ // For Tab key, as "accepts-tab" property of |text_view_| is set to FALSE,
+ // if IME did not handle it then "move-focus" signal will be emitted by the
+ // default signal handler of |text_view_|. So we can intercept "move-focus"
+ // signal of |text_view_| to know if a Tab key press event was handled by IME,
+ // and trigger Tab to search behavior when necessary in the signal handler.
//
- // We need dinstinguish if IME handled the key event or not, and avoid above
- // built-in operation if IME did not handle the key event. Because we don't
- // want the content of omnibox to be changed before triggering our special
- // behavior. Otherwise our special behavior would not be performed correctly.
+ // But for Enter key, if IME did not handle the key event, the default signal
+ // handler will delete current selection range and insert '\n' and always
+ // return TRUE. We need to prevent |text_view_| from performing this default
+ // action if IME did not handle the key event, because we don't want the
+ // content of omnibox to be changed before triggering our special behavior.
+ // Otherwise our special behavior would not be performed correctly.
//
// But there is no way for us to prevent GtkTextView from handling the key
- // event and performing above built-in operation. So in order to achieve our
- // goal, "insert-text" signal of |text_buffer_| object is intercepted, and
+ // event and performing built-in operation. So in order to achieve our goal,
+ // "insert-text" signal of |text_buffer_| object is intercepted, and
// following actions are done in the signal handler:
// - If there is only one character in inserted text, save it in
// char_inserted_.
// - Filter out all new line and tab characters.
//
- // So if char_inserted_ equals to '\t' after calling |text_view_|'s
- // default signal handler against a Tab key press event, then we can sure this
- // Tab key press event is handled by GtkTextView instead of IME. Then we can
- // perform the special behavior of Tab key safely.
+ // So if |char_inserted_| equals '\n' after calling |text_view_|'s
+ // default signal handler against an Enter key press event, then we know that
+ // the Enter key press event was handled by GtkTextView rather than IME, and
+ // can perform the special behavior for Enter key safely.
//
- // Enter key press event can be treated in the same way.
- //
// Now the last thing is to prevent the content of omnibox from being changed
// by GtkTextView when Tab or Enter key is pressed. Because we can't prevent
- // it, we use backup and restore trick: If Tab or Enter is pressed, backup the
- // content of omnibox before sending the key event to |text_view_|, and then
- // restore it afterwards if IME did not handle the event.
+ // it, we use a backup and restore trick: If Enter is pressed, backup the
+ // content of omnibox before sending the key event to |text_view_|, and
+ // then restore it afterwards if IME did not handle the event.
GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(widget);
- bool tab_pressed = ((event->keyval == GDK_Tab ||
- event->keyval == GDK_ISO_Left_Tab ||
- event->keyval == GDK_KP_Tab) &&
- !(event->state & GDK_CONTROL_MASK));
bool enter_pressed = (event->keyval == GDK_Return ||
event->keyval == GDK_ISO_Enter ||
event->keyval == GDK_KP_Enter);
- gchar* original_text = NULL;
+ std::wstring original_text;
- // Tab and Enter key will have special behavior if it's not handled by IME.
+ // Enter key will have special behavior if it's not handled by IME.
// We need save the original content of |text_buffer_| and restore it when
// necessary, because GtkTextView might alter the content.
- if (tab_pressed || enter_pressed) {
- GtkTextIter start, end;
- gtk_text_buffer_get_bounds(text_buffer_, &start, &end);
- original_text = gtk_text_buffer_get_text(text_buffer_, &start, &end, FALSE);
-
- // Reset these variable, which may be set in "insert-text" signal handler.
- // So that we can know if Tab or Enter key event is handled by IME or not.
+ if (enter_pressed) {
+ original_text = GetText();
+ // Reset |char_inserted_|, which may be set in the "insert-text" signal
+ // handler, so that we'll know if an Enter key event was handled by IME.
char_inserted_ = 0;
}
+ // Set |tab_was_pressed_| to true if it's a Tab key press event, so that our
+ // handler of "move-focus" signal can trigger Tab to search behavior when
+ // necessary.
+ tab_was_pressed_ = ((event->keyval == GDK_Tab ||
+ event->keyval == GDK_ISO_Left_Tab ||
+ event->keyval == GDK_KP_Tab) &&
+ !(event->state & GDK_CONTROL_MASK));
+
// Call the default handler, so that IME can work as normal.
- // New line and tab characters will be filtered out by our "insert-text"
+ // New line characters will be filtered out by our "insert-text"
// signal handler attached to |text_buffer_| object.
gboolean result = klass->key_press_event(widget, event);
- bool tab_inserted = (char_inserted_ == '\t');
- bool new_line_inserted = (char_inserted_ == '\n' || char_inserted_ == '\r');
- if ((tab_pressed && tab_inserted) || (enter_pressed && new_line_inserted)) {
- // Tab or Enter key is handled by GtkTextView, so we are sure that it is not
- // handled by IME.
- // Revert the original content in case it has been altered.
- // Call gtk_text_buffer_{begin|end}_user_action() to make sure |model_| will
- // be updated correctly.
- gtk_text_buffer_begin_user_action(text_buffer_);
- gtk_text_buffer_set_text(text_buffer_, original_text, -1);
- gtk_text_buffer_end_user_action(text_buffer_);
- }
+ // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can
+ // only be triggered by pressing Tab key.
+ tab_was_pressed_ = false;
- if (original_text)
- g_free(original_text);
-
- if (tab_pressed && tab_inserted) {
- if (model_->is_keyword_hint() && !model_->keyword().empty()) {
- model_->AcceptKeyword();
- } else {
- // Handle move focus by ourselves.
- static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
- g_signal_emit(widget, signal_id, 0, (event->state & GDK_SHIFT_MASK) ?
- GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
- }
- result = TRUE;
- } else if (enter_pressed && new_line_inserted) {
+ if (enter_pressed && (char_inserted_ == '\n' || char_inserted_ == '\r')) {
bool alt_held = (event->state & GDK_MOD1_MASK);
+ // Revert the original text in case the text has been changed.
+ SetUserText(original_text);
model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
result = TRUE;
} else if (!result && event->keyval == GDK_Escape &&
(event->state & gtk_accelerator_get_default_mod_mask()) == 0) {
- // We can handle Escape key if |text_view_| did not handle it.
- // If it's not handled by us, then we need propagate it upto parent
+ // We can handle the Escape key if |text_view_| did not handle it.
+ // If it's not handled by us, then we need to propagate it up to the parent
// widgets, so that Escape accelerator can still work.
result = model_->OnEscapeKeyPressed();
+ } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) {
+ // Omnibox2 can switch its contents while pressing a control key. To switch
+ // the contents of omnibox2, we notify the AutocompleteEditModel class when
+ // the control-key state is changed.
+ model_->OnControlKeyChanged(true);
}
- // If the key event is not handled by |text_view_| and us, then we need
+ // If the key event is not handled by |text_view_| or us, then we need to
// propagate the key event up to parent widgets by returning FALSE.
- // In this case we need stop the signal emission explicitly to prevent the
+ // In this case we need to stop the signal emission explicitly to prevent the
// default "key-press-event" handler of |text_view_| from being called again.
if (!result) {
static guint signal_id =
@@ -652,6 +659,13 @@
gboolean AutocompleteEditViewGtk::HandleKeyRelease(GtkWidget* widget,
GdkEventKey* event) {
+ if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) {
+ // Omnibox2 can switch its contents while pressing a control key. To switch
+ // the contents of omnibox2, we notify the AutocompleteEditModel class when
+ // the control-key state is changed.
+ model_->OnControlKeyChanged(false);
Dean McNamee 2009/08/21 18:21:35 I am still not happy with this code, but I will le
+ }
+
// Even though we handled the press ourselves, let GtkTextView handle the
// release. It shouldn't do anything particularly interesting, but it will
// handle the IME work for us.
@@ -872,8 +886,8 @@
//
// If there was only a single character, then it might be generated by a key
// event. In this case, we save the single character to help our
- // "key-press-event" signal handler distinguish if a Tab or Enter key event
- // is handled by IME or not.
+ // "key-press-event" signal handler distinguish if an Enter key event is
+ // handled by IME or not.
if (len == 1)
char_inserted_ = text[0];
@@ -923,6 +937,21 @@
g_signal_stop_emission(text_view_, signal_id, 0);
}
+void AutocompleteEditViewGtk::HandleViewMoveFocus(GtkWidget* widget) {
+ // Trigger Tab to search behavior only when Tab key is pressed.
+ if (tab_was_pressed_ && model_->is_keyword_hint() &&
+ !model_->keyword().empty()) {
+ model_->AcceptKeyword();
+
+ // If Tab to search behavior is triggered, then stop the signal emission to
+ // prevent the focus from being moved.
+ static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET);
+ g_signal_stop_emission(widget, signal_id, 0);
+ }
+
+ // Propagate the signal so that focus can be moved as normal.
+}
+
void AutocompleteEditViewGtk::HandleCopyClipboard() {
// On copy, we manually update the PRIMARY selection to contain the
// highlighted text. This matches Firefox -- we highlight the URL but don't
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698