| 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 |