Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Unified Diff: ui/views/controls/textfield/textfield_model.cc

Issue 2119813002: views::Textfield: Implement yank editing command. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address review comments. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 7c6d5917f209fdcfbc0b5bb6c1c71ad1622e0044..45ab2aae843a85969761497602c6596e4e4ea5dc 100644
--- a/ui/views/controls/textfield/textfield_model.cc
+++ b/ui/views/controls/textfield/textfield_model.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
@@ -263,6 +264,24 @@ gfx::Range GetFirstEmphasizedRange(const ui::CompositionText& composition) {
return gfx::Range::InvalidRange();
}
+// Returns a reference to the kill buffer which holds the text to be inserted on
+// executing yank command. 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& GetKillBuffer() {
sky 2016/07/22 15:22:49 return a pointer (references are generally restric
karandeepb 2016/07/25 06:38:11 Done.
+ CR_DEFINE_STATIC_LOCAL(base::string16, kill_buffer, ());
+ DCHECK(base::MessageLoopForUI::IsCurrent());
+ return kill_buffer;
+}
+
+// Helper method to set the kill buffer.
+void SetKillBuffer(const base::string16& buffer) {
+ base::string16& kill_buffer = GetKillBuffer();
+ kill_buffer = buffer;
+}
+
} // namespace
using internal::Edit;
@@ -325,13 +344,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)
+ SetKillBuffer(GetSelectedText());
DeleteSelection();
return true;
}
@@ -339,20 +360,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)
+ SetKillBuffer(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)
+ SetKillBuffer(GetSelectedText());
DeleteSelection();
return true;
}
@@ -360,7 +385,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);
msw 2016/07/22 17:44:03 optional nit: |previous_grapheme_index| for consis
karandeepb 2016/07/25 06:38:11 Done.
- ExecuteAndRecordDelete(gfx::Range(cursor_position, previous_char), true);
+ gfx::Range range_to_delete(cursor_position, previous_char);
+ if (add_to_kill_buffer)
+ SetKillBuffer(GetTextFromRange(range_to_delete));
+ ExecuteAndRecordDelete(range_to_delete, true);
return true;
}
return false;
@@ -557,6 +585,15 @@ bool TextfieldModel::Transpose() {
return true;
}
+bool TextfieldModel::Yank() {
+ const base::string16& kill_buffer = GetKillBuffer();
+ if (!kill_buffer.empty() || HasSelection()) {
msw 2016/07/22 17:44:03 Why would this try to insert an empty string if th
karandeepb 2016/07/25 06:38:11 That's how Yank works on Mac/Cocoa. Open a new Chr
msw 2016/07/25 18:35:49 Ah, so it's just doing a delete in that case? Okay
karandeepb 2016/07/26 03:45:41 Yeah!
+ InsertTextInternal(kill_buffer, false);
+ return true;
+ }
+ return false;
+}
+
bool TextfieldModel::HasSelection() const {
return !render_text_->selection().is_empty();
}
@@ -672,6 +709,11 @@ void TextfieldModel::ClearEditHistory() {
current_edit_ = edit_history_.end();
}
+// static
+void TextfieldModel::ClearKillBufferForTesting() {
+ SetKillBuffer(base::string16());
+}
+
/////////////////////////////////////////////////////////////////
// TextfieldModel: private

Powered by Google App Engine
This is Rietveld 408576698