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

Side by Side Diff: ui/views/controls/textfield/textfield.cc

Issue 2029733003: Views: Replace resource ids with ui::TextEditCommand enum for text editing commands in Textfield. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: === Created 4 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/views/controls/textfield/textfield.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/trace_event/trace_event.h" 10 #include "base/trace_event/trace_event.h"
11 #include "build/build_config.h" 11 #include "build/build_config.h"
12 #include "ui/accessibility/ax_view_state.h" 12 #include "ui/accessibility/ax_view_state.h"
13 #include "ui/base/clipboard/scoped_clipboard_writer.h" 13 #include "ui/base/clipboard/scoped_clipboard_writer.h"
14 #include "ui/base/cursor/cursor.h" 14 #include "ui/base/cursor/cursor.h"
15 #include "ui/base/default_style.h" 15 #include "ui/base/default_style.h"
16 #include "ui/base/dragdrop/drag_drop_types.h" 16 #include "ui/base/dragdrop/drag_drop_types.h"
17 #include "ui/base/dragdrop/drag_utils.h" 17 #include "ui/base/dragdrop/drag_utils.h"
18 #include "ui/base/ime/input_method.h" 18 #include "ui/base/ime/input_method.h"
19 #include "ui/base/ime/text_edit_commands.h"
19 #include "ui/base/resource/resource_bundle.h" 20 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/base/ui_base_switches_util.h" 21 #include "ui/base/ui_base_switches_util.h"
21 #include "ui/compositor/canvas_painter.h" 22 #include "ui/compositor/canvas_painter.h"
22 #include "ui/compositor/scoped_animation_duration_scale_mode.h" 23 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
23 #include "ui/display/display.h" 24 #include "ui/display/display.h"
24 #include "ui/display/screen.h" 25 #include "ui/display/screen.h"
25 #include "ui/events/base_event_utils.h" 26 #include "ui/events/base_event_utils.h"
26 #include "ui/events/event.h" 27 #include "ui/events/event.h"
27 #include "ui/events/keycodes/keyboard_codes.h" 28 #include "ui/events/keycodes/keyboard_codes.h"
28 #include "ui/gfx/canvas.h" 29 #include "ui/gfx/canvas.h"
(...skipping 15 matching lines...) Expand all
44 #include "ui/views/views_delegate.h" 45 #include "ui/views/views_delegate.h"
45 #include "ui/views/widget/widget.h" 46 #include "ui/views/widget/widget.h"
46 47
47 #if defined(OS_WIN) 48 #if defined(OS_WIN)
48 #include "base/win/win_util.h" 49 #include "base/win/win_util.h"
49 #include "ui/base/win/osk_display_manager.h" 50 #include "ui/base/win/osk_display_manager.h"
50 #endif 51 #endif
51 52
52 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 53 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
53 #include "base/strings/utf_string_conversions.h" 54 #include "base/strings/utf_string_conversions.h"
54 #include "ui/events/linux/text_edit_command_auralinux.h" 55 #include "ui/base/ime/linux/text_edit_command_auralinux.h"
55 #include "ui/events/linux/text_edit_key_bindings_delegate_auralinux.h" 56 #include "ui/base/ime/linux/text_edit_key_bindings_delegate_auralinux.h"
56 #endif 57 #endif
57 58
58 namespace views { 59 namespace views {
59 60
60 namespace { 61 namespace {
61 62
62 // Default placeholder text color. 63 // Default placeholder text color.
63 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY; 64 const SkColor kDefaultPlaceholderTextColor = SK_ColorLTGRAY;
64 65
65 const int kNoCommand = 0;
66
67 void ConvertRectToScreen(const View* src, gfx::Rect* r) { 66 void ConvertRectToScreen(const View* src, gfx::Rect* r) {
68 DCHECK(src); 67 DCHECK(src);
69 68
70 gfx::Point new_origin = r->origin(); 69 gfx::Point new_origin = r->origin();
71 View::ConvertPointToScreen(src, &new_origin); 70 View::ConvertPointToScreen(src, &new_origin);
72 r->set_origin(new_origin); 71 r->set_origin(new_origin);
73 } 72 }
74 73
75 // Get the drag selection timer delay, respecting animation scaling for testing. 74 // Get the drag selection timer delay, respecting animation scaling for testing.
76 int GetDragSelectionDelay() { 75 int GetDragSelectionDelay() {
77 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) { 76 switch (ui::ScopedAnimationDurationScaleMode::duration_scale_mode()) {
78 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION: return 100; 77 case ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION: return 100;
79 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION: return 25; 78 case ui::ScopedAnimationDurationScaleMode::FAST_DURATION: return 25;
80 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION: return 400; 79 case ui::ScopedAnimationDurationScaleMode::SLOW_DURATION: return 400;
81 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION: return 1; 80 case ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION: return 1;
82 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION: return 0; 81 case ui::ScopedAnimationDurationScaleMode::ZERO_DURATION: return 0;
83 } 82 }
84 return 100; 83 return 100;
85 } 84 }
86 85
87 // Get the default command for a given key |event|. 86 // Get the default command for a given key |event|.
88 int GetCommandForKeyEvent(const ui::KeyEvent& event) { 87 ui::TextEditCommand GetCommandForKeyEvent(const ui::KeyEvent& event) {
89 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode()) 88 if (event.type() != ui::ET_KEY_PRESSED || event.IsUnicodeKeyCode())
90 return kNoCommand; 89 return ui::TextEditCommand::INVALID_COMMAND;
91 90
92 const bool shift = event.IsShiftDown(); 91 const bool shift = event.IsShiftDown();
93 const bool control = event.IsControlDown(); 92 const bool control = event.IsControlDown();
94 const bool alt = event.IsAltDown() || event.IsAltGrDown(); 93 const bool alt = event.IsAltDown() || event.IsAltGrDown();
95 switch (event.key_code()) { 94 switch (event.key_code()) {
96 case ui::VKEY_Z: 95 case ui::VKEY_Z:
97 if (control && !shift && !alt) 96 if (control && !shift && !alt)
98 return IDS_APP_UNDO; 97 return ui::TextEditCommand::UNDO;
99 return (control && shift && !alt) ? IDS_APP_REDO : kNoCommand; 98 return (control && shift && !alt) ? ui::TextEditCommand::REDO
99 : ui::TextEditCommand::INVALID_COMMAND;
100 case ui::VKEY_Y: 100 case ui::VKEY_Y:
101 return (control && !alt) ? IDS_APP_REDO : kNoCommand; 101 return (control && !alt) ? ui::TextEditCommand::REDO
102 : ui::TextEditCommand::INVALID_COMMAND;
102 case ui::VKEY_A: 103 case ui::VKEY_A:
103 return (control && !alt) ? IDS_APP_SELECT_ALL : kNoCommand; 104 return (control && !alt) ? ui::TextEditCommand::SELECT_ALL
105 : ui::TextEditCommand::INVALID_COMMAND;
104 case ui::VKEY_X: 106 case ui::VKEY_X:
105 return (control && !alt) ? IDS_APP_CUT : kNoCommand; 107 return (control && !alt) ? ui::TextEditCommand::CUT
108 : ui::TextEditCommand::INVALID_COMMAND;
106 case ui::VKEY_C: 109 case ui::VKEY_C:
107 return (control && !alt) ? IDS_APP_COPY : kNoCommand; 110 return (control && !alt) ? ui::TextEditCommand::COPY
111 : ui::TextEditCommand::INVALID_COMMAND;
108 case ui::VKEY_V: 112 case ui::VKEY_V:
109 return (control && !alt) ? IDS_APP_PASTE : kNoCommand; 113 return (control && !alt) ? ui::TextEditCommand::PASTE
114 : ui::TextEditCommand::INVALID_COMMAND;
110 case ui::VKEY_RIGHT: 115 case ui::VKEY_RIGHT:
111 // Ignore alt+right, which may be a browser navigation shortcut. 116 // Ignore alt+right, which may be a browser navigation shortcut.
112 if (alt) 117 if (alt)
113 return kNoCommand; 118 return ui::TextEditCommand::INVALID_COMMAND;
114 if (!shift) 119 if (!shift) {
115 return control ? IDS_MOVE_WORD_RIGHT : IDS_MOVE_RIGHT; 120 return control ? ui::TextEditCommand::MOVE_WORD_RIGHT
116 return control ? IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION : 121 : ui::TextEditCommand::MOVE_RIGHT;
117 IDS_MOVE_RIGHT_AND_MODIFY_SELECTION; 122 }
123 return control ? ui::TextEditCommand::MOVE_WORD_RIGHT_AND_MODIFY_SELECTION
124 : ui::TextEditCommand::MOVE_RIGHT_AND_MODIFY_SELECTION;
118 case ui::VKEY_LEFT: 125 case ui::VKEY_LEFT:
119 // Ignore alt+left, which may be a browser navigation shortcut. 126 // Ignore alt+left, which may be a browser navigation shortcut.
120 if (alt) 127 if (alt)
121 return kNoCommand; 128 return ui::TextEditCommand::INVALID_COMMAND;
122 if (!shift) 129 if (!shift) {
123 return control ? IDS_MOVE_WORD_LEFT : IDS_MOVE_LEFT; 130 return control ? ui::TextEditCommand::MOVE_WORD_LEFT
124 return control ? IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION : 131 : ui::TextEditCommand::MOVE_LEFT;
125 IDS_MOVE_LEFT_AND_MODIFY_SELECTION; 132 }
133 return control ? ui::TextEditCommand::MOVE_WORD_LEFT_AND_MODIFY_SELECTION
134 : ui::TextEditCommand::MOVE_LEFT_AND_MODIFY_SELECTION;
126 case ui::VKEY_HOME: 135 case ui::VKEY_HOME:
127 return shift ? IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION : 136 return shift ? ui::TextEditCommand::
128 IDS_MOVE_TO_BEGINNING_OF_LINE; 137 MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION
138 : ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE;
129 case ui::VKEY_END: 139 case ui::VKEY_END:
130 return shift ? IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION : 140 return shift
131 IDS_MOVE_TO_END_OF_LINE; 141 ? ui::TextEditCommand::MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION
142 : ui::TextEditCommand::MOVE_TO_END_OF_LINE;
132 case ui::VKEY_BACK: 143 case ui::VKEY_BACK:
133 if (!control) 144 if (!control)
134 return IDS_DELETE_BACKWARD; 145 return ui::TextEditCommand::DELETE_BACKWARD;
135 #if defined(OS_LINUX) 146 #if defined(OS_LINUX)
136 // Only erase by line break on Linux and ChromeOS. 147 // Only erase by line break on Linux and ChromeOS.
137 if (shift) 148 if (shift)
138 return IDS_DELETE_TO_BEGINNING_OF_LINE; 149 return ui::TextEditCommand::DELETE_TO_BEGINNING_OF_LINE;
139 #endif 150 #endif
140 return IDS_DELETE_WORD_BACKWARD; 151 return ui::TextEditCommand::DELETE_WORD_BACKWARD;
141 case ui::VKEY_DELETE: 152 case ui::VKEY_DELETE:
142 #if defined(OS_LINUX) 153 #if defined(OS_LINUX)
143 // Only erase by line break on Linux and ChromeOS. 154 // Only erase by line break on Linux and ChromeOS.
144 if (shift && control) 155 if (shift && control)
145 return IDS_DELETE_TO_END_OF_LINE; 156 return ui::TextEditCommand::DELETE_TO_END_OF_LINE;
146 #endif 157 #endif
147 if (control) 158 if (control)
148 return IDS_DELETE_WORD_FORWARD; 159 return ui::TextEditCommand::DELETE_WORD_FORWARD;
149 return shift ? IDS_APP_CUT : IDS_DELETE_FORWARD; 160 return shift ? ui::TextEditCommand::CUT
161 : ui::TextEditCommand::DELETE_FORWARD;
150 case ui::VKEY_INSERT: 162 case ui::VKEY_INSERT:
151 if (control && !shift) 163 if (control && !shift)
152 return IDS_APP_COPY; 164 return ui::TextEditCommand::COPY;
153 return (shift && !control) ? IDS_APP_PASTE : kNoCommand; 165 return (shift && !control) ? ui::TextEditCommand::PASTE
166 : ui::TextEditCommand::INVALID_COMMAND;
154 default: 167 default:
155 return kNoCommand; 168 return ui::TextEditCommand::INVALID_COMMAND;
156 } 169 }
157 } 170 }
158 171
159 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
160 // Convert a custom text edit |command| to the equivalent views command ID.
161 int GetViewsCommand(const ui::TextEditCommandAuraLinux& command, bool rtl) {
162 const bool select = command.extend_selection();
163 switch (command.command_id()) {
164 case ui::TextEditCommandAuraLinux::COPY:
165 return IDS_APP_COPY;
166 case ui::TextEditCommandAuraLinux::CUT:
167 return IDS_APP_CUT;
168 case ui::TextEditCommandAuraLinux::DELETE_BACKWARD:
169 return IDS_DELETE_BACKWARD;
170 case ui::TextEditCommandAuraLinux::DELETE_FORWARD:
171 return IDS_DELETE_FORWARD;
172 case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_LINE:
173 case ui::TextEditCommandAuraLinux::DELETE_TO_BEGINING_OF_PARAGRAPH:
174 return IDS_DELETE_TO_BEGINNING_OF_LINE;
175 case ui::TextEditCommandAuraLinux::DELETE_TO_END_OF_LINE:
176 case ui::TextEditCommandAuraLinux::DELETE_TO_END_OF_PARAGRAPH:
177 return IDS_DELETE_TO_END_OF_LINE;
178 case ui::TextEditCommandAuraLinux::DELETE_WORD_BACKWARD:
179 return IDS_DELETE_WORD_BACKWARD;
180 case ui::TextEditCommandAuraLinux::DELETE_WORD_FORWARD:
181 return IDS_DELETE_WORD_FORWARD;
182 case ui::TextEditCommandAuraLinux::INSERT_TEXT:
183 return kNoCommand;
184 case ui::TextEditCommandAuraLinux::MOVE_BACKWARD:
185 if (rtl)
186 return select ? IDS_MOVE_RIGHT_AND_MODIFY_SELECTION : IDS_MOVE_RIGHT;
187 return select ? IDS_MOVE_LEFT_AND_MODIFY_SELECTION : IDS_MOVE_LEFT;
188 case ui::TextEditCommandAuraLinux::MOVE_DOWN:
189 return IDS_MOVE_DOWN;
190 case ui::TextEditCommandAuraLinux::MOVE_FORWARD:
191 if (rtl)
192 return select ? IDS_MOVE_LEFT_AND_MODIFY_SELECTION : IDS_MOVE_LEFT;
193 return select ? IDS_MOVE_RIGHT_AND_MODIFY_SELECTION : IDS_MOVE_RIGHT;
194 case ui::TextEditCommandAuraLinux::MOVE_LEFT:
195 return select ? IDS_MOVE_LEFT_AND_MODIFY_SELECTION : IDS_MOVE_LEFT;
196 case ui::TextEditCommandAuraLinux::MOVE_PAGE_DOWN:
197 case ui::TextEditCommandAuraLinux::MOVE_PAGE_UP:
198 return kNoCommand;
199 case ui::TextEditCommandAuraLinux::MOVE_RIGHT:
200 return select ? IDS_MOVE_RIGHT_AND_MODIFY_SELECTION : IDS_MOVE_RIGHT;
201 case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_DOCUMENT:
202 case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_LINE:
203 case ui::TextEditCommandAuraLinux::MOVE_TO_BEGINING_OF_PARAGRAPH:
204 return select ? IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION :
205 IDS_MOVE_TO_BEGINNING_OF_LINE;
206 case ui::TextEditCommandAuraLinux::MOVE_TO_END_OF_DOCUMENT:
207 case ui::TextEditCommandAuraLinux::MOVE_TO_END_OF_LINE:
208 case ui::TextEditCommandAuraLinux::MOVE_TO_END_OF_PARAGRAPH:
209 return select ? IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION :
210 IDS_MOVE_TO_END_OF_LINE;
211 case ui::TextEditCommandAuraLinux::MOVE_UP:
212 return IDS_MOVE_UP;
213 case ui::TextEditCommandAuraLinux::MOVE_WORD_BACKWARD:
214 if (rtl) {
215 return select ? IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION :
216 IDS_MOVE_WORD_RIGHT;
217 }
218 return select ? IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION :
219 IDS_MOVE_WORD_LEFT;
220 case ui::TextEditCommandAuraLinux::MOVE_WORD_FORWARD:
221 if (rtl) {
222 return select ? IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION :
223 IDS_MOVE_WORD_LEFT;
224 }
225 return select ? IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION :
226 IDS_MOVE_WORD_RIGHT;
227 case ui::TextEditCommandAuraLinux::MOVE_WORD_LEFT:
228 return select ? IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION :
229 IDS_MOVE_WORD_LEFT;
230 case ui::TextEditCommandAuraLinux::MOVE_WORD_RIGHT:
231 return select ? IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION :
232 IDS_MOVE_WORD_RIGHT;
233 case ui::TextEditCommandAuraLinux::PASTE:
234 return IDS_APP_PASTE;
235 case ui::TextEditCommandAuraLinux::SELECT_ALL:
236 return IDS_APP_SELECT_ALL;
237 case ui::TextEditCommandAuraLinux::SET_MARK:
238 case ui::TextEditCommandAuraLinux::UNSELECT:
239 case ui::TextEditCommandAuraLinux::INVALID_COMMAND:
240 return kNoCommand;
241 }
242 return kNoCommand;
243 }
244 #endif
245
246 const gfx::FontList& GetDefaultFontList() { 172 const gfx::FontList& GetDefaultFontList() {
247 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 173 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
248 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta); 174 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta);
249 } 175 }
250 176
177 // Returns the ui::TextEditCommand corresponding to the |command_id| menu
178 // action. |has_selection| is true if the textfield has an active selection.
179 // Keep in sync with UpdateContextMenu.
180 ui::TextEditCommand GetTextEditCommandFromMenuCommand(int command_id,
181 bool has_selection) {
182 switch (command_id) {
183 case IDS_APP_UNDO:
184 return ui::TextEditCommand::UNDO;
185 case IDS_APP_CUT:
186 return ui::TextEditCommand::CUT;
187 case IDS_APP_COPY:
188 return ui::TextEditCommand::COPY;
189 case IDS_APP_PASTE:
190 return ui::TextEditCommand::PASTE;
191 case IDS_APP_DELETE:
192 // The DELETE menu action only works in case of an active selection.
193 if (has_selection)
194 return ui::TextEditCommand::DELETE_FORWARD;
195 break;
196 case IDS_APP_SELECT_ALL:
197 return ui::TextEditCommand::SELECT_ALL;
198 }
199 return ui::TextEditCommand::INVALID_COMMAND;
200 }
201
251 } // namespace 202 } // namespace
252 203
253 // static 204 // static
254 const char Textfield::kViewClassName[] = "Textfield"; 205 const char Textfield::kViewClassName[] = "Textfield";
255 const int Textfield::kTextPadding = 3; 206 const int Textfield::kTextPadding = 3;
256 207
257 // static 208 // static
258 size_t Textfield::GetCaretBlinkMs() { 209 size_t Textfield::GetCaretBlinkMs() {
259 static const size_t default_value = 500; 210 static const size_t default_value = 500;
260 #if defined(OS_WIN) 211 #if defined(OS_WIN)
261 static const size_t system_value = ::GetCaretBlinkTime(); 212 static const size_t system_value = ::GetCaretBlinkTime();
262 if (system_value != 0) 213 if (system_value != 0)
263 return (system_value == INFINITE) ? 0 : system_value; 214 return (system_value == INFINITE) ? 0 : system_value;
264 #endif 215 #endif
265 return default_value; 216 return default_value;
266 } 217 }
267 218
268 Textfield::Textfield() 219 Textfield::Textfield()
269 : model_(new TextfieldModel(this)), 220 : model_(new TextfieldModel(this)),
270 controller_(NULL), 221 controller_(NULL),
271 scheduled_edit_command_(kNoCommand), 222 scheduled_text_edit_command_(ui::TextEditCommand::INVALID_COMMAND),
272 read_only_(false), 223 read_only_(false),
273 default_width_in_chars_(0), 224 default_width_in_chars_(0),
274 use_default_text_color_(true), 225 use_default_text_color_(true),
275 use_default_background_color_(true), 226 use_default_background_color_(true),
276 use_default_selection_text_color_(true), 227 use_default_selection_text_color_(true),
277 use_default_selection_background_color_(true), 228 use_default_selection_background_color_(true),
278 text_color_(SK_ColorBLACK), 229 text_color_(SK_ColorBLACK),
279 background_color_(SK_ColorWHITE), 230 background_color_(SK_ColorWHITE),
280 selection_text_color_(SK_ColorWHITE), 231 selection_text_color_(SK_ColorWHITE),
281 selection_background_color_(SK_ColorBLUE), 232 selection_background_color_(SK_ColorBLUE),
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 } 510 }
560 511
561 void Textfield::ClearEditHistory() { 512 void Textfield::ClearEditHistory() {
562 model_->ClearEditHistory(); 513 model_->ClearEditHistory();
563 } 514 }
564 515
565 void Textfield::SetAccessibleName(const base::string16& name) { 516 void Textfield::SetAccessibleName(const base::string16& name) {
566 accessible_name_ = name; 517 accessible_name_ = name;
567 } 518 }
568 519
569 void Textfield::ExecuteCommand(int command_id) {
570 ExecuteCommand(command_id, ui::EF_NONE);
571 }
572
573 bool Textfield::HasTextBeingDragged() { 520 bool Textfield::HasTextBeingDragged() {
574 return initiating_drag_; 521 return initiating_drag_;
575 } 522 }
576 523
577 //////////////////////////////////////////////////////////////////////////////// 524 ////////////////////////////////////////////////////////////////////////////////
578 // Textfield, View overrides: 525 // Textfield, View overrides:
579 526
580 gfx::Insets Textfield::GetInsets() const { 527 gfx::Insets Textfield::GetInsets() const {
581 gfx::Insets insets = View::GetInsets(); 528 gfx::Insets insets = View::GetInsets();
582 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); 529 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 drag_selection_timer_.Stop(); 633 drag_selection_timer_.Stop();
687 // Cancel suspected drag initiations, the user was clicking in the selection. 634 // Cancel suspected drag initiations, the user was clicking in the selection.
688 if (initiating_drag_) 635 if (initiating_drag_)
689 MoveCursorTo(event.location(), false); 636 MoveCursorTo(event.location(), false);
690 initiating_drag_ = false; 637 initiating_drag_ = false;
691 UpdateSelectionClipboard(); 638 UpdateSelectionClipboard();
692 OnAfterUserAction(); 639 OnAfterUserAction();
693 } 640 }
694 641
695 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) { 642 bool Textfield::OnKeyPressed(const ui::KeyEvent& event) {
696 int edit_command = scheduled_edit_command_; 643 ui::TextEditCommand edit_command = scheduled_text_edit_command_;
697 scheduled_edit_command_ = kNoCommand; 644 scheduled_text_edit_command_ = ui::TextEditCommand::INVALID_COMMAND;
698 645
699 // Since HandleKeyEvent() might destroy |this|, get a weak pointer and verify 646 // Since HandleKeyEvent() might destroy |this|, get a weak pointer and verify
700 // it isn't null before proceeding. 647 // it isn't null before proceeding.
701 base::WeakPtr<Textfield> textfield(weak_ptr_factory_.GetWeakPtr()); 648 base::WeakPtr<Textfield> textfield(weak_ptr_factory_.GetWeakPtr());
702 649
703 bool handled = controller_ && controller_->HandleKeyEvent(this, event); 650 bool handled = controller_ && controller_->HandleKeyEvent(this, event);
704 651
705 if (!textfield) 652 if (!textfield)
706 return handled; 653 return handled;
707 654
708 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 655 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
709 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = 656 ui::TextEditKeyBindingsDelegateAuraLinux* delegate =
710 ui::GetTextEditKeyBindingsDelegate(); 657 ui::GetTextEditKeyBindingsDelegate();
711 std::vector<ui::TextEditCommandAuraLinux> commands; 658 std::vector<ui::TextEditCommandAuraLinux> commands;
712 if (!handled && delegate && delegate->MatchEvent(event, &commands)) { 659 if (!handled && delegate && delegate->MatchEvent(event, &commands)) {
713 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
714 for (size_t i = 0; i < commands.size(); ++i) { 660 for (size_t i = 0; i < commands.size(); ++i) {
715 const int command = GetViewsCommand(commands[i], rtl); 661 if (IsTextEditCommandEnabled(commands[i].command())) {
716 if (IsCommandIdEnabled(command)) { 662 ExecuteTextEditCommand(commands[i].command());
717 ExecuteCommand(command);
718 handled = true; 663 handled = true;
719 } 664 }
720 } 665 }
721 return handled; 666 return handled;
722 } 667 }
723 #endif 668 #endif
724 669
725 if (edit_command == kNoCommand) 670 if (edit_command == ui::TextEditCommand::INVALID_COMMAND)
726 edit_command = GetCommandForKeyEvent(event); 671 edit_command = GetCommandForKeyEvent(event);
727 672
728 if (!handled && IsCommandIdEnabled(edit_command)) { 673 if (!handled && IsTextEditCommandEnabled(edit_command)) {
729 ExecuteCommand(edit_command); 674 ExecuteTextEditCommand(edit_command);
730 handled = true; 675 handled = true;
731 } 676 }
732 return handled; 677 return handled;
733 } 678 }
734 679
735 void Textfield::OnGestureEvent(ui::GestureEvent* event) { 680 void Textfield::OnGestureEvent(ui::GestureEvent* event) {
736 switch (event->type()) { 681 switch (event->type()) {
737 case ui::ET_GESTURE_TAP_DOWN: 682 case ui::ET_GESTURE_TAP_DOWN:
738 RequestFocus(); 683 RequestFocus();
739 ShowImeIfNeeded(); 684 ShowImeIfNeeded();
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
823 break; 768 break;
824 default: 769 default:
825 return; 770 return;
826 } 771 }
827 } 772 }
828 773
829 // This function is called by BrowserView to execute clipboard commands. 774 // This function is called by BrowserView to execute clipboard commands.
830 bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) { 775 bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) {
831 ui::KeyEvent event(accelerator.type(), accelerator.key_code(), 776 ui::KeyEvent event(accelerator.type(), accelerator.key_code(),
832 accelerator.modifiers()); 777 accelerator.modifiers());
833 ExecuteCommand(GetCommandForKeyEvent(event)); 778 ExecuteTextEditCommand(GetCommandForKeyEvent(event));
834 return true; 779 return true;
835 } 780 }
836 781
837 bool Textfield::CanHandleAccelerators() const { 782 bool Textfield::CanHandleAccelerators() const {
838 return GetRenderText()->focused() && View::CanHandleAccelerators(); 783 return GetRenderText()->focused() && View::CanHandleAccelerators();
839 } 784 }
840 785
841 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { 786 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) {
842 SelectAll(false); 787 SelectAll(false);
843 } 788 }
844 789
845 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { 790 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) {
846 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) 791 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
847 // Skip any accelerator handling that conflicts with custom keybindings. 792 // Skip any accelerator handling that conflicts with custom keybindings.
848 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = 793 ui::TextEditKeyBindingsDelegateAuraLinux* delegate =
849 ui::GetTextEditKeyBindingsDelegate(); 794 ui::GetTextEditKeyBindingsDelegate();
850 std::vector<ui::TextEditCommandAuraLinux> commands; 795 std::vector<ui::TextEditCommandAuraLinux> commands;
851 if (delegate && delegate->MatchEvent(event, &commands)) { 796 if (delegate && delegate->MatchEvent(event, &commands)) {
852 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
853 for (size_t i = 0; i < commands.size(); ++i) 797 for (size_t i = 0; i < commands.size(); ++i)
854 if (IsCommandIdEnabled(GetViewsCommand(commands[i], rtl))) 798 if (IsTextEditCommandEnabled(commands[i].command()))
855 return true; 799 return true;
856 } 800 }
857 #endif 801 #endif
858 802
859 // Skip backspace accelerator handling; editable textfields handle this key. 803 // Skip backspace accelerator handling; editable textfields handle this key.
860 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes. 804 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes.
861 const bool is_backspace = event.key_code() == ui::VKEY_BACK; 805 const bool is_backspace = event.key_code() == ui::VKEY_BACK;
862 return (is_backspace && !read_only()) || event.IsUnicodeKeyCode(); 806 return (is_backspace && !read_only()) || event.IsUnicodeKeyCode();
863 } 807 }
864 808
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1217 } 1161 }
1218 1162
1219 //////////////////////////////////////////////////////////////////////////////// 1163 ////////////////////////////////////////////////////////////////////////////////
1220 // Textfield, ui::SimpleMenuModel::Delegate overrides: 1164 // Textfield, ui::SimpleMenuModel::Delegate overrides:
1221 1165
1222 bool Textfield::IsCommandIdChecked(int command_id) const { 1166 bool Textfield::IsCommandIdChecked(int command_id) const {
1223 return true; 1167 return true;
1224 } 1168 }
1225 1169
1226 bool Textfield::IsCommandIdEnabled(int command_id) const { 1170 bool Textfield::IsCommandIdEnabled(int command_id) const {
1227 base::string16 result; 1171 return Textfield::IsTextEditCommandEnabled(
1228 bool editable = !read_only(); 1172 GetTextEditCommandFromMenuCommand(command_id, HasSelection()));
1229 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
1230 switch (command_id) {
1231 case IDS_APP_UNDO:
1232 return editable && model_->CanUndo();
1233 case IDS_APP_REDO:
1234 return editable && model_->CanRedo();
1235 case IDS_APP_CUT:
1236 return editable && readable && model_->HasSelection();
1237 case IDS_APP_COPY:
1238 return readable && model_->HasSelection();
1239 case IDS_APP_PASTE:
1240 ui::Clipboard::GetForCurrentThread()->ReadText(
1241 ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1242 return editable && !result.empty();
1243 case IDS_APP_DELETE:
1244 return editable && model_->HasSelection();
1245 case IDS_APP_SELECT_ALL:
1246 return !text().empty();
1247 case IDS_DELETE_FORWARD:
1248 case IDS_DELETE_BACKWARD:
1249 case IDS_DELETE_TO_BEGINNING_OF_LINE:
1250 case IDS_DELETE_TO_END_OF_LINE:
1251 case IDS_DELETE_WORD_BACKWARD:
1252 case IDS_DELETE_WORD_FORWARD:
1253 return editable;
1254 case IDS_MOVE_LEFT:
1255 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION:
1256 case IDS_MOVE_RIGHT:
1257 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION:
1258 case IDS_MOVE_WORD_LEFT:
1259 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
1260 case IDS_MOVE_WORD_RIGHT:
1261 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
1262 case IDS_MOVE_TO_BEGINNING_OF_LINE:
1263 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
1264 case IDS_MOVE_TO_END_OF_LINE:
1265 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
1266 return true;
1267 default:
1268 return false;
1269 }
1270 } 1173 }
1271 1174
1272 bool Textfield::GetAcceleratorForCommandId(int command_id, 1175 bool Textfield::GetAcceleratorForCommandId(int command_id,
1273 ui::Accelerator* accelerator) { 1176 ui::Accelerator* accelerator) {
1274 switch (command_id) { 1177 switch (command_id) {
1275 case IDS_APP_UNDO: 1178 case IDS_APP_UNDO:
1276 *accelerator = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN); 1179 *accelerator = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN);
1277 return true; 1180 return true;
1278 1181
1279 case IDS_APP_CUT: 1182 case IDS_APP_CUT:
(...skipping 11 matching lines...) Expand all
1291 case IDS_APP_SELECT_ALL: 1194 case IDS_APP_SELECT_ALL:
1292 *accelerator = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN); 1195 *accelerator = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN);
1293 return true; 1196 return true;
1294 1197
1295 default: 1198 default:
1296 return false; 1199 return false;
1297 } 1200 }
1298 } 1201 }
1299 1202
1300 void Textfield::ExecuteCommand(int command_id, int event_flags) { 1203 void Textfield::ExecuteCommand(int command_id, int event_flags) {
1301 DestroyTouchSelection(); 1204 Textfield::ExecuteTextEditCommand(
1302 1205 GetTextEditCommandFromMenuCommand(command_id, HasSelection()));
1303 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent
1304 // modifications of the command should happen here.
1305 if (HasSelection()) {
1306 switch (command_id) {
1307 case IDS_DELETE_WORD_BACKWARD:
1308 case IDS_DELETE_TO_BEGINNING_OF_LINE:
1309 command_id = IDS_DELETE_BACKWARD;
1310 break;
1311 case IDS_DELETE_WORD_FORWARD:
1312 case IDS_DELETE_TO_END_OF_LINE:
1313 command_id = IDS_DELETE_FORWARD;
1314 break;
1315 }
1316 }
1317
1318 if (!IsCommandIdEnabled(command_id))
1319 return;
1320
1321 bool text_changed = false;
1322 bool cursor_changed = false;
1323 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
1324 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT;
1325 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT;
1326 gfx::SelectionModel selection_model = GetSelectionModel();
1327
1328 OnBeforeUserAction();
1329 switch (command_id) {
1330 case IDS_APP_UNDO:
1331 text_changed = cursor_changed = model_->Undo();
1332 break;
1333 case IDS_APP_REDO:
1334 text_changed = cursor_changed = model_->Redo();
1335 break;
1336 case IDS_APP_CUT:
1337 text_changed = cursor_changed = Cut();
1338 break;
1339 case IDS_APP_COPY:
1340 Copy();
1341 break;
1342 case IDS_APP_PASTE:
1343 text_changed = cursor_changed = Paste();
1344 break;
1345 case IDS_APP_DELETE:
1346 text_changed = cursor_changed = model_->Delete();
1347 break;
1348 case IDS_APP_SELECT_ALL:
1349 SelectAll(false);
1350 break;
1351 case IDS_DELETE_BACKWARD:
1352 text_changed = cursor_changed = model_->Backspace();
1353 break;
1354 case IDS_DELETE_FORWARD:
1355 text_changed = cursor_changed = model_->Delete();
1356 break;
1357 case IDS_DELETE_TO_END_OF_LINE:
1358 model_->MoveCursor(gfx::LINE_BREAK, end, true);
1359 text_changed = cursor_changed = model_->Delete();
1360 break;
1361 case IDS_DELETE_TO_BEGINNING_OF_LINE:
1362 model_->MoveCursor(gfx::LINE_BREAK, begin, true);
1363 text_changed = cursor_changed = model_->Backspace();
1364 break;
1365 case IDS_DELETE_WORD_BACKWARD:
1366 model_->MoveCursor(gfx::WORD_BREAK, begin, true);
1367 text_changed = cursor_changed = model_->Backspace();
1368 break;
1369 case IDS_DELETE_WORD_FORWARD:
1370 model_->MoveCursor(gfx::WORD_BREAK, end, true);
1371 text_changed = cursor_changed = model_->Delete();
1372 break;
1373 case IDS_MOVE_LEFT:
1374 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
1375 break;
1376 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION:
1377 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
1378 break;
1379 case IDS_MOVE_RIGHT:
1380 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
1381 break;
1382 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION:
1383 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
1384 break;
1385 case IDS_MOVE_WORD_LEFT:
1386 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false);
1387 break;
1388 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
1389 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
1390 break;
1391 case IDS_MOVE_WORD_RIGHT:
1392 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
1393 break;
1394 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
1395 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
1396 break;
1397 case IDS_MOVE_TO_BEGINNING_OF_LINE:
1398 model_->MoveCursor(gfx::LINE_BREAK, begin, false);
1399 break;
1400 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
1401 model_->MoveCursor(gfx::LINE_BREAK, begin, true);
1402 break;
1403 case IDS_MOVE_TO_END_OF_LINE:
1404 model_->MoveCursor(gfx::LINE_BREAK, end, false);
1405 break;
1406 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
1407 model_->MoveCursor(gfx::LINE_BREAK, end, true);
1408 break;
1409 default:
1410 NOTREACHED();
1411 break;
1412 }
1413
1414 cursor_changed |= GetSelectionModel() != selection_model;
1415 if (cursor_changed)
1416 UpdateSelectionClipboard();
1417 UpdateAfterChange(text_changed, cursor_changed);
1418 OnAfterUserAction();
1419 } 1206 }
1420 1207
1421 //////////////////////////////////////////////////////////////////////////////// 1208 ////////////////////////////////////////////////////////////////////////////////
1422 // Textfield, ui::TextInputClient overrides: 1209 // Textfield, ui::TextInputClient overrides:
1423 1210
1424 void Textfield::SetCompositionText(const ui::CompositionText& composition) { 1211 void Textfield::SetCompositionText(const ui::CompositionText& composition) {
1425 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) 1212 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE)
1426 return; 1213 return;
1427 1214
1428 OnBeforeUserAction(); 1215 OnBeforeUserAction();
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
1634 1421
1635 range.set_start(range.start() - before); 1422 range.set_start(range.start() - before);
1636 range.set_end(range.end() + after); 1423 range.set_end(range.end() + after);
1637 gfx::Range text_range; 1424 gfx::Range text_range;
1638 if (GetTextRange(&text_range) && text_range.Contains(range)) 1425 if (GetTextRange(&text_range) && text_range.Contains(range))
1639 DeleteRange(range); 1426 DeleteRange(range);
1640 } 1427 }
1641 1428
1642 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {} 1429 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {}
1643 1430
1644 bool Textfield::IsEditCommandEnabled(int command_id) const { 1431 bool Textfield::IsTextEditCommandEnabled(ui::TextEditCommand command) const {
1645 return IsCommandIdEnabled(command_id); 1432 base::string16 result;
1433 bool editable = !read_only();
1434 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
1435 switch (command) {
1436 case ui::TextEditCommand::DELETE_BACKWARD:
1437 case ui::TextEditCommand::DELETE_FORWARD:
1438 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_LINE:
1439 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_PARAGRAPH:
1440 case ui::TextEditCommand::DELETE_TO_END_OF_LINE:
1441 case ui::TextEditCommand::DELETE_TO_END_OF_PARAGRAPH:
1442 case ui::TextEditCommand::DELETE_WORD_BACKWARD:
1443 case ui::TextEditCommand::DELETE_WORD_FORWARD:
1444 return editable;
1445 case ui::TextEditCommand::MOVE_BACKWARD:
1446 case ui::TextEditCommand::MOVE_BACKWARD_AND_MODIFY_SELECTION:
1447 case ui::TextEditCommand::MOVE_FORWARD:
1448 case ui::TextEditCommand::MOVE_FORWARD_AND_MODIFY_SELECTION:
1449 case ui::TextEditCommand::MOVE_LEFT:
1450 case ui::TextEditCommand::MOVE_LEFT_AND_MODIFY_SELECTION:
1451 case ui::TextEditCommand::MOVE_RIGHT:
1452 case ui::TextEditCommand::MOVE_RIGHT_AND_MODIFY_SELECTION:
1453 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_DOCUMENT:
1454 case ui::TextEditCommand::
1455 MOVE_TO_BEGINNING_OF_DOCUMENT_AND_MODIFY_SELECTION:
1456 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE:
1457 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
1458 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_PARAGRAPH:
1459 case ui::TextEditCommand::
1460 MOVE_TO_BEGINNING_OF_PARAGRAPH_AND_MODIFY_SELECTION:
1461 case ui::TextEditCommand::MOVE_TO_END_OF_DOCUMENT:
1462 case ui::TextEditCommand::MOVE_TO_END_OF_DOCUMENT_AND_MODIFY_SELECTION:
1463 case ui::TextEditCommand::MOVE_TO_END_OF_LINE:
1464 case ui::TextEditCommand::MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
1465 case ui::TextEditCommand::MOVE_TO_END_OF_PARAGRAPH:
1466 case ui::TextEditCommand::MOVE_TO_END_OF_PARAGRAPH_AND_MODIFY_SELECTION:
1467 case ui::TextEditCommand::MOVE_WORD_BACKWARD:
1468 case ui::TextEditCommand::MOVE_WORD_BACKWARD_AND_MODIFY_SELECTION:
1469 case ui::TextEditCommand::MOVE_WORD_FORWARD:
1470 case ui::TextEditCommand::MOVE_WORD_FORWARD_AND_MODIFY_SELECTION:
1471 case ui::TextEditCommand::MOVE_WORD_LEFT:
1472 case ui::TextEditCommand::MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
1473 case ui::TextEditCommand::MOVE_WORD_RIGHT:
1474 case ui::TextEditCommand::MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
1475 return true;
1476 case ui::TextEditCommand::UNDO:
1477 return editable && model_->CanUndo();
1478 case ui::TextEditCommand::REDO:
1479 return editable && model_->CanRedo();
1480 case ui::TextEditCommand::CUT:
1481 return editable && readable && model_->HasSelection();
1482 case ui::TextEditCommand::COPY:
1483 return readable && model_->HasSelection();
1484 case ui::TextEditCommand::PASTE:
1485 ui::Clipboard::GetForCurrentThread()->ReadText(
1486 ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1487 return editable && !result.empty();
1488 case ui::TextEditCommand::SELECT_ALL:
1489 return !text().empty();
1490 case ui::TextEditCommand::MOVE_DOWN:
1491 case ui::TextEditCommand::MOVE_DOWN_AND_MODIFY_SELECTION:
1492 case ui::TextEditCommand::MOVE_PAGE_DOWN:
1493 case ui::TextEditCommand::MOVE_PAGE_DOWN_AND_MODIFY_SELECTION:
1494 case ui::TextEditCommand::MOVE_PAGE_UP:
1495 case ui::TextEditCommand::MOVE_PAGE_UP_AND_MODIFY_SELECTION:
1496 case ui::TextEditCommand::MOVE_UP:
1497 case ui::TextEditCommand::MOVE_UP_AND_MODIFY_SELECTION:
1498 case ui::TextEditCommand::INSERT_TEXT:
1499 case ui::TextEditCommand::SET_MARK:
1500 case ui::TextEditCommand::UNSELECT:
1501 case ui::TextEditCommand::INVALID_COMMAND:
1502 return false;
1503 }
1504 NOTREACHED();
1505 return false;
1646 } 1506 }
1647 1507
1648 void Textfield::SetEditCommandForNextKeyEvent(int command_id) { 1508 void Textfield::SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) {
1649 DCHECK_EQ(kNoCommand, scheduled_edit_command_); 1509 DCHECK_EQ(ui::TextEditCommand::INVALID_COMMAND, scheduled_text_edit_command_);
1650 scheduled_edit_command_ = command_id; 1510 scheduled_text_edit_command_ = command;
1651 } 1511 }
1652 1512
1653 //////////////////////////////////////////////////////////////////////////////// 1513 ////////////////////////////////////////////////////////////////////////////////
1654 // Textfield, protected: 1514 // Textfield, protected:
1655 1515
1656 void Textfield::DoInsertChar(base::char16 ch) { 1516 void Textfield::DoInsertChar(base::char16 ch) {
1657 OnBeforeUserAction(); 1517 OnBeforeUserAction();
1658 skip_input_method_cancel_composition_ = true; 1518 skip_input_method_cancel_composition_ = true;
1659 if (GetRenderText()->insert_mode()) 1519 if (GetRenderText()->insert_mode())
1660 model_->InsertChar(ch); 1520 model_->InsertChar(ch);
1661 else 1521 else
1662 model_->ReplaceChar(ch); 1522 model_->ReplaceChar(ch);
1663 skip_input_method_cancel_composition_ = false; 1523 skip_input_method_cancel_composition_ = false;
1664 1524
1665 UpdateAfterChange(true, true); 1525 UpdateAfterChange(true, true);
1666 OnAfterUserAction(); 1526 OnAfterUserAction();
1667 } 1527 }
1668 1528
1669 gfx::RenderText* Textfield::GetRenderText() const { 1529 gfx::RenderText* Textfield::GetRenderText() const {
1670 return model_->render_text(); 1530 return model_->render_text();
1671 } 1531 }
1672 1532
1673 base::string16 Textfield::GetSelectionClipboardText() const { 1533 base::string16 Textfield::GetSelectionClipboardText() const {
1674 base::string16 selection_clipboard_text; 1534 base::string16 selection_clipboard_text;
1675 ui::Clipboard::GetForCurrentThread()->ReadText( 1535 ui::Clipboard::GetForCurrentThread()->ReadText(
1676 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); 1536 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text);
1677 return selection_clipboard_text; 1537 return selection_clipboard_text;
1678 } 1538 }
1679 1539
1540 void Textfield::ExecuteTextEditCommand(ui::TextEditCommand command) {
1541 DestroyTouchSelection();
1542
1543 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent
1544 // modifications of the command should happen here.
1545 if (HasSelection()) {
1546 switch (command) {
1547 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_LINE:
1548 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_PARAGRAPH:
1549 case ui::TextEditCommand::DELETE_TO_END_OF_LINE:
1550 case ui::TextEditCommand::DELETE_TO_END_OF_PARAGRAPH:
1551 case ui::TextEditCommand::DELETE_WORD_BACKWARD:
1552 case ui::TextEditCommand::DELETE_WORD_FORWARD:
1553 command = ui::TextEditCommand::DELETE_FORWARD;
1554 break;
1555 default:
1556 break;
1557 }
1558 }
1559
1560 // We only execute the commands enabled in Textfield::IsTextEditCommandEnabled
1561 // below. Hence don't do a virtual IsTextEditCommandEnabled call.
1562 if (!Textfield::IsTextEditCommandEnabled(command))
1563 return;
1564
1565 bool text_changed = false;
1566 bool cursor_changed = false;
1567 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT;
1568 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT;
1569 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT;
1570 gfx::SelectionModel selection_model = GetSelectionModel();
1571
1572 OnBeforeUserAction();
1573 switch (command) {
1574 case ui::TextEditCommand::DELETE_BACKWARD:
1575 text_changed = cursor_changed = model_->Backspace();
1576 break;
1577 case ui::TextEditCommand::DELETE_FORWARD:
1578 text_changed = cursor_changed = model_->Delete();
1579 break;
1580 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_LINE:
1581 case ui::TextEditCommand::DELETE_TO_BEGINNING_OF_PARAGRAPH:
1582 model_->MoveCursor(gfx::LINE_BREAK, begin, true);
1583 text_changed = cursor_changed = model_->Backspace();
1584 break;
1585 case ui::TextEditCommand::DELETE_TO_END_OF_LINE:
1586 case ui::TextEditCommand::DELETE_TO_END_OF_PARAGRAPH:
1587 model_->MoveCursor(gfx::LINE_BREAK, end, true);
1588 text_changed = cursor_changed = model_->Delete();
1589 break;
1590 case ui::TextEditCommand::DELETE_WORD_BACKWARD:
1591 model_->MoveCursor(gfx::WORD_BREAK, begin, true);
1592 text_changed = cursor_changed = model_->Backspace();
1593 break;
1594 case ui::TextEditCommand::DELETE_WORD_FORWARD:
1595 model_->MoveCursor(gfx::WORD_BREAK, end, true);
1596 text_changed = cursor_changed = model_->Delete();
1597 break;
1598 case ui::TextEditCommand::MOVE_BACKWARD:
1599 model_->MoveCursor(gfx::CHARACTER_BREAK, begin, false);
1600 break;
1601 case ui::TextEditCommand::MOVE_BACKWARD_AND_MODIFY_SELECTION:
1602 model_->MoveCursor(gfx::CHARACTER_BREAK, begin, true);
1603 break;
1604 case ui::TextEditCommand::MOVE_FORWARD:
1605 model_->MoveCursor(gfx::CHARACTER_BREAK, end, false);
1606 break;
1607 case ui::TextEditCommand::MOVE_FORWARD_AND_MODIFY_SELECTION:
1608 model_->MoveCursor(gfx::CHARACTER_BREAK, end, true);
1609 break;
1610 case ui::TextEditCommand::MOVE_LEFT:
1611 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false);
1612 break;
1613 case ui::TextEditCommand::MOVE_LEFT_AND_MODIFY_SELECTION:
1614 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true);
1615 break;
1616 case ui::TextEditCommand::MOVE_RIGHT:
1617 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false);
1618 break;
1619 case ui::TextEditCommand::MOVE_RIGHT_AND_MODIFY_SELECTION:
1620 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true);
1621 break;
1622 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_DOCUMENT:
1623 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE:
1624 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_PARAGRAPH:
1625 model_->MoveCursor(gfx::LINE_BREAK, begin, false);
1626 break;
1627 case ui::TextEditCommand::
1628 MOVE_TO_BEGINNING_OF_DOCUMENT_AND_MODIFY_SELECTION:
1629 case ui::TextEditCommand::MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION:
1630 case ui::TextEditCommand::
1631 MOVE_TO_BEGINNING_OF_PARAGRAPH_AND_MODIFY_SELECTION:
1632 model_->MoveCursor(gfx::LINE_BREAK, begin, true);
1633 break;
1634 case ui::TextEditCommand::MOVE_TO_END_OF_DOCUMENT:
1635 case ui::TextEditCommand::MOVE_TO_END_OF_LINE:
1636 case ui::TextEditCommand::MOVE_TO_END_OF_PARAGRAPH:
1637 model_->MoveCursor(gfx::LINE_BREAK, end, false);
1638 break;
1639 case ui::TextEditCommand::MOVE_TO_END_OF_DOCUMENT_AND_MODIFY_SELECTION:
1640 case ui::TextEditCommand::MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION:
1641 case ui::TextEditCommand::MOVE_TO_END_OF_PARAGRAPH_AND_MODIFY_SELECTION:
1642 model_->MoveCursor(gfx::LINE_BREAK, end, true);
1643 break;
1644 case ui::TextEditCommand::MOVE_WORD_BACKWARD:
1645 model_->MoveCursor(gfx::WORD_BREAK, begin, false);
1646 break;
1647 case ui::TextEditCommand::MOVE_WORD_BACKWARD_AND_MODIFY_SELECTION:
1648 model_->MoveCursor(gfx::WORD_BREAK, begin, true);
1649 break;
1650 case ui::TextEditCommand::MOVE_WORD_FORWARD:
1651 model_->MoveCursor(gfx::WORD_BREAK, end, false);
1652 break;
1653 case ui::TextEditCommand::MOVE_WORD_FORWARD_AND_MODIFY_SELECTION:
1654 model_->MoveCursor(gfx::WORD_BREAK, end, true);
1655 break;
1656 case ui::TextEditCommand::MOVE_WORD_LEFT:
1657 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false);
1658 break;
1659 case ui::TextEditCommand::MOVE_WORD_LEFT_AND_MODIFY_SELECTION:
1660 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true);
1661 break;
1662 case ui::TextEditCommand::MOVE_WORD_RIGHT:
1663 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false);
1664 break;
1665 case ui::TextEditCommand::MOVE_WORD_RIGHT_AND_MODIFY_SELECTION:
1666 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true);
1667 break;
1668 case ui::TextEditCommand::UNDO:
1669 text_changed = cursor_changed = model_->Undo();
1670 break;
1671 case ui::TextEditCommand::REDO:
1672 text_changed = cursor_changed = model_->Redo();
1673 break;
1674 case ui::TextEditCommand::CUT:
1675 text_changed = cursor_changed = Cut();
1676 break;
1677 case ui::TextEditCommand::COPY:
1678 Copy();
1679 break;
1680 case ui::TextEditCommand::PASTE:
1681 text_changed = cursor_changed = Paste();
1682 break;
1683 case ui::TextEditCommand::SELECT_ALL:
1684 SelectAll(false);
1685 break;
1686 case ui::TextEditCommand::MOVE_DOWN:
1687 case ui::TextEditCommand::MOVE_DOWN_AND_MODIFY_SELECTION:
1688 case ui::TextEditCommand::MOVE_PAGE_DOWN:
1689 case ui::TextEditCommand::MOVE_PAGE_DOWN_AND_MODIFY_SELECTION:
1690 case ui::TextEditCommand::MOVE_PAGE_UP:
1691 case ui::TextEditCommand::MOVE_PAGE_UP_AND_MODIFY_SELECTION:
1692 case ui::TextEditCommand::MOVE_UP:
1693 case ui::TextEditCommand::MOVE_UP_AND_MODIFY_SELECTION:
1694 case ui::TextEditCommand::INSERT_TEXT:
1695 case ui::TextEditCommand::SET_MARK:
1696 case ui::TextEditCommand::UNSELECT:
1697 case ui::TextEditCommand::INVALID_COMMAND:
1698 NOTREACHED();
1699 break;
1700 }
1701
1702 cursor_changed |= GetSelectionModel() != selection_model;
1703 if (cursor_changed)
1704 UpdateSelectionClipboard();
1705 UpdateAfterChange(text_changed, cursor_changed);
1706 OnAfterUserAction();
1707 }
1708
1680 //////////////////////////////////////////////////////////////////////////////// 1709 ////////////////////////////////////////////////////////////////////////////////
1681 // Textfield, private: 1710 // Textfield, private:
1682 1711
1683 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1712 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1684 if (!read_only()) { 1713 if (!read_only()) {
1685 SetText(new_value); 1714 SetText(new_value);
1686 ClearSelection(); 1715 ClearSelection();
1687 } 1716 }
1688 } 1717 }
1689 1718
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1846 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); 1875 context_menu_contents_.reset(new ui::SimpleMenuModel(this));
1847 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO); 1876 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO);
1848 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); 1877 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR);
1849 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); 1878 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT);
1850 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); 1879 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY);
1851 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); 1880 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE);
1852 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); 1881 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE);
1853 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); 1882 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR);
1854 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, 1883 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL,
1855 IDS_APP_SELECT_ALL); 1884 IDS_APP_SELECT_ALL);
1885
1886 // If the controller adds menu commands, also override ExecuteCommand() and
1887 // IsCommandIdEnabled() as appropriate, for the commands added.
1856 if (controller_) 1888 if (controller_)
1857 controller_->UpdateContextMenu(context_menu_contents_.get()); 1889 controller_->UpdateContextMenu(context_menu_contents_.get());
1858 } 1890 }
1859 context_menu_runner_.reset( 1891 context_menu_runner_.reset(
1860 new MenuRunner(context_menu_contents_.get(), 1892 new MenuRunner(context_menu_contents_.get(),
1861 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU)); 1893 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU));
1862 } 1894 }
1863 1895
1864 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) { 1896 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) {
1865 if (event.IsOnlyLeftMouseButton()) { 1897 if (event.IsOnlyLeftMouseButton()) {
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1929 RequestFocus(); 1961 RequestFocus();
1930 model_->MoveCursorTo(mouse); 1962 model_->MoveCursorTo(mouse);
1931 if (!selection_clipboard_text.empty()) { 1963 if (!selection_clipboard_text.empty()) {
1932 model_->InsertText(selection_clipboard_text); 1964 model_->InsertText(selection_clipboard_text);
1933 UpdateAfterChange(true, true); 1965 UpdateAfterChange(true, true);
1934 } 1966 }
1935 OnAfterUserAction(); 1967 OnAfterUserAction();
1936 } 1968 }
1937 1969
1938 } // namespace views 1970 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/textfield.h ('k') | ui/views/controls/textfield/textfield_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698