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 |