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) && |
|
tapted
2016/06/09 04:10:03
I'm still dubious about the merit of the `IsMenuCo
karandeepb
2016/06/09 04:51:42
IsMenuCommand is replaced by ui::TextEditCommand G
tapted
2016/06/09 05:02:01
Gotcha - it makes a lot more sense with that conte
| |
| 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 11 matching lines...) Expand all Loading... | |
| 1295 case IDS_APP_SELECT_ALL: | 1265 case IDS_APP_SELECT_ALL: |
| 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 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent | |
| 1306 // modifications of the command should happen here. | |
| 1307 if (HasSelection()) { | |
| 1308 switch (command_id) { | |
| 1309 case IDS_DELETE_WORD_BACKWARD: | |
| 1310 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1311 command_id = IDS_DELETE_BACKWARD; | |
| 1312 break; | |
| 1313 case IDS_DELETE_WORD_FORWARD: | |
| 1314 case IDS_DELETE_TO_END_OF_LINE: | |
| 1315 command_id = IDS_DELETE_FORWARD; | |
| 1316 break; | |
| 1317 } | |
| 1318 } | |
| 1319 | |
| 1320 // We only execute the commands enabled in Textfield::IsCommandIdEnabled | |
| 1321 // below. Hence don't do a virtual IsCommandIdEnabled call. | |
| 1322 if (!Textfield::IsCommandIdEnabled(command_id)) | 1275 if (!Textfield::IsCommandIdEnabled(command_id)) |
| 1323 return; | 1276 return; |
| 1324 | 1277 Textfield::ExecuteEditCommand(command_id); |
| 1325 DestroyTouchSelection(); | |
| 1326 | |
| 1327 bool text_changed = false; | |
| 1328 bool cursor_changed = false; | |
| 1329 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | |
| 1330 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT; | |
| 1331 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT; | |
| 1332 gfx::SelectionModel selection_model = GetSelectionModel(); | |
| 1333 | |
| 1334 OnBeforeUserAction(); | |
| 1335 switch (command_id) { | |
| 1336 case IDS_APP_UNDO: | |
| 1337 text_changed = cursor_changed = model_->Undo(); | |
| 1338 break; | |
| 1339 case IDS_APP_REDO: | |
| 1340 text_changed = cursor_changed = model_->Redo(); | |
| 1341 break; | |
| 1342 case IDS_APP_CUT: | |
| 1343 text_changed = cursor_changed = Cut(); | |
| 1344 break; | |
| 1345 case IDS_APP_COPY: | |
| 1346 Copy(); | |
| 1347 break; | |
| 1348 case IDS_APP_PASTE: | |
| 1349 text_changed = cursor_changed = Paste(); | |
| 1350 break; | |
| 1351 case IDS_APP_DELETE: | |
| 1352 text_changed = cursor_changed = model_->Delete(); | |
| 1353 break; | |
| 1354 case IDS_APP_SELECT_ALL: | |
| 1355 SelectAll(false); | |
| 1356 break; | |
| 1357 case IDS_DELETE_BACKWARD: | |
| 1358 text_changed = cursor_changed = model_->Backspace(); | |
| 1359 break; | |
| 1360 case IDS_DELETE_FORWARD: | |
| 1361 text_changed = cursor_changed = model_->Delete(); | |
| 1362 break; | |
| 1363 case IDS_DELETE_TO_END_OF_LINE: | |
| 1364 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1365 text_changed = cursor_changed = model_->Delete(); | |
| 1366 break; | |
| 1367 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1368 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1369 text_changed = cursor_changed = model_->Backspace(); | |
| 1370 break; | |
| 1371 case IDS_DELETE_WORD_BACKWARD: | |
| 1372 model_->MoveCursor(gfx::WORD_BREAK, begin, true); | |
| 1373 text_changed = cursor_changed = model_->Backspace(); | |
| 1374 break; | |
| 1375 case IDS_DELETE_WORD_FORWARD: | |
| 1376 model_->MoveCursor(gfx::WORD_BREAK, end, true); | |
| 1377 text_changed = cursor_changed = model_->Delete(); | |
| 1378 break; | |
| 1379 case IDS_MOVE_LEFT: | |
| 1380 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false); | |
| 1381 break; | |
| 1382 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1383 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true); | |
| 1384 break; | |
| 1385 case IDS_MOVE_RIGHT: | |
| 1386 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1387 break; | |
| 1388 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1389 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1390 break; | |
| 1391 case IDS_MOVE_WORD_LEFT: | |
| 1392 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false); | |
| 1393 break; | |
| 1394 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1395 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true); | |
| 1396 break; | |
| 1397 case IDS_MOVE_WORD_RIGHT: | |
| 1398 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1399 break; | |
| 1400 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1401 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1402 break; | |
| 1403 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1404 model_->MoveCursor(gfx::LINE_BREAK, begin, false); | |
| 1405 break; | |
| 1406 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1407 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1408 break; | |
| 1409 case IDS_MOVE_TO_END_OF_LINE: | |
| 1410 model_->MoveCursor(gfx::LINE_BREAK, end, false); | |
| 1411 break; | |
| 1412 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1413 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1414 break; | |
| 1415 default: | |
| 1416 NOTREACHED(); | |
| 1417 break; | |
| 1418 } | |
| 1419 | |
| 1420 cursor_changed |= GetSelectionModel() != selection_model; | |
| 1421 if (cursor_changed) | |
| 1422 UpdateSelectionClipboard(); | |
| 1423 UpdateAfterChange(text_changed, cursor_changed); | |
| 1424 OnAfterUserAction(); | |
| 1425 } | 1278 } |
| 1426 | 1279 |
| 1427 //////////////////////////////////////////////////////////////////////////////// | 1280 //////////////////////////////////////////////////////////////////////////////// |
| 1428 // Textfield, ui::TextInputClient overrides: | 1281 // Textfield, ui::TextInputClient overrides: |
| 1429 | 1282 |
| 1430 void Textfield::SetCompositionText(const ui::CompositionText& composition) { | 1283 void Textfield::SetCompositionText(const ui::CompositionText& composition) { |
| 1431 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) | 1284 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE) |
| 1432 return; | 1285 return; |
| 1433 | 1286 |
| 1434 OnBeforeUserAction(); | 1287 OnBeforeUserAction(); |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1637 range.set_start(range.start() - before); | 1490 range.set_start(range.start() - before); |
| 1638 range.set_end(range.end() + after); | 1491 range.set_end(range.end() + after); |
| 1639 gfx::Range text_range; | 1492 gfx::Range text_range; |
| 1640 if (GetTextRange(&text_range) && text_range.Contains(range)) | 1493 if (GetTextRange(&text_range) && text_range.Contains(range)) |
| 1641 DeleteRange(range); | 1494 DeleteRange(range); |
| 1642 } | 1495 } |
| 1643 | 1496 |
| 1644 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {} | 1497 void Textfield::EnsureCaretInRect(const gfx::Rect& rect) {} |
| 1645 | 1498 |
| 1646 bool Textfield::IsEditCommandEnabled(int command_id) const { | 1499 bool Textfield::IsEditCommandEnabled(int command_id) const { |
| 1647 return IsCommandIdEnabled(command_id); | 1500 base::string16 result; |
| 1501 bool editable = !read_only(); | |
| 1502 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD; | |
| 1503 switch (command_id) { | |
| 1504 case IDS_APP_UNDO: | |
| 1505 return editable && model_->CanUndo(); | |
| 1506 case IDS_APP_REDO: | |
| 1507 return editable && model_->CanRedo(); | |
| 1508 case IDS_APP_CUT: | |
| 1509 return editable && readable && model_->HasSelection(); | |
| 1510 case IDS_APP_COPY: | |
| 1511 return readable && model_->HasSelection(); | |
| 1512 case IDS_APP_PASTE: | |
| 1513 ui::Clipboard::GetForCurrentThread()->ReadText( | |
| 1514 ui::CLIPBOARD_TYPE_COPY_PASTE, &result); | |
| 1515 return editable && !result.empty(); | |
| 1516 case IDS_APP_DELETE: | |
| 1517 return editable && model_->HasSelection(); | |
| 1518 case IDS_APP_SELECT_ALL: | |
| 1519 return !text().empty(); | |
| 1520 case IDS_DELETE_FORWARD: | |
| 1521 case IDS_DELETE_BACKWARD: | |
| 1522 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1523 case IDS_DELETE_TO_END_OF_LINE: | |
| 1524 case IDS_DELETE_WORD_BACKWARD: | |
| 1525 case IDS_DELETE_WORD_FORWARD: | |
| 1526 return editable; | |
| 1527 case IDS_MOVE_LEFT: | |
| 1528 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1529 case IDS_MOVE_RIGHT: | |
| 1530 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1531 case IDS_MOVE_WORD_LEFT: | |
| 1532 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1533 case IDS_MOVE_WORD_RIGHT: | |
| 1534 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1535 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1536 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1537 case IDS_MOVE_TO_END_OF_LINE: | |
| 1538 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1539 return true; | |
| 1540 default: | |
| 1541 return false; | |
| 1542 } | |
| 1648 } | 1543 } |
| 1649 | 1544 |
| 1650 void Textfield::SetEditCommandForNextKeyEvent(int command_id) { | 1545 void Textfield::SetEditCommandForNextKeyEvent(int command_id) { |
| 1651 DCHECK_EQ(kNoCommand, scheduled_edit_command_); | 1546 DCHECK_EQ(kNoCommand, scheduled_edit_command_); |
| 1652 scheduled_edit_command_ = command_id; | 1547 scheduled_edit_command_ = command_id; |
| 1653 } | 1548 } |
| 1654 | 1549 |
| 1655 //////////////////////////////////////////////////////////////////////////////// | 1550 //////////////////////////////////////////////////////////////////////////////// |
| 1656 // Textfield, protected: | 1551 // Textfield, protected: |
| 1657 | 1552 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1672 return model_->render_text(); | 1567 return model_->render_text(); |
| 1673 } | 1568 } |
| 1674 | 1569 |
| 1675 base::string16 Textfield::GetSelectionClipboardText() const { | 1570 base::string16 Textfield::GetSelectionClipboardText() const { |
| 1676 base::string16 selection_clipboard_text; | 1571 base::string16 selection_clipboard_text; |
| 1677 ui::Clipboard::GetForCurrentThread()->ReadText( | 1572 ui::Clipboard::GetForCurrentThread()->ReadText( |
| 1678 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); | 1573 ui::CLIPBOARD_TYPE_SELECTION, &selection_clipboard_text); |
| 1679 return selection_clipboard_text; | 1574 return selection_clipboard_text; |
| 1680 } | 1575 } |
| 1681 | 1576 |
| 1577 void Textfield::ExecuteEditCommand(int command_id) { | |
| 1578 // Some codepaths may bypass GetCommandForKeyEvent, so any selection-dependent | |
| 1579 // modifications of the command should happen here. | |
| 1580 if (HasSelection()) { | |
| 1581 switch (command_id) { | |
| 1582 case IDS_DELETE_WORD_BACKWARD: | |
| 1583 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1584 command_id = IDS_DELETE_BACKWARD; | |
| 1585 break; | |
| 1586 case IDS_DELETE_WORD_FORWARD: | |
| 1587 case IDS_DELETE_TO_END_OF_LINE: | |
| 1588 command_id = IDS_DELETE_FORWARD; | |
| 1589 break; | |
| 1590 } | |
| 1591 } | |
| 1592 | |
| 1593 // We only execute the commands enabled in Textfield::IsEditCommandEnabled | |
| 1594 // below. Hence don't do a virtual IsEditCommandEnabled call. | |
| 1595 if (!Textfield::IsEditCommandEnabled(command_id)) | |
| 1596 return; | |
| 1597 | |
| 1598 DestroyTouchSelection(); | |
| 1599 | |
| 1600 bool text_changed = false; | |
| 1601 bool cursor_changed = false; | |
| 1602 bool rtl = GetTextDirection() == base::i18n::RIGHT_TO_LEFT; | |
| 1603 gfx::VisualCursorDirection begin = rtl ? gfx::CURSOR_RIGHT : gfx::CURSOR_LEFT; | |
| 1604 gfx::VisualCursorDirection end = rtl ? gfx::CURSOR_LEFT : gfx::CURSOR_RIGHT; | |
| 1605 gfx::SelectionModel selection_model = GetSelectionModel(); | |
| 1606 | |
| 1607 OnBeforeUserAction(); | |
| 1608 switch (command_id) { | |
| 1609 case IDS_APP_UNDO: | |
| 1610 text_changed = cursor_changed = model_->Undo(); | |
| 1611 break; | |
| 1612 case IDS_APP_REDO: | |
| 1613 text_changed = cursor_changed = model_->Redo(); | |
| 1614 break; | |
| 1615 case IDS_APP_CUT: | |
| 1616 text_changed = cursor_changed = Cut(); | |
| 1617 break; | |
| 1618 case IDS_APP_COPY: | |
| 1619 Copy(); | |
| 1620 break; | |
| 1621 case IDS_APP_PASTE: | |
| 1622 text_changed = cursor_changed = Paste(); | |
| 1623 break; | |
| 1624 case IDS_APP_DELETE: | |
| 1625 text_changed = cursor_changed = model_->Delete(); | |
| 1626 break; | |
| 1627 case IDS_APP_SELECT_ALL: | |
| 1628 SelectAll(false); | |
| 1629 break; | |
| 1630 case IDS_DELETE_BACKWARD: | |
| 1631 text_changed = cursor_changed = model_->Backspace(); | |
| 1632 break; | |
| 1633 case IDS_DELETE_FORWARD: | |
| 1634 text_changed = cursor_changed = model_->Delete(); | |
| 1635 break; | |
| 1636 case IDS_DELETE_TO_END_OF_LINE: | |
| 1637 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1638 text_changed = cursor_changed = model_->Delete(); | |
| 1639 break; | |
| 1640 case IDS_DELETE_TO_BEGINNING_OF_LINE: | |
| 1641 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1642 text_changed = cursor_changed = model_->Backspace(); | |
| 1643 break; | |
| 1644 case IDS_DELETE_WORD_BACKWARD: | |
| 1645 model_->MoveCursor(gfx::WORD_BREAK, begin, true); | |
| 1646 text_changed = cursor_changed = model_->Backspace(); | |
| 1647 break; | |
| 1648 case IDS_DELETE_WORD_FORWARD: | |
| 1649 model_->MoveCursor(gfx::WORD_BREAK, end, true); | |
| 1650 text_changed = cursor_changed = model_->Delete(); | |
| 1651 break; | |
| 1652 case IDS_MOVE_LEFT: | |
| 1653 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, false); | |
| 1654 break; | |
| 1655 case IDS_MOVE_LEFT_AND_MODIFY_SELECTION: | |
| 1656 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_LEFT, true); | |
| 1657 break; | |
| 1658 case IDS_MOVE_RIGHT: | |
| 1659 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1660 break; | |
| 1661 case IDS_MOVE_RIGHT_AND_MODIFY_SELECTION: | |
| 1662 model_->MoveCursor(gfx::CHARACTER_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1663 break; | |
| 1664 case IDS_MOVE_WORD_LEFT: | |
| 1665 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, false); | |
| 1666 break; | |
| 1667 case IDS_MOVE_WORD_LEFT_AND_MODIFY_SELECTION: | |
| 1668 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_LEFT, true); | |
| 1669 break; | |
| 1670 case IDS_MOVE_WORD_RIGHT: | |
| 1671 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, false); | |
| 1672 break; | |
| 1673 case IDS_MOVE_WORD_RIGHT_AND_MODIFY_SELECTION: | |
| 1674 model_->MoveCursor(gfx::WORD_BREAK, gfx::CURSOR_RIGHT, true); | |
| 1675 break; | |
| 1676 case IDS_MOVE_TO_BEGINNING_OF_LINE: | |
| 1677 model_->MoveCursor(gfx::LINE_BREAK, begin, false); | |
| 1678 break; | |
| 1679 case IDS_MOVE_TO_BEGINNING_OF_LINE_AND_MODIFY_SELECTION: | |
| 1680 model_->MoveCursor(gfx::LINE_BREAK, begin, true); | |
| 1681 break; | |
| 1682 case IDS_MOVE_TO_END_OF_LINE: | |
| 1683 model_->MoveCursor(gfx::LINE_BREAK, end, false); | |
| 1684 break; | |
| 1685 case IDS_MOVE_TO_END_OF_LINE_AND_MODIFY_SELECTION: | |
| 1686 model_->MoveCursor(gfx::LINE_BREAK, end, true); | |
| 1687 break; | |
| 1688 default: | |
| 1689 NOTREACHED(); | |
| 1690 break; | |
| 1691 } | |
| 1692 | |
| 1693 cursor_changed |= GetSelectionModel() != selection_model; | |
| 1694 if (cursor_changed) | |
| 1695 UpdateSelectionClipboard(); | |
| 1696 UpdateAfterChange(text_changed, cursor_changed); | |
| 1697 OnAfterUserAction(); | |
| 1698 } | |
| 1699 | |
| 1682 //////////////////////////////////////////////////////////////////////////////// | 1700 //////////////////////////////////////////////////////////////////////////////// |
| 1683 // Textfield, private: | 1701 // Textfield, private: |
| 1684 | 1702 |
| 1685 void Textfield::AccessibilitySetValue(const base::string16& new_value) { | 1703 void Textfield::AccessibilitySetValue(const base::string16& new_value) { |
| 1686 if (!read_only()) { | 1704 if (!read_only()) { |
| 1687 SetText(new_value); | 1705 SetText(new_value); |
| 1688 ClearSelection(); | 1706 ClearSelection(); |
| 1689 } | 1707 } |
| 1690 } | 1708 } |
| 1691 | 1709 |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1848 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); | 1866 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); |
| 1849 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO); | 1867 context_menu_contents_->AddItemWithStringId(IDS_APP_UNDO, IDS_APP_UNDO); |
| 1850 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); | 1868 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); |
| 1851 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); | 1869 context_menu_contents_->AddItemWithStringId(IDS_APP_CUT, IDS_APP_CUT); |
| 1852 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); | 1870 context_menu_contents_->AddItemWithStringId(IDS_APP_COPY, IDS_APP_COPY); |
| 1853 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); | 1871 context_menu_contents_->AddItemWithStringId(IDS_APP_PASTE, IDS_APP_PASTE); |
| 1854 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); | 1872 context_menu_contents_->AddItemWithStringId(IDS_APP_DELETE, IDS_APP_DELETE); |
| 1855 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); | 1873 context_menu_contents_->AddSeparator(ui::NORMAL_SEPARATOR); |
| 1856 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, | 1874 context_menu_contents_->AddItemWithStringId(IDS_APP_SELECT_ALL, |
| 1857 IDS_APP_SELECT_ALL); | 1875 IDS_APP_SELECT_ALL); |
| 1876 | |
| 1877 // If the controller adds menu commands, also override ExecuteCommand() and | |
| 1878 // IsCommandIdEnabled() as appropriate, for the commands added. | |
|
tapted
2016/06/09 04:10:03
I don't think it makes sense for UpdateContextMenu
karandeepb
2016/06/09 04:51:43
Yeah, I agree. Will wait for owner's review on thi
| |
| 1858 if (controller_) | 1879 if (controller_) |
| 1859 controller_->UpdateContextMenu(context_menu_contents_.get()); | 1880 controller_->UpdateContextMenu(context_menu_contents_.get()); |
| 1860 } | 1881 } |
| 1861 context_menu_runner_.reset( | 1882 context_menu_runner_.reset( |
| 1862 new MenuRunner(context_menu_contents_.get(), | 1883 new MenuRunner(context_menu_contents_.get(), |
| 1863 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU)); | 1884 MenuRunner::HAS_MNEMONICS | MenuRunner::CONTEXT_MENU)); |
| 1864 } | 1885 } |
| 1865 | 1886 |
| 1866 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) { | 1887 void Textfield::TrackMouseClicks(const ui::MouseEvent& event) { |
| 1867 if (event.IsOnlyLeftMouseButton()) { | 1888 if (event.IsOnlyLeftMouseButton()) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1931 RequestFocus(); | 1952 RequestFocus(); |
| 1932 model_->MoveCursorTo(mouse); | 1953 model_->MoveCursorTo(mouse); |
| 1933 if (!selection_clipboard_text.empty()) { | 1954 if (!selection_clipboard_text.empty()) { |
| 1934 model_->InsertText(selection_clipboard_text); | 1955 model_->InsertText(selection_clipboard_text); |
| 1935 UpdateAfterChange(true, true); | 1956 UpdateAfterChange(true, true); |
| 1936 } | 1957 } |
| 1937 OnAfterUserAction(); | 1958 OnAfterUserAction(); |
| 1938 } | 1959 } |
| 1939 | 1960 |
| 1940 } // namespace views | 1961 } // namespace views |
| OLD | NEW |