Chromium Code Reviews| OLD | NEW |
|---|---|
| 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" |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 } | 241 } |
| 242 return kNoCommand; | 242 return kNoCommand; |
| 243 } | 243 } |
| 244 #endif | 244 #endif |
| 245 | 245 |
| 246 const gfx::FontList& GetDefaultFontList() { | 246 const gfx::FontList& GetDefaultFontList() { |
| 247 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 247 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 248 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta); | 248 return rb.GetFontListWithDelta(ui::kLabelFontSizeDelta); |
| 249 } | 249 } |
| 250 | 250 |
| 251 // Returns true if |command_id| is a menu action installed by this textfield. | |
| 252 // Keep in sync with UpdateContextMenu. | |
| 253 bool IsMenuCommand(int command_id) { | |
| 254 switch (command_id) { | |
| 255 case IDS_APP_UNDO: | |
| 256 case IDS_APP_CUT: | |
| 257 case IDS_APP_COPY: | |
| 258 case IDS_APP_PASTE: | |
| 259 case IDS_APP_DELETE: | |
| 260 case IDS_APP_SELECT_ALL: | |
| 261 return true; | |
| 262 } | |
| 263 return false; | |
| 264 } | |
| 265 | |
| 251 } // namespace | 266 } // namespace |
| 252 | 267 |
| 253 // static | 268 // static |
| 254 const char Textfield::kViewClassName[] = "Textfield"; | 269 const char Textfield::kViewClassName[] = "Textfield"; |
| 255 const int Textfield::kTextPadding = 3; | 270 const int Textfield::kTextPadding = 3; |
| 256 | 271 |
| 257 // static | 272 // static |
| 258 size_t Textfield::GetCaretBlinkMs() { | 273 size_t Textfield::GetCaretBlinkMs() { |
| 259 static const size_t default_value = 500; | 274 static const size_t default_value = 500; |
| 260 #if defined(OS_WIN) | 275 #if defined(OS_WIN) |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 563 } | 578 } |
| 564 | 579 |
| 565 void Textfield::ClearEditHistory() { | 580 void Textfield::ClearEditHistory() { |
| 566 model_->ClearEditHistory(); | 581 model_->ClearEditHistory(); |
| 567 } | 582 } |
| 568 | 583 |
| 569 void Textfield::SetAccessibleName(const base::string16& name) { | 584 void Textfield::SetAccessibleName(const base::string16& name) { |
| 570 accessible_name_ = name; | 585 accessible_name_ = name; |
| 571 } | 586 } |
| 572 | 587 |
| 573 void Textfield::ExecuteCommand(int command_id) { | |
| 574 ExecuteCommand(command_id, ui::EF_NONE); | |
| 575 } | |
| 576 | |
| 577 bool Textfield::HasTextBeingDragged() { | 588 bool Textfield::HasTextBeingDragged() { |
| 578 return initiating_drag_; | 589 return initiating_drag_; |
| 579 } | 590 } |
| 580 | 591 |
| 581 //////////////////////////////////////////////////////////////////////////////// | 592 //////////////////////////////////////////////////////////////////////////////// |
| 582 // Textfield, View overrides: | 593 // Textfield, View overrides: |
| 583 | 594 |
| 584 gfx::Insets Textfield::GetInsets() const { | 595 gfx::Insets Textfield::GetInsets() const { |
| 585 gfx::Insets insets = View::GetInsets(); | 596 gfx::Insets insets = View::GetInsets(); |
| 586 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); | 597 insets += gfx::Insets(kTextPadding, kTextPadding, kTextPadding, kTextPadding); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 710 return handled; | 721 return handled; |
| 711 | 722 |
| 712 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 723 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 713 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = | 724 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = |
| 714 ui::GetTextEditKeyBindingsDelegate(); | 725 ui::GetTextEditKeyBindingsDelegate(); |
| 715 std::vector<ui::TextEditCommandAuraLinux> commands; | 726 std::vector<ui::TextEditCommandAuraLinux> commands; |
| 716 if (!handled && delegate && delegate->MatchEvent(event, &commands)) { | 727 if (!handled && delegate && delegate->MatchEvent(event, &commands)) { |
| 717 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | 728 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; |
| 718 for (size_t i = 0; i < commands.size(); ++i) { | 729 for (size_t i = 0; i < commands.size(); ++i) { |
| 719 const int command = GetViewsCommand(commands[i], rtl); | 730 const int command = GetViewsCommand(commands[i], rtl); |
| 720 if (IsCommandIdEnabled(command)) { | 731 if (IsEditCommandEnabled(command)) { |
| 721 ExecuteCommand(command); | 732 ExecuteEditCommand(command); |
| 722 handled = true; | 733 handled = true; |
| 723 } | 734 } |
| 724 } | 735 } |
| 725 return handled; | 736 return handled; |
| 726 } | 737 } |
| 727 #endif | 738 #endif |
| 728 | 739 |
| 729 if (edit_command == kNoCommand) | 740 if (edit_command == kNoCommand) |
| 730 edit_command = GetCommandForKeyEvent(event); | 741 edit_command = GetCommandForKeyEvent(event); |
| 731 | 742 |
| 732 if (!handled && IsCommandIdEnabled(edit_command)) { | 743 if (!handled && IsEditCommandEnabled(edit_command)) { |
| 733 ExecuteCommand(edit_command); | 744 ExecuteEditCommand(edit_command); |
| 734 handled = true; | 745 handled = true; |
| 735 } | 746 } |
| 736 return handled; | 747 return handled; |
| 737 } | 748 } |
| 738 | 749 |
| 739 void Textfield::OnGestureEvent(ui::GestureEvent* event) { | 750 void Textfield::OnGestureEvent(ui::GestureEvent* event) { |
| 740 switch (event->type()) { | 751 switch (event->type()) { |
| 741 case ui::ET_GESTURE_TAP_DOWN: | 752 case ui::ET_GESTURE_TAP_DOWN: |
| 742 RequestFocus(); | 753 RequestFocus(); |
| 743 ShowImeIfNeeded(); | 754 ShowImeIfNeeded(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 827 break; | 838 break; |
| 828 default: | 839 default: |
| 829 return; | 840 return; |
| 830 } | 841 } |
| 831 } | 842 } |
| 832 | 843 |
| 833 // This function is called by BrowserView to execute clipboard commands. | 844 // This function is called by BrowserView to execute clipboard commands. |
| 834 bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) { | 845 bool Textfield::AcceleratorPressed(const ui::Accelerator& accelerator) { |
| 835 ui::KeyEvent event(accelerator.type(), accelerator.key_code(), | 846 ui::KeyEvent event(accelerator.type(), accelerator.key_code(), |
| 836 accelerator.modifiers()); | 847 accelerator.modifiers()); |
| 837 ExecuteCommand(GetCommandForKeyEvent(event)); | 848 ExecuteEditCommand(GetCommandForKeyEvent(event)); |
| 838 return true; | 849 return true; |
| 839 } | 850 } |
| 840 | 851 |
| 841 bool Textfield::CanHandleAccelerators() const { | 852 bool Textfield::CanHandleAccelerators() const { |
| 842 return GetRenderText()->focused() && View::CanHandleAccelerators(); | 853 return GetRenderText()->focused() && View::CanHandleAccelerators(); |
| 843 } | 854 } |
| 844 | 855 |
| 845 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { | 856 void Textfield::AboutToRequestFocusFromTabTraversal(bool reverse) { |
| 846 SelectAll(false); | 857 SelectAll(false); |
| 847 } | 858 } |
| 848 | 859 |
| 849 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { | 860 bool Textfield::SkipDefaultKeyEventProcessing(const ui::KeyEvent& event) { |
| 850 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) | 861 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) |
| 851 // Skip any accelerator handling that conflicts with custom keybindings. | 862 // Skip any accelerator handling that conflicts with custom keybindings. |
| 852 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = | 863 ui::TextEditKeyBindingsDelegateAuraLinux* delegate = |
| 853 ui::GetTextEditKeyBindingsDelegate(); | 864 ui::GetTextEditKeyBindingsDelegate(); |
| 854 std::vector<ui::TextEditCommandAuraLinux> commands; | 865 std::vector<ui::TextEditCommandAuraLinux> commands; |
| 855 if (delegate && delegate->MatchEvent(event, &commands)) { | 866 if (delegate && delegate->MatchEvent(event, &commands)) { |
| 856 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | 867 const bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; |
| 857 for (size_t i = 0; i < commands.size(); ++i) | 868 for (size_t i = 0; i < commands.size(); ++i) |
| 858 if (IsCommandIdEnabled(GetViewsCommand(commands[i], rtl))) | 869 if (IsEditCommandEnabled(GetViewsCommand(commands[i], rtl))) |
| 859 return true; | 870 return true; |
| 860 } | 871 } |
| 861 #endif | 872 #endif |
| 862 | 873 |
| 863 // Skip backspace accelerator handling; editable textfields handle this key. | 874 // Skip backspace accelerator handling; editable textfields handle this key. |
| 864 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes. | 875 // Also skip processing Windows [Alt]+<num-pad digit> Unicode alt-codes. |
| 865 const bool is_backspace = event.key_code() == ui::VKEY_BACK; | 876 const bool is_backspace = event.key_code() == ui::VKEY_BACK; |
| 866 return (is_backspace && !read_only()) || event.IsUnicodeKeyCode(); | 877 return (is_backspace && !read_only()) || event.IsUnicodeKeyCode(); |
| 867 } | 878 } |
| 868 | 879 |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1221 } | 1232 } |
| 1222 | 1233 |
| 1223 //////////////////////////////////////////////////////////////////////////////// | 1234 //////////////////////////////////////////////////////////////////////////////// |
| 1224 // Textfield, ui::SimpleMenuModel::Delegate overrides: | 1235 // Textfield, ui::SimpleMenuModel::Delegate overrides: |
| 1225 | 1236 |
| 1226 bool Textfield::IsCommandIdChecked(int command_id) const { | 1237 bool Textfield::IsCommandIdChecked(int command_id) const { |
| 1227 return true; | 1238 return true; |
| 1228 } | 1239 } |
| 1229 | 1240 |
| 1230 bool Textfield::IsCommandIdEnabled(int command_id) const { | 1241 bool Textfield::IsCommandIdEnabled(int command_id) const { |
| 1231 base::string16 result; | 1242 return IsMenuCommand(command_id) && |
| 1232 bool editable = !read_only(); | 1243 Textfield::IsEditCommandEnabled(command_id); |
| 1233 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD; | |
| 1234 switch (command_id) { | |
| 1235 case IDS_APP_UNDO: | |
| 1236 return editable && model_->CanUndo(); | |
| 1237 case IDS_APP_REDO: | |
| 1238 return editable && model_->CanRedo(); | |
| 1239 case IDS_APP_CUT: | |
| 1240 return editable && readable && model_->HasSelection(); | |
| 1241 case IDS_APP_COPY: | |
| 1242 return readable && model_->HasSelection(); | |
| 1243 case IDS_APP_PASTE: | |
| 1244 ui::Clipboard::GetForCurrentThread()->ReadText( | |
| 1245 ui::CLIPBOARD_TYPE_COPY_PASTE, &result); | |
| 1246 return editable && !result.empty(); | |
| 1247 case IDS_APP_DELETE: | |
| 1248 return editable && model_->HasSelection(); | |
| 1249 case IDS_APP_SELECT_ALL: | |
| 1250 return !text().empty(); | |
| 1251 case IDS_DELETE_FORWARD: | |
| 1252 case IDS_DELETE_BACKWARD: | |
| 1253 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1254 case IDS_DELETE_TO_END_OF_LINE: | |
| 1255 case IDS_DELETE_WORD_BACKWARD: | |
| 1256 case IDS_DELETE_WORD_FORWARD: | |
| 1257 return editable; | |
| 1258 case IDS_MOVE_LEFT: | |
| 1259 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1260 case IDS_MOVE_RIGHT: | |
| 1261 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1262 case IDS_MOVE_WORD_LEFT: | |
| 1263 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1264 case IDS_MOVE_WORD_RIGHT: | |
| 1265 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1266 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1267 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1268 case IDS_MOVE_TO_END_OF_LINE: | |
| 1269 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1270 return true; | |
| 1271 default: | |
| 1272 return false; | |
| 1273 } | |
| 1274 } | 1244 } |
| 1275 | 1245 |
| 1276 bool Textfield::GetAcceleratorForCommandId(int command_id, | 1246 bool Textfield::GetAcceleratorForCommandId(int command_id, |
| 1277 ui::Accelerator* accelerator) { | 1247 ui::Accelerator* accelerator) { |
| 1278 switch (command_id) { | 1248 switch (command_id) { |
| 1279 case IDS_APP_UNDO: | 1249 case IDS_APP_UNDO: |
| 1280 *accelerator = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN); | 1250 *accelerator = ui::Accelerator(ui::VKEY_Z, ui::EF_CONTROL_DOWN); |
| 1281 return true; | 1251 return true; |
| 1282 | 1252 |
| 1283 case IDS_APP_CUT: | 1253 case IDS_APP_CUT: |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1296 *accelerator = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN); | 1266 *accelerator = ui::Accelerator(ui::VKEY_A, ui::EF_CONTROL_DOWN); |
| 1297 return true; | 1267 return true; |
| 1298 | 1268 |
| 1299 default: | 1269 default: |
| 1300 return false; | 1270 return false; |
| 1301 } | 1271 } |
| 1302 } | 1272 } |
| 1303 | 1273 |
| 1304 void Textfield::ExecuteCommand(int command_id, int event_flags) { | 1274 void Textfield::ExecuteCommand(int command_id, int event_flags) { |
| 1305 DestroyTouchSelection(); | 1275 DestroyTouchSelection(); |
| 1306 | 1276 if (!Textfield::IsCommandIdEnabled(command_id)) |
|
karandeepb
2016/06/09 10:47:10
This was a virtual call earlier. However doing Tex
msw
2016/06/10 00:07:50
Yeah, this is probably more correct; subclasses sh
msw
2016/06/10 00:07:50
optional nit: invert this check and inline the Exe
karandeepb
2016/06/10 05:52:36
Done.
| |
| 1307 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent | |
| 1308 // modifications of the command should happen here. | |
| 1309 if (HasSelection()) { | |
| 1310 switch (command_id) { | |
| 1311 case IDS_DELETE_WORD_BACKWARD: | |
| 1312 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1313 command_id = IDS_DELETE_BACKWARD; | |
| 1314 break; | |
| 1315 case IDS_DELETE_WORD_FORWARD: | |
| 1316 case IDS_DELETE_TO_END_OF_LINE: | |
| 1317 command_id = IDS_DELETE_FORWARD; | |
| 1318 break; | |
| 1319 } | |
| 1320 } | |
| 1321 | |
| 1322 if (!IsCommandIdEnabled(command_id)) | |
| 1323 return; | 1277 return; |
| 1324 | 1278 Textfield::ExecuteEditCommand(command_id); |
| 1325 bool text_changed = false; | |
| 1326 bool cursor_changed = false; | |
| 1327 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | |
| 1328 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT; | |
| 1329 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT; | |
| 1330 gfx::SelectionModel selection_model = GetSelectionModel(); | |
| 1331 | |
| 1332 OnBeforeUserAction(); | |
| 1333 switch (command_id) { | |
| 1334 case IDS_APP_UNDO: | |
| 1335 text_changed = cursor_changed = model_->Undo(); | |
| 1336 break; | |
| 1337 case IDS_APP_REDO: | |
| 1338 text_changed = cursor_changed = model_->Redo(); | |
| 1339 break; | |
| 1340 case IDS_APP_CUT: | |
| 1341 text_changed = cursor_changed = Cut(); | |
| 1342 break; | |
| 1343 case IDS_APP_COPY: | |
| 1344 Copy(); | |
| 1345 break; | |
| 1346 case IDS_APP_PASTE: | |
| 1347 text_changed = cursor_changed = Paste(); | |
| 1348 break; | |
| 1349 case IDS_APP_DELETE: | |
| 1350 text_changed = cursor_changed = model_->Delete(); | |
| 1351 break; | |
| 1352 case IDS_APP_SELECT_ALL: | |
| 1353 SelectAll(false); | |
| 1354 break; | |
| 1355 case IDS_DELETE_BACKWARD: | |
| 1356 text_changed = cursor_changed = model_->Backspace(); | |
| 1357 break; | |
| 1358 case IDS_DELETE_FORWARD: | |
| 1359 text_changed = cursor_changed = model_->Delete(); | |
| 1360 break; | |
| 1361 case IDS_DELETE_TO_END_OF_LINE: | |
| 1362 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1363 text_changed = cursor_changed = model_->Delete(); | |
| 1364 break; | |
| 1365 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1366 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1367 text_changed = cursor_changed = model_->Backspace(); | |
| 1368 break; | |
| 1369 case IDS_DELETE_WORD_BACKWARD: | |
| 1370 model_->MoveCursor(gfx::WORD_BREAK, begin, true); | |
| 1371 text_changed = cursor_changed = model_->Backspace(); | |
| 1372 break; | |
| 1373 case IDS_DELETE_WORD_FORWARD: | |
| 1374 model_->MoveCursor(gfx::WORD_BREAK, end, true); | |
| 1375 text_changed = cursor_changed = model_->Delete(); | |
| 1376 break; | |
| 1377 case IDS_MOVE_LEFT: | |
| 1378 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false); | |
| 1379 break; | |
| 1380 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1381 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true); | |
| 1382 break; | |
| 1383 case IDS_MOVE_RIGHT: | |
| 1384 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1385 break; | |
| 1386 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1387 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1388 break; | |
| 1389 case IDS_MOVE_WORD_LEFT: | |
| 1390 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false); | |
| 1391 break; | |
| 1392 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1393 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true); | |
| 1394 break; | |
| 1395 case IDS_MOVE_WORD_RIGHT: | |
| 1396 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1397 break; | |
| 1398 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1399 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1400 break; | |
| 1401 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1402 model_->MoveCursor(gfx::LINE_BREAK, begin, false); | |
| 1403 break; | |
| 1404 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1405 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1406 break; | |
| 1407 case IDS_MOVE_TO_END_OF_LINE: | |
| 1408 model_->MoveCursor(gfx::LINE_BREAK, end, false); | |
| 1409 break; | |
| 1410 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1411 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1412 break; | |
| 1413 default: | |
| 1414 NOTREACHED(); | |
| 1415 break; | |
| 1416 } | |
| 1417 | |
| 1418 cursor_changed |= GetSelectionModel() != selection_model; | |
| 1419 if (cursor_changed) | |
| 1420 UpdateSelectionClipboard(); | |
| 1421 UpdateAfterChange(text_changed, cursor_changed); | |
| 1422 OnAfterUserAction(); | |
| 1423 } | 1279 } |
| 1424 | 1280 |
| 1425 //////////////////////////////////////////////////////////////////////////////// | 1281 //////////////////////////////////////////////////////////////////////////////// |
| 1426 // Textfield, ui::TextInputClient overrides: | 1282 // Textfield, ui::TextInputClient overrides: |
| 1427 | 1283 |
| 1428 void Textfield::SetCompositionText(const ui::CompositionText& composition) { | 1284 void Textfield::SetCompositionText(const ui::CompositionText& composition) { |
| 1429 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) | 1285 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) |
| 1430 return; | 1286 return; |
| 1431 | 1287 |
| 1432 OnBeforeUserAction(); | 1288 OnBeforeUserAction(); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1635 range.set_start(range.start() - before); | 1491 range.set_start(range.start() - before); |
| 1636 range.set_end(range.end() + after); | 1492 range.set_end(range.end() + after); |
| 1637 gfx::Range text_range; | 1493 gfx::Range text_range; |
| 1638 if (GetTextRange(&text_range) && text_range.Contains(range)) | 1494 if (GetTextRange(&text_range) && text_range.Contains(range)) |
| 1639 DeleteRange(range); | 1495 DeleteRange(range); |
| 1640 } | 1496 } |
| 1641 | 1497 |
| 1642 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {} | 1498 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {} |
| 1643 | 1499 |
| 1644 bool Textfield::IsEditCommandEnabled(int command_id) const { | 1500 bool Textfield::IsEditCommandEnabled(int command_id) const { |
| 1645 return IsCommandIdEnabled(command_id); | 1501 base::string16 result; |
| 1502 bool editable = !read_only(); | |
| 1503 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD; | |
| 1504 switch (command_id) { | |
| 1505 case IDS_APP_UNDO: | |
| 1506 return editable && model_->CanUndo(); | |
| 1507 case IDS_APP_REDO: | |
| 1508 return editable && model_->CanRedo(); | |
| 1509 case IDS_APP_CUT: | |
| 1510 return editable && readable && model_->HasSelection(); | |
| 1511 case IDS_APP_COPY: | |
| 1512 return readable && model_->HasSelection(); | |
| 1513 case IDS_APP_PASTE: | |
| 1514 ui::Clipboard::GetForCurrentThread()->ReadText( | |
| 1515 ui::CLIPBOARD_TYPE_COPY_PASTE, &result); | |
| 1516 return editable && !result.empty(); | |
| 1517 case IDS_APP_DELETE: | |
| 1518 return editable && model_->HasSelection(); | |
| 1519 case IDS_APP_SELECT_ALL: | |
| 1520 return !text().empty(); | |
| 1521 case IDS_DELETE_FORWARD: | |
| 1522 case IDS_DELETE_BACKWARD: | |
| 1523 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1524 case IDS_DELETE_TO_END_OF_LINE: | |
| 1525 case IDS_DELETE_WORD_BACKWARD: | |
| 1526 case IDS_DELETE_WORD_FORWARD: | |
| 1527 return editable; | |
| 1528 case IDS_MOVE_LEFT: | |
| 1529 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1530 case IDS_MOVE_RIGHT: | |
| 1531 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1532 case IDS_MOVE_WORD_LEFT: | |
| 1533 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1534 case IDS_MOVE_WORD_RIGHT: | |
| 1535 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1536 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1537 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1538 case IDS_MOVE_TO_END_OF_LINE: | |
| 1539 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1540 return true; | |
| 1541 default: | |
| 1542 return false; | |
| 1543 } | |
| 1646 } | 1544 } |
| 1647 | 1545 |
| 1648 void Textfield::SetEditCommandForNextKeyEvent(int command_id) { | 1546 void Textfield::SetEditCommandForNextKeyEvent(int command_id) { |
| 1649 DCHECK_EQ(kNoCommand, scheduled_edit_command_); | 1547 DCHECK_EQ(kNoCommand, scheduled_edit_command_); |
| 1650 scheduled_edit_command_ = command_id; | 1548 scheduled_edit_command_ = command_id; |
| 1651 } | 1549 } |
| 1652 | 1550 |
| 1653 //////////////////////////////////////////////////////////////////////////////// | 1551 //////////////////////////////////////////////////////////////////////////////// |
| 1654 // Textfield, protected: | 1552 // Textfield, protected: |
| 1655 | 1553 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1670 return model_->render_text(); | 1568 return model_->render_text(); |
| 1671 } | 1569 } |
| 1672 | 1570 |
| 1673 base::string16 Textfield::GetSelectionClipboardText() const { | 1571 base::string16 Textfield::GetSelectionClipboardText() const { |
| 1674 base::string16 selection_clipboard_text; | 1572 base::string16 selection_clipboard_text; |
| 1675 ui::Clipboard::GetForCurrentThread()->ReadText( | 1573 ui::Clipboard::GetForCurrentThread()->ReadText( |
| 1676 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); | 1574 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); |
| 1677 return selection_clipboard_text; | 1575 return selection_clipboard_text; |
| 1678 } | 1576 } |
| 1679 | 1577 |
| 1578 void Textfield::ExecuteEditCommand(int command_id) { | |
| 1579 DestroyTouchSelection(); | |
| 1580 | |
| 1581 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent | |
| 1582 // modifications of the command should happen here. | |
| 1583 if (HasSelection()) { | |
| 1584 switch (command_id) { | |
| 1585 case IDS_DELETE_WORD_BACKWARD: | |
| 1586 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1587 command_id = IDS_DELETE_BACKWARD; | |
| 1588 break; | |
| 1589 case IDS_DELETE_WORD_FORWARD: | |
| 1590 case IDS_DELETE_TO_END_OF_LINE: | |
| 1591 command_id = IDS_DELETE_FORWARD; | |
| 1592 break; | |
| 1593 } | |
| 1594 } | |
| 1595 | |
| 1596 // We only execute the commands enabled in Textfield::IsEditCommandEnabled | |
| 1597 // below. Hence don't do a virtual IsEditCommandEnabled call. | |
| 1598 if (!Textfield::IsEditCommandEnabled(command_id)) | |
| 1599 return; | |
| 1600 | |
| 1601 bool text_changed = false; | |
| 1602 bool cursor_changed = false; | |
| 1603 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | |
| 1604 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT; | |
| 1605 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT; | |
| 1606 gfx::SelectionModel selection_model = GetSelectionModel(); | |
| 1607 | |
| 1608 OnBeforeUserAction(); | |
| 1609 switch (command_id) { | |
| 1610 case IDS_APP_UNDO: | |
| 1611 text_changed = cursor_changed = model_->Undo(); | |
| 1612 break; | |
| 1613 case IDS_APP_REDO: | |
| 1614 text_changed = cursor_changed = model_->Redo(); | |
| 1615 break; | |
| 1616 case IDS_APP_CUT: | |
| 1617 text_changed = cursor_changed = Cut(); | |
| 1618 break; | |
| 1619 case IDS_APP_COPY: | |
| 1620 Copy(); | |
| 1621 break; | |
| 1622 case IDS_APP_PASTE: | |
| 1623 text_changed = cursor_changed = Paste(); | |
| 1624 break; | |
| 1625 case IDS_APP_DELETE: | |
| 1626 text_changed = cursor_changed = model_->Delete(); | |
| 1627 break; | |
| 1628 case IDS_APP_SELECT_ALL: | |
| 1629 SelectAll(false); | |
| 1630 break; | |
| 1631 case IDS_DELETE_BACKWARD: | |
| 1632 text_changed = cursor_changed = model_->Backspace(); | |
| 1633 break; | |
| 1634 case IDS_DELETE_FORWARD: | |
| 1635 text_changed = cursor_changed = model_->Delete(); | |
| 1636 break; | |
| 1637 case IDS_DELETE_TO_END_OF_LINE: | |
| 1638 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1639 text_changed = cursor_changed = model_->Delete(); | |
| 1640 break; | |
| 1641 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1642 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1643 text_changed = cursor_changed = model_->Backspace(); | |
| 1644 break; | |
| 1645 case IDS_DELETE_WORD_BACKWARD: | |
| 1646 model_->MoveCursor(gfx::WORD_BREAK, begin, true); | |
| 1647 text_changed = cursor_changed = model_->Backspace(); | |
| 1648 break; | |
| 1649 case IDS_DELETE_WORD_FORWARD: | |
| 1650 model_->MoveCursor(gfx::WORD_BREAK, end, true); | |
| 1651 text_changed = cursor_changed = model_->Delete(); | |
| 1652 break; | |
| 1653 case IDS_MOVE_LEFT: | |
| 1654 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false); | |
| 1655 break; | |
| 1656 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1657 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true); | |
| 1658 break; | |
| 1659 case IDS_MOVE_RIGHT: | |
| 1660 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1661 break; | |
| 1662 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1663 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1664 break; | |
| 1665 case IDS_MOVE_WORD_LEFT: | |
| 1666 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false); | |
| 1667 break; | |
| 1668 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1669 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true); | |
| 1670 break; | |
| 1671 case IDS_MOVE_WORD_RIGHT: | |
| 1672 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1673 break; | |
| 1674 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1675 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1676 break; | |
| 1677 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1678 model_->MoveCursor(gfx::LINE_BREAK, begin, false); | |
| 1679 break; | |
| 1680 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1681 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1682 break; | |
| 1683 case IDS_MOVE_TO_END_OF_LINE: | |
| 1684 model_->MoveCursor(gfx::LINE_BREAK, end, false); | |
| 1685 break; | |
| 1686 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1687 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1688 break; | |
| 1689 default: | |
| 1690 NOTREACHED(); | |
| 1691 break; | |
| 1692 } | |
| 1693 | |
| 1694 cursor_changed |= GetSelectionModel() != selection_model; | |
| 1695 if (cursor_changed) | |
| 1696 UpdateSelectionClipboard(); | |
| 1697 UpdateAfterChange(text_changed, cursor_changed); | |
| 1698 OnAfterUserAction(); | |
| 1699 } | |
| 1700 | |
| 1680 //////////////////////////////////////////////////////////////////////////////// | 1701 //////////////////////////////////////////////////////////////////////////////// |
| 1681 // Textfield, private: | 1702 // Textfield, private: |
| 1682 | 1703 |
| 1683 void Textfield::AccessibilitySetValue(const base::string16& new_value) { | 1704 void Textfield::AccessibilitySetValue(const base::string16& new_value) { |
| 1684 if (!read_only()) { | 1705 if (!read_only()) { |
| 1685 SetText(new_value); | 1706 SetText(new_value); |
| 1686 ClearSelection(); | 1707 ClearSelection(); |
| 1687 } | 1708 } |
| 1688 } | 1709 } |
| 1689 | 1710 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1846 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); | 1867 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); |
| 1847 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO); | 1868 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO); |
| 1848 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); | 1869 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); |
| 1849 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); | 1870 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); |
| 1850 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); | 1871 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); |
| 1851 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); | 1872 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); |
| 1852 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); | 1873 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); |
| 1853 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); | 1874 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); |
| 1854 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, | 1875 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, |
| 1855 IDS_APP_SELECT_ALL); | 1876 IDS_APP_SELECT_ALL); |
| 1877 | |
| 1878 // If the controller adds menu commands, also override ExecuteCommand() and | |
| 1879 // IsCommandIdEnabled() as appropriate, for the commands added. | |
|
karandeepb
2016/06/09 10:47:10
It seems weird that the controller can update the
msw
2016/06/10 00:07:50
That's a good point. Making Textfield::UpdateConte
karandeepb
2016/06/10 05:52:36
WIll do this in a follow-up after this set of CLs
| |
| 1856 if (controller_) | 1880 if (controller_) |
| 1857 controller_->UpdateContextMenu(context_menu_contents_.get()); | 1881 controller_->UpdateContextMenu(context_menu_contents_.get()); |
| 1858 } | 1882 } |
| 1859 context_menu_runner_.reset( | 1883 context_menu_runner_.reset( |
| 1860 new MenuRunner(context_menu_contents_.get(), | 1884 new MenuRunner(context_menu_contents_.get(), |
| 1861 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU)); | 1885 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU)); |
| 1862 } | 1886 } |
| 1863 | 1887 |
| 1864 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) { | 1888 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) { |
| 1865 if (event.IsOnlyLeftMouseButton()) { | 1889 if (event.IsOnlyLeftMouseButton()) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1929 RequestFocus(); | 1953 RequestFocus(); |
| 1930 model_->MoveCursorTo(mouse); | 1954 model_->MoveCursorTo(mouse); |
| 1931 if (!selection_clipboard_text.empty()) { | 1955 if (!selection_clipboard_text.empty()) { |
| 1932 model_->InsertText(selection_clipboard_text); | 1956 model_->InsertText(selection_clipboard_text); |
| 1933 UpdateAfterChange(true, true); | 1957 UpdateAfterChange(true, true); |
| 1934 } | 1958 } |
| 1935 OnAfterUserAction(); | 1959 OnAfterUserAction(); |
| 1936 } | 1960 } |
| 1937 | 1961 |
| 1938 } // namespace views | 1962 } // namespace views |
| OLD | NEW |