Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: views/controls/textfield/textfield_views_model.cc

Issue 8044004: Clean up of SelectionModel (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: add comment about 'next' in ReplaceTextInternal Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 if (HasCompositionText()) 383 if (HasCompositionText())
384 ConfirmCompositionText(); 384 ConfirmCompositionText();
385 render_text_->MoveCursorRight(break_type, select); 385 render_text_->MoveCursorRight(break_type, select);
386 } 386 }
387 387
388 bool TextfieldViewsModel::MoveCursorTo(const gfx::SelectionModel& selection) { 388 bool TextfieldViewsModel::MoveCursorTo(const gfx::SelectionModel& selection) {
389 if (HasCompositionText()) { 389 if (HasCompositionText()) {
390 ConfirmCompositionText(); 390 ConfirmCompositionText();
391 // ConfirmCompositionText() updates cursor position. Need to reflect it in 391 // ConfirmCompositionText() updates cursor position. Need to reflect it in
392 // the SelectionModel parameter of MoveCursorTo(). 392 // the SelectionModel parameter of MoveCursorTo().
393 gfx::SelectionModel sel(selection); 393 if (render_text_->GetSelectionStart() != selection.selection_end())
394 sel.set_selection_start(render_text_->GetSelectionStart()); 394 return render_text_->SelectRange(ui::Range(
395 render_text_->GetSelectionStart(), selection.selection_end()));
396 gfx::SelectionModel sel(selection.selection_end(),
397 selection.caret_pos(),
398 selection.caret_placement());
395 return render_text_->MoveCursorTo(sel); 399 return render_text_->MoveCursorTo(sel);
396 } 400 }
397 return render_text_->MoveCursorTo(selection); 401 return render_text_->MoveCursorTo(selection);
398 } 402 }
399 403
400 bool TextfieldViewsModel::MoveCursorTo(const gfx::Point& point, bool select) { 404 bool TextfieldViewsModel::MoveCursorTo(const gfx::Point& point, bool select) {
401 if (HasCompositionText()) 405 if (HasCompositionText())
402 ConfirmCompositionText(); 406 ConfirmCompositionText();
403 return render_text_->MoveCursorTo(point, select); 407 return render_text_->MoveCursorTo(point, select);
404 } 408 }
405 409
406 string16 TextfieldViewsModel::GetSelectedText() const { 410 string16 TextfieldViewsModel::GetSelectedText() const {
407 return GetText().substr(render_text_->MinOfSelection(), 411 return GetText().substr(render_text_->MinOfSelection(),
408 (render_text_->MaxOfSelection() - render_text_->MinOfSelection())); 412 (render_text_->MaxOfSelection() - render_text_->MinOfSelection()));
409 } 413 }
410 414
415 void TextfieldViewsModel::GetSelectedRange(ui::Range* range) const {
416 range->set_start(render_text_->GetSelectionStart());
417 range->set_end(render_text_->GetCursorPosition());
418 }
419
420 void TextfieldViewsModel::SelectRange(const ui::Range& range) {
421 if (HasCompositionText())
422 ConfirmCompositionText();
423 render_text_->SelectRange(range);
424 }
425
411 void TextfieldViewsModel::GetSelectionModel(gfx::SelectionModel* sel) const { 426 void TextfieldViewsModel::GetSelectionModel(gfx::SelectionModel* sel) const {
412 *sel = render_text_->selection_model(); 427 *sel = render_text_->selection_model();
413 } 428 }
414 429
415 void TextfieldViewsModel::SelectSelectionModel(const gfx::SelectionModel& sel) { 430 void TextfieldViewsModel::SelectSelectionModel(const gfx::SelectionModel& sel) {
416 if (HasCompositionText()) 431 if (HasCompositionText())
417 ConfirmCompositionText(); 432 ConfirmCompositionText();
418 render_text_->MoveCursorTo(sel); 433 render_text_->MoveCursorTo(sel);
419 } 434 }
420 435
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 507
493 bool TextfieldViewsModel::Cut() { 508 bool TextfieldViewsModel::Cut() {
494 if (!HasCompositionText() && HasSelection()) { 509 if (!HasCompositionText() && HasSelection()) {
495 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate 510 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate
496 ->GetClipboard()).WriteText(GetSelectedText()); 511 ->GetClipboard()).WriteText(GetSelectedText());
497 // A trick to let undo/redo handle cursor correctly. 512 // A trick to let undo/redo handle cursor correctly.
498 // Undoing CUT moves the cursor to the end of the change rather 513 // Undoing CUT moves the cursor to the end of the change rather
499 // than beginning, unlike Delete/Backspace. 514 // than beginning, unlike Delete/Backspace.
500 // TODO(oshima): Change Delete/Backspace to use DeleteSelection, 515 // TODO(oshima): Change Delete/Backspace to use DeleteSelection,
501 // update DeleteEdit and remove this trick. 516 // update DeleteEdit and remove this trick.
502 gfx::SelectionModel sel(render_text_->GetCursorPosition(), 517 render_text_->SelectRange(ui::Range(render_text_->GetCursorPosition(),
503 render_text_->GetSelectionStart(), 518 render_text_->GetSelectionStart()));
504 render_text_->GetSelectionStart(),
505 gfx::SelectionModel::LEADING);
506 render_text_->MoveCursorTo(sel);
507 DeleteSelection(); 519 DeleteSelection();
508 return true; 520 return true;
509 } 521 }
510 return false; 522 return false;
511 } 523 }
512 524
513 void TextfieldViewsModel::Copy() { 525 void TextfieldViewsModel::Copy() {
514 if (!HasCompositionText() && HasSelection()) { 526 if (!HasCompositionText() && HasSelection()) {
515 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate 527 ui::ScopedClipboardWriter(views::ViewsDelegate::views_delegate
516 ->GetClipboard()).WriteText(GetSelectedText()); 528 ->GetClipboard()).WriteText(GetSelectedText());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 render_text_->SetText(new_text.insert(cursor, composition.text)); 587 render_text_->SetText(new_text.insert(cursor, composition.text));
576 ui::Range range(cursor, cursor + composition.text.length()); 588 ui::Range range(cursor, cursor + composition.text.length());
577 render_text_->SetCompositionRange(range); 589 render_text_->SetCompositionRange(range);
578 // TODO(msw): Support multiple composition underline ranges. 590 // TODO(msw): Support multiple composition underline ranges.
579 591
580 if (composition.selection.IsValid()) { 592 if (composition.selection.IsValid()) {
581 size_t start = 593 size_t start =
582 std::min(range.start() + composition.selection.start(), range.end()); 594 std::min(range.start() + composition.selection.start(), range.end());
583 size_t end = 595 size_t end =
584 std::min(range.start() + composition.selection.end(), range.end()); 596 std::min(range.start() + composition.selection.end(), range.end());
585 gfx::SelectionModel sel(start, end); 597 render_text_->SelectRange(ui::Range(start, end));
586 render_text_->MoveCursorTo(sel);
587 } else { 598 } else {
588 render_text_->SetCursorPosition(range.end()); 599 render_text_->SetCursorPosition(range.end());
589 } 600 }
590 } 601 }
591 602
592 void TextfieldViewsModel::ConfirmCompositionText() { 603 void TextfieldViewsModel::ConfirmCompositionText() {
593 DCHECK(HasCompositionText()); 604 DCHECK(HasCompositionText());
594 ui::Range range = render_text_->GetCompositionRange(); 605 ui::Range range = render_text_->GetCompositionRange();
595 string16 text = GetText().substr(range.start(), range.length()); 606 string16 text = GetText().substr(range.start(), range.length());
596 // TODO(oshima): current behavior on ChromeOS is a bit weird and not 607 // TODO(oshima): current behavior on ChromeOS is a bit weird and not
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 ExecuteAndRecordInsert(text, mergeable); 658 ExecuteAndRecordInsert(text, mergeable);
648 } 659 }
649 } 660 }
650 661
651 void TextfieldViewsModel::ReplaceTextInternal(const string16& text, 662 void TextfieldViewsModel::ReplaceTextInternal(const string16& text,
652 bool mergeable) { 663 bool mergeable) {
653 if (HasCompositionText()) { 664 if (HasCompositionText()) {
654 CancelCompositionText(); 665 CancelCompositionText();
655 } else if (!HasSelection()) { 666 } else if (!HasSelection()) {
656 size_t cursor = GetCursorPosition(); 667 size_t cursor = GetCursorPosition();
657 gfx::SelectionModel sel(render_text_->selection_model()); 668 const gfx::SelectionModel& model = render_text_->selection_model();
658 sel.set_selection_start(render_text_->GetIndexOfNextGrapheme(cursor)); 669 // When there is no selection, the default is to replace the next grapheme
659 render_text_->MoveCursorTo(sel); 670 // with |text|. So, need to find the index of next grapheme first.
671 size_t next = render_text_->GetIndexOfNextGrapheme(cursor);
672 if (next == model.selection_end())
673 render_text_->MoveCursorTo(model);
674 else
675 render_text_->SelectRange(ui::Range(next, model.selection_end()));
660 } 676 }
661 // Edit history is recorded in InsertText. 677 // Edit history is recorded in InsertText.
662 InsertTextInternal(text, mergeable); 678 InsertTextInternal(text, mergeable);
663 } 679 }
664 680
665 void TextfieldViewsModel::ClearEditHistory() { 681 void TextfieldViewsModel::ClearEditHistory() {
666 STLDeleteContainerPointers(edit_history_.begin(), 682 STLDeleteContainerPointers(edit_history_.begin(),
667 edit_history_.end()); 683 edit_history_.end());
668 edit_history_.clear(); 684 edit_history_.clear();
669 current_edit_ = edit_history_.end(); 685 current_edit_ = edit_history_.end();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 if (delete_from != delete_to) 786 if (delete_from != delete_to)
771 render_text_->SetText(text.erase(delete_from, delete_to - delete_from)); 787 render_text_->SetText(text.erase(delete_from, delete_to - delete_from));
772 if (!new_text.empty()) 788 if (!new_text.empty())
773 render_text_->SetText(text.insert(new_text_insert_at, new_text)); 789 render_text_->SetText(text.insert(new_text_insert_at, new_text));
774 render_text_->SetCursorPosition(new_cursor_pos); 790 render_text_->SetCursorPosition(new_cursor_pos);
775 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't). 791 // TODO(oshima): mac selects the text that is just undone (but gtk doesn't).
776 // This looks fine feature and we may want to do the same. 792 // This looks fine feature and we may want to do the same.
777 } 793 }
778 794
779 } // namespace views 795 } // namespace views
OLDNEW
« no previous file with comments | « views/controls/textfield/textfield_views_model.h ('k') | views/controls/textfield/textfield_views_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698