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

Unified Diff: ui/views/controls/textfield/textfield.cc

Issue 211593006: Make Views Textfield key handling execute commands. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Convert remaining key handling to commands, fix enabled checks. Created 6 years, 9 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 | « ui/base/strings/ui_strings.grd ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/views/controls/textfield/textfield.cc
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc
index f3f58593762e27544c5edf5a8c10c871a0fb5ae6..d1a357da60e063d85a22e9dde6548db3ab12d447 100644
--- a/ui/views/controls/textfield/textfield.cc
+++ b/ui/views/controls/textfield/textfield.cc
@@ -424,124 +424,115 @@ bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
if (handled)
return true;
- // TODO(oshima): Refactor and consolidate with ExecuteCommand.
if (event.type() == ui::ET_KEY_PRESSED) {
ui::KeyboardCode key_code = event.key_code();
if (key_code == ui::VKEY_TAB || event.IsUnicodeKeyCode())
return false;
- gfx::RenderText* render_text = GetRenderText();
- const bool editable = !read_only();
- const bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
const bool shift = event.IsShiftDown();
const bool control = event.IsControlDown();
const bool alt = event.IsAltDown() || event.IsAltGrDown();
- bool text_changed = false;
- bool cursor_changed = false;
+ // TODO(msw): Make a helper CommandForKeyEvent or similar.
OnBeforeUserAction();
switch (key_code) {
case ui::VKEY_Z:
- if (control && !shift && !alt && editable)
- cursor_changed = text_changed = model_->Undo();
- else if (control && shift && !alt && editable)
- cursor_changed = text_changed = model_->Redo();
+ if (control && !shift && !alt)
+ ExecuteCommand(IDS_APP_UNDO);
+ else if (control && shift && !alt)
+ ExecuteCommand(IDS_APP_REDO);
break;
case ui::VKEY_Y:
- if (control && !alt && editable)
- cursor_changed = text_changed = model_->Redo();
+ if (control && !alt)
+ ExecuteCommand(IDS_APP_REDO);
break;
case ui::VKEY_A:
- if (control && !alt) {
- model_->SelectAll(false);
- UpdateSelectionClipboard();
- cursor_changed = true;
- }
+ if (control && !alt)
+ ExecuteCommand(IDS_APP_SELECT_ALL);
break;
case ui::VKEY_X:
- if (control && !alt && editable && readable)
- cursor_changed = text_changed = Cut();
+ if (control && !alt)
+ ExecuteCommand(IDS_APP_CUT);
break;
case ui::VKEY_C:
- if (control && !alt && readable)
- Copy();
+ if (control && !alt)
+ ExecuteCommand(IDS_APP_COPY);
break;
case ui::VKEY_V:
- if (control && !alt && editable)
- cursor_changed = text_changed = Paste();
+ if (control && !alt)
+ ExecuteCommand(IDS_APP_PASTE);
break;
case ui::VKEY_RIGHT:
- case ui::VKEY_LEFT: {
- // We should ignore the alt-left/right keys because alt key doesn't make
- // any special effects for them and they can be shortcut keys such like
- // forward/back of the browser history.
+ // Ignore alt+right, which may be a browser navigation shortcut.
if (alt)
break;
- const gfx::Range selection_range = render_text->selection();
- model_->MoveCursor(
- control ? gfx::WORD_BREAK : gfx::CHARACTER_BREAK,
- (key_code == ui::VKEY_RIGHT) ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT,
- shift);
- UpdateSelectionClipboard();
- cursor_changed = render_text->selection() != selection_range;
+ if (shift) {
+ ExecuteCommand(control ? IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION :
+ IDS_MOVE_RIGHT_AND_MODIFY_SELECTION);
+ } else {
+ ExecuteCommand(control ? IDS_MOVE_WORD_RIGHT : IDS_MOVE_RIGHT);
+ }
+ break;
+ case ui::VKEY_LEFT:
+ // Ignore alt+left, which may be a browser navigation shortcut.
+ if (alt)
+ break;
+ if (shift) {
+ ExecuteCommand(control ? IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION :
+ IDS_MOVE_LEFT_AND_MODIFY_SELECTION);
+ } else {
+ ExecuteCommand(control ? IDS_MOVE_WORD_LEFT : IDS_MOVE_LEFT);
+ }
break;
- }
- case ui::VKEY_END:
case ui::VKEY_HOME:
- if ((key_code == ui::VKEY_HOME) ==
- (render_text->GetTextDirection() == base::i18n::RIGHT_TO_LEFT))
- model_->MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_RIGHT, shift);
- else
- model_->MoveCursor(gfx::LINE_BREAK, gfx::CURSOR_LEFT, shift);
- UpdateSelectionClipboard();
- cursor_changed = true;
+ ExecuteCommand(shift ? IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION :
+ IDS_MOVE_TO_BEGINNING_OF_LINE);
+ break;
+ case ui::VKEY_END:
+ ExecuteCommand(shift? IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION :
+ IDS_MOVE_TO_END_OF_LINE);
break;
case ui::VKEY_BACK:
+ if (control && !model_->HasSelection()) {
+ if (shift) {
+#if defined(OS_LINUX)
+ // Only erase by line break on Linux and ChromeOS.
+ ExecuteCommand(IDS_DELETE_TO_BEGINNING_OF_LINE);
+#endif
+ } else {
+ ExecuteCommand(IDS_DELETE_WORD_BACKWARD);
+ }
+ } else {
+ ExecuteCommand(IDS_DELETE_BACKWARD);
+ }
+ break;
case ui::VKEY_DELETE:
- if (!editable)
- break;
- if (!model_->HasSelection()) {
- gfx::VisualCursorDirection direction = (key_code == ui::VKEY_DELETE) ?
- gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT;
- if (shift && control) {
- // If shift and control are pressed, erase up to the next line break
- // on Linux and ChromeOS. Otherwise, do nothing.
+ if (control && !model_->HasSelection()) {
+ if (shift) {
#if defined(OS_LINUX)
- model_->MoveCursor(gfx::LINE_BREAK, direction, true);
-#else
- break;
+ // Only erase by line break on Linux and ChromeOS.
+ ExecuteCommand(IDS_DELETE_TO_END_OF_LINE);
#endif
- } else if (control) {
- // If only control is pressed, then erase the previous/next word.
- model_->MoveCursor(gfx::WORD_BREAK, direction, true);
+ } else {
+ ExecuteCommand(IDS_DELETE_WORD_FORWARD);
}
+ } else if (shift && model_->HasSelection()) {
+ ExecuteCommand(IDS_APP_CUT);
+ } else {
+ ExecuteCommand(IDS_DELETE_FORWARD);
}
- if (key_code == ui::VKEY_BACK)
- model_->Backspace();
- else if (shift && model_->HasSelection() && readable)
- Cut();
- else
- model_->Delete();
-
- // Consume backspace and delete keys even if the edit did nothing. This
- // prevents potential unintended side-effects of further event handling.
- text_changed = true;
break;
case ui::VKEY_INSERT:
- if (control && !shift && readable)
- Copy();
- else if (shift && !control && editable)
- cursor_changed = text_changed = Paste();
+ if (control && !shift)
+ ExecuteCommand(IDS_APP_COPY);
+ else if (shift && !control)
+ ExecuteCommand(IDS_APP_PASTE);
break;
default:
- break;
+ return false;
}
- // We must have input method in order to support text input.
- DCHECK(GetInputMethod());
- UpdateAfterChange(text_changed, cursor_changed);
- OnAfterUserAction();
- return (text_changed || cursor_changed);
+ return true;
}
return false;
}
@@ -960,6 +951,8 @@ bool Textfield::IsCommandIdEnabled(int command_id) const {
switch (command_id) {
case IDS_APP_UNDO:
return editable && model_->CanUndo();
+ case IDS_APP_REDO:
+ return editable && model_->CanRedo();
case IDS_APP_CUT:
return editable && readable && model_->HasSelection();
case IDS_APP_COPY:
@@ -972,6 +965,26 @@ bool Textfield::IsCommandIdEnabled(int command_id) const {
return editable && model_->HasSelection();
case IDS_APP_SELECT_ALL:
return !text().empty();
+ case IDS_DELETE_FORWARD:
+ case IDS_DELETE_BACKWARD:
+ case IDS_DELETE_TO_BEGINNING_OF_LINE:
+ case IDS_DELETE_TO_END_OF_LINE:
+ case IDS_DELETE_WORD_BACKWARD:
+ case IDS_DELETE_WORD_FORWARD:
+ return editable;
+ case IDS_MOVE_LEFT:
+ case IDS_MOVE_LEFT_AND_MODIFY_SELECTION:
Elliot Glaysher 2014/03/28 22:47:49 So, if we're going to have versions for the events
msw 2014/03/28 22:55:29 The separate _AND_MODIFY_SELECTION commands come f
+ case IDS_MOVE_RIGHT:
+ case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION:
+ case IDS_MOVE_WORD_LEFT:
+ case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
+ case IDS_MOVE_WORD_RIGHT:
+ case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
+ case IDS_MOVE_TO_BEGINNING_OF_LINE:
+ case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
+ case IDS_MOVE_TO_END_OF_LINE:
+ case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
+ return true;
default:
return false;
}
@@ -988,31 +1001,102 @@ void Textfield::ExecuteCommand(int command_id, int event_flags) {
return;
bool text_changed = false;
+ bool cursor_changed = false;
+ bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
+ gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT;
+ gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT;
+ gfx::Range selection_range = GetSelectedRange();
+
OnBeforeUserAction();
switch (command_id) {
case IDS_APP_UNDO:
- text_changed = model_->Undo();
+ text_changed = cursor_changed = model_->Undo();
+ break;
+ case IDS_APP_REDO:
+ text_changed = cursor_changed = model_->Redo();
break;
case IDS_APP_CUT:
- text_changed = Cut();
+ text_changed = cursor_changed = Cut();
break;
case IDS_APP_COPY:
Copy();
break;
case IDS_APP_PASTE:
- text_changed = Paste();
+ text_changed = cursor_changed = Paste();
break;
case IDS_APP_DELETE:
- text_changed = model_->Delete();
+ text_changed = cursor_changed = model_->Delete();
break;
case IDS_APP_SELECT_ALL:
SelectAll(false);
break;
+ case IDS_DELETE_BACKWARD:
+ text_changed = cursor_changed = model_->Backspace();
+ break;
+ case IDS_DELETE_FORWARD:
+ text_changed = cursor_changed = model_->Delete();
+ break;
+ case IDS_DELETE_TO_END_OF_LINE:
+ model_->MoveCursor(gfx::LINE_BREAK, end, true);
+ text_changed = cursor_changed = model_->Delete();
+ break;
+ case IDS_DELETE_TO_BEGINNING_OF_LINE:
+ model_->MoveCursor(gfx::LINE_BREAK, begin, true);
+ text_changed = cursor_changed = model_->Backspace();
+ break;
+ case IDS_DELETE_WORD_BACKWARD:
+ model_->MoveCursor(gfx::WORD_BREAK, begin, true);
+ text_changed = cursor_changed = model_->Backspace();
+ break;
+ case IDS_DELETE_WORD_FORWARD:
+ model_->MoveCursor(gfx::WORD_BREAK, end, true);
+ text_changed = cursor_changed = model_->Delete();
+ break;
+ case IDS_MOVE_LEFT:
+ model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
+ break;
+ case IDS_MOVE_LEFT_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
+ break;
+ case IDS_MOVE_RIGHT:
+ model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
+ break;
+ case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
+ break;
+ case IDS_MOVE_WORD_LEFT:
+ model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false);
+ break;
+ case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
+ break;
+ case IDS_MOVE_WORD_RIGHT:
+ model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
+ break;
+ case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
+ break;
+ case IDS_MOVE_TO_BEGINNING_OF_LINE:
+ model_->MoveCursor(gfx::LINE_BREAK, begin, false);
+ break;
+ case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::LINE_BREAK, begin, true);
+ break;
+ case IDS_MOVE_TO_END_OF_LINE:
+ model_->MoveCursor(gfx::LINE_BREAK, end, false);
+ break;
+ case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
+ model_->MoveCursor(gfx::LINE_BREAK, end, true);
+ break;
default:
NOTREACHED();
break;
}
- UpdateAfterChange(text_changed, text_changed);
+
+ cursor_changed |= GetSelectedRange() != selection_range;
+ if (cursor_changed)
+ UpdateSelectionClipboard();
+ UpdateAfterChange(text_changed, cursor_changed);
OnAfterUserAction();
}
« no previous file with comments | « ui/base/strings/ui_strings.grd ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698