OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_views_model.h" | 5 #include "ui/views/controls/textfield/textfield_views_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/i18n/break_iterator.h" | 9 #include "base/i18n/break_iterator.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/utf_offset_string_conversions.h" | |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "ui/base/clipboard/clipboard.h" | 14 #include "ui/base/clipboard/clipboard.h" |
14 #include "ui/base/clipboard/scoped_clipboard_writer.h" | 15 #include "ui/base/clipboard/scoped_clipboard_writer.h" |
15 #include "ui/base/range/range.h" | 16 #include "ui/base/range/range.h" |
16 #include "ui/gfx/canvas.h" | 17 #include "ui/gfx/canvas.h" |
17 #include "ui/gfx/font.h" | 18 #include "ui/gfx/font.h" |
18 #include "ui/gfx/render_text.h" | 19 #include "ui/gfx/render_text.h" |
19 #include "ui/views/controls/textfield/textfield.h" | 20 #include "ui/views/controls/textfield/textfield.h" |
20 #include "ui/views/views_delegate.h" | 21 #include "ui/views/views_delegate.h" |
21 | 22 |
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
354 bool TextfieldViewsModel::Backspace() { | 355 bool TextfieldViewsModel::Backspace() { |
355 if (HasCompositionText()) { | 356 if (HasCompositionText()) { |
356 // No undo/redo for composition text. | 357 // No undo/redo for composition text. |
357 CancelCompositionText(); | 358 CancelCompositionText(); |
358 return true; | 359 return true; |
359 } | 360 } |
360 if (HasSelection()) { | 361 if (HasSelection()) { |
361 DeleteSelection(); | 362 DeleteSelection(); |
362 return true; | 363 return true; |
363 } | 364 } |
364 if (GetCursorPosition() > 0) { | 365 size_t cursor_position = GetCursorPosition(); |
365 size_t cursor_position = GetCursorPosition(); | 366 if (cursor_position > 0) { |
366 ExecuteAndRecordDelete(cursor_position, cursor_position - 1, true); | 367 size_t previous_char = Utf16OffsetToIndex(GetText(), cursor_position, -1); |
msw
2012/03/01 22:48:54
Add a comment explaining why this must be done, pl
benrg
2012/03/02 00:06:08
Done.
| |
368 ExecuteAndRecordDelete(cursor_position, previous_char, true); | |
367 return true; | 369 return true; |
368 } | 370 } |
369 return false; | 371 return false; |
370 } | 372 } |
371 | 373 |
372 size_t TextfieldViewsModel::GetCursorPosition() const { | 374 size_t TextfieldViewsModel::GetCursorPosition() const { |
373 return render_text_->GetCursorPosition(); | 375 return render_text_->GetCursorPosition(); |
374 } | 376 } |
375 | 377 |
376 void TextfieldViewsModel::MoveCursor(gfx::BreakType break_type, | 378 void TextfieldViewsModel::MoveCursor(gfx::BreakType break_type, |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
491 current_edit_ = edit_history_.begin(); | 493 current_edit_ = edit_history_.begin(); |
492 else | 494 else |
493 current_edit_ ++; | 495 current_edit_ ++; |
494 string16 old = GetText(); | 496 string16 old = GetText(); |
495 size_t old_cursor = GetCursorPosition(); | 497 size_t old_cursor = GetCursorPosition(); |
496 (*current_edit_)->Redo(this); | 498 (*current_edit_)->Redo(this); |
497 return old != GetText() || old_cursor != GetCursorPosition(); | 499 return old != GetText() || old_cursor != GetCursorPosition(); |
498 } | 500 } |
499 | 501 |
500 bool TextfieldViewsModel::Cut() { | 502 bool TextfieldViewsModel::Cut() { |
501 if (!HasCompositionText() && HasSelection()) { | 503 if (!HasCompositionText() && HasSelection() && !render_text_->is_obscured()) { |
502 ui::ScopedClipboardWriter( | 504 ui::ScopedClipboardWriter( |
503 views::ViewsDelegate::views_delegate->GetClipboard(), | 505 views::ViewsDelegate::views_delegate->GetClipboard(), |
504 ui::Clipboard::BUFFER_STANDARD).WriteText(GetSelectedText()); | 506 ui::Clipboard::BUFFER_STANDARD).WriteText(GetSelectedText()); |
505 // A trick to let undo/redo handle cursor correctly. | 507 // A trick to let undo/redo handle cursor correctly. |
506 // Undoing CUT moves the cursor to the end of the change rather | 508 // Undoing CUT moves the cursor to the end of the change rather |
507 // than beginning, unlike Delete/Backspace. | 509 // than beginning, unlike Delete/Backspace. |
508 // TODO(oshima): Change Delete/Backspace to use DeleteSelection, | 510 // TODO(oshima): Change Delete/Backspace to use DeleteSelection, |
509 // update DeleteEdit and remove this trick. | 511 // update DeleteEdit and remove this trick. |
510 render_text_->SelectRange(ui::Range(render_text_->GetCursorPosition(), | 512 render_text_->SelectRange(ui::Range(render_text_->GetCursorPosition(), |
511 render_text_->GetSelectionStart())); | 513 render_text_->GetSelectionStart())); |
512 DeleteSelection(); | 514 DeleteSelection(); |
513 return true; | 515 return true; |
514 } | 516 } |
515 return false; | 517 return false; |
516 } | 518 } |
517 | 519 |
518 bool TextfieldViewsModel::Copy() { | 520 bool TextfieldViewsModel::Copy() { |
519 if (!HasCompositionText() && HasSelection()) { | 521 if (!HasCompositionText() && HasSelection() && !render_text_->is_obscured()) { |
520 ui::ScopedClipboardWriter( | 522 ui::ScopedClipboardWriter( |
521 views::ViewsDelegate::views_delegate->GetClipboard(), | 523 views::ViewsDelegate::views_delegate->GetClipboard(), |
522 ui::Clipboard::BUFFER_STANDARD).WriteText(GetSelectedText()); | 524 ui::Clipboard::BUFFER_STANDARD).WriteText(GetSelectedText()); |
523 return true; | 525 return true; |
524 } | 526 } |
525 return false; | 527 return false; |
526 } | 528 } |
527 | 529 |
528 bool TextfieldViewsModel::Paste() { | 530 bool TextfieldViewsModel::Paste() { |
529 string16 result; | 531 string16 result; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
776 if (delete_from != delete_to) | 778 if (delete_from != delete_to) |
777 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); | 779 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); |
778 if (!new_text.empty()) | 780 if (!new_text.empty()) |
779 render_text_->SetText(text.insert(new_text_insert_at, new_text)); | 781 render_text_->SetText(text.insert(new_text_insert_at, new_text)); |
780 render_text_->SetCursorPosition(new_cursor_pos); | 782 render_text_->SetCursorPosition(new_cursor_pos); |
781 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). | 783 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). |
782 // This looks fine feature and we may want to do the same. | 784 // This looks fine feature and we may want to do the same. |
783 } | 785 } |
784 | 786 |
785 } // namespace views | 787 } // namespace views |
OLD | NEW |