diff options
author | varunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-12 02:33:38 +0000 |
---|---|---|
committer | varunjain@chromium.org <varunjain@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-01-12 02:33:38 +0000 |
commit | 2689f76aca1f632b92fdd1d7be1b4bf06671aa36 (patch) | |
tree | 6e701af6c68d8996f0bce911f4e48d6d4c4e31ee | |
parent | 8f5e1aa2f31c69609e12f7030da4ff9da1ec1a23 (diff) | |
download | chromium_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.cc | 12 | ||||
-rw-r--r-- | views/controls/textfield/native_textfield_views.h | 1 | ||||
-rw-r--r-- | views/controls/textfield/textfield_views_model.cc | 35 | ||||
-rw-r--r-- | views/controls/textfield/textfield_views_model.h | 11 | ||||
-rw-r--r-- | views/controls/textfield/textfield_views_model_unittest.cc | 59 | ||||
-rw-r--r-- | views/test/test_views_delegate.h | 49 | ||||
-rw-r--r-- | views/view_unittest.cc | 39 | ||||
-rw-r--r-- | views/views.gyp | 1 |
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', |