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 // Don't render the underline for composition which is configured as |
msw
2015/03/26 20:22:48
nit: "Don't render transparent composition underli
Shu Chen
2015/03/30 03:56:21
Done.
| |
569 // transparent color. | |
570 if (composition.underlines.size() > 0 && composition.underlines[0].color != 0) | |
571 render_text_->SetCompositionRange(composition_range_); | |
572 else | |
573 render_text_->SetCompositionRange(gfx::Range::InvalidRange()); | |
569 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition); | 574 gfx::Range emphasized_range = GetFirstEmphasizedRange(composition); |
570 if (emphasized_range.IsValid()) { | 575 if (emphasized_range.IsValid()) { |
571 // This is a workaround due to the lack of support in RenderText to draw | 576 // 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 | 577 // a thick underline. In a composition returned from an IME, the segment |
573 // emphasized by a thick underline usually represents the target clause. | 578 // emphasized by a thick underline usually represents the target clause. |
574 // Because the target clause is more important than the actual selection | 579 // 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 | 580 // range (or caret position) in the composition here we use a selection-like |
576 // marker instead to show this range. | 581 // marker instead to show this range. |
577 // TODO(yukawa, msw): Support thick underlines and remove this workaround. | 582 // TODO(yukawa, msw): Support thick underlines and remove this workaround. |
578 render_text_->SelectRange(gfx::Range( | 583 render_text_->SelectRange(gfx::Range( |
579 cursor + emphasized_range.GetMin(), | 584 cursor + emphasized_range.GetMin(), |
580 cursor + emphasized_range.GetMax())); | 585 cursor + emphasized_range.GetMax())); |
581 } else if (!composition.selection.is_empty()) { | 586 } else if (!composition.selection.is_empty()) { |
582 render_text_->SelectRange(gfx::Range( | 587 render_text_->SelectRange(gfx::Range( |
583 cursor + composition.selection.GetMin(), | 588 cursor + composition.selection.GetMin(), |
584 cursor + composition.selection.GetMax())); | 589 cursor + composition.selection.GetMax())); |
585 } else { | 590 } else { |
586 render_text_->SetCursorPosition(cursor + composition.selection.end()); | 591 render_text_->SetCursorPosition(cursor + composition.selection.end()); |
587 } | 592 } |
588 } | 593 } |
589 | 594 |
590 void TextfieldModel::ConfirmCompositionText() { | 595 void TextfieldModel::ConfirmCompositionText() { |
591 DCHECK(HasCompositionText()); | 596 DCHECK(HasCompositionText()); |
592 gfx::Range range = render_text_->GetCompositionRange(); | 597 base::string16 composition = text().substr( |
593 base::string16 composition = text().substr(range.start(), range.length()); | 598 composition_range_.start(), composition_range_.length()); |
594 // TODO(oshima): current behavior on ChromeOS is a bit weird and not | 599 // 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. | 600 // sure exactly how this should work. Find out and fix if necessary. |
596 AddOrMergeEditHistory(new InsertEdit(false, composition, range.start())); | 601 AddOrMergeEditHistory( |
597 render_text_->SetCursorPosition(range.end()); | 602 new InsertEdit(false, composition, composition_range_.start())); |
603 render_text_->SetCursorPosition(composition_range_.end()); | |
598 ClearComposition(); | 604 ClearComposition(); |
599 if (delegate_) | 605 if (delegate_) |
600 delegate_->OnCompositionTextConfirmedOrCleared(); | 606 delegate_->OnCompositionTextConfirmedOrCleared(); |
601 } | 607 } |
602 | 608 |
603 void TextfieldModel::CancelCompositionText() { | 609 void TextfieldModel::CancelCompositionText() { |
604 DCHECK(HasCompositionText()); | 610 DCHECK(HasCompositionText()); |
605 gfx::Range range = render_text_->GetCompositionRange(); | 611 gfx::Range range = composition_range_; |
606 ClearComposition(); | 612 ClearComposition(); |
607 base::string16 new_text = text(); | 613 base::string16 new_text = text(); |
608 render_text_->SetText(new_text.erase(range.start(), range.length())); | 614 render_text_->SetText(new_text.erase(range.start(), range.length())); |
609 render_text_->SetCursorPosition(range.start()); | 615 render_text_->SetCursorPosition(range.start()); |
610 if (delegate_) | 616 if (delegate_) |
611 delegate_->OnCompositionTextConfirmedOrCleared(); | 617 delegate_->OnCompositionTextConfirmedOrCleared(); |
612 } | 618 } |
613 | 619 |
614 void TextfieldModel::ClearComposition() { | 620 void TextfieldModel::ClearComposition() { |
615 render_text_->SetCompositionRange(gfx::Range::InvalidRange()); | 621 composition_range_ = gfx::Range::InvalidRange(); |
622 render_text_->SetCompositionRange(composition_range_); | |
616 } | 623 } |
617 | 624 |
618 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const { | 625 void TextfieldModel::GetCompositionTextRange(gfx::Range* range) const { |
619 *range = gfx::Range(render_text_->GetCompositionRange()); | 626 *range = composition_range_; |
620 } | 627 } |
621 | 628 |
622 bool TextfieldModel::HasCompositionText() const { | 629 bool TextfieldModel::HasCompositionText() const { |
623 return !render_text_->GetCompositionRange().is_empty(); | 630 return !composition_range_.is_empty(); |
624 } | 631 } |
625 | 632 |
626 void TextfieldModel::ClearEditHistory() { | 633 void TextfieldModel::ClearEditHistory() { |
627 STLDeleteElements(&edit_history_); | 634 STLDeleteElements(&edit_history_); |
628 current_edit_ = edit_history_.end(); | 635 current_edit_ = edit_history_.end(); |
629 } | 636 } |
630 | 637 |
631 ///////////////////////////////////////////////////////////////// | 638 ///////////////////////////////////////////////////////////////// |
632 // TextfieldModel: private | 639 // TextfieldModel: private |
633 | 640 |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 ClearComposition(); | 767 ClearComposition(); |
761 if (delete_from != delete_to) | 768 if (delete_from != delete_to) |
762 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); | 769 render_text_->SetText(old_text.erase(delete_from, delete_to - delete_from)); |
763 if (!new_text.empty()) | 770 if (!new_text.empty()) |
764 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); | 771 render_text_->SetText(old_text.insert(new_text_insert_at, new_text)); |
765 render_text_->SetCursorPosition(new_cursor_pos); | 772 render_text_->SetCursorPosition(new_cursor_pos); |
766 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). | 773 // TODO(oshima): Select text that was just undone, like Mac (but not GTK). |
767 } | 774 } |
768 | 775 |
769 } // namespace views | 776 } // namespace views |
OLD | NEW |