summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvarunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-12 02:33:38 +0000
committervarunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-12 02:33:38 +0000
commit2689f76aca1f632b92fdd1d7be1b4bf06671aa36 (patch)
tree6e701af6c68d8996f0bce911f4e48d6d4c4e31ee
parent8f5e1aa2f31c69609e12f7030da4ff9da1ec1a23 (diff)
downloadchromium_src-2689f76aca1f632b92fdd1d7be1b4bf06671aa36.zip
chromium_src-2689f76aca1f632b92fdd1d7be1b4bf06671aa36.tar.gz
chromium_src-2689f76aca1f632b92fdd1d7be1b4bf06671aa36.tar.bz2
Implement clipboard features in views textfield.
BUG=none TEST=Added new test. Review URL: http://codereview.chromium.org/6004010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@71136 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--views/controls/textfield/native_textfield_views.cc12
-rw-r--r--views/controls/textfield/native_textfield_views.h1
-rw-r--r--views/controls/textfield/textfield_views_model.cc35
-rw-r--r--views/controls/textfield/textfield_views_model.h11
-rw-r--r--views/controls/textfield/textfield_views_model_unittest.cc59
-rw-r--r--views/test/test_views_delegate.h49
-rw-r--r--views/view_unittest.cc39
-rw-r--r--views/views.gyp1
8 files changed, 168 insertions, 39 deletions
diff --git a/views/controls/textfield/native_textfield_views.cc b/views/controls/textfield/native_textfield_views.cc
index 2a42c5a..923de0c 100644
--- a/views/controls/textfield/native_textfield_views.cc
+++ b/views/controls/textfield/native_textfield_views.cc
@@ -445,6 +445,18 @@ bool NativeTextfieldViews::HandleKeyEvent(const KeyEvent& key_event) {
cursor_changed = true;
}
break;
+ case app::VKEY_X:
+ if (control)
+ text_changed = model_->Cut();
+ break;
+ case app::VKEY_C:
+ if (control)
+ model_->Copy();
+ break;
+ case app::VKEY_V:
+ if (control)
+ text_changed = model_->Paste();
+ break;
case app::VKEY_RIGHT:
control ? model_->MoveCursorToNextWord(selection)
: model_->MoveCursorRight(selection);
diff --git a/views/controls/textfield/native_textfield_views.h b/views/controls/textfield/native_textfield_views.h
index f87c42a..b8b4e6e 100644
--- a/views/controls/textfield/native_textfield_views.h
+++ b/views/controls/textfield/native_textfield_views.h
@@ -26,7 +26,6 @@ class TextfieldViewsModel;
// No platform specific code is used.
// Following features are not yet supported.
// * BIDI
-// * Clipboard (Cut & Paste).
// * Context Menu.
// * IME/i18n support.
// * X selection (only if we want to support).
diff --git a/views/controls/textfield/textfield_views_model.cc b/views/controls/textfield/textfield_views_model.cc
index 0f5b23b..7111ac2 100644
--- a/views/controls/textfield/textfield_views_model.cc
+++ b/views/controls/textfield/textfield_views_model.cc
@@ -10,6 +10,9 @@
#include "base/logging.h"
#include "base/utf_string_conversions.h"
#include "gfx/font.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
+#include "views/views_delegate.h"
namespace views {
@@ -225,6 +228,38 @@ void TextfieldViewsModel::ClearSelection() {
selection_begin_ = cursor_pos_;
}
+bool TextfieldViewsModel::Cut() {
+ if (HasSelection()) {
+ ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate
+ ->GetClipboard()).WriteText(GetSelectedText());
+ DeleteSelection();
+ return true;
+ }
+ return false;
+}
+
+void TextfieldViewsModel::Copy() {
+ if (HasSelection()) {
+ ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate
+ ->GetClipboard()).WriteText(GetSelectedText());
+ }
+}
+
+bool TextfieldViewsModel::Paste() {
+ string16 result;
+ views::ViewsDelegate::views_delegate->GetClipboard()
+ ->ReadText(ui::Clipboard::BUFFER_STANDARD, &result);
+ if (!result.empty()) {
+ if (HasSelection())
+ DeleteSelection();
+ text_.insert(cursor_pos_, result);
+ cursor_pos_ += result.length();
+ ClearSelection();
+ return true;
+ }
+ return false;
+}
+
bool TextfieldViewsModel::HasSelection() const {
return selection_begin_ != cursor_pos_;
}
diff --git a/views/controls/textfield/textfield_views_model.h b/views/controls/textfield/textfield_views_model.h
index 219a8c7..c1fa375 100644
--- a/views/controls/textfield/textfield_views_model.h
+++ b/views/controls/textfield/textfield_views_model.h
@@ -126,6 +126,17 @@ class TextfieldViewsModel {
return GetVisibleText(0U, text_.length());
}
+ // Cuts the currently selected text and puts it to clipboard. Returns true
+ // if text has changed after cutting.
+ bool Cut();
+
+ // Copies the currently selected text and puts it to clipboard.
+ void Copy();
+
+ // Pastes text from the clipboard at current cursor position. Returns true
+ // if text has changed after pasting.
+ bool Paste();
+
private:
friend class NativeTextfieldViews;
diff --git a/views/controls/textfield/textfield_views_model_unittest.cc b/views/controls/textfield/textfield_views_model_unittest.cc
index fa09efa..388c8c3 100644
--- a/views/controls/textfield/textfield_views_model_unittest.cc
+++ b/views/controls/textfield/textfield_views_model_unittest.cc
@@ -2,9 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/message_loop.h"
+#include "base/scoped_ptr.h"
#include "base/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "ui/base/clipboard/scoped_clipboard_writer.h"
#include "views/controls/textfield/textfield_views_model.h"
+#include "views/test/test_views_delegate.h"
+#include "views/views_delegate.h"
namespace views {
@@ -282,4 +288,57 @@ TEST(TextfieldViewsModelTest, SetText) {
EXPECT_EQ(0U, model.cursor_pos());
}
+TEST(TextfieldViewsModelTest, Clipboard) {
+ views::ViewsDelegate::views_delegate = new TestViewsDelegate();
+ ui::Clipboard* clipboard
+ = views::ViewsDelegate::views_delegate->GetClipboard();
+ string16 initial_clipboard_text;
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &initial_clipboard_text);
+ string16 clipboard_text;
+ TextfieldViewsModel model;
+ model.Append(ASCIIToUTF16("HELLO WORLD"));
+ model.MoveCursorToEnd(false);
+
+ // Test for cut: Empty selection.
+ EXPECT_FALSE(model.Cut());
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text);
+ EXPECT_STR_EQ(UTF16ToUTF8(initial_clipboard_text), clipboard_text);
+ EXPECT_STR_EQ("HELLO WORLD", model.text());
+ EXPECT_EQ(11U, model.cursor_pos());
+
+ // Test for cut: Non-empty selection.
+ model.MoveCursorToPreviousWord(true);
+ EXPECT_TRUE(model.Cut());
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text);
+ EXPECT_STR_EQ("WORLD", clipboard_text);
+ EXPECT_STR_EQ("HELLO ", model.text());
+ EXPECT_EQ(6U, model.cursor_pos());
+
+ // Test for copy: Empty selection.
+ model.Copy();
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text);
+ EXPECT_STR_EQ("WORLD", clipboard_text);
+ EXPECT_STR_EQ("HELLO ", model.text());
+ EXPECT_EQ(6U, model.cursor_pos());
+
+ // Test for copy: Non-empty selection.
+ model.Append(ASCIIToUTF16("HELLO WORLD"));
+ model.SelectAll();
+ model.Copy();
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text);
+ EXPECT_STR_EQ("HELLO HELLO WORLD", clipboard_text);
+ EXPECT_STR_EQ("HELLO HELLO WORLD", model.text());
+ EXPECT_EQ(0U, model.cursor_pos());
+
+ // Test for paste.
+ model.ClearSelection();
+ model.MoveCursorToEnd(false);
+ model.MoveCursorToPreviousWord(true);
+ EXPECT_TRUE(model.Paste());
+ clipboard->ReadText(ui::Clipboard::BUFFER_STANDARD, &clipboard_text);
+ EXPECT_STR_EQ("HELLO HELLO WORLD", clipboard_text);
+ EXPECT_STR_EQ("HELLO HELLO HELLO HELLO WORLD", model.text());
+ EXPECT_EQ(29U, model.cursor_pos());
+}
+
} // namespace views
diff --git a/views/test/test_views_delegate.h b/views/test/test_views_delegate.h
new file mode 100644
index 0000000..7b379f8
--- /dev/null
+++ b/views/test/test_views_delegate.h
@@ -0,0 +1,49 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/scoped_ptr.h"
+#include "ui/base/clipboard/clipboard.h"
+#include "views/views_delegate.h"
+
+class TestViewsDelegate : public views::ViewsDelegate {
+ public:
+ TestViewsDelegate() {}
+ virtual ~TestViewsDelegate() {}
+
+ // Overridden from views::ViewsDelegate:
+ virtual ui::Clipboard* GetClipboard() const {
+ if (!clipboard_.get()) {
+ // Note that we need a MessageLoop for the next call to work.
+ clipboard_.reset(new ui::Clipboard);
+ }
+ return clipboard_.get();
+ }
+ virtual void SaveWindowPlacement(const std::wstring& window_name,
+ const gfx::Rect& bounds,
+ bool maximized) {
+ }
+ virtual bool GetSavedWindowBounds(const std::wstring& window_name,
+ gfx::Rect* bounds) const {
+ return false;
+ }
+ virtual bool GetSavedMaximizedState(const std::wstring& window_name,
+ bool* maximized) const {
+ return false;
+ }
+ virtual void NotifyAccessibilityEvent(
+ views::View* view, AccessibilityTypes::Event event_type) {}
+#if defined(OS_WIN)
+ virtual HICON GetDefaultWindowIcon() const {
+ return NULL;
+ }
+#endif
+ virtual void AddRef() {}
+ virtual void ReleaseRef() {}
+
+ private:
+ mutable scoped_ptr<ui::Clipboard> clipboard_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestViewsDelegate);
+};
+
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index f5d564d..d29af08 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -29,6 +29,7 @@
#if defined(OS_WIN)
#include "views/widget/widget_win.h"
#include "views/controls/button/native_button_win.h"
+#include "views/test/test_views_delegate.h"
#elif defined(OS_LINUX)
#include "views/widget/widget_gtk.h"
#include "views/window/window_gtk.h"
@@ -840,44 +841,6 @@ TEST_F(ViewTest, Textfield) {
}
#if defined(OS_WIN)
-class TestViewsDelegate : public views::ViewsDelegate {
- public:
- TestViewsDelegate() {}
- virtual ~TestViewsDelegate() {}
-
- // Overridden from views::ViewsDelegate:
- virtual ui::Clipboard* GetClipboard() const {
- if (!clipboard_.get()) {
- // Note that we need a MessageLoop for the next call to work.
- clipboard_.reset(new ui::Clipboard);
- }
- return clipboard_.get();
- }
- virtual void SaveWindowPlacement(const std::wstring& window_name,
- const gfx::Rect& bounds,
- bool maximized) {
- }
- virtual bool GetSavedWindowBounds(const std::wstring& window_name,
- gfx::Rect* bounds) const {
- return false;
- }
- virtual bool GetSavedMaximizedState(const std::wstring& window_name,
- bool* maximized) const {
- return false;
- }
- virtual void NotifyAccessibilityEvent(
- views::View* view, AccessibilityTypes::Event event_type) {}
- virtual HICON GetDefaultWindowIcon() const {
- return NULL;
- }
- virtual void AddRef() {}
- virtual void ReleaseRef() {}
-
- private:
- mutable scoped_ptr<ui::Clipboard> clipboard_;
-
- DISALLOW_COPY_AND_ASSIGN(TestViewsDelegate);
-};
// Tests that the Textfield view respond appropiately to cut/copy/paste.
TEST_F(ViewTest, TextfieldCutCopyPaste) {
diff --git a/views/views.gyp b/views/views.gyp
index 73f35e5..dee51e3 100644
--- a/views/views.gyp
+++ b/views/views.gyp
@@ -441,6 +441,7 @@
'focus/focus_manager_unittest.cc',
'grid_layout_unittest.cc',
'run_all_unittests.cc',
+ 'test/test_views_delegate.h',
'view_unittest.cc',
'<(SHARED_INTERMEDIATE_DIR)/app/app_resources/app_resources.rc',