Chromium Code Reviews| Index: ui/views/controls/textfield/textfield_model.cc |
| diff --git a/ui/views/controls/textfield/textfield_model.cc b/ui/views/controls/textfield/textfield_model.cc |
| index d5bec8b33248d549600280d137186bbcf8557850..b2ae001f4c3c862aa115a274595cdf2a384abe72 100644 |
| --- a/ui/views/controls/textfield/textfield_model.cc |
| +++ b/ui/views/controls/textfield/textfield_model.cc |
| @@ -251,6 +251,13 @@ class DeleteEdit : public Edit { |
| namespace { |
| +// Buffer containing the text to be inserted on executing yank command. This |
| +// is a singleton since it needs to be persisted across multiple textfields. |
| +// On Mac, the size of the kill ring (no. of buffers) is controlled by |
| +// NSTextKillRingSize, a text system default. However to keep things simple, |
| +// the default kill ring size of 1 (i.e. a single buffer) is assumed. |
| +base::string16 g_kill_buffer_; |
| + |
|
karandeepb
2016/07/01 05:49:16
Ideally this should persist across the whole app i
|
| // Returns the first segment that is visually emphasized. Usually it's used for |
| // representing the target clause (on Windows). Returns an invalid range if |
| // there is no such a range. |
| @@ -325,13 +332,15 @@ void TextfieldModel::Append(const base::string16& new_text) { |
| ClearSelection(); |
| } |
| -bool TextfieldModel::Delete() { |
| +bool TextfieldModel::Delete(bool add_to_kill_buffer) { |
| if (HasCompositionText()) { |
| // No undo/redo for composition text. |
| CancelCompositionText(); |
| return true; |
| } |
| if (HasSelection()) { |
| + if (add_to_kill_buffer) |
| + g_kill_buffer_ = GetSelectedText(); |
| DeleteSelection(); |
| return true; |
| } |
| @@ -339,20 +348,24 @@ bool TextfieldModel::Delete() { |
| size_t cursor_position = GetCursorPosition(); |
| size_t next_grapheme_index = render_text_->IndexOfAdjacentGrapheme( |
| cursor_position, gfx::CURSOR_FORWARD); |
| - ExecuteAndRecordDelete(gfx::Range(cursor_position, next_grapheme_index), |
| - true); |
| + gfx::Range range_to_delete(cursor_position, next_grapheme_index); |
| + if (add_to_kill_buffer) |
| + g_kill_buffer_ = GetTextFromRange(range_to_delete); |
| + ExecuteAndRecordDelete(range_to_delete, true); |
| return true; |
| } |
| return false; |
| } |
| -bool TextfieldModel::Backspace() { |
| +bool TextfieldModel::Backspace(bool add_to_kill_buffer) { |
| if (HasCompositionText()) { |
| // No undo/redo for composition text. |
| CancelCompositionText(); |
| return true; |
| } |
| if (HasSelection()) { |
| + if (add_to_kill_buffer) |
| + g_kill_buffer_ = GetSelectedText(); |
| DeleteSelection(); |
| return true; |
| } |
| @@ -360,7 +373,10 @@ bool TextfieldModel::Backspace() { |
| if (cursor_position > 0) { |
| // Delete one code point, which may be two UTF-16 words. |
| size_t previous_char = gfx::UTF16OffsetToIndex(text(), cursor_position, -1); |
| - ExecuteAndRecordDelete(gfx::Range(cursor_position, previous_char), true); |
| + gfx::Range range_to_delete(cursor_position, previous_char); |
| + if (add_to_kill_buffer) |
| + g_kill_buffer_ = GetTextFromRange(range_to_delete); |
| + ExecuteAndRecordDelete(range_to_delete, true); |
| return true; |
| } |
| return false; |
| @@ -527,6 +543,14 @@ bool TextfieldModel::Paste() { |
| return true; |
| } |
| +bool TextfieldModel::Yank() { |
| + if (!g_kill_buffer_.empty() || HasSelection()) { |
| + InsertTextInternal(g_kill_buffer_, false); |
| + return true; |
| + } |
| + return false; |
| +} |
| + |
| bool TextfieldModel::HasSelection() const { |
| return !render_text_->selection().is_empty(); |
| } |