| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/controls/textfield/textfield_views_model.h" | 5 #include "views/controls/textfield/textfield_views_model.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 render_text_->SetCursorPosition(new_cursor); | 313 render_text_->SetCursorPosition(new_cursor); |
| 314 } | 314 } |
| 315 ClearSelection(); | 315 ClearSelection(); |
| 316 return changed; | 316 return changed; |
| 317 } | 317 } |
| 318 | 318 |
| 319 void TextfieldViewsModel::Append(const string16& text) { | 319 void TextfieldViewsModel::Append(const string16& text) { |
| 320 if (HasCompositionText()) | 320 if (HasCompositionText()) |
| 321 ConfirmCompositionText(); | 321 ConfirmCompositionText(); |
| 322 size_t save = GetCursorPosition(); | 322 size_t save = GetCursorPosition(); |
| 323 MoveCursorRight(gfx::LINE_BREAK, false); | 323 if (render_text_->GetTextDirection() == base::i18n::LEFT_TO_RIGHT) |
| 324 MoveCursorRight(gfx::LINE_BREAK, false); |
| 325 else |
| 326 MoveCursorLeft(gfx::LINE_BREAK, false); |
| 324 InsertText(text); | 327 InsertText(text); |
| 325 render_text_->SetCursorPosition(save); | 328 render_text_->SetCursorPosition(save); |
| 326 ClearSelection(); | 329 ClearSelection(); |
| 327 } | 330 } |
| 328 | 331 |
| 329 bool TextfieldViewsModel::Delete() { | 332 bool TextfieldViewsModel::Delete() { |
| 330 if (HasCompositionText()) { | 333 if (HasCompositionText()) { |
| 331 // No undo/redo for composition text. | 334 // No undo/redo for composition text. |
| 332 CancelCompositionText(); | 335 CancelCompositionText(); |
| 333 return true; | 336 return true; |
| 334 } | 337 } |
| 335 if (HasSelection()) { | 338 if (HasSelection()) { |
| 336 DeleteSelection(); | 339 DeleteSelection(); |
| 337 return true; | 340 return true; |
| 338 } | 341 } |
| 339 if (GetText().length() > GetCursorPosition()) { | 342 if (GetText().length() > GetCursorPosition()) { |
| 340 size_t cursor_position = GetCursorPosition(); | 343 size_t cursor_position = GetCursorPosition(); |
| 341 ExecuteAndRecordDelete(cursor_position, cursor_position + 1, true); | 344 size_t next_grapheme_index = |
| 345 render_text_->GetIndexOfNextGrapheme(cursor_position); |
| 346 ExecuteAndRecordDelete(cursor_position, next_grapheme_index, true); |
| 342 return true; | 347 return true; |
| 343 } | 348 } |
| 344 return false; | 349 return false; |
| 345 } | 350 } |
| 346 | 351 |
| 347 bool TextfieldViewsModel::Backspace() { | 352 bool TextfieldViewsModel::Backspace() { |
| 348 if (HasCompositionText()) { | 353 if (HasCompositionText()) { |
| 349 // No undo/redo for composition text. | 354 // No undo/redo for composition text. |
| 350 CancelCompositionText(); | 355 CancelCompositionText(); |
| 351 return true; | 356 return true; |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 } | 654 } |
| 650 } | 655 } |
| 651 | 656 |
| 652 void TextfieldViewsModel::ReplaceTextInternal(const string16& text, | 657 void TextfieldViewsModel::ReplaceTextInternal(const string16& text, |
| 653 bool mergeable) { | 658 bool mergeable) { |
| 654 if (HasCompositionText()) { | 659 if (HasCompositionText()) { |
| 655 CancelCompositionText(); | 660 CancelCompositionText(); |
| 656 } else if (!HasSelection()) { | 661 } else if (!HasSelection()) { |
| 657 size_t cursor = GetCursorPosition(); | 662 size_t cursor = GetCursorPosition(); |
| 658 gfx::SelectionModel sel(render_text_->selection_model()); | 663 gfx::SelectionModel sel(render_text_->selection_model()); |
| 659 sel.set_selection_start(cursor + text.length()); | 664 sel.set_selection_start(render_text_->GetIndexOfNextGrapheme(cursor)); |
| 660 render_text_->MoveCursorTo(sel); | 665 render_text_->MoveCursorTo(sel); |
| 661 } | 666 } |
| 662 // Edit history is recorded in InsertText. | 667 // Edit history is recorded in InsertText. |
| 663 InsertTextInternal(text, mergeable); | 668 InsertTextInternal(text, mergeable); |
| 664 } | 669 } |
| 665 | 670 |
| 666 void TextfieldViewsModel::ClearEditHistory() { | 671 void TextfieldViewsModel::ClearEditHistory() { |
| 667 STLDeleteContainerPointers(edit_history_.begin(), | 672 STLDeleteContainerPointers(edit_history_.begin(), |
| 668 edit_history_.end()); | 673 edit_history_.end()); |
| 669 edit_history_.clear(); | 674 edit_history_.clear(); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 if (delete_from != delete_to) | 776 if (delete_from != delete_to) |
| 772 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); | 777 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); |
| 773 if (!new_text.empty()) | 778 if (!new_text.empty()) |
| 774 render_text_->SetText(text.insert(new_text_insert_at, new_text)); | 779 render_text_->SetText(text.insert(new_text_insert_at, new_text)); |
| 775 render_text_->SetCursorPosition(new_cursor_pos); | 780 render_text_->SetCursorPosition(new_cursor_pos); |
| 776 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). | 781 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). |
| 777 // This looks fine feature and we may want to do the same. | 782 // This looks fine feature and we may want to do the same. |
| 778 } | 783 } |
| 779 | 784 |
| 780 } // namespace views | 785 } // namespace views |
| OLD | NEW |