OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_model.h" | 5 #include "ui/views/controls/textfield/textfield_model.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
557 CancelCompositionText(); | 557 CancelCompositionText(); |
558 else if (HasSelection()) | 558 else if (HasSelection()) |
559 DeleteSelection(); | 559 DeleteSelection(); |
560 | 560 |
561 if (composition.text.empty()) | 561 if (composition.text.empty()) |
562 return; | 562 return; |
563 | 563 |
564 size_t cursor = GetCursorPosition(); | 564 size_t cursor = GetCursorPosition(); |
565 base::string16 new_text = text(); | 565 base::string16 new_text = text(); |
566 render_text_->SetText(new_text.insert(cursor, composition.text)); | 566 render_text_->SetText(new_text.insert(cursor, composition.text)); |
567 gfx::Range range(cursor, cursor + composition.text.length()); | 567 composition_range_ = gfx::Range(cursor, cursor + composition.text.length()); |
568 render_text_->SetCompositionRange(range); | 568 if (composition.underlines.size() > 0 && composition.underlines[0].color != 0) |
msw
2015/03/24 20:19:01
nit: add a comment here to explain this behavior;
Shu Chen
2015/03/26 04:22:13
Done.
| |
569 render_text_->SetCompositionRange(composition_range_); | |
570 else | |
571 render_text_->SetCompositionRange(gfx::Range()); | |
569 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition); | 572 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition); |
570 if (emphasized_range.IsValid()) { | 573 if (emphasized_range.IsValid()) { |
571 // This is a workaround due to the lack of support in RenderText to draw | 574 // This is a workaround due to the lack of support in RenderText to draw |
572 // a thick underline. In a composition returned from an IME, the segment | 575 // a thick underline. In a composition returned from an IME, the segment |
573 // emphasized by a thick underline usually represents the target clause. | 576 // emphasized by a thick underline usually represents the target clause. |
574 // Because the target clause is more important than the actual selection | 577 // Because the target clause is more important than the actual selection |
575 // range (or caret position) in the composition here we use a selection-like | 578 // range (or caret position) in the composition here we use a selection-like |
576 // marker instead to show this range. | 579 // marker instead to show this range. |
577 // TODO(yukawa, msw): Support thick underlines and remove this workaround. | 580 // TODO(yukawa, msw): Support thick underlines and remove this workaround. |
578 render_text_->SelectRange(gfx::Range( | 581 render_text_->SelectRange(gfx::Range( |
579 cursor + emphasized_range.GetMin(), | 582 cursor + emphasized_range.GetMin(), |
580 cursor + emphasized_range.GetMax())); | 583 cursor + emphasized_range.GetMax())); |
581 } else if (!composition.selection.is_empty()) { | 584 } else if (!composition.selection.is_empty()) { |
582 render_text_->SelectRange(gfx::Range( | 585 render_text_->SelectRange(gfx::Range( |
583 cursor + composition.selection.GetMin(), | 586 cursor + composition.selection.GetMin(), |
584 cursor + composition.selection.GetMax())); | 587 cursor + composition.selection.GetMax())); |
585 } else { | 588 } else { |
586 render_text_->SetCursorPosition(cursor + composition.selection.end()); | 589 render_text_->SetCursorPosition(cursor + composition.selection.end()); |
587 } | 590 } |
588 } | 591 } |
589 | 592 |
590 void TextfieldModel::ConfirmCompositionText() { | 593 void TextfieldModel::ConfirmCompositionText() { |
591 DCHECK(HasCompositionText()); | 594 DCHECK(HasCompositionText()); |
592 gfx::Range range = render_text_->GetCompositionRange(); | 595 base::string16 composition = text().substr( |
593 base::string16 composition = text().substr(range.start(), range.length()); | 596 composition_range_.start(), composition_range_.length()); |
594 // 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 |
595 // sure exactly how this should work. Find out and fix if necessary. | 598 // sure exactly how this should work. Find out and fix if necessary. |
596 AddOrMergeEditHistory(new InsertEdit(false, composition, range.start())); | 599 AddOrMergeEditHistory( |
597 render_text_->SetCursorPosition(range.end()); | 600 new InsertEdit(false, composition, composition_range_.start())); |
601 render_text_->SetCursorPosition(composition_range_.end()); | |
598 ClearComposition(); | 602 ClearComposition(); |
599 if (delegate_) | 603 if (delegate_) |
600 delegate_->OnCompositionTextConfirmedOrCleared(); | 604 delegate_->OnCompositionTextConfirmedOrCleared(); |
601 } | 605 } |
602 | 606 |
603 void TextfieldModel::CancelCompositionText() { | 607 void TextfieldModel::CancelCompositionText() { |
604 DCHECK(HasCompositionText()); | 608 DCHECK(HasCompositionText()); |
605 gfx::Range range = render_text_->GetCompositionRange(); | |
606 ClearComposition(); | 609 ClearComposition(); |
607 base::string16 new_text = text(); | 610 base::string16 new_text = text(); |
608 render_text_->SetText(new_text.erase(range.start(), range.length())); | 611 render_text_->SetText(new_text.erase( |
609 render_text_->SetCursorPosition(range.start()); | 612 composition_range_.start(), composition_range_.length())); |
613 render_text_->SetCursorPosition(composition_range_.start()); | |
610 if (delegate_) | 614 if (delegate_) |
611 delegate_->OnCompositionTextConfirmedOrCleared(); | 615 delegate_->OnCompositionTextConfirmedOrCleared(); |
612 } | 616 } |
613 | 617 |
614 void TextfieldModel::ClearComposition() { | 618 void TextfieldModel::ClearComposition() { |
msw
2015/03/24 20:19:01
Shouldn't this also clear |composition_range_|?
Shu Chen
2015/03/26 04:22:13
Done.
| |
615 render_text_->SetCompositionRange(gfx::Range::InvalidRange()); | 619 render_text_->SetCompositionRange(gfx::Range::InvalidRange()); |
616 } | 620 } |
617 | 621 |
618 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const { | 622 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const { |
619 *range = gfx::Range(render_text_->GetCompositionRange()); | 623 *range = composition_range_; |
620 } | 624 } |
621 | 625 |
622 bool TextfieldModel::HasCompositionText() const { | 626 bool TextfieldModel::HasCompositionText() const { |
623 return !render_text_->GetCompositionRange().is_empty(); | 627 return !composition_range_.is_empty(); |
624 } | 628 } |
625 | 629 |
626 void TextfieldModel::ClearEditHistory() { | 630 void TextfieldModel::ClearEditHistory() { |
627 STLDeleteElements(&edit_history_); | 631 STLDeleteElements(&edit_history_); |
628 current_edit_ = edit_history_.end(); | 632 current_edit_ = edit_history_.end(); |
629 } | 633 } |
630 | 634 |
631 ///////////////////////////////////////////////////////////////// | 635 ///////////////////////////////////////////////////////////////// |
632 // TextfieldModel: private | 636 // TextfieldModel: private |
633 | 637 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 ClearComposition(); | 764 ClearComposition(); |
761 if (delete_from != delete_to) | 765 if (delete_from != delete_to) |
762 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); | 766 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); |
763 if (!new_text.empty()) | 767 if (!new_text.empty()) |
764 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); | 768 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); |
765 render_text_->SetCursorPosition(new_cursor_pos); | 769 render_text_->SetCursorPosition(new_cursor_pos); |
766 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). | 770 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). |
767 } | 771 } |
768 | 772 |
769 } // namespace views | 773 } // namespace views |
OLD | NEW |