OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_model.h" | 5 #include "ui/views/controls/textfield/textfield_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 if (HasCompositionText()) | 434 if (HasCompositionText()) |
435 ConfirmCompositionText(); | 435 ConfirmCompositionText(); |
436 render_text_->ClearSelection(); | 436 render_text_->ClearSelection(); |
437 } | 437 } |
438 | 438 |
439 bool TextfieldModel::CanUndo() { | 439 bool TextfieldModel::CanUndo() { |
440 return edit_history_.size() && current_edit_ != edit_history_.end(); | 440 return edit_history_.size() && current_edit_ != edit_history_.end(); |
441 } | 441 } |
442 | 442 |
443 bool TextfieldModel::CanRedo() { | 443 bool TextfieldModel::CanRedo() { |
444 if (!edit_history_.size()) | 444 if (edit_history_.empty()) |
445 return false; | 445 return false; |
446 // There is no redo iff the current edit is the last element in the history. | 446 // There is no redo iff the current edit is the last element in the history. |
447 EditHistory::iterator iter = current_edit_; | 447 EditHistory::iterator iter = current_edit_; |
448 return iter == edit_history_.end() || // at the top. | 448 return iter == edit_history_.end() || // at the top. |
449 ++iter != edit_history_.end(); | 449 ++iter != edit_history_.end(); |
450 } | 450 } |
451 | 451 |
452 bool TextfieldModel::Undo() { | 452 bool TextfieldModel::Undo() { |
453 if (!CanUndo()) | 453 if (!CanUndo()) |
454 return false; | 454 return false; |
455 DCHECK(!HasCompositionText()); | 455 DCHECK(!HasCompositionText()); |
456 if (HasCompositionText()) | 456 if (HasCompositionText()) |
457 CancelCompositionText(); | 457 CancelCompositionText(); |
458 | 458 |
459 base::string16 old = text(); | 459 base::string16 old = text(); |
460 size_t old_cursor = GetCursorPosition(); | 460 size_t old_cursor = GetCursorPosition(); |
461 (*current_edit_)->Commit(); | 461 (*current_edit_)->Commit(); |
462 (*current_edit_)->Undo(this); | 462 (*current_edit_)->Undo(this); |
463 | 463 |
464 if (current_edit_ == edit_history_.begin()) | 464 if (current_edit_ == edit_history_.begin()) |
465 current_edit_ = edit_history_.end(); | 465 current_edit_ = edit_history_.end(); |
466 else | 466 else |
467 current_edit_--; | 467 --current_edit_; |
468 return old != text() || old_cursor != GetCursorPosition(); | 468 return old != text() || old_cursor != GetCursorPosition(); |
469 } | 469 } |
470 | 470 |
471 bool TextfieldModel::Redo() { | 471 bool TextfieldModel::Redo() { |
472 if (!CanRedo()) | 472 if (!CanRedo()) |
473 return false; | 473 return false; |
474 DCHECK(!HasCompositionText()); | 474 DCHECK(!HasCompositionText()); |
475 if (HasCompositionText()) | 475 if (HasCompositionText()) |
476 CancelCompositionText(); | 476 CancelCompositionText(); |
477 | 477 |
478 if (current_edit_ == edit_history_.end()) | 478 if (current_edit_ == edit_history_.end()) |
479 current_edit_ = edit_history_.begin(); | 479 current_edit_ = edit_history_.begin(); |
480 else | 480 else |
481 current_edit_ ++; | 481 ++current_edit_; |
482 base::string16 old = text(); | 482 base::string16 old = text(); |
483 size_t old_cursor = GetCursorPosition(); | 483 size_t old_cursor = GetCursorPosition(); |
484 (*current_edit_)->Redo(this); | 484 (*current_edit_)->Redo(this); |
485 return old != text() || old_cursor != GetCursorPosition(); | 485 return old != text() || old_cursor != GetCursorPosition(); |
486 } | 486 } |
487 | 487 |
488 bool TextfieldModel::Cut() { | 488 bool TextfieldModel::Cut() { |
489 if (!HasCompositionText() && HasSelection() && !render_text_->obscured()) { | 489 if (!HasCompositionText() && HasSelection() && !render_text_->obscured()) { |
490 ui::ScopedClipboardWriter( | 490 ui::ScopedClipboardWriter( |
491 ui::CLIPBOARD_TYPE_COPY_PASTE).WriteText(GetSelectedText()); | 491 ui::CLIPBOARD_TYPE_COPY_PASTE).WriteText(GetSelectedText()); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 } | 709 } |
710 | 710 |
711 void TextfieldModel::ClearRedoHistory() { | 711 void TextfieldModel::ClearRedoHistory() { |
712 if (edit_history_.begin() == edit_history_.end()) | 712 if (edit_history_.begin() == edit_history_.end()) |
713 return; | 713 return; |
714 if (current_edit_ == edit_history_.end()) { | 714 if (current_edit_ == edit_history_.end()) { |
715 ClearEditHistory(); | 715 ClearEditHistory(); |
716 return; | 716 return; |
717 } | 717 } |
718 EditHistory::iterator delete_start = current_edit_; | 718 EditHistory::iterator delete_start = current_edit_; |
719 delete_start++; | 719 ++delete_start; |
720 STLDeleteContainerPointers(delete_start, edit_history_.end()); | 720 STLDeleteContainerPointers(delete_start, edit_history_.end()); |
721 edit_history_.erase(delete_start, edit_history_.end()); | 721 edit_history_.erase(delete_start, edit_history_.end()); |
722 } | 722 } |
723 | 723 |
724 void TextfieldModel::ExecuteAndRecordDelete(gfx::Range range, bool mergeable) { | 724 void TextfieldModel::ExecuteAndRecordDelete(gfx::Range range, bool mergeable) { |
725 size_t old_text_start = range.GetMin(); | 725 size_t old_text_start = range.GetMin(); |
726 const base::string16 old_text = text().substr(old_text_start, range.length()); | 726 const base::string16 old_text = text().substr(old_text_start, range.length()); |
727 bool backward = range.is_reversed(); | 727 bool backward = range.is_reversed(); |
728 Edit* edit = new DeleteEdit(mergeable, old_text, old_text_start, backward); | 728 Edit* edit = new DeleteEdit(mergeable, old_text, old_text_start, backward); |
729 bool delete_edit = AddOrMergeEditHistory(edit); | 729 bool delete_edit = AddOrMergeEditHistory(edit); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
782 // to the history, and return true to delete |edit| after redo. | 782 // to the history, and return true to delete |edit| after redo. |
783 return true; | 783 return true; |
784 } | 784 } |
785 edit_history_.push_back(edit); | 785 edit_history_.push_back(edit); |
786 if (current_edit_ == edit_history_.end()) { | 786 if (current_edit_ == edit_history_.end()) { |
787 // If there is no redoable edit, this is the 1st edit because RedoHistory | 787 // If there is no redoable edit, this is the 1st edit because RedoHistory |
788 // has been already deleted. | 788 // has been already deleted. |
789 DCHECK_EQ(1u, edit_history_.size()); | 789 DCHECK_EQ(1u, edit_history_.size()); |
790 current_edit_ = edit_history_.begin(); | 790 current_edit_ = edit_history_.begin(); |
791 } else { | 791 } else { |
792 current_edit_++; | 792 ++current_edit_; |
793 } | 793 } |
794 return false; | 794 return false; |
795 } | 795 } |
796 | 796 |
797 void TextfieldModel::ModifyText(size_t delete_from, | 797 void TextfieldModel::ModifyText(size_t delete_from, |
798 size_t delete_to, | 798 size_t delete_to, |
799 const base::string16& new_text, | 799 const base::string16& new_text, |
800 size_t new_text_insert_at, | 800 size_t new_text_insert_at, |
801 size_t new_cursor_pos) { | 801 size_t new_cursor_pos) { |
802 DCHECK_LE(delete_from, delete_to); | 802 DCHECK_LE(delete_from, delete_to); |
803 base::string16 old_text = text(); | 803 base::string16 old_text = text(); |
804 ClearComposition(); | 804 ClearComposition(); |
805 if (delete_from != delete_to) | 805 if (delete_from != delete_to) |
806 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); | 806 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); |
807 if (!new_text.empty()) | 807 if (!new_text.empty()) |
808 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); | 808 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); |
809 render_text_->SetCursorPosition(new_cursor_pos); | 809 render_text_->SetCursorPosition(new_cursor_pos); |
810 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). | 810 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). |
811 } | 811 } |
812 | 812 |
813 } // namespace views | 813 } // namespace views |
OLD | NEW |