OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "views/controls/textfield/textfield_views_model.h" | 5 #include "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" |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 } | 391 } |
392 return render_text_->MoveCursorTo(selection); | 392 return render_text_->MoveCursorTo(selection); |
393 } | 393 } |
394 | 394 |
395 bool TextfieldViewsModel::MoveCursorTo(const gfx::Point& point, bool select) { | 395 bool TextfieldViewsModel::MoveCursorTo(const gfx::Point& point, bool select) { |
396 if (HasCompositionText()) | 396 if (HasCompositionText()) |
397 ConfirmCompositionText(); | 397 ConfirmCompositionText(); |
398 return render_text_->MoveCursorTo(point, select); | 398 return render_text_->MoveCursorTo(point, select); |
399 } | 399 } |
400 | 400 |
401 std::vector<gfx::Rect> TextfieldViewsModel::GetSelectionBounds() const { | |
402 return render_text_->GetSubstringBounds(render_text_->GetSelectionStart(), | |
403 render_text_->GetCursorPosition()); | |
404 } | |
405 | |
406 string16 TextfieldViewsModel::GetSelectedText() const { | 401 string16 TextfieldViewsModel::GetSelectedText() const { |
407 return GetText().substr(render_text_->MinOfSelection(), | 402 return GetText().substr(render_text_->MinOfSelection(), |
408 (render_text_->MaxOfSelection() - render_text_->MinOfSelection())); | 403 (render_text_->MaxOfSelection() - render_text_->MinOfSelection())); |
409 } | 404 } |
410 | 405 |
411 void TextfieldViewsModel::GetSelectedRange(ui::Range* range) const { | 406 void TextfieldViewsModel::GetSelectedRange(ui::Range* range) const { |
412 range->set_start(render_text_->GetSelectionStart()); | 407 range->set_start(render_text_->GetSelectionStart()); |
413 range->set_end(render_text_->GetCursorPosition()); | 408 range->set_end(render_text_->GetCursorPosition()); |
414 } | 409 } |
415 | 410 |
416 void TextfieldViewsModel::SelectRange(const ui::Range& range) { | 411 void TextfieldViewsModel::SelectRange(const ui::Range& range) { |
417 gfx::SelectionModel selection(range.start(), range.end()); | 412 gfx::SelectionModel selection(range.start(), range.end()); |
418 SelectSelectionModel(selection); | 413 SelectSelectionModel(selection); |
419 } | 414 } |
420 | 415 |
421 void TextfieldViewsModel::SelectSelectionModel(const gfx::SelectionModel& sel) { | 416 void TextfieldViewsModel::SelectSelectionModel(const gfx::SelectionModel& sel) { |
422 if (HasCompositionText()) | 417 if (HasCompositionText()) |
423 ConfirmCompositionText(); | 418 ConfirmCompositionText(); |
424 render_text_->SetSelectionModel(sel); | 419 render_text_->MoveCursorTo(sel); |
425 } | 420 } |
426 | 421 |
427 void TextfieldViewsModel::SelectAll() { | 422 void TextfieldViewsModel::SelectAll() { |
428 if (HasCompositionText()) | 423 if (HasCompositionText()) |
429 ConfirmCompositionText(); | 424 ConfirmCompositionText(); |
430 render_text_->SelectAll(); | 425 render_text_->SelectAll(); |
431 } | 426 } |
432 | 427 |
433 void TextfieldViewsModel::SelectWord() { | 428 void TextfieldViewsModel::SelectWord() { |
434 if (HasCompositionText()) | 429 if (HasCompositionText()) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
502 ->GetClipboard()).WriteText(GetSelectedText()); | 497 ->GetClipboard()).WriteText(GetSelectedText()); |
503 // A trick to let undo/redo handle cursor correctly. | 498 // A trick to let undo/redo handle cursor correctly. |
504 // Undoing CUT moves the cursor to the end of the change rather | 499 // Undoing CUT moves the cursor to the end of the change rather |
505 // than beginning, unlike Delete/Backspace. | 500 // than beginning, unlike Delete/Backspace. |
506 // TODO(oshima): Change Delete/Backspace to use DeleteSelection, | 501 // TODO(oshima): Change Delete/Backspace to use DeleteSelection, |
507 // update DeleteEdit and remove this trick. | 502 // update DeleteEdit and remove this trick. |
508 gfx::SelectionModel sel(render_text_->GetCursorPosition(), | 503 gfx::SelectionModel sel(render_text_->GetCursorPosition(), |
509 render_text_->GetSelectionStart(), | 504 render_text_->GetSelectionStart(), |
510 render_text_->GetSelectionStart(), | 505 render_text_->GetSelectionStart(), |
511 gfx::SelectionModel::LEADING); | 506 gfx::SelectionModel::LEADING); |
512 render_text_->SetSelectionModel(sel); | 507 render_text_->MoveCursorTo(sel); |
513 DeleteSelection(); | 508 DeleteSelection(); |
514 return true; | 509 return true; |
515 } | 510 } |
516 return false; | 511 return false; |
517 } | 512 } |
518 | 513 |
519 void TextfieldViewsModel::Copy() { | 514 void TextfieldViewsModel::Copy() { |
520 if (!HasCompositionText() && HasSelection()) { | 515 if (!HasCompositionText() && HasSelection()) { |
521 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate | 516 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate |
522 ->GetClipboard()).WriteText(GetSelectedText()); | 517 ->GetClipboard()).WriteText(GetSelectedText()); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 ui::Range range(cursor, cursor + composition.text.length()); | 577 ui::Range range(cursor, cursor + composition.text.length()); |
583 render_text_->SetCompositionRange(range); | 578 render_text_->SetCompositionRange(range); |
584 // TODO(msw): Support multiple composition underline ranges. | 579 // TODO(msw): Support multiple composition underline ranges. |
585 | 580 |
586 if (composition.selection.IsValid()) { | 581 if (composition.selection.IsValid()) { |
587 size_t start = | 582 size_t start = |
588 std::min(range.start() + composition.selection.start(), range.end()); | 583 std::min(range.start() + composition.selection.start(), range.end()); |
589 size_t end = | 584 size_t end = |
590 std::min(range.start() + composition.selection.end(), range.end()); | 585 std::min(range.start() + composition.selection.end(), range.end()); |
591 gfx::SelectionModel sel(start, end); | 586 gfx::SelectionModel sel(start, end); |
592 render_text_->SetSelectionModel(sel); | 587 render_text_->MoveCursorTo(sel); |
593 } else { | 588 } else { |
594 render_text_->SetCursorPosition(range.end()); | 589 render_text_->SetCursorPosition(range.end()); |
595 } | 590 } |
596 } | 591 } |
597 | 592 |
598 void TextfieldViewsModel::ConfirmCompositionText() { | 593 void TextfieldViewsModel::ConfirmCompositionText() { |
599 DCHECK(HasCompositionText()); | 594 DCHECK(HasCompositionText()); |
600 ui::Range range = render_text_->GetCompositionRange(); | 595 ui::Range range = render_text_->GetCompositionRange(); |
601 string16 text = GetText().substr(range.start(), range.length()); | 596 string16 text = GetText().substr(range.start(), range.length()); |
602 // TODO(oshima): current behavior on ChromeOS is a bit weird and not | 597 // TODO(oshima): current behavior on ChromeOS is a bit weird and not |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 } | 650 } |
656 | 651 |
657 void TextfieldViewsModel::ReplaceTextInternal(const string16& text, | 652 void TextfieldViewsModel::ReplaceTextInternal(const string16& text, |
658 bool mergeable) { | 653 bool mergeable) { |
659 if (HasCompositionText()) { | 654 if (HasCompositionText()) { |
660 CancelCompositionText(); | 655 CancelCompositionText(); |
661 } else if (!HasSelection()) { | 656 } else if (!HasSelection()) { |
662 size_t cursor = GetCursorPosition(); | 657 size_t cursor = GetCursorPosition(); |
663 gfx::SelectionModel sel(render_text_->selection_model()); | 658 gfx::SelectionModel sel(render_text_->selection_model()); |
664 sel.set_selection_start(cursor + text.length()); | 659 sel.set_selection_start(cursor + text.length()); |
665 render_text_->SetSelectionModel(sel); | 660 render_text_->MoveCursorTo(sel); |
666 } | 661 } |
667 // Edit history is recorded in InsertText. | 662 // Edit history is recorded in InsertText. |
668 InsertTextInternal(text, mergeable); | 663 InsertTextInternal(text, mergeable); |
669 } | 664 } |
670 | 665 |
671 void TextfieldViewsModel::ClearEditHistory() { | 666 void TextfieldViewsModel::ClearEditHistory() { |
672 STLDeleteContainerPointers(edit_history_.begin(), | 667 STLDeleteContainerPointers(edit_history_.begin(), |
673 edit_history_.end()); | 668 edit_history_.end()); |
674 edit_history_.clear(); | 669 edit_history_.clear(); |
675 current_edit_ = edit_history_.end(); | 670 current_edit_ = edit_history_.end(); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
775 if (delete_from != delete_to) | 770 if (delete_from != delete_to) |
776 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); | 771 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); |
777 if (!new_text.empty()) | 772 if (!new_text.empty()) |
778 render_text_->SetText(text.insert(new_text_insert_at, new_text)); | 773 render_text_->SetText(text.insert(new_text_insert_at, new_text)); |
779 render_text_->SetCursorPosition(new_cursor_pos); | 774 render_text_->SetCursorPosition(new_cursor_pos); |
780 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). | 775 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). |
781 // This looks fine feature and we may want to do the same. | 776 // This looks fine feature and we may want to do the same. |
782 } | 777 } |
783 | 778 |
784 } // namespace views | 779 } // namespace views |
OLD | NEW |